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_clock.h"
10 #include "bs_tracing.h"
11 #if defined(NRF54L15) || defined(NRF54L15_XXAA)
12 #include "NHW_54L_CLOCK.h"
13 #else
14 #include "NHW_CLOCK.h"
15 #endif
16
clock_number_from_ptr(NRF_CLOCK_Type * p_reg)17 static int clock_number_from_ptr(NRF_CLOCK_Type * p_reg)
18 {
19 union NRF_CLKPWR_Type *p = (union NRF_CLKPWR_Type *)p_reg;
20
21 int i = ( (int)p - (int)&NRF_CLKPWR_regs[0] ) / sizeof(union NRF_CLKPWR_Type);
22 return i;
23 }
24
nrf_clock_int_enable(NRF_CLOCK_Type * p_reg,uint32_t mask)25 void nrf_clock_int_enable(NRF_CLOCK_Type * p_reg, uint32_t mask)
26 {
27 p_reg->INTENSET = mask;
28
29 int i = clock_number_from_ptr(p_reg);
30 nhw_CLOCK_regw_sideeffects_INTENSET(i);
31 }
32
nrf_clock_int_disable(NRF_CLOCK_Type * p_reg,uint32_t mask)33 void nrf_clock_int_disable(NRF_CLOCK_Type * p_reg, uint32_t mask)
34 {
35 p_reg->INTENCLR = mask;
36
37 int i = clock_number_from_ptr(p_reg);
38 nhw_CLOCK_regw_sideeffects_INTENCLR(i);
39 }
40
nrf_clock_task_trigger(NRF_CLOCK_Type * p_reg,nrf_clock_task_t task)41 void nrf_clock_task_trigger(NRF_CLOCK_Type * p_reg, nrf_clock_task_t task)
42 {
43 *((volatile uint32_t *)((uint8_t *)p_reg + (uint32_t)task)) = 0x1UL;
44
45 int i = clock_number_from_ptr(p_reg);
46
47 #define CASE_TASK(TASKN) \
48 case NRF_CLOCK_TASK_##TASKN: nhw_CLOCK_regw_sideeffects_TASKS_##TASKN(i); break;
49
50 switch (task) {
51 #if NRF_CLOCK_HAS_XO
52 case NRF_CLOCK_TASK_HFCLKSTART: nhw_CLOCK_regw_sideeffects_TASKS_XOSTART(i); break;
53 case NRF_CLOCK_TASK_HFCLKSTOP : nhw_CLOCK_regw_sideeffects_TASKS_XOSTOP(i); break;
54 #else
55 CASE_TASK(HFCLKSTART)
56 CASE_TASK(HFCLKSTOP)
57 #endif
58 #if NRF_CLOCK_HAS_PLL
59 CASE_TASK(PLLSTART)
60 CASE_TASK(PLLSTOP)
61 #endif
62 CASE_TASK(LFCLKSTART)
63 CASE_TASK(LFCLKSTOP)
64 #if NRF_CLOCK_HAS_CALIBRATION
65 CASE_TASK(CAL)
66 #endif
67 #if NRF_CLOCK_HAS_CALIBRATION_TIMER
68 CASE_TASK(CTSTART)
69 CASE_TASK(CTSTOP)
70 #endif
71 #if NRF_CLOCK_HAS_HFCLKAUDIO
72 CASE_TASK(HFCLKAUDIOSTART)
73 CASE_TASK(HFCLKAUDIOSTOP)
74 #endif
75 #if NRF_CLOCK_HAS_HFCLK192M
76 CASE_TASK(HFCLK192MSTART)
77 CASE_TASK(HFCLK192MSTOP)
78 #endif
79 //Note: XOTUNE and XOTUNEABORT missing from the HAL at this point
80 default:
81 bs_trace_error_line_time("Not supported task started in nrf_clock, %d\n", task);
82 break;
83 }
84 #undef CASE_TASK
85 }
86
nrf_clock_event_clear(NRF_CLOCK_Type * p_reg,nrf_clock_event_t event)87 void nrf_clock_event_clear(NRF_CLOCK_Type * p_reg, nrf_clock_event_t event)
88 {
89 *((volatile uint32_t *)((uint8_t *)p_reg + (uint32_t)event)) = 0x0UL;
90
91 int i = clock_number_from_ptr(p_reg);
92 nhw_pwrclk_regw_sideeffects_EVENTS_all(i);
93 }
94
95 #if defined(DPPI_PRESENT)
96
nrf_clock_subscribe_common(NRF_CLOCK_Type * p_reg,nrf_clock_task_t task)97 static void nrf_clock_subscribe_common(NRF_CLOCK_Type * p_reg,
98 nrf_clock_task_t task)
99 {
100 int i = clock_number_from_ptr(p_reg);
101
102 #define CASE_TASK(TASKN) \
103 case NRF_CLOCK_TASK_##TASKN: nhw_CLOCK_regw_sideeffects_SUBSCRIBE_##TASKN(i); break;
104
105 switch (task) {
106 #if NRF_CLOCK_HAS_XO
107 case NRF_CLOCK_TASK_HFCLKSTART: nhw_CLOCK_regw_sideeffects_SUBSCRIBE_XOSTART(i); break;
108 case NRF_CLOCK_TASK_HFCLKSTOP: nhw_CLOCK_regw_sideeffects_SUBSCRIBE_XOSTOP(i); break;
109 #else
110 CASE_TASK(HFCLKSTART)
111 CASE_TASK(HFCLKSTOP)
112 #endif
113 #if NRF_CLOCK_HAS_PLL
114 CASE_TASK(PLLSTART)
115 CASE_TASK(PLLSTOP)
116 #endif
117 CASE_TASK(LFCLKSTART)
118 CASE_TASK(LFCLKSTOP)
119 #if NRF_CLOCK_HAS_CALIBRATION
120 CASE_TASK(CAL)
121 #endif
122 #if NRF_CLOCK_HAS_HFCLKAUDIO
123 CASE_TASK(HFCLKAUDIOSTART)
124 CASE_TASK(HFCLKAUDIOSTOP)
125 #endif
126 #if NRF_CLOCK_HAS_HFCLK192M
127 CASE_TASK(HFCLK192MSTART)
128 CASE_TASK(HFCLK192MSTOP)
129 #endif
130 //Note: XOTUNE and XOTUNEABORT missing from the HAL at this point
131 default:
132 bs_trace_error_line_time("Attempted to subscribe to a not-supported task in the nrf_clock (%i)\n",
133 task);
134 break;
135 }
136 #undef CASE_TASK
137 }
138
nrf_clock_subscribe_set(NRF_CLOCK_Type * p_reg,nrf_clock_task_t task,uint8_t channel)139 void nrf_clock_subscribe_set(NRF_CLOCK_Type * p_reg,
140 nrf_clock_task_t task,
141 uint8_t channel)
142 {
143 *((volatile uint32_t *) ((uint8_t *) p_reg + (uint32_t) task + 0x80uL)) =
144 ((uint32_t)channel | NRF_SUBSCRIBE_PUBLISH_ENABLE);
145 nrf_clock_subscribe_common(p_reg, task);
146 }
147
nrf_clock_subscribe_clear(NRF_CLOCK_Type * p_reg,nrf_clock_task_t task)148 void nrf_clock_subscribe_clear(NRF_CLOCK_Type * p_reg,
149 nrf_clock_task_t task)
150 {
151 *((volatile uint32_t *) ((uint8_t *) p_reg + (uint32_t) task + 0x80uL)) = 0;
152 nrf_clock_subscribe_common(p_reg, task);
153 }
154
155 #endif /* defined(DPPI_PRESENT) */
156