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 #include "NHW_CLOCK.h"
12
clock_number_from_ptr(NRF_CLOCK_Type * p_reg)13 static int clock_number_from_ptr(NRF_CLOCK_Type * p_reg)
14 {
15 union NRF_CLKPWR_Type *p = (union NRF_CLKPWR_Type *)p_reg;
16
17 int i = ( (int)p - (int)&NRF_CLKPWR_regs[0] ) / sizeof(union NRF_CLKPWR_Type);
18 return i;
19 }
20
nrf_clock_int_enable(NRF_CLOCK_Type * p_reg,uint32_t mask)21 void nrf_clock_int_enable(NRF_CLOCK_Type * p_reg, uint32_t mask)
22 {
23 p_reg->INTENSET = mask;
24
25 int i = clock_number_from_ptr(p_reg);
26 nhw_clock_regw_sideeffects_INTENSET(i);
27 }
28
nrf_clock_int_disable(NRF_CLOCK_Type * p_reg,uint32_t mask)29 void nrf_clock_int_disable(NRF_CLOCK_Type * p_reg, uint32_t mask)
30 {
31 p_reg->INTENCLR = mask;
32
33 int i = clock_number_from_ptr(p_reg);
34 nhw_clock_regw_sideeffects_INTENCLR(i);
35 }
36
nrf_clock_task_trigger(NRF_CLOCK_Type * p_reg,nrf_clock_task_t task)37 void nrf_clock_task_trigger(NRF_CLOCK_Type * p_reg, nrf_clock_task_t task)
38 {
39 *((volatile uint32_t *)((uint8_t *)p_reg + (uint32_t)task)) = 0x1UL;
40
41 int i = clock_number_from_ptr(p_reg);
42
43 #define CASE_TASK(TASKN) \
44 case NRF_CLOCK_TASK_##TASKN: nhw_clock_regw_sideeffects_TASKS_##TASKN(i); break;
45
46 switch (task) {
47 CASE_TASK(HFCLKSTART)
48 CASE_TASK(HFCLKSTOP)
49 CASE_TASK(LFCLKSTART)
50 CASE_TASK(LFCLKSTOP)
51 CASE_TASK(CAL)
52 #if NRF_CLOCK_HAS_CALIBRATION_TIMER
53 CASE_TASK(CTSTART)
54 CASE_TASK(CTSTOP)
55 #endif
56 #if NRF_CLOCK_HAS_HFCLKAUDIO
57 CASE_TASK(HFCLKAUDIOSTART)
58 CASE_TASK(HFCLKAUDIOSTOP)
59 #endif
60 #if NRF_CLOCK_HAS_HFCLK192M
61 CASE_TASK(HFCLK192MSTART)
62 CASE_TASK(HFCLK192MSTOP)
63 #endif
64 default:
65 bs_trace_error_line_time("Not supported task started in nrf_clock, %d\n", task);
66 break;
67 }
68 #undef CASE_TASK
69 }
70
nrf_clock_event_clear(NRF_CLOCK_Type * p_reg,nrf_clock_event_t event)71 void nrf_clock_event_clear(NRF_CLOCK_Type * p_reg, nrf_clock_event_t event)
72 {
73 *((volatile uint32_t *)((uint8_t *)p_reg + (uint32_t)event)) = 0x0UL;
74
75 int i = clock_number_from_ptr(p_reg);
76 nhw_pwrclk_regw_sideeffects_EVENTS_all(i);
77 }
78
79 #if defined(DPPI_PRESENT)
80
nrf_clock_subscribe_common(NRF_CLOCK_Type * p_reg,nrf_clock_task_t task)81 static void nrf_clock_subscribe_common(NRF_CLOCK_Type * p_reg,
82 nrf_clock_task_t task)
83 {
84 int i = clock_number_from_ptr(p_reg);
85
86 #define CASE_TASK(TASKN) \
87 case NRF_CLOCK_TASK_##TASKN: nhw_clock_regw_sideeffects_SUBSCRIBE_##TASKN(i); break;
88
89 switch (task) {
90 CASE_TASK(HFCLKSTART)
91 CASE_TASK(HFCLKSTOP)
92 CASE_TASK(LFCLKSTART)
93 CASE_TASK(LFCLKSTOP)
94 CASE_TASK(CAL)
95 #if NRF_CLOCK_HAS_HFCLKAUDIO
96 CASE_TASK(HFCLKAUDIOSTART)
97 CASE_TASK(HFCLKAUDIOSTOP)
98 #endif
99 #if NRF_CLOCK_HAS_HFCLK192M
100 CASE_TASK(HFCLK192MSTART)
101 CASE_TASK(HFCLK192MSTOP)
102 #endif
103 default:
104 bs_trace_error_line_time("Attempted to subscribe to a not-supported task in the nrf_clock (%i)\n",
105 task);
106 break;
107 }
108 #undef CASE_TASK
109 }
110
nrf_clock_subscribe_set(NRF_CLOCK_Type * p_reg,nrf_clock_task_t task,uint8_t channel)111 void nrf_clock_subscribe_set(NRF_CLOCK_Type * p_reg,
112 nrf_clock_task_t task,
113 uint8_t channel)
114 {
115 *((volatile uint32_t *) ((uint8_t *) p_reg + (uint32_t) task + 0x80uL)) =
116 ((uint32_t)channel | NRF_SUBSCRIBE_PUBLISH_ENABLE);
117 nrf_clock_subscribe_common(p_reg, task);
118 }
119
nrf_clock_subscribe_clear(NRF_CLOCK_Type * p_reg,nrf_clock_task_t task)120 void nrf_clock_subscribe_clear(NRF_CLOCK_Type * p_reg,
121 nrf_clock_task_t task)
122 {
123 *((volatile uint32_t *) ((uint8_t *) p_reg + (uint32_t) task + 0x80uL)) = 0;
124 nrf_clock_subscribe_common(p_reg, task);
125 }
126
127 #endif /* defined(DPPI_PRESENT) */
128