timer4 accuracy

S in development environment :Windows7
HARD :(Taiyo Yuden)EBSHSN Series Evaluation Board : Central / Peripherals
CPU :(Nordic) nRF52832 / ARMR Cortex?-M4F 32 bit processor 28-pin Land Grid Array / 15GPIOs / SWD
Soft Ver:nRF5_SDK_15.2.0_9412b96
clock :RC transmission setting

I switched the terminal output to Low / Hi at 1-second intervals with two peripheral devices and checked whether the switching timing is synchronized,
but did not synchronize, please tell me how to synchronize

Thank you very much.

Parents
  • Hi,

    Assuming you have no problem with your SW implementation, the accuracy of the timer is given by the accuracy of the HF clock, which  is given by the clock source. If you use the internal RC oscillator (HFINT), the accuracy is at worst <±6 %. In other words very inaccurate, so you should always use the crystal oscillator (HFXO) when you need a decent accuracy. In that case the accuracy is given by the accuracy of the crystal you are using.

  • I switched from the CR oscillator (HFINT) to the 32.768 kHz crystal oscillator (HFXO) and checked the operation, but it was not synchronized.
    The contents of the timer settings will be attached, so please point out the mistake.
    Thank you very much.

    SAMPLE.c
    Source program excerpt on timer4 control
    ------------------------------------------------------------------------------------------
    << sdk_config.h (Excerpt of timer program) >>
    // <q> NRFX_TIMER4_ENABLED  - Enable TIMER4 instance
    #ifndef NRFX_TIMER4_ENABLED
    #define NRFX_TIMER4_ENABLED 0
    #endif
    
    // <o> TIMER_DEFAULT_CONFIG_IRQ_PRIORITY  - Interrupt priority
    // <i> Priorities 0,2 (nRF51) and 0,1,4,5 (nRF52) are reserved for SoftDevice
    // <0=> 0 (highest) 
    // <1=> 1 
    // <2=> 2 
    // <3=> 3 
    // <4=> 4 
    // <5=> 5 
    // <6=> 6 
    // <7=> 7 
    #ifndef TIMER_DEFAULT_CONFIG_IRQ_PRIORITY
    #define TIMER_DEFAULT_CONFIG_IRQ_PRIORITY 6
    #endif
    
    // <q> TIMER4_ENABLED  - Enable TIMER4 instance
    #ifndef TIMER4_ENABLED
    #define TIMER4_ENABLED 1
    #endif
    
    //==========================================================
    
    // <h> Clock - SoftDevice clock configuration
    
    //==========================================================
    // <o> NRF_SDH_CLOCK_LF_SRC  - SoftDevice clock source.
    // <0=> NRF_CLOCK_LF_SRC_RC 
    // <1=> NRF_CLOCK_LF_SRC_XTAL 
    // <2=> NRF_CLOCK_LF_SRC_SYNTH 
    #ifndef NRF_SDH_CLOCK_LF_SRC
    #define NRF_SDH_CLOCK_LF_SRC 1
    #endif
    
    // <o> NRF_SDH_CLOCK_LF_RC_CTIV - SoftDevice calibration timer interval. 
    #ifndef NRF_SDH_CLOCK_LF_RC_CTIV
    #define NRF_SDH_CLOCK_LF_RC_CTIV 0
    #endif
    
    // <o> NRF_SDH_CLOCK_LF_RC_TEMP_CTIV - SoftDevice calibration timer interval under constant temperature. 
    // <i> How often (in number of calibration intervals) the RC oscillator shall be calibrated
    // <i>  if the temperature has not changed.
    #ifndef NRF_SDH_CLOCK_LF_RC_TEMP_CTIV
    #define NRF_SDH_CLOCK_LF_RC_TEMP_CTIV 0
    #endif
    
    // <o> NRF_SDH_CLOCK_LF_ACCURACY  - External clock accuracy used in the LL to compute timing.
    // <0=> NRF_CLOCK_LF_ACCURACY_250_PPM 
    // <1=> NRF_CLOCK_LF_ACCURACY_500_PPM 
    // <2=> NRF_CLOCK_LF_ACCURACY_150_PPM 
    // <3=> NRF_CLOCK_LF_ACCURACY_100_PPM 
    // <4=> NRF_CLOCK_LF_ACCURACY_75_PPM 
    // <5=> NRF_CLOCK_LF_ACCURACY_50_PPM 
    // <6=> NRF_CLOCK_LF_ACCURACY_30_PPM 
    // <7=> NRF_CLOCK_LF_ACCURACY_20_PPM 
    // <8=> NRF_CLOCK_LF_ACCURACY_10_PPM 
    // <9=> NRF_CLOCK_LF_ACCURACY_5_PPM 
    // <10=> NRF_CLOCK_LF_ACCURACY_2_PPM 
    // <11=> NRF_CLOCK_LF_ACCURACY_1_PPM 
    #ifndef NRF_SDH_CLOCK_LF_ACCURACY
    #define NRF_SDH_CLOCK_LF_ACCURACY 7
    #endif
    
    
    ------------------------------------------------------------------------------------------
    << boards.h (Excerpt of timer program) >>
    // Low frequency clock source to be used by the SoftDevice
    /*< Xtal clock setting >*/
    #define NRF_CLOCK_LFCLKSRC      {.source       = NRF_CLOCK_LF_SRC_XTAL,			\
    								 .rc_ctiv      = 0,								\
    								 .rc_temp_ctiv = 0,								\
    								 .accuracy     = NRF_CLOCK_LF_ACCURACY_20_PPM}
    
    								 
    ------------------------------------------------------------------------------------------
    << main.c (Excerpt of timer program) >>
    
    /** @brief Handler for timer4 (100us) events. */
    void timer4_event_handler(nrf_timer_event_t event_type, void* p_context)
    {
        switch (event_type)
        {
            case NRF_TIMER_EVENT_COMPARE4:	/* timer 4 events */
                Control_counter ++;				/* Control_counter update */
    			Con_Com_tim ++;					/* BLE connection communication timer count */
                break;
    
            default:
                break;
        }
    }
    /**@brief Function for initializing the timer4 module. */
    static void Conterl_timer_init(void)
    {
        uint32_t time_ticks;
        uint32_t err_code = NRF_SUCCESS;
    
        nrf_drv_timer_config_t timer_cfg = NRF_DRV_TIMER_DEFAULT_CONFIG;
        err_code = nrf_drv_timer_init(&Ctl_timer, &timer_cfg, timer4_event_handler);
        APP_ERROR_CHECK(err_code);
    
        time_ticks = nrf_drv_timer_us_to_ticks(&Ctl_timer, 100);
    
        nrf_drv_timer_extended_compare(
             &Ctl_timer, NRF_TIMER_CC_CHANNEL4, time_ticks, NRF_TIMER_SHORT_COMPARE4_CLEAR_MASK, true);
    
    	Control_counter = 0;			/* 100us count reset */
    	Con_Com_tim = 0;				/* BLE connection communication timer reset */
    	nrf_drv_timer_enable(&Ctl_timer);
    }
    

  • Hi,

    there seems to be a misunderstanding here. The TIMER peripherals use the HF clock, so it has nothing to do with the 32.768 kHz oscillator. The timer will use the HFCLK, which use a HFINT (RC) or HFXO (32 MHz crystal) as reference. So to get an accurate TIMER, you nee to enable the HFXO.

    If you are testing without a SoftDevice, then you can simply enable it like this:

        NRF_CLOCK->EVENTS_HFCLKSTARTED = 0;
        NRF_CLOCK->TASKS_HFCLKSTART    = 1;
    
        while (NRF_CLOCK->EVENTS_HFCLKSTARTED == 0)
        {
            // Do nothing while waiting for the clock to start
        }

    If you are using a SoftDevice you should call sd_clock_hfclk_request().

    In the end, if you want to make a clean solution that works with all other SDK drivers and libraries you should use the clock driver and call nrf_drv_clock_hfclk_request().

Reply Children