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

What is the purpose of nrf_drv_clock_init() in usbd_ble_uart and usbd_cdc_acm examples

Hi,

1. In my last post, (https://devzone.nordicsemi.com/f/nordic-q-a/60300/questions-on-usbd_cdc_acm-example), in question #1 a nice explanation was given regarding the use of nrf_drv_clock.h in the usbd_cdc_acm example. In the usbd_ble_uart example though, the app_timer handles the low_frequency clock for the softdevice, so,  why can't we use a second instance of app_timer for the usbd library to work and we have to add nrf_drv_clock_init()? Because if I undrstand correctly the app_timer will not stop if at least one instance of it is using it. Right?

2. I am confused with the purpose of the different timer and clock libraries and drivers in the SDK

 I found this post ( https://devzone.nordicsemi.com/f/nordic-q-a/10952/timer-vs-app_timer/40933#40933) that clears out the relation between app_timer library and timer driver. But there are other drivers / libraries that I cannot understand their purpose and how/if they relate to each other.

For example,

  • app_timer.h
  • nrf_drv_clock.h
  • nrf_drv_timer.h

Could you please give me a guideline or indicate me some post that explains the timer and clock drivers and libraries and how they relate (or not) to each other

Thank you for your time!

Parents
  • Hi,

    In the usbd_ble_uart example though, the app_timer handles the low_frequency clock for the softdevice, so,  why can't we use a second instance of app_timer for the usbd library to work and we have to add nrf_drv_clock_init()?

    This is a misunderstanding. There are several things that need to be clarified:

    1. The low frequency (32.768 kHz) clock (LFCLK) can be used by any peripheral that needs it. As log as it is running, all peripherals having the clock as input can use it.
    2. There is no relationship between the app_timer and nrf_drv_clock other than that the 32.768 kHz clock must be running for the app timer to work. If the SoftDevice is enabled, the clock always runs, so you don't need to think about this.
    3. You can have an arbitrary number of app timers. The app timer uses RTC1 peripheral, and adding more app_timer instances does not mean that you need to use more HW resources (other than slightly more RAM and CPU processing time).
    Because if I undrstand correctly the app_timer will not stop if at least one instance of it is using it. Right?

     I did not fully understand the question here. Please remember that the app timer (timer library) is a SW timer library, which depends on the RTC and LFCLK, but there are no other requirements. As long as the clock runs, the app timer will work. The amount of app timers you have or don't have does not influence the LFCLK. One exception is if the app timer is the only user of the LFCLK and a SoftDevice is not enabled. In that case, the clock driver will stop the clock when it is no longer in use. But that should not be a problem since it is not used. (And if you want the clock to keep running for some reason and the SoftDevice is not enabled, you can configure it to do so by setting APP_TIMER_KEEPS_RTC_ACTIVE to 1 in your applications sdk_config.h. 

    Could you please give me a guideline or indicate me some post that explains the timer and clock drivers and libraries and how they relate (or not) to each other

    These are different concepts that are somewhat related.

    • app_timer: Is a SW timer library that uses the RTC peripheral, that in turn use the LFCLK.
    • nrf_drv_clock is a driver for handling the LFCLK. It is not really of any use if you are using a SoftDevice, except for requesting HFCLK in case you need to enable the HFXO (high-frequency crystal oscillator) for some reason.
    • nrf_drv_timer: This is the driver for the TIMER peripheral. You can think of that as an equivalent to the RTC, but it uses the HF clock instead of the LF clock.

    I recommend you try to understand this from both a HW and SW perspective. To describe this difference, you can start with the two clocks:

    • LFCLK (32.768 kHz) is a low power clock that typically constantly runs
      • This is used to clock the RTC, which is used for timekeeping in the SoftDevice (RTC0) and for time keeping, delaying, regular events etc in the application via the application timer library (RTC1). It can also be used for other purposes.
    • HFCLK (64 MHz). This is the clock that runs the CPU, the TIMER peripheral and is also needed by the Radio. When the radio is used or an accurate HF clock is needed, the xtal oscillator is used. If not, the internal RC is used to clock the CPU.

    The nrf_drv_clock driver is used to control both the HFCLK and LFCLK. As mentioned, you do not need to think about it in a device using a SoftDevice. And in most simple applications without a SoftDevice, you just need to initialize the driver and start the LFCLK, since having that running is required for the application timer, which in turn is used all over the SDK.

  • Hi, Thank you for your reply it is very helpful.

    I did not fully understand the question here

    To rephrase, since the softdevice uses the app_timer to run its processes this means that the LFCLK is enabled by the softdevice. So, why can't we add one more app_timer instance to be used with the app_usbd library and remove nrf_drv_clock_init() ? I mean that if there are two instances, one for the softdevice and one for the app_usbd library (that uses the usb module), then the LFCLK will not be disabled until both modules that use it will stop. Right? In that case we don't need the  nrf_drv_clock_init() (and its internal counter that keeps count of the modules that use the LFCLK) because as long there is one active instance of the app_timer the LFCLK will not be deactivated.

    nrf_drv_clock is a driver for handling the LFCLK. It is not really of any use if you are using a SoftDevice

    Why then, is the nrf_drv_clock_init()  being used in the usbd_ble_uart example since the softdevice is used?

    I mean that if the nrf_drv_clock driver handles the lfclk and the app_timer uses the lfclk to function, and the softdevice uses the app_timer for its internal processes, why we must  call again the nrf_drv_clock through the nrf_drv_clock_init() function, since it is already used in the first step?

       ...
       ...
       ...
       
       buttons_leds_init();
    
        app_usbd_serial_num_generate();
    
        ret = nrf_drv_clock_init();
        APP_ERROR_CHECK(ret);
    
        NRF_LOG_INFO("USBD BLE UART example started.");
    
        ret = app_usbd_init(&usbd_config);
        APP_ERROR_CHECK(ret);
    
        app_usbd_class_inst_t const * class_cdc_acm = app_usbd_cdc_acm_class_inst_get(&m_app_cdc_acm);
        ret = app_usbd_class_append(class_cdc_acm);
        
        ...
        ...
        ...

Reply
  • Hi, Thank you for your reply it is very helpful.

    I did not fully understand the question here

    To rephrase, since the softdevice uses the app_timer to run its processes this means that the LFCLK is enabled by the softdevice. So, why can't we add one more app_timer instance to be used with the app_usbd library and remove nrf_drv_clock_init() ? I mean that if there are two instances, one for the softdevice and one for the app_usbd library (that uses the usb module), then the LFCLK will not be disabled until both modules that use it will stop. Right? In that case we don't need the  nrf_drv_clock_init() (and its internal counter that keeps count of the modules that use the LFCLK) because as long there is one active instance of the app_timer the LFCLK will not be deactivated.

    nrf_drv_clock is a driver for handling the LFCLK. It is not really of any use if you are using a SoftDevice

    Why then, is the nrf_drv_clock_init()  being used in the usbd_ble_uart example since the softdevice is used?

    I mean that if the nrf_drv_clock driver handles the lfclk and the app_timer uses the lfclk to function, and the softdevice uses the app_timer for its internal processes, why we must  call again the nrf_drv_clock through the nrf_drv_clock_init() function, since it is already used in the first step?

       ...
       ...
       ...
       
       buttons_leds_init();
    
        app_usbd_serial_num_generate();
    
        ret = nrf_drv_clock_init();
        APP_ERROR_CHECK(ret);
    
        NRF_LOG_INFO("USBD BLE UART example started.");
    
        ret = app_usbd_init(&usbd_config);
        APP_ERROR_CHECK(ret);
    
        app_usbd_class_inst_t const * class_cdc_acm = app_usbd_cdc_acm_class_inst_get(&m_app_cdc_acm);
        ret = app_usbd_class_append(class_cdc_acm);
        
        ...
        ...
        ...

Children
  • Hi, 

    masterLee said:
    To rephrase, since the softdevice uses the app_timer to run its processes this means that the LFCLK is enabled by the softdevice.

    No, the SoftDevice does not use the app_timer. The app timer is a SDK library which use RTC1. The SoftDevice use RTC0, but what they have in common is that both the SoftDevice and the app timer library rely on the LFCLK running.

    masterLee said:
    So, why can't we add one more app_timer instance to be used with the app_usbd library and remove nrf_drv_clock_init() ?

    You can add as many app timer instances as you like. There is no limit.

    masterLee said:
    Why then, is the nrf_drv_clock_init()  being used in the usbd_ble_uart example since the softdevice is used?

    That is because the USBD library uses the clock driver for requesting the crystal HFCLK when it needs a high accuracy HF clock. This has no relationship with the app timer what so ever since that uses the LFCLK.

    masterLee said:
    I mean that if the nrf_drv_clock driver handles the lfclk and the app_timer uses the lfclk to function, and the softdevice uses the app_timer for its internal processes, why we must  call again the nrf_drv_clock through the nrf_drv_clock_init() function, since it is already used in the first step?

    You don't. But again, in this example, the clock driver is used to control the HF clock. So this is completely unrelated, though I can see how you get it mixed since the same driver is used to control both the LF clock and the HF clock.

  • Aaah,  OK now I think I got it. HFCLK is the common point. Yes,  you mentioned it in your first reply but I didn't make the connection. Really sorry for that!

    OK great I can proceed in peace now Slight smile

    Thank you for your help once again!

    Best Regards!!

Related