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