1 /*
2 * Copyright (c) 2016-2018 Nordic Semiconductor ASA
3 * Copyright (c) 2016 Vinayak Kariappa Chettimada
4 *
5 * SPDX-License-Identifier: Apache-2.0
6 */
7
8 #include <stdint.h>
9 #include <stdbool.h>
10
11 #include <zephyr/sys/util.h>
12
13 #include "hal/cntr.h"
14
15 #include "util/memq.h"
16 #include "util/mayfly.h"
17
18 #include "ticker/ticker.h"
19
20 #include "ll_sw/lll.h"
21
22 #include "hal/debug.h"
23
24 #define TICKER_MAYFLY_CALL_ID_ISR TICKER_USER_ID_LLL
25 #define TICKER_MAYFLY_CALL_ID_TRIGGER TICKER_USER_ID_ULL_HIGH
26 #define TICKER_MAYFLY_CALL_ID_WORKER TICKER_USER_ID_ULL_HIGH
27 #define TICKER_MAYFLY_CALL_ID_JOB TICKER_USER_ID_ULL_LOW
28 #define TICKER_MAYFLY_CALL_ID_PROGRAM TICKER_USER_ID_THREAD
29
30 static uint8_t const caller_id_lut[] = {
31 TICKER_CALL_ID_ISR,
32 TICKER_CALL_ID_WORKER,
33 TICKER_CALL_ID_JOB,
34 TICKER_CALL_ID_PROGRAM
35 };
36
hal_ticker_instance0_caller_id_get(uint8_t user_id)37 uint8_t hal_ticker_instance0_caller_id_get(uint8_t user_id)
38 {
39 uint8_t caller_id;
40
41 LL_ASSERT(user_id < sizeof(caller_id_lut));
42
43 caller_id = caller_id_lut[user_id];
44 LL_ASSERT(caller_id != TICKER_CALL_ID_NONE);
45
46 return caller_id;
47 }
48
hal_ticker_instance0_sched(uint8_t caller_id,uint8_t callee_id,uint8_t chain,void * instance)49 void hal_ticker_instance0_sched(uint8_t caller_id, uint8_t callee_id, uint8_t chain,
50 void *instance)
51 {
52 /* return value not checked as we allow multiple calls to schedule
53 * before being actually needing the work to complete before new
54 * schedule.
55 */
56 switch (caller_id) {
57 case TICKER_CALL_ID_ISR:
58 switch (callee_id) {
59 case TICKER_CALL_ID_JOB:
60 {
61 static memq_link_t link;
62 static struct mayfly m = {0, 0, &link, NULL,
63 ticker_job};
64
65 m.param = instance;
66
67 /* TODO: scheduler lock, if preemptive threads used */
68 mayfly_enqueue(TICKER_MAYFLY_CALL_ID_ISR,
69 TICKER_MAYFLY_CALL_ID_JOB,
70 chain,
71 &m);
72 }
73 break;
74
75 default:
76 LL_ASSERT(0);
77 break;
78 }
79 break;
80
81 case TICKER_CALL_ID_TRIGGER:
82 switch (callee_id) {
83 case TICKER_CALL_ID_WORKER:
84 {
85 static memq_link_t link;
86 static struct mayfly m = {0, 0, &link, NULL,
87 ticker_worker};
88
89 m.param = instance;
90
91 mayfly_enqueue(TICKER_MAYFLY_CALL_ID_TRIGGER,
92 TICKER_MAYFLY_CALL_ID_WORKER,
93 chain,
94 &m);
95 }
96 break;
97
98 default:
99 LL_ASSERT(0);
100 break;
101 }
102 break;
103
104 case TICKER_CALL_ID_WORKER:
105 switch (callee_id) {
106 case TICKER_CALL_ID_JOB:
107 {
108 static memq_link_t link;
109 static struct mayfly m = {0, 0, &link, NULL,
110 ticker_job};
111
112 m.param = instance;
113
114 mayfly_enqueue(TICKER_MAYFLY_CALL_ID_WORKER,
115 TICKER_MAYFLY_CALL_ID_JOB,
116 chain,
117 &m);
118 }
119 break;
120
121 default:
122 LL_ASSERT(0);
123 break;
124 }
125 break;
126
127 case TICKER_CALL_ID_JOB:
128 switch (callee_id) {
129 case TICKER_CALL_ID_WORKER:
130 {
131 static memq_link_t link;
132 static struct mayfly m = {0, 0, &link, NULL,
133 ticker_worker};
134
135 m.param = instance;
136
137 mayfly_enqueue(TICKER_MAYFLY_CALL_ID_JOB,
138 TICKER_MAYFLY_CALL_ID_WORKER,
139 chain,
140 &m);
141 }
142 break;
143
144 case TICKER_CALL_ID_JOB:
145 {
146 static memq_link_t link;
147 static struct mayfly m = {0, 0, &link, NULL,
148 ticker_job};
149
150 m.param = instance;
151
152 mayfly_enqueue(TICKER_MAYFLY_CALL_ID_JOB,
153 TICKER_MAYFLY_CALL_ID_JOB,
154 chain,
155 &m);
156 }
157 break;
158
159 default:
160 LL_ASSERT(0);
161 break;
162 }
163 break;
164
165 case TICKER_CALL_ID_PROGRAM:
166 switch (callee_id) {
167 case TICKER_CALL_ID_JOB:
168 {
169 static memq_link_t link;
170 static struct mayfly m = {0, 0, &link, NULL,
171 ticker_job};
172
173 m.param = instance;
174
175 /* TODO: scheduler lock, if preemptive threads used */
176 mayfly_enqueue(TICKER_MAYFLY_CALL_ID_PROGRAM,
177 TICKER_MAYFLY_CALL_ID_JOB,
178 chain,
179 &m);
180 }
181 break;
182
183 default:
184 LL_ASSERT(0);
185 break;
186 }
187 break;
188
189 default:
190 LL_ASSERT(0);
191 break;
192 }
193 }
194
hal_ticker_instance0_trigger_set(uint32_t value)195 void hal_ticker_instance0_trigger_set(uint32_t value)
196 {
197 #if defined(CONFIG_BT_CTLR_NRF_GRTC)
198 cntr_cmp_set(HAL_CNTR_GRTC_CC_IDX_TICKER, value);
199 #else /* !CONFIG_BT_CTLR_NRF_GRTC */
200 cntr_cmp_set(0U, value);
201 #endif /* !CONFIG_BT_CTLR_NRF_GRTC */
202 }
203