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