1 /*
2 * Copyright (c) 2017 Oticon A/S
3 * Copyright (c) 2023 Nordic Semiconductor ASA
4 *
5 * SPDX-License-Identifier: Apache-2.0
6 *
7 * Note that the function prototypes are taken from the NRFx HAL
8 */
9 #include "hal/nrf_rtc.h"
10 #include "bs_tracing.h"
11 #include "NHW_RTC.h"
12
rtc_number_from_ptr(NRF_RTC_Type const * p_reg)13 static int rtc_number_from_ptr(NRF_RTC_Type const * p_reg){
14 int i = ( (int)p_reg - (int)&NRF_RTC_regs[0] ) / sizeof(NRF_RTC_Type);
15 return i;
16 }
17
nrf_rtc_cc_set(NRF_RTC_Type * p_reg,uint32_t ch,uint32_t cc_val)18 void nrf_rtc_cc_set(NRF_RTC_Type * p_reg, uint32_t ch, uint32_t cc_val)
19 {
20 p_reg->CC[ch] = cc_val;
21 int i = rtc_number_from_ptr(p_reg);
22 nhw_rtc_regw_sideeffects_CC(i, ch);
23 }
24
nrf_rtc_int_enable(NRF_RTC_Type * p_reg,uint32_t mask)25 void nrf_rtc_int_enable(NRF_RTC_Type * p_reg, uint32_t mask)
26 {
27 int i = rtc_number_from_ptr(p_reg);
28 p_reg->INTENSET = mask;
29 nhw_rtc_regw_sideeffect_INTENSET(i);
30 }
31
nrf_rtc_int_disable(NRF_RTC_Type * p_reg,uint32_t mask)32 void nrf_rtc_int_disable(NRF_RTC_Type * p_reg, uint32_t mask)
33 {
34 int i = rtc_number_from_ptr(p_reg);
35 p_reg->INTENCLR = mask;
36 nhw_rtc_regw_sideeffect_INTENCLR(i);
37 }
38
nrf_rtc_counter_get(NRF_RTC_Type const * p_reg)39 uint32_t nrf_rtc_counter_get(NRF_RTC_Type const * p_reg)
40 {
41 int i = rtc_number_from_ptr(p_reg);
42 nhw_rtc_update_COUNTER(i);
43 return p_reg->COUNTER;
44 }
45
nrf_rtc_task_trigger(NRF_RTC_Type * p_reg,nrf_rtc_task_t task)46 void nrf_rtc_task_trigger(NRF_RTC_Type * p_reg, nrf_rtc_task_t task)
47 {
48 *(uint32_t *)((uint32_t)p_reg + task) = 1;
49
50 int i = rtc_number_from_ptr(p_reg);
51
52 if ( task == NRF_RTC_TASK_START ) {
53 nhw_rtc_regw_sideeffect_TASKS_START(i);
54 } else if ( task == NRF_RTC_TASK_STOP ) {
55 nhw_rtc_regw_sideeffect_TASKS_STOP(i);
56 } else if ( task == NRF_RTC_TASK_CLEAR ) {
57 nhw_rtc_regw_sideeffect_TASKS_CLEAR(i);
58 } else if ( task == NRF_RTC_TASK_TRIGGER_OVERFLOW ) {
59 nhw_rtc_regw_sideeffect_TASKS_TRIGOVRFLW(i);
60 #if defined(RTC_TASKS_CAPTURE_TASKS_CAPTURE_Msk)
61 } else if ( task >= NRF_RTC_TASK_CAPTURE_0 ) {
62 int cc = (task - NRF_RTC_TASK_CAPTURE_0)/sizeof(uint32_t);
63 nhw_rtc_regw_sideeffect_TASKS_CAPTURE(i, cc);
64 #endif
65 } else {
66 bs_trace_error_line_time("Not supported task started in nrf_rtc %i\n", i);
67 }
68 }
69
nrf_rtc_event_clear(NRF_RTC_Type * p_reg,nrf_rtc_event_t event)70 void nrf_rtc_event_clear(NRF_RTC_Type * p_reg, nrf_rtc_event_t event)
71 {
72 *((volatile uint32_t *)((uint8_t *)p_reg + (uint32_t)event)) = 0;
73
74 int i = rtc_number_from_ptr(p_reg);
75 nhw_rtc_regw_sideeffects_EVENTS_all(i);
76 }
77
nrf_rtc_event_enable(NRF_RTC_Type * p_reg,uint32_t mask)78 void nrf_rtc_event_enable(NRF_RTC_Type * p_reg, uint32_t mask)
79 {
80 int i = rtc_number_from_ptr(p_reg);
81 p_reg->EVTENSET = mask;
82 nhw_rtc_regw_sideeffect_EVTENSET(i);
83 }
84
nrf_rtc_event_disable(NRF_RTC_Type * p_reg,uint32_t event)85 void nrf_rtc_event_disable(NRF_RTC_Type * p_reg, uint32_t event)
86 {
87 int i = rtc_number_from_ptr(p_reg);
88 p_reg->EVTENCLR = event;
89 nhw_rtc_regw_sideeffect_EVTENCLR(i);
90 }
91
92 #if defined(DPPI_PRESENT)
93
nrf_rtc_subscribe_common(NRF_RTC_Type * p_reg,nrf_rtc_task_t task)94 static void nrf_rtc_subscribe_common(NRF_RTC_Type * p_reg,
95 nrf_rtc_task_t task)
96 {
97 int i = rtc_number_from_ptr(p_reg);
98
99 if (task == NRF_RTC_TASK_START) {
100 nrf_rtc_regw_sideeffects_SUBSCRIBE_START(i);
101 } else if (task == NRF_RTC_TASK_STOP) {
102 nrf_rtc_regw_sideeffects_SUBSCRIBE_STOP(i);
103 } else if (task == NRF_RTC_TASK_CLEAR) {
104 nrf_rtc_regw_sideeffects_SUBSCRIBE_CLEAR(i);
105 } else if (task == NRF_RTC_TASK_TRIGGER_OVERFLOW) {
106 nrf_rtc_regw_sideeffects_SUBSCRIBE_TRIGOVRFLW(i);
107 #if defined(RTC_TASKS_CAPTURE_TASKS_CAPTURE_Msk)
108 } else if (task >= NRF_RTC_TASK_CAPTURE_0) {
109 int cc_n = (task - NRF_RTC_TASK_CAPTURE_0)/sizeof(uint32_t);
110 nhw_rtc_regw_sideeffects_SUBSCRIBE_CAPTURE(i, cc_n);
111 #endif
112 } else {
113 bs_trace_error_line_time("Attempted to subscribe to a not-supported task in the nrf_rtc (%i)\n",
114 task);
115 }
116 }
117
nrf_rtc_subscribe_set(NRF_RTC_Type * p_reg,nrf_rtc_task_t task,uint8_t channel)118 void nrf_rtc_subscribe_set(NRF_RTC_Type * p_reg,
119 nrf_rtc_task_t task,
120 uint8_t channel)
121 {
122 *((volatile uint32_t *) ((uint8_t *) p_reg + (uint32_t) task + 0x80uL)) =
123 ((uint32_t)channel | NRF_SUBSCRIBE_PUBLISH_ENABLE);
124 nrf_rtc_subscribe_common(p_reg, task);
125 }
126
nrf_rtc_subscribe_clear(NRF_RTC_Type * p_reg,nrf_rtc_task_t task)127 void nrf_rtc_subscribe_clear(NRF_RTC_Type * p_reg,
128 nrf_rtc_task_t task)
129 {
130 *((volatile uint32_t *) ((uint8_t *) p_reg + (uint32_t) task + 0x80uL)) = 0;
131 nrf_rtc_subscribe_common(p_reg, task);
132 }
133
134 #endif /* defined(DPPI_PRESENT) */
135