Beware that this post is related to an SDK in maintenance mode
More Info: Consider nRF Connect SDK for new designs

get RTC count via PPI gpio (shared with app_timer)

Hello,

I using the "nRF5_SDK_17.1.0_ddde560" and want to capture the current RTC count though a gpio (low_to_high event) via PPI. I want to use the RTC2 (used by app_timer in the project) because RTC0 and RTC1 used by softdevice and freertos. I need the app_timer because is used by ble. What I figured out is that only CC[0] and CC[1] is used by the app_timer of the RTC2. Is that true? Now my question: Could be there a problem of using the CC[2] or CC[3] by my own. I want only to capture the RTC count on an interrupt event to use the count value so set some timings with the app_timer. I don't want to get the count value inside an interrupt because some other stuff (isr etc.) could process while this happens when i want to capture the RTC counter value. I'm using the nRF52832, nRF52833 and nRF52840 (I think there is no big difference to the RTC between this devices right?). 

Thx and best regards

Julian

Parents
  • Yes, its possible, I have implemented this before. Using PPI, configure and connect just the RTC's tick event (not tick interrupt) to a timer in counter mode, triggering its count task. Have GPIOTE trigger the counter's capture task when your gpio event occurs. Then read the counter using nrfx_timer_capture_get whenever you have time. Since the timer is in counter mode, there is no added power usage and the counter is now 32 bits wide vs 24 on the rtc.  As long as the rate of your gpio is not faster than the time you eventually get to read the timer, it works well. Something like this:

        nrfx_gpiote_init();
    
        // Input pins
        nrfx_gpiote_in_config_t in1 = NRFX_GPIOTE_CONFIG_IN_SENSE_LOTOHI(true);
        nrfx_gpiote_in_init(LIS2DS12_INT1_PIN, &in1, OnGpioIsr);
        nrfx_gpiote_in_event_enable(LIS2DS12_INT1_PIN, true);
    
        // Rtc
        NRF_RTC2->EVTEN = RTC_EVTENCLR_TICK_Enabled;
        
        // Counter
        nrfx_timer_config_t counterConfig = NRFX_TIMER_DEFAULT_CONFIG; 
        counterConfig.mode                = NRF_TIMER_MODE_LOW_POWER_COUNTER;
        counterConfig.bit_width           = NRF_TIMER_BIT_WIDTH_32;
        nrfx_timer_init(&rtcCounter, &counterConfig, NeverCalledIsr);
    
        // Rtc-Counter channel
        nrfx_ppi_channel_alloc(&ppiChannelRtcToCounter);
        nrfx_ppi_channel_assign(
            ppiChannelRtcToCounter, 
            (uint32_t)&NRF_RTC2->EVENTS_TICK,
            nrfx_timer_task_address_get(&rtcCounter, NRF_TIMER_TASK_COUNT));
        nrfx_ppi_channel_enable(ppiChannelRtcToCounter);
    
        // Gpiote-Counter channel
        nrfx_ppi_channel_alloc(&ppiChannelGpioToCounter);
        nrfx_ppi_channel_assign(
            ppiChannelGpioToCounter, 
            nrfx_gpiote_in_event_addr_get(LIS2DS12_INT1_PIN),
            nrfx_timer_task_address_get(&rtcCounter, NRF_TIMER_TASK_CAPTURE0));
        nrfx_ppi_channel_enable(ppiChannelGpioToCounter);

  • Nice solution. I have implemented this. But now I have the problem that the current increases above ~100uA at RTC PRESCALER=0. The tick event maybe increases the current much. When I increase the PRESCALER then the current decreases too. I want to use the RTC at PRESCALER=0.

  • The counter is causing the 16M clock to start up which adds that current. That can be fixed by changing my previous code that sets up the counter. Remove the line to start/enable the counter (only needed for timers, not counters), and configure it as a low power counter. That will remove the 100uA. I've editing that previous code too.

        // Counter
        nrfx_timer_config_t counterConfig = NRFX_TIMER_DEFAULT_CONFIG; 
        counterConfig.mode                = NRF_TIMER_MODE_LOW_POWER_COUNTER;
        counterConfig.bit_width           = NRF_TIMER_BIT_WIDTH_32;
        nrfx_timer_init(&rtcCounter, &counterConfig, NeverCalledIsr);
        

  • This did't solved my problem too. I think it's not the problem of the counter from the timer. It happens even when I only start the RTC2 and enable the RTC2 tick event (total current of the nrf: without tick event 4uA and with 172uA at RTC2 PRESCALER=0, or 19uA at a RTC2 PRESCALER=32). I assume that you started the RTC2 before right? I think the problem is that the tick event is to frequently (1/32.768kHz --> 30.51us). Firstly I though its happend because I use freertos and softdevice.

    // rtc
    nrf_drv_rtc_enable(&rtc);
    nrf_drv_rtc_tick_enable(&rtc,false); // NRF_RTC2->EVTEN = RTC_EVTENCLR_TICK_Enabled;
    
    // return 0; // [INFO] when return here still high current (because tick event to frequently?) 
    
    // counter
    nrf_drv_timer_config_t timer_cfg = NRF_DRV_TIMER_DEFAULT_CONFIG;
    // timer_cfg.p_context = (void*)&timer_handle;
    timer_cfg.mode = NRF_TIMER_MODE_LOW_POWER_COUNTER;
    timer_cfg.bit_width = NRF_TIMER_BIT_WIDTH_32;
    err_code = nrf_drv_timer_init(&timer_handle, &timer_cfg, timer_event_handler);
    APP_ERROR_CHECK(err_code);
    // nrf_drv_timer_enable(&timer_handle);
    
    // rtc-counter channel
    err_code = nrf_drv_ppi_channel_alloc(&m_ppi_channel_rtc_to_counter);
    APP_ERROR_CHECK(err_code);
    err_code = nrf_drv_ppi_channel_assign(  m_ppi_channel_rtc_to_counter,
                                            nrf_drv_rtc_event_address_get(&rtc, NRF_RTC_EVENT_TICK),
                                            nrf_drv_timer_task_address_get(&timer_handle, NRF_TIMER_TASK_COUNT));
    APP_ERROR_CHECK(err_code);
    err_code = nrf_drv_ppi_channel_enable(m_ppi_channel_rtc_to_counter);
    APP_ERROR_CHECK(err_code);

