1717#include <haly/nrfy_rtc.h>
1818#include <zephyr/irq.h>
1919
20+ /* Ensure that selected counter bit width is within its maximum hardware width. */
21+ BUILD_ASSERT (CONFIG_NRF_RTC_COUNTER_BIT_WIDTH <= 24 , "Counter bit width exceeds maximum width." );
22+
23+ #if (CONFIG_NRF_RTC_COUNTER_BIT_WIDTH < 24 )
24+ #define CUSTOM_COUNTER_BIT_WIDTH 1
25+ #include "nrfx_ppi.h"
26+ #else
27+ #define CUSTOM_COUNTER_BIT_WIDTH 0
28+ #endif
29+
2030#define RTC_PRETICK (IS_ENABLED(CONFIG_SOC_NRF53_RTC_PRETICK) && \
2131 IS_ENABLED(CONFIG_SOC_NRF5340_CPUNET))
2232
2333#define EXT_CHAN_COUNT CONFIG_NRF_RTC_TIMER_USER_CHAN_COUNT
24- #define CHAN_COUNT (EXT_CHAN_COUNT + 1)
34+ #define CHAN_COUNT (EXT_CHAN_COUNT + 1 + CUSTOM_COUNTER_BIT_WIDTH )
2535
2636#define RTC NRF_RTC1
2737#define RTC_IRQn NRFX_IRQ_NUMBER_GET(RTC)
@@ -33,7 +43,7 @@ BUILD_ASSERT(CHAN_COUNT <= CHAN_COUNT_MAX, "Not enough compare channels");
3343BUILD_ASSERT (DT_NODE_HAS_STATUS (DT_NODELABEL (RTC_LABEL ), disabled ),
3444 "Counter for RTC1 must be disabled" );
3545
36- #define COUNTER_BIT_WIDTH 24U
46+ #define COUNTER_BIT_WIDTH CONFIG_NRF_RTC_COUNTER_BIT_WIDTH
3747#define COUNTER_SPAN BIT(COUNTER_BIT_WIDTH)
3848#define COUNTER_MAX (COUNTER_SPAN - 1U)
3949#define COUNTER_HALF_SPAN (COUNTER_SPAN / 2U)
@@ -565,8 +575,13 @@ void rtc_nrf_isr(const void *arg)
565575 rtc_pretick_rtc1_isr_hook ();
566576 }
567577
568- if (nrfy_rtc_int_enable_check (RTC , NRF_RTC_INT_OVERFLOW_MASK ) &&
569- nrfy_rtc_events_process (RTC , NRF_RTC_INT_OVERFLOW_MASK )) {
578+ if ((nrfy_rtc_int_enable_check (RTC , NRF_RTC_INT_OVERFLOW_MASK ) &&
579+ nrfy_rtc_events_process (RTC , NRF_RTC_INT_OVERFLOW_MASK )) ||
580+ #if CUSTOM_COUNTER_BIT_WIDTH
581+ (nrfy_rtc_int_enable_check (RTC , NRF_RTC_INT_COMPARE1_MASK ) &&
582+ nrfy_rtc_events_process (RTC , NRF_RTC_INT_COMPARE1_MASK )) ||
583+ #endif
584+ 0 ) {
570585 overflow_cnt ++ ;
571586 }
572587
@@ -702,7 +717,9 @@ uint32_t sys_clock_cycle_get_32(void)
702717static void int_event_disable_rtc (void )
703718{
704719 uint32_t mask = NRF_RTC_INT_TICK_MASK |
720+ #if !CUSTOM_COUNTER_BIT_WIDTH
705721 NRF_RTC_INT_OVERFLOW_MASK |
722+ #endif
706723 NRF_RTC_INT_COMPARE0_MASK |
707724 NRF_RTC_INT_COMPARE1_MASK |
708725 NRF_RTC_INT_COMPARE2_MASK |
@@ -734,7 +751,9 @@ static int sys_clock_driver_init(void)
734751 nrfy_rtc_int_enable (RTC , NRF_RTC_CHANNEL_INT_MASK (chan ));
735752 }
736753
754+ #if !CUSTOM_COUNTER_BIT_WIDTH
737755 nrfy_rtc_int_enable (RTC , NRF_RTC_INT_OVERFLOW_MASK );
756+ #endif
738757
739758 NVIC_ClearPendingIRQ (RTC_IRQn );
740759
@@ -747,7 +766,7 @@ static int sys_clock_driver_init(void)
747766
748767 int_mask = BIT_MASK (CHAN_COUNT );
749768 if (CONFIG_NRF_RTC_TIMER_USER_CHAN_COUNT ) {
750- alloc_mask = BIT_MASK (EXT_CHAN_COUNT ) << 1 ;
769+ alloc_mask = BIT_MASK (EXT_CHAN_COUNT ) << ( 1 + CUSTOM_COUNTER_BIT_WIDTH ) ;
751770 }
752771
753772 uint32_t initial_timeout = IS_ENABLED (CONFIG_TICKLESS_KERNEL ) ?
@@ -766,6 +785,28 @@ static int sys_clock_driver_init(void)
766785 z_nrf_clock_control_lf_on (mode );
767786#endif
768787
788+ #if CUSTOM_COUNTER_BIT_WIDTH
789+ /* Use channel 1 for wrapping. */
790+ uint8_t chan = 1 ;
791+ nrf_rtc_event_t evt = NRF_RTC_CHANNEL_EVENT_ADDR (chan );
792+ nrfx_err_t result ;
793+ nrf_ppi_channel_t ch ;
794+
795+ nrfy_rtc_event_enable (RTC , NRF_RTC_CHANNEL_INT_MASK (chan ));
796+ nrfy_rtc_cc_set (RTC , chan , COUNTER_MAX );
797+ uint32_t evt_addr ;
798+ uint32_t task_addr ;
799+
800+ evt_addr = nrfy_rtc_event_address_get (RTC , evt );
801+ task_addr = nrfy_rtc_task_address_get (RTC , NRF_RTC_TASK_CLEAR );
802+
803+ result = nrfx_ppi_channel_alloc (& ch );
804+ if (result != NRFX_SUCCESS ) {
805+ return - ENODEV ;
806+ }
807+ (void )nrfx_ppi_channel_assign (ch , evt_addr , task_addr );
808+ (void )nrfx_ppi_channel_enable (ch );
809+ #endif
769810 return 0 ;
770811}
771812
0 commit comments