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

Accurate sample rate with ncs

Are there any examples of sampling something like an I2C bus at a constant sample rate? I have seen issues myself with the k_sleep and k_busy_wait not giving accurate delays. Tested with a salae logic analyser. I haven't tested the timings of the k_timer yet.

I have seen this https://github.com/zephyrproject-rtos/zephyr/issues/6498 when looking into the inaccuracy of the delay functions above

Parents Reply Children
  • Hi,

     

    I can confirm that k_* timed functions in < 10 ms are very jittery. Even a k_timer instance will not be matching 100 Hz directly (measured to 12 ms at my end).

    What I can recommend is to use either a high speed TIMER, or use RTC0 (RTC1 used by the kernel), to generate this event. RTC0 will be able to give 32768/328 Hz = ~99,9 Hz, but would require the use of either nrfx driver or bare metal implementation. If you want to look at selecting the nrfx driver, I have a project here where other nrfx components are manually selected in the application kconfig (required at this time, due to entries having no prompt):

    https://github.com/Rallare/fw-nrfconnect-nrf/blob/nrf9160_samples/samples/nrf9160/nrfx_timed_signal/Kconfig

     

    Kind regards,

    Håkon

  • Hi Hakon,

    I tried implementing the timer with RTC0 but it is crashing when I try writing to the Prescaler register within nrfx_rtc_init. 

    __STATIC_INLINE void nrf_rtc_prescaler_set(NRF_RTC_Type * p_reg, uint32_t val)
    {
        NRFX_ASSERT(val <= (RTC_PRESCALER_PRESCALER_Msk >> RTC_PRESCALER_PRESCALER_Pos));
        p_reg->PRESCALER = val;
    }

    The timer instance and configuration seem ok

    __func__                      "nrfx_rtc_init"    0x00030aec    14    const char[14]                
    handler                       0x0002a9f7         r2            4     void(nrfx_rtc_int_type_t)*    
        *                         rtc_handler        0x0002a9f7    2     void(nrfx_rtc_int_type_t)     
    p_config                      0x20024be0         r1            6     const nrfx_rtc_config_t*      
        *                         <struct>           0x20024be0    6     struct                        
            prescaler             327                0x20024be0    2     short unsigned int            
            interrupt_priority    7                  0x20024be2    1     unsigned char                 
            tick_latency          65                 0x20024be3    1     unsigned char                 
            reliable              false              0x20024be4    0     _Bool                         
    p_instance                    0x00030a88         r0            8     const nrfx_rtc_t*             
        *                         <struct>           0x00030a88    8     struct                        
            p_reg                 0x40014000         0x00030a88    4     NRF_RTC_Type*                 
            irq                   RTC0_IRQn          0x00030a8c    1     enum                          
            instance_id           0x00               0x00030a8d    1     unsigned char                 
            cc_channel_count      0x04               0x00030a8e    1     unsigned char                 
    

    And I made this change in spm to move it to the non-secure domain

    diff --git a/subsys/spm/spm.c b/subsys/spm/spm.c
    index ec00037..23b7ecf 100644
    --- a/subsys/spm/spm.c
    +++ b/subsys/spm/spm.c
    @@ -287,6 +287,7 @@ static void spm_config_peripherals(void)
            static const struct periph_cfg periph[] = {
                    PERIPH("NRF_P0", NRF_P0, CONFIG_SPM_NRF_P0_NS),
                    PERIPH("NRF_CLOCK", NRF_CLOCK, CONFIG_SPM_NRF_CLOCK_NS),
    +               PERIPH("NRF_RTC0", NRF_RTC0, CONFIG_SPM_NRF_RTC0_NS),
                    PERIPH("NRF_RTC1", NRF_RTC1, CONFIG_SPM_NRF_RTC1_NS),
                    PERIPH("NRF_NVMC", NRF_NVMC, CONFIG_SPM_NRF_NVMC_NS),
                    PERIPH("NRF_UARTE1", NRF_UARTE1, CONFIG_SPM_NRF_UARTE1_NS),

    See what the issue is here?

    Also I added "CONFIG_COMPILER_OPT="-DNRFX_RTC_ENABLED=1 -DNRFX_RTC0_ENABLED=1"" to get it to compile

  • Hi,

     

    I took the rtc sample from nRF5 SDK and did a port of it and put it here:

    https://github.com/Rallare/fw-nrfconnect-nrf/tree/nrf9160_samples/samples/nrf9160/nrfx/rtc

     

    Could you try it and see if it works at your end?

     

    Kind regards,

    Håkon

  • Ok got it working now, didn't know I needed to add this to ncs/nrf/subsys/spm/Kconfig as well make the change in spm.c

    config SPM_NRF_RTC0_NS
    	bool "RTC0 is Non-Secure"
    	default y

    Is there a reason there is manual changes needed in the SDK to enable RTC0 in the non-secure domain?

  • Glad to hear that you got it working.

    RonanB96 said:
    Is there a reason there is manual changes needed in the SDK to enable RTC0 in the non-secure domain?

    I do not have a good answer here, other than the inherited behavior from Cortex M33 core, as all peripherals reset value is secure mode. Since the modem requires you to be in non-secure mode in order to communicate with it, it is then normal that the application would also reside in this defined area. I'll input this to the developers as a feature request, ie: set most peripherals to non-secure.

     

    Kind regards,

    Håkon

Related