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 #if defined(TIMER_TASKS_SHUTDOWN_TASKS_SHUTDOWN_Msk)
45   } else if (task == NRF_TIMER_TASK_SHUTDOWN) {
46     nhw_timer_regw_sideeffects_TASKS_SHUTDOWN(i);
47 #endif
48   } else if (task >= NRF_TIMER_TASK_CAPTURE0) {
49     int task_nbr = (task - NRF_TIMER_TASK_CAPTURE0)/sizeof(uint32_t);
50     nhw_timer_regw_sideeffects_TASKS_CAPTURE(i, task_nbr);
51   } else {
52     bs_trace_error_line_time("Not supported task started in nrf_timer%i\n",
53                              (int) task);
54   }
55 }
56 
nrf_timer_event_clear(NRF_TIMER_Type * p_reg,nrf_timer_event_t event)57 void nrf_timer_event_clear(NRF_TIMER_Type *  p_reg,
58                            nrf_timer_event_t event)
59 {
60     *((volatile uint32_t *)((uint8_t *)p_reg + (uint32_t)event)) = 0x0UL;
61     int t = timer_number_from_ptr(p_reg);
62     nhw_timer_regw_sideeffects_EVENTS_all(t);
63 }
64 
nrf_timer_int_enable(NRF_TIMER_Type * p_reg,uint32_t mask)65 void nrf_timer_int_enable(NRF_TIMER_Type * p_reg,
66                           uint32_t         mask)
67 {
68     int i = timer_number_from_ptr(p_reg);
69     p_reg->INTENSET = mask;
70     nhw_timer_regw_sideeffects_INTENSET(i);
71 }
72 
nrf_timer_int_disable(NRF_TIMER_Type * p_reg,uint32_t mask)73 void nrf_timer_int_disable(NRF_TIMER_Type * p_reg,
74                            uint32_t         mask)
75 {
76     int i = timer_number_from_ptr(p_reg);
77     p_reg->INTENCLR = mask;
78     nhw_timer_regw_sideeffects_INTENCLR(i);
79 }
80 
81 #if defined(DPPI_PRESENT)
82 
nrf_timer_subscribe_common(NRF_TIMER_Type * p_reg,nrf_timer_task_t task)83 static void nrf_timer_subscribe_common(NRF_TIMER_Type * p_reg,
84                                        nrf_timer_task_t task)
85 {
86   int i = timer_number_from_ptr(p_reg);
87 
88   if (task == NRF_TIMER_TASK_START) {
89     nhw_timer_regw_sideeffects_SUBSCRIBE_START(i);
90   } else if (task == NRF_TIMER_TASK_STOP) {
91     nhw_timer_regw_sideeffects_SUBSCRIBE_STOP(i);
92   } else if (task == NRF_TIMER_TASK_COUNT) {
93     nhw_timer_regw_sideeffects_SUBSCRIBE_COUNT(i);
94   } else if (task == NRF_TIMER_TASK_CLEAR) {
95     nhw_timer_regw_sideeffects_SUBSCRIBE_CLEAR(i);
96 #if defined(TIMER_TASKS_SHUTDOWN_TASKS_SHUTDOWN_Msk)
97   } else if (task == NRF_TIMER_TASK_SHUTDOWN) {
98     nhw_timer_regw_sideeffects_SUBSCRIBE_SHUTDOWN(i);
99 #endif
100   } else if (task >= NRF_TIMER_TASK_CAPTURE0) {
101     int task_nbr = (task - NRF_TIMER_TASK_CAPTURE0)/sizeof(uint32_t);
102     nhw_timer_regw_sideeffects_SUBSCRIBE_CAPTURE(i, task_nbr);
103   } else {
104     bs_trace_error_line_time("Attempted to subscribe to a not-supported task in the nrf_timer (%i)\n",
105                              task);
106   }
107 }
108 
nrf_timer_subscribe_set(NRF_TIMER_Type * p_reg,nrf_timer_task_t task,uint8_t channel)109 void nrf_timer_subscribe_set(NRF_TIMER_Type * p_reg,
110                              nrf_timer_task_t task,
111                              uint8_t          channel)
112 {
113     *((volatile uint32_t *) ((uint8_t *) p_reg + (uint32_t) task + 0x80uL)) =
114             ((uint32_t)channel | NRF_SUBSCRIBE_PUBLISH_ENABLE);
115     nrf_timer_subscribe_common(p_reg, task);
116 }
117 
nrf_timer_subscribe_clear(NRF_TIMER_Type * p_reg,nrf_timer_task_t task)118 void nrf_timer_subscribe_clear(NRF_TIMER_Type * p_reg,
119                                nrf_timer_task_t task)
120 {
121     *((volatile uint32_t *) ((uint8_t *) p_reg + (uint32_t) task + 0x80uL)) = 0;
122     nrf_timer_subscribe_common(p_reg, task);
123 }
124 
125 #endif /* defined(DPPI_PRESENT) */
126