This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

nRF52840 SDK16 - RTC Driver general questions - instance, initialization, and channels

Hi everyone,

I want to use the RTC module in my code, and I have some questions.

1. What I have understood so far is that the nRF52840 has three RTCs (RTC0, RTC1, RTC2). RTC0 is used by the SD and RTC1 from the application timer software. So it's safer using RTC2 for events generation, right?

2. What is the id parameter when calling the NRFX_RTC_INSTANCE macro for creating an RTC instance? For example, if I use RTC2 the id value must be 2, while if I use RTC2 the id value must be 1?

3. The PRESCALER register is a 12-bit register, meaning that the maximum value is 4095, giving a tick every 125 ms. So, with the TICK event, the maximum event period is limited to 125ms?

4. Each RTC has four compare channels, right? The function to set a compare channel is nrfx_rtc_cc_set. According to the function's description, the second parameter is the channel of the instance. So the value of this parameter could be 1,2,3, or 4? For example, can I use all of the four compare channels of RTC2 like this?

static void rtc_config(void) {
  uint32_t err_code;

  // Initialize RTC instance
  nrf_drv_rtc_config_t config = NRF_DRV_RTC_DEFAULT_CONFIG;
  config.prescaler = 327; //100Hz (10ms)
  err_code = nrf_drv_rtc_init(&rtc, &config, rtc_handler);
  APP_ERROR_CHECK(err_code);

  err_code = nrf_drv_rtc_cc_set(&rtc, 0, 1, true); // compare event occurs every 10ms at channel 0
  APP_ERROR_CHECK(err_code);
  
  err_code = nrf_drv_rtc_cc_set(&rtc, 1, 2, true); // compare event occurs every 20ms at channel 1
  APP_ERROR_CHECK(err_code);
  
  err_code = nrf_drv_rtc_cc_set(&rtc, 2, 3, true); // compare event occurs every 30ms at channel 2
  APP_ERROR_CHECK(err_code);
  
  err_code = nrf_drv_rtc_cc_set(&rtc, 3, 4, true); // compare event occurs every 40ms at channel 3
  APP_ERROR_CHECK(err_code);

  // Power on RTC instance
  nrf_drv_rtc_enable(&rtc);
}

Thanks

Nick

  • Hi Nick

    1. What I have understood so far is that the nRF52840 has three RTCs (RTC0, RTC1, RTC2). RTC0 is used by the SD and RTC1 from the application timer software. So it's safer using RTC2 for events generation, right?

    This is correct. The SoftDevice uses RTC0, and the app_timer uses RTC1, so if you use both then only RTC2 will be available to the application. 

    Are you sure that you could not just use app_timer callbacks for your event generation?

    2. What is the id parameter when calling the NRFX_RTC_INSTANCE macro for creating an RTC instance? For example, if I use RTC2 the id value must be 2, while if I use RTC2 the id value must be 1?

    Yes. The ID parameter simply refers to the peripheral instance ID, so id 0 means RTC0, id 1 means RTC1 and so on. 

    If you pick an ID that is already in use you should get an error message when compiling. 

    3. The PRESCALER register is a 12-bit register, meaning that the maximum value is 4095, giving a tick every 125 ms. So, with the TICK event, the maximum event period is limited to 125ms?

    That is correct. If you want a longer event period you need to use a compare register and enable one of the compare events. 

    4. Each RTC has four compare channels, right? The function to set a compare channel is nrfx_rtc_cc_set. According to the function's description, the second parameter is the channel of the instance. So the value of this parameter could be 1,2,3, or 4? For example, can I use all of the four compare channels of RTC2 like this?

    This is detailed here. RTC0 has 3 CC registers, while RTC1 and RTC2 has 4 CC registers. 

     Your code looks correct to me. This should enable all four CC registers with different values, and interrupts enabled.

    Best regards
    Torbjørn

  • Thank you !!

    Are you sure that you could not just use app_timer callbacks for your event generation?

    My plan is to connect RTC events with SAADC tasks through PPI. I've read that is suggested to use RTC rather than application timer for this task (and more specifically RTC2 since RTC0 is reserved by the Soft Device and RTC1 by the application timer)

    What is the RTC HAL? I've noticed there are functions and macros not included in nrfx driver. Should I use the Hardware access layer in combination with nrfx?

  • Hi Nick

    If you need very accurate timing for the SAADC sampling I agree that using PPI and a dedicated RTC or timer is a better approach, yes. You can use the app_timer also, but then there will be some hundreds of microseconds of timing jitter since you will be affected by high priority interrupts in the system. 

    Nikosant03 said:
    What is the RTC HAL? I've noticed there are functions and macros not included in nrfx driver. Should I use the Hardware access layer in combination with nrfx?

    HAL is short for 'Hardware Abstraction Layer', and is a small wrapper around the hardware peripheral registers to make them easier to access. The NRFX layer sits on top of the HAL layer, and from an application perspective it should be sufficient to access the NRFX interface, and let NRFX interface to the HAL layer underneath. 

    Best regards
    Torbjørn

  • Thank you Ovrebekk,

    HAL is short for 'Hardware Abstraction Layer', and is a small wrapper around the hardware peripheral registers to make them easier to access. The NRFX layer sits on top of the HAL layer, and from an application perspective it should be sufficient to access the NRFX interface, and let NRFX interface to the HAL layer underneath. 

    So the stack is like this?

    With that being said accessing just the NRFX API is enough. Are there any cases where I should use the HAL? For example, if I want to change the prescaler setting, the HAL has the RTC_FREQ_TO_PRESCALER macro that is convenient for this task. 

  • Hi Nick

    Sorry, the information I gave you earlier was a bit imprecise. 

    In the nRF5 SDK there is actually one more layer that is usually involved, for historical reasons. 

    In the older SDK's we had the nrf_drv set of drivers, which included drivers for all the different peripherals in the part. 

    Then at a later stage it was decided to pull the low level drivers out of the SDK into a separate module, called nrfx, which could be shared also with other software packages (such as the newer nRF Connect SDK, which is the replacement for the nRF5 SDK going forward). 

    But in order not to break compatibility with all the existing SDK examples using the nrf_drv API's we included a legacy integration layer in the SDK, which redirects all the nrf_drv calls to nrfx calls. 

    So in fact when you develop applications in the nRF5 SDK you will use the nrf_drv API in your application, which is then redirected to the nrfx implementation, which will again use the HAL files underneath. 

    Hopefully this all made sense ;)

    Nikosant03 said:
    Are there any cases where I should use the HAL? For example, if I want to change the prescaler setting, the HAL has the RTC_FREQ_TO_PRESCALER macro that is convenient for this task. 

    If the HAL has some functionality that you can't find in the higher layers it is OK to use it, as long as you avoid using any functions or macros that already exist in nrf_drv or nrfx. 

    Best regards
    Torbjørn

Related