This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

timer accuracy

Hi,

I am using 

  • nRF52840
  • SDK 15.3.0
  • Keil IDE
  • The soft device is S140 
  • JLinkRTTViewer for debug

I am using app_timer to control the LED On time.

the app_timer works correctly without SD event.

However, when an SD event (e.g disconnect) occurs, the LED is turned on for a shorter time than the app_timer value.

Question 1

     Why does this happen?

     Is it because app_timer priority is lower than SD event?

Question 2

   Which timer should be used to be less affected by SD events?

Please advise.

Parents
  • Hi,

    Why does this happen?

    Is it because app_timer priority is lower than SD event?

    Yes. App timer it's software timers based on one hardware timer.

    Question 2

    Which timer should be used to be less affected by SD events?

    Another hardware timer with PPI for GPIOTE control. Yes, it is resource-intensive, but in this case you will not have problems managing the LED flashing. It will happen automatically without the participation of code and the kernel.

    Or for example, you can use the PWM module. At least 2 flashing modes can be arranged on it. But you need to spend a little time studying the documentation.

    Good luck

  • Hi, CheMax

    I want to have an exact timer that can be used in a program regardless of the sd event.

    Another hardware timer with PPI for GPIOTE control. Yes, it is resource-intensive, but in this case you will not have problems managing the LED flashing. It will happen automatically without the participation of code and the kernel.

    => I ask you for an example program or an additional explanation (documentation)

    Best regards,

  • Hi, Alex

    when working with a chip, I do not use the functions of working with peripherals from Nordic. That is, I use direct work with registers for certain reasons.
    I do not have a ready code for working with a regular LED, but, in principle, this code will cause the output to be inverted every second.

    #define LED_PIN     15
    #define LED_PORT    1
    #define LED_GPIOTE  4
    #define LED_PPI_CH  10
    
    
    // pin p1.15 (port 1 pin 15) as output without pull
    NRF_P1->PIN_CNF[LED_PIN] = ((GPIO_PIN_CNF_SENSE_Disabled   << GPIO_PIN_CNF_SENSE_Pos ) 
                                |(GPIO_PIN_CNF_DRIVE_S0S1       << GPIO_PIN_CNF_DRIVE_Pos ) 
                                |(GPIO_PIN_CNF_PULL_Disabled    << GPIO_PIN_CNF_PULL_Pos  ) 
                                |(GPIO_PIN_CNF_INPUT_Disconnect << GPIO_PIN_CNF_INPUT_Pos ) 
                                |(GPIO_PIN_CNF_DIR_Output       << GPIO_PIN_CNF_DIR_Pos   ));
    
    // gpiote configuration
    NRF_GPIOTE->CONFIG[LED_GPIOTE] = (GPIOTE_CONFIG_MODE_Task	<< GPIOTE_CONFIG_MODE_Pos)
                                   | (LED_PIN )				<< GPIOTE_CONFIG_PSEL_Pos)
                                   | (LED_PORT)				<< GPIOTE_CONFIG_PORT_Pos);
    
    // Timer 4 for example
    NRF_TIMER4->MODE       = TIMER_MODE_MODE_Timer<<TIMER_MODE_MODE_Pos;
    NRF_TIMER4->BITMODE    = TIMER_BITMODE_BITMODE_32Bit << TIMER_BITMODE_BITMODE_Pos;
    NRF_TIMER4->PRESCALER  = 0x09;
    NRF_TIMER4->CC[0]      = 31250/2; // 500 ms
    NRF_TIMER4->SHORTS     = TIMER_SHORTS_COMPARE0_CLEAR_Enabled << TIMER_SHORTS_COMPARE0_CLEAR_Pos;
    
    // Connect timer event to gpio toggle task
    NRF_PPI->CH[LED_PPI_CH].EEP = (uint32_t)&NRF_TIMER4->EVENTS_COMPARE[0];
    NRF_PPI->CH[LED_PPI_CH].TEP = (uint32_t)&NRF_GPIOTE->TASKS_OUT[LED_GPIOTE];
    
    // Run PPI channel
    NRF_PPI->CHEN |= 1 << LED_PPI_CH;
    // Run timer
    NRF_TIMER4->TASKS_START = 1;
    This is not the most beautiful and neat solution, but as a starting point it will go.

    Note: This code is placed in the main.c after after all functions ending in init:

    ble_stack_init();
    gap_params_init();
    gatt_init();
    services_init();
    advertising_init();
    conn_params_init();

    From the documentation, I use only the Product Specification(aka datasheet). Accordingly, sections for studying this: PPI, TIMER, GPIO, GPIOTE. 

    There is some text, but it needs to be understood. Without this, it will be difficult to use this chip at full power.

    P.S. maybe someone will add an example with standard functions?

    Good luck

