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