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 
10 #include <stdint.h>
11 #include "hal/nrf_timer.h"
12 #include "bs_tracing.h"
13 #include "NHW_TIMER.h"
14 
timer_number_from_ptr(NRF_TIMER_Type * p_reg)15 static int timer_number_from_ptr(NRF_TIMER_Type * p_reg){
16   int i = ( (int)p_reg - (int)&NRF_TIMER_regs[0] ) / sizeof(NRF_TIMER_Type);
17   return i;
18 }
19 
nrf_timer_cc_set(NRF_TIMER_Type * p_reg,nrf_timer_cc_channel_t cc_channel,uint32_t cc_value)20 void nrf_timer_cc_set(NRF_TIMER_Type * p_reg,
21     nrf_timer_cc_channel_t cc_channel,
22     uint32_t               cc_value)
23 {
24   int i = timer_number_from_ptr(p_reg);
25   p_reg->CC[cc_channel] = cc_value;
26   nhw_timer_regw_sideeffects_CC(i, cc_channel);
27 }
28 
nrf_timer_task_trigger(NRF_TIMER_Type * p_reg,nrf_timer_task_t task)29 void nrf_timer_task_trigger(NRF_TIMER_Type * p_reg,
30                             nrf_timer_task_t task)
31 {
32   int i = timer_number_from_ptr(p_reg);
33 
34   *((volatile uint32_t *)((uint8_t *)p_reg + (uint32_t)task)) = 0x1UL;
35 
36   if (task == NRF_TIMER_TASK_START) {
37     nhw_timer_regw_sideeffects_TASKS_START(i);
38   } else if (task == NRF_TIMER_TASK_STOP) {
39     nhw_timer_regw_sideeffects_TASKS_STOP(i);
40   } else if (task == NRF_TIMER_TASK_COUNT) {
41     nhw_timer_regw_sideeffects_TASKS_COUNT(i);
42   } else if (task == NRF_TIMER_TASK_CLEAR) {
43     nhw_timer_regw_sideeffects_TASKS_CLEAR(i);
44   } else if (task == NRF_TIMER_TASK_SHUTDOWN) {
45     nhw_timer_regw_sideeffects_TASKS_SHUTDOWN(i);
46   } else if (task >= NRF_TIMER_TASK_CAPTURE0) {
47     int task_nbr = (task - NRF_TIMER_TASK_CAPTURE0)/sizeof(uint32_t);
48     nhw_timer_regw_sideeffects_TASKS_CAPTURE(i, task_nbr);
49   } else {
50     bs_trace_error_line_time("Not supported task started in nrf_timer%i\n",
51                              (int) task);
52   }
53 }
54 
nrf_timer_event_clear(NRF_TIMER_Type * p_reg,nrf_timer_event_t event)55 void nrf_timer_event_clear(NRF_TIMER_Type *  p_reg,
56                            nrf_timer_event_t event)
57 {
58     *((volatile uint32_t *)((uint8_t *)p_reg + (uint32_t)event)) = 0x0UL;
59     int t = timer_number_from_ptr(p_reg);
60     nhw_timer_regw_sideeffects_EVENTS_all(t);
61 }
62 
nrf_timer_int_enable(NRF_TIMER_Type * p_reg,uint32_t mask)63 void nrf_timer_int_enable(NRF_TIMER_Type * p_reg,
64                           uint32_t         mask)
65 {
66     int i = timer_number_from_ptr(p_reg);
67     p_reg->INTENSET = mask;
68     nhw_timer_regw_sideeffects_INTENSET(i);
69 }
70 
nrf_timer_int_disable(NRF_TIMER_Type * p_reg,uint32_t mask)71 void nrf_timer_int_disable(NRF_TIMER_Type * p_reg,
72                            uint32_t         mask)
73 {
74     int i = timer_number_from_ptr(p_reg);
75     p_reg->INTENCLR = mask;
76     nhw_timer_regw_sideeffects_INTENCLR(i);
77 }
78 
79 #if defined(DPPI_PRESENT)
80 
nrf_timer_subscribe_common(NRF_TIMER_Type * p_reg,nrf_timer_task_t task)81 static void nrf_timer_subscribe_common(NRF_TIMER_Type * p_reg,
82                                        nrf_timer_task_t task)
83 {
84   int i = timer_number_from_ptr(p_reg);
85 
86   if (task == NRF_TIMER_TASK_START) {
87     nhw_timer_regw_sideeffects_SUBSCRIBE_START(i);
88   } else if (task == NRF_TIMER_TASK_STOP) {
89     nhw_timer_regw_sideeffects_SUBSCRIBE_STOP(i);
90   } else if (task == NRF_TIMER_TASK_COUNT) {
91     nhw_timer_regw_sideeffects_SUBSCRIBE_COUNT(i);
92   } else if (task == NRF_TIMER_TASK_CLEAR) {
93     nhw_timer_regw_sideeffects_SUBSCRIBE_CLEAR(i);
94   } else if (task == NRF_TIMER_TASK_SHUTDOWN) {
95     nhw_timer_regw_sideeffects_SUBSCRIBE_SHUTDOWN(i);
96   } else if (task >= NRF_TIMER_TASK_CAPTURE0) {
97     int task_nbr = (task - NRF_TIMER_TASK_CAPTURE0)/sizeof(uint32_t);
98     nhw_timer_regw_sideeffects_SUBSCRIBE_CAPTURE(i, task_nbr);
99   } else {
100     bs_trace_error_line_time("Attempted to subscribe to a not-supported task in the nrf_timer (%i)\n",
101                              task);
102   }
103 }
104 
nrf_timer_subscribe_set(NRF_TIMER_Type * p_reg,nrf_timer_task_t task,uint8_t channel)105 void nrf_timer_subscribe_set(NRF_TIMER_Type * p_reg,
106                              nrf_timer_task_t task,
107                              uint8_t          channel)
108 {
109     *((volatile uint32_t *) ((uint8_t *) p_reg + (uint32_t) task + 0x80uL)) =
110             ((uint32_t)channel | NRF_SUBSCRIBE_PUBLISH_ENABLE);
111     nrf_timer_subscribe_common(p_reg, task);
112 }
113 
nrf_timer_subscribe_clear(NRF_TIMER_Type * p_reg,nrf_timer_task_t task)114 void nrf_timer_subscribe_clear(NRF_TIMER_Type * p_reg,
115                                nrf_timer_task_t task)
116 {
117     *((volatile uint32_t *) ((uint8_t *) p_reg + (uint32_t) task + 0x80uL)) = 0;
118     nrf_timer_subscribe_common(p_reg, task);
119 }
120 
121 #endif /* defined(DPPI_PRESENT) */
122