Reply
  • This did't solved my problem too. I think it's not the problem of the counter from the timer. It happens even when I only start the RTC2 and enable the RTC2 tick event (total current of the nrf: without tick event 4uA and with 172uA at RTC2 PRESCALER=0, or 19uA at a RTC2 PRESCALER=32). I assume that you started the RTC2 before right? I think the problem is that the tick event is to frequently (1/32.768kHz --> 30.51us). Firstly I though its happend because I use freertos and softdevice.

    // rtc
    nrf_drv_rtc_enable(&rtc);
    nrf_drv_rtc_tick_enable(&rtc,false); // NRF_RTC2->EVTEN = RTC_EVTENCLR_TICK_Enabled;
    
    // return 0; // [INFO] when return here still high current (because tick event to frequently?) 
    
    // counter
    nrf_drv_timer_config_t timer_cfg = NRF_DRV_TIMER_DEFAULT_CONFIG;
    // timer_cfg.p_context = (void*)&timer_handle;
    timer_cfg.mode = NRF_TIMER_MODE_LOW_POWER_COUNTER;
    timer_cfg.bit_width = NRF_TIMER_BIT_WIDTH_32;
    err_code = nrf_drv_timer_init(&timer_handle, &timer_cfg, timer_event_handler);
    APP_ERROR_CHECK(err_code);
    // nrf_drv_timer_enable(&timer_handle);
    
    // rtc-counter channel
    err_code = nrf_drv_ppi_channel_alloc(&m_ppi_channel_rtc_to_counter);
    APP_ERROR_CHECK(err_code);
    err_code = nrf_drv_ppi_channel_assign(  m_ppi_channel_rtc_to_counter,
                                            nrf_drv_rtc_event_address_get(&rtc, NRF_RTC_EVENT_TICK),
                                            nrf_drv_timer_task_address_get(&timer_handle, NRF_TIMER_TASK_COUNT));
    APP_ERROR_CHECK(err_code);
    err_code = nrf_drv_ppi_channel_enable(m_ppi_channel_rtc_to_counter);
    APP_ERROR_CHECK(err_code);

Children
Related