1 /*
2 * Copyright (c) 2024 Nordic Semiconductor ASA
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 *
6 * Note that the function prototypes are taken from the NRFx HAL
7 */
8 #include "hal/nrf_grtc.h"
9 #include "bs_tracing.h"
10 #include "NHW_GRTC.h"
11
nrf_grtc_sys_counter_cc_set(NRF_GRTC_Type * p_reg,uint8_t cc_channel,uint64_t cc_value)12 void nrf_grtc_sys_counter_cc_set(NRF_GRTC_Type * p_reg,
13 uint8_t cc_channel,
14 uint64_t cc_value)
15 {
16 #if NRF_GRTC_HAS_EXTENDED
17 NRFX_ASSERT(cc_channel < NRF_GRTC_SYSCOUNTER_CC_COUNT);
18 #else
19 NRFX_ASSERT(cc_channel < NRF_GRTC_SYSCOUNTER_CC_COUNT &&
20 cc_channel > NRF_GRTC_MAIN_CC_CHANNEL);
21 #endif
22 uint32_t cc_h = (uint32_t)(cc_value >> 32);
23 NRFX_ASSERT(cc_h <= NRF_GRTC_SYSCOUNTER_CCH_MASK);
24
25 p_reg->CC[cc_channel].CCL = (uint32_t)cc_value;
26 nhw_GRTC_regw_sideeffects_CC_CCL(0, cc_channel);
27 p_reg->CC[cc_channel].CCH = cc_h & NRF_GRTC_SYSCOUNTER_CCH_MASK;
28 nhw_GRTC_regw_sideeffects_CC_CCH(0, cc_channel);
29 }
30
nrf_grtc_sys_counter_cc_add_set(NRF_GRTC_Type * p_reg,uint8_t cc_channel,uint32_t value,nrf_grtc_cc_add_reference_t reference)31 void nrf_grtc_sys_counter_cc_add_set(NRF_GRTC_Type * p_reg,
32 uint8_t cc_channel,
33 uint32_t value,
34 nrf_grtc_cc_add_reference_t reference)
35 {
36 #if NRF_GRTC_HAS_EXTENDED
37 NRFX_ASSERT(cc_channel < NRF_GRTC_SYSCOUNTER_CC_COUNT);
38 #else
39 NRFX_ASSERT(cc_channel < NRF_GRTC_SYSCOUNTER_CC_COUNT &&
40 cc_channel > NRF_GRTC_MAIN_CC_CHANNEL);
41 #endif
42 NRFX_ASSERT(value <= NRF_GRTC_SYSCOUNTER_CCADD_MASK);
43
44 p_reg->CC[cc_channel].CCADD = ((uint32_t)reference << GRTC_CC_CCADD_REFERENCE_Pos) |
45 (value & NRF_GRTC_SYSCOUNTER_CCADD_MASK);
46 nhw_GRTC_regw_sideeffects_CC_CCADD(0, cc_channel);
47 }
48
nrf_grtc_int_enable(NRF_GRTC_Type * p_reg,uint32_t mask)49 void nrf_grtc_int_enable(NRF_GRTC_Type * p_reg, uint32_t mask)
50 {
51 p_reg->GRTC_INTENSET = mask;
52 nhw_GRTC_regw_sideeffects_INTENSET(0, GRTC_IRQ_GROUP);
53 }
54
nrf_grtc_int_disable(NRF_GRTC_Type * p_reg,uint32_t mask)55 void nrf_grtc_int_disable(NRF_GRTC_Type * p_reg, uint32_t mask)
56 {
57 p_reg->GRTC_INTENCLR = mask;
58 nhw_GRTC_regw_sideeffects_INTENCLR(0, GRTC_IRQ_GROUP);
59 }
60
61 #define INTENGRPOFFSET (offsetof(NRF_GRTC_Type, INTENSET1) - offsetof(NRF_GRTC_Type, INTENSET0))
62
nrf_grtc_int_group_enable(NRF_GRTC_Type * p_reg,uint8_t group_idx,uint32_t mask)63 void nrf_grtc_int_group_enable(NRF_GRTC_Type * p_reg,
64 uint8_t group_idx,
65 uint32_t mask)
66 {
67 *(uint32_t*)((char*)p_reg->INTENSET0 + INTENGRPOFFSET*group_idx) = mask;
68 nhw_GRTC_regw_sideeffects_INTENSET(0, group_idx);
69 }
70
nrf_grtc_int_group_disable(NRF_GRTC_Type * p_reg,uint8_t group_idx,uint32_t mask)71 void nrf_grtc_int_group_disable(NRF_GRTC_Type * p_reg,
72 uint8_t group_idx,
73 uint32_t mask)
74 {
75 *(uint32_t*)((char*)p_reg->INTENCLR0 + INTENGRPOFFSET*group_idx) = mask;
76 nhw_GRTC_regw_sideeffects_INTENCLR(0, group_idx);
77 }
78
nrf_grtc_subscribe_set(NRF_GRTC_Type * p_reg,nrf_grtc_task_t task,uint8_t channel)79 void nrf_grtc_subscribe_set(NRF_GRTC_Type * p_reg,
80 nrf_grtc_task_t task,
81 uint8_t channel)
82 {
83 #if NRF_GRTC_HAS_EXTENDED
84 NRFX_ASSERT((task != NRF_GRTC_TASK_START) &&
85 (task != NRF_GRTC_TASK_CLEAR) &&
86 (task != NRF_GRTC_TASK_STOP));
87 #endif
88
89 *((volatile uint32_t *) ((uint8_t *) p_reg + (uint32_t) task + 0x80uL)) =
90 ((uint32_t)channel | NRF_SUBSCRIBE_PUBLISH_ENABLE);
91
92 int task_nbr = (task - NRF_GRTC_TASK_CAPTURE_0)/sizeof(uint32_t);
93
94 nhw_GRTC_regw_sideeffects_SUBSCRIBE_CAPTURE(0, task_nbr);
95 }
96
nrf_grtc_subscribe_clear(NRF_GRTC_Type * p_reg,nrf_grtc_task_t task)97 void nrf_grtc_subscribe_clear(NRF_GRTC_Type * p_reg,
98 nrf_grtc_task_t task)
99 {
100 #if NRF_GRTC_HAS_EXTENDED
101 NRFX_ASSERT((task != NRF_GRTC_TASK_START) &&
102 (task != NRF_GRTC_TASK_CLEAR) &&
103 (task != NRF_GRTC_TASK_STOP));
104 #endif
105
106 *((volatile uint32_t *) ((uint8_t *) p_reg + (uint32_t) task + 0x80uL)) = 0;
107
108 int task_nbr = (task - NRF_GRTC_TASK_CAPTURE_0)/sizeof(uint32_t);
109
110 nhw_GRTC_regw_sideeffects_SUBSCRIBE_CAPTURE(0, task_nbr);
111 }
112
nrf_grtc_event_clear(NRF_GRTC_Type * p_reg,nrf_grtc_event_t event)113 void nrf_grtc_event_clear(NRF_GRTC_Type * p_reg, nrf_grtc_event_t event)
114 {
115 *((volatile uint32_t *)((uint8_t *)p_reg + (uint32_t)event)) = 0x0UL;
116
117 nhw_GRTC_regw_sideeffects_EVENTS_all(0);
118 }
119
120
nrf_grtc_sys_counter_low_get(NRF_GRTC_Type const * p_reg)121 uint32_t nrf_grtc_sys_counter_low_get(NRF_GRTC_Type const * p_reg)
122 {
123 (void) p_reg;
124 #if NRF_GRTC_HAS_SYSCOUNTER_ARRAY
125 return nhw_GRTC_regr_sideeffects_SYSCOUNTERL(0, NRF_GRTC_DOMAIN_INDEX);
126 #else
127 #error "Not supported"
128 #endif // NRF_GRTC_HAS_SYSCOUNTER_ARRAY
129
130 }
131
nrf_grtc_sys_counter_high_get(NRF_GRTC_Type const * p_reg)132 uint32_t nrf_grtc_sys_counter_high_get(NRF_GRTC_Type const * p_reg)
133 {
134 (void) p_reg;
135 #if NRF_GRTC_HAS_SYSCOUNTER_ARRAY
136 return nhw_GRTC_regr_sideeffects_SYSCOUNTERH(0, NRF_GRTC_DOMAIN_INDEX);
137 #else
138 #error "Not supported"
139 #endif // NRF_GRTC_HAS_SYSCOUNTER_ARRAY
140 }
141
nrf_grtc_sys_counter_get(NRF_GRTC_Type const * p_reg)142 uint64_t nrf_grtc_sys_counter_get(NRF_GRTC_Type const * p_reg)
143 {
144 nhw_GRTC_regr_sideeffects_SYSCOUNTERL(0, NRF_GRTC_DOMAIN_INDEX);
145 nhw_GRTC_regr_sideeffects_SYSCOUNTERH(0, NRF_GRTC_DOMAIN_INDEX);
146 return *((const uint64_t volatile *)&p_reg->GRTC_SYSCOUNTER.SYSCOUNTERL);
147 }
148
nrf_grtc_sys_counter_overflow_check(NRF_GRTC_Type const * p_reg)149 bool nrf_grtc_sys_counter_overflow_check(NRF_GRTC_Type const * p_reg)
150 {
151 nhw_GRTC_regr_sideeffects_SYSCOUNTERH(0, NRF_GRTC_DOMAIN_INDEX);
152 return (p_reg->GRTC_SYSCOUNTER.SYSCOUNTERH &
153 GRTC_SYSCOUNTER_SYSCOUNTERH_OVERFLOW_Msk) ? true : false;
154 }
155
nrf_grtc_sys_counter_indexed_get(NRF_GRTC_Type const * p_reg,uint8_t index)156 uint64_t nrf_grtc_sys_counter_indexed_get(NRF_GRTC_Type const * p_reg,
157 uint8_t index)
158 {
159 nhw_GRTC_regr_sideeffects_SYSCOUNTERL(0, index);
160 nhw_GRTC_regr_sideeffects_SYSCOUNTERH(0, index);
161 return *((const uint64_t volatile *)&p_reg->SYSCOUNTER[index]);
162 }
163
nrf_grtc_task_trigger(NRF_GRTC_Type * p_reg,nrf_grtc_task_t grtc_task)164 void nrf_grtc_task_trigger(NRF_GRTC_Type * p_reg, nrf_grtc_task_t grtc_task)
165 {
166 uint inst = 0;
167 *((volatile uint32_t *)((uint8_t *)p_reg + (uint32_t)grtc_task)) = 0x1UL;
168
169 if ((grtc_task >= NRF_GRTC_TASK_CAPTURE_0) && (grtc_task < NRF_GRTC_TASK_START)) {
170 int task_nbr = (grtc_task - NRF_GRTC_TASK_CAPTURE_0)/sizeof(uint32_t);
171 nhw_GRTC_regw_sideeffects_TASKS_CAPTURE(inst, task_nbr);
172 } else if (grtc_task == NRF_GRTC_TASK_START) {
173 nhw_GRTC_regw_sideeffects_TASKS_START(inst);
174 } else if (grtc_task == NRF_GRTC_TASK_STOP) {
175 nhw_GRTC_regw_sideeffects_TASKS_STOP(inst);
176 } else if (grtc_task == NRF_GRTC_TASK_CLEAR) {
177 nhw_GRTC_regw_sideeffects_TASKS_CLEAR(inst);
178 #if NRF_GRTC_HAS_PWM
179 } else if (grtc_task == NRF_GRTC_TASK_PWM_START) {
180 nhw_GRTC_regw_sideeffects_TASKS_PWMSTART(inst);
181 } else if (grtc_task == NRF_GRTC_TASK_PWM_STOP) {
182 nhw_GRTC_regw_sideeffects_TASKS_PWMSTOP(inst);
183 #endif
184 } else {
185 bs_trace_error_time_line("GRTC task %i not known\n", grtc_task);
186 }
187 }
188
nrf_grtc_sys_counter_compare_event_enable(NRF_GRTC_Type * p_reg,uint8_t cc_channel)189 void nrf_grtc_sys_counter_compare_event_enable(NRF_GRTC_Type * p_reg,
190 uint8_t cc_channel)
191 {
192
193 #if NRF_GRTC_HAS_EXTENDED
194 NRFX_ASSERT(cc_channel < NRF_GRTC_SYSCOUNTER_CC_COUNT);
195 #else
196 NRFX_ASSERT(cc_channel < NRF_GRTC_SYSCOUNTER_CC_COUNT &&
197 cc_channel > NRF_GRTC_MAIN_CC_CHANNEL);
198 #endif
199 p_reg->CC[cc_channel].CCEN = GRTC_CC_CCEN_ACTIVE_Enable;
200 nhw_GRTC_regw_sideeffects_CC_CCEN(0, cc_channel);
201 }
202
nrf_grtc_sys_counter_compare_event_disable(NRF_GRTC_Type * p_reg,uint8_t cc_channel)203 NRF_STATIC_INLINE void nrf_grtc_sys_counter_compare_event_disable(NRF_GRTC_Type * p_reg,
204 uint8_t cc_channel)
205 {
206 #if NRF_GRTC_HAS_EXTENDED
207 NRFX_ASSERT(cc_channel < NRF_GRTC_SYSCOUNTER_CC_COUNT);
208 #else
209 NRFX_ASSERT(cc_channel < NRF_GRTC_SYSCOUNTER_CC_COUNT &&
210 cc_channel > NRF_GRTC_MAIN_CC_CHANNEL);
211 #endif
212 p_reg->CC[cc_channel].CCEN = GRTC_CC_CCEN_ACTIVE_Disable;
213 nhw_GRTC_regw_sideeffects_CC_CCEN(0, cc_channel);
214 }
215