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