Reply
  • Hi, Alex

    when working with a chip, I do not use the functions of working with peripherals from Nordic. That is, I use direct work with registers for certain reasons.
    I do not have a ready code for working with a regular LED, but, in principle, this code will cause the output to be inverted every second.

    #define LED_PIN     15
    #define LED_PORT    1
    #define LED_GPIOTE  4
    #define LED_PPI_CH  10
    
    
    // pin p1.15 (port 1 pin 15) as output without pull
    NRF_P1->PIN_CNF[LED_PIN] = ((GPIO_PIN_CNF_SENSE_Disabled   << GPIO_PIN_CNF_SENSE_Pos ) 
                                |(GPIO_PIN_CNF_DRIVE_S0S1       << GPIO_PIN_CNF_DRIVE_Pos ) 
                                |(GPIO_PIN_CNF_PULL_Disabled    << GPIO_PIN_CNF_PULL_Pos  ) 
                                |(GPIO_PIN_CNF_INPUT_Disconnect << GPIO_PIN_CNF_INPUT_Pos ) 
                                |(GPIO_PIN_CNF_DIR_Output       << GPIO_PIN_CNF_DIR_Pos   ));
    
    // gpiote configuration
    NRF_GPIOTE->CONFIG[LED_GPIOTE] = (GPIOTE_CONFIG_MODE_Task	<< GPIOTE_CONFIG_MODE_Pos)
                                   | (LED_PIN )				<< GPIOTE_CONFIG_PSEL_Pos)
                                   | (LED_PORT)				<< GPIOTE_CONFIG_PORT_Pos);
    
    // Timer 4 for example
    NRF_TIMER4->MODE       = TIMER_MODE_MODE_Timer<<TIMER_MODE_MODE_Pos;
    NRF_TIMER4->BITMODE    = TIMER_BITMODE_BITMODE_32Bit << TIMER_BITMODE_BITMODE_Pos;
    NRF_TIMER4->PRESCALER  = 0x09;
    NRF_TIMER4->CC[0]      = 31250/2; // 500 ms
    NRF_TIMER4->SHORTS     = TIMER_SHORTS_COMPARE0_CLEAR_Enabled << TIMER_SHORTS_COMPARE0_CLEAR_Pos;
    
    // Connect timer event to gpio toggle task
    NRF_PPI->CH[LED_PPI_CH].EEP = (uint32_t)&NRF_TIMER4->EVENTS_COMPARE[0];
    NRF_PPI->CH[LED_PPI_CH].TEP = (uint32_t)&NRF_GPIOTE->TASKS_OUT[LED_GPIOTE];
    
    // Run PPI channel
    NRF_PPI->CHEN |= 1 << LED_PPI_CH;
    // Run timer
    NRF_TIMER4->TASKS_START = 1;
    This is not the most beautiful and neat solution, but as a starting point it will go.

    Note: This code is placed in the main.c after after all functions ending in init:

    ble_stack_init();
    gap_params_init();
    gatt_init();
    services_init();
    advertising_init();
    conn_params_init();

    From the documentation, I use only the Product Specification(aka datasheet). Accordingly, sections for studying this: PPI, TIMER, GPIO, GPIOTE. 

    There is some text, but it needs to be understood. Without this, it will be difficult to use this chip at full power.

    P.S. maybe someone will add an example with standard functions?

    Good luck

Children
No Data
Related