Skip to content

Commit 4e0a072

Browse files
drivers: timer: nrf_rtc_timer: Allow use of custom bit width
Allowed use of counter bit width lower than hardware 24. In that case, PPI connection is estabilished to trigger clear tast once maximum value is reached. Signed-off-by: Michał Stasiak <michal.stasiak@nordicsemi.no>
1 parent af4e875 commit 4e0a072

File tree

5 files changed

+72
-6
lines changed

5 files changed

+72
-6
lines changed

drivers/timer/Kconfig.nrf_rtc

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,4 +42,12 @@ config NRF_RTC_TIMER_TRIGGER_OVERFLOW
4242
When enabled, a function can be used to trigger RTC overflow and
4343
effectively shift time into the future.
4444

45+
config NRF_RTC_COUNTER_BIT_WIDTH
46+
int "Bit width of RTC counter"
47+
default 24
48+
help
49+
Use custom bit width of RTC counter. If bit width other than 24 bits
50+
is used then one RTC channel will be reserved to control wrapping via
51+
PPI connections.
52+
4553
endif # NRF_RTC_TIMER

drivers/timer/nrf_rtc_timer.c

Lines changed: 46 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -17,11 +17,21 @@
1717
#include <haly/nrfy_rtc.h>
1818
#include <zephyr/irq.h>
1919

20+
/* Ensure that selected counter bit width is withing 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");
3343
BUILD_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)
@@ -560,8 +570,13 @@ void rtc_nrf_isr(const void *arg)
560570
rtc_pretick_rtc1_isr_hook();
561571
}
562572

563-
if (nrfy_rtc_int_enable_check(RTC, NRF_RTC_INT_OVERFLOW_MASK) &&
564-
nrfy_rtc_events_process(RTC, NRF_RTC_INT_OVERFLOW_MASK)) {
573+
if ((nrfy_rtc_int_enable_check(RTC, NRF_RTC_INT_OVERFLOW_MASK) &&
574+
nrfy_rtc_events_process(RTC, NRF_RTC_INT_OVERFLOW_MASK)) ||
575+
#if CUSTOM_COUNTER_BIT_WIDTH
576+
(nrfy_rtc_int_enable_check(RTC, NRF_RTC_INT_COMPARE1_MASK) &&
577+
nrfy_rtc_events_process(RTC, NRF_RTC_INT_COMPARE1_MASK)) ||
578+
#endif
579+
0) {
565580
overflow_cnt++;
566581
}
567582

@@ -697,7 +712,9 @@ uint32_t sys_clock_cycle_get_32(void)
697712
static void int_event_disable_rtc(void)
698713
{
699714
uint32_t mask = NRF_RTC_INT_TICK_MASK |
715+
#if !CUSTOM_COUNTER_BIT_WIDTH
700716
NRF_RTC_INT_OVERFLOW_MASK |
717+
#endif
701718
NRF_RTC_INT_COMPARE0_MASK |
702719
NRF_RTC_INT_COMPARE1_MASK |
703720
NRF_RTC_INT_COMPARE2_MASK |
@@ -729,7 +746,9 @@ static int sys_clock_driver_init(void)
729746
nrfy_rtc_int_enable(RTC, NRF_RTC_CHANNEL_INT_MASK(chan));
730747
}
731748

749+
#if !CUSTOM_COUNTER_BIT_WIDTH
732750
nrfy_rtc_int_enable(RTC, NRF_RTC_INT_OVERFLOW_MASK);
751+
#endif
733752

734753
NVIC_ClearPendingIRQ(RTC_IRQn);
735754

@@ -742,7 +761,7 @@ static int sys_clock_driver_init(void)
742761

743762
int_mask = BIT_MASK(CHAN_COUNT);
744763
if (CONFIG_NRF_RTC_TIMER_USER_CHAN_COUNT) {
745-
alloc_mask = BIT_MASK(EXT_CHAN_COUNT) << 1;
764+
alloc_mask = BIT_MASK(EXT_CHAN_COUNT) << (1 + CUSTOM_COUNTER_BIT_WIDTH);
746765
}
747766

748767
uint32_t initial_timeout = IS_ENABLED(CONFIG_TICKLESS_KERNEL) ?
@@ -761,6 +780,28 @@ static int sys_clock_driver_init(void)
761780
z_nrf_clock_control_lf_on(mode);
762781
#endif
763782

783+
#if CUSTOM_COUNTER_BIT_WIDTH
784+
/* Use channel 1 for wrapping. */
785+
uint8_t chan = 1;
786+
nrf_rtc_event_t evt = NRF_RTC_CHANNEL_EVENT_ADDR(chan);
787+
nrfx_err_t result;
788+
nrf_ppi_channel_t ch;
789+
790+
nrfy_rtc_event_enable(RTC, NRF_RTC_CHANNEL_INT_MASK(chan));
791+
nrfy_rtc_cc_set(RTC, chan, COUNTER_MAX);
792+
uint32_t evt_addr;
793+
uint32_t task_addr;
794+
795+
evt_addr = nrfy_rtc_event_address_get(RTC, evt);
796+
task_addr = nrfy_rtc_task_address_get(RTC, NRF_RTC_TASK_CLEAR);
797+
798+
result = nrfx_ppi_channel_alloc(&ch);
799+
if (result != NRFX_SUCCESS) {
800+
return -ENODEV;
801+
}
802+
(void)nrfx_ppi_channel_assign(ch, evt_addr, task_addr);
803+
(void)nrfx_ppi_channel_enable(ch);
804+
#endif
764805
return 0;
765806
}
766807

include/zephyr/drivers/timer/nrf_rtc_timer.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ extern "C" {
1515

1616
/** @brief Maximum allowed time span that is considered to be in the future.
1717
*/
18-
#define NRF_RTC_TIMER_MAX_SCHEDULE_SPAN BIT(23)
18+
#define NRF_RTC_TIMER_MAX_SCHEDULE_SPAN BIT(CONFIG_NRF_RTC_COUNTER_BIT_WIDTH - 1)
1919

2020
/** @brief RTC timer compare event handler.
2121
*

tests/drivers/timer/nrf_rtc_timer/src/main.c

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -361,6 +361,11 @@ static void overflow_sched_handler(int32_t id, uint64_t expire_time,
361361
*/
362362
ZTEST(nrf_rtc_timer, test_overflow)
363363
{
364+
/* For bit width lower than default 24, overflow injection is not possible. */
365+
if (CONFIG_NRF_RTC_COUNTER_BIT_WIDTH < 24)
366+
{
367+
ztest_test_skip();
368+
}
364369
PRINT("RTC ticks before overflow injection: %u\r\n",
365370
(uint32_t)z_nrf_rtc_timer_read());
366371

tests/drivers/timer/nrf_rtc_timer/testcase.yaml

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,3 +23,15 @@ tests:
2323
- nrf5340bsim/nrf5340/cpunet
2424
integration_platforms:
2525
- nrf52dk/nrf52832
26+
27+
drivers.timer.nrf_rtc_timer_16_bits:
28+
tags:
29+
- drivers
30+
- timer
31+
platform_allow:
32+
- nrf52dk/nrf52832
33+
integration_platforms:
34+
- nrf52dk/nrf52832
35+
extra_configs:
36+
- CONFIG_ZERO_LATENCY_IRQS=y
37+
- CONFIG_NRF_RTC_COUNTER_BIT_WIDTH=16

0 commit comments

Comments
 (0)