1 /*
2  * SPDX-FileCopyrightText: 2015-2022 The Apache Software Foundation (ASF)
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  *
6  * SPDX-FileContributor: 2019-2022 Espressif Systems (Shanghai) CO LTD
7  */
8 
9 #ifndef _NIMBLE_NPL_OS_H_
10 #define _NIMBLE_NPL_OS_H_
11 
12 #include <assert.h>
13 #include <stdint.h>
14 #include <string.h>
15 #include "freertos/FreeRTOS.h"
16 #include "freertos/queue.h"
17 #include "freertos/semphr.h"
18 #include "freertos/task.h"
19 #include "freertos/timers.h"
20 #include "esp_timer.h"
21 
22 #ifdef __cplusplus
23 extern "C" {
24 #endif
25 
26 #ifndef ARRAY_SIZE
27 #define ARRAY_SIZE(array) \
28         (sizeof(array) / sizeof((array)[0]))
29 #endif
30 
31 extern int ets_printf(const char *fmt, ...);
32 #define  BLE_LL_ASSERT(con)                         \
33     do{                                             \
34         if(!(con))  {                               \
35             ets_printf("assertion:%s\n",#con);      \
36             ets_printf("line:%d,function:%s\n", __LINE__, __func__);\
37             assert(0);                              \
38         }                                           \
39     }while(0)
40 
41 #define BLE_NPL_OS_ALIGNMENT    (4)/*ble_npl_get_os_alignment()*/
42 
43 #define BLE_NPL_TIME_FOREVER    ble_npl_get_time_forever()
44 
45 /* This should be compatible with TickType_t */
46 typedef uint32_t ble_npl_time_t;
47 typedef int32_t ble_npl_stime_t;
48 
49 struct ble_npl_event;
50 typedef void ble_npl_event_fn(struct ble_npl_event *ev);
51 
52 struct ble_npl_event {
53     void *event;
54 };
55 
56 struct ble_npl_eventq {
57     void *eventq;
58 };
59 
60 struct ble_npl_callout {
61     void *co;
62 };
63 
64 struct ble_npl_mutex {
65     void *mutex;
66 };
67 
68 struct ble_npl_sem {
69     void *sem;
70 };
71 
72 /*
73  * Simple APIs are just defined as static inline below, but some are a bit more
74  * complex or require some global state variables and thus are defined in .c
75  * file instead and static inline wrapper just calls proper implementation.
76  * We need declarations of these functions and they are defined in header below.
77  */
78 #include "npl_freertos.h"
79 
80 struct npl_funcs_t {
81     bool (*p_ble_npl_os_started)(void);
82     void *(*p_ble_npl_get_current_task_id)(void);
83     void (*p_ble_npl_eventq_init)(struct ble_npl_eventq *);
84     void (*p_ble_npl_eventq_deinit)(struct ble_npl_eventq *);
85     struct ble_npl_event * (*p_ble_npl_eventq_get)(struct ble_npl_eventq *, ble_npl_time_t);
86     void (*p_ble_npl_eventq_put)(struct ble_npl_eventq *, struct ble_npl_event *);
87     void (*p_ble_npl_eventq_remove)(struct ble_npl_eventq *, struct ble_npl_event *);
88     void (*p_ble_npl_event_run)(struct ble_npl_event *);
89     bool (*p_ble_npl_eventq_is_empty)(struct ble_npl_eventq *);
90     void (*p_ble_npl_event_init)(struct ble_npl_event *, ble_npl_event_fn *, void *);
91     void (*p_ble_npl_event_deinit)(struct ble_npl_event *);
92     void (*p_ble_npl_event_reset)(struct ble_npl_event *);
93     bool (*p_ble_npl_event_is_queued)(struct ble_npl_event *);
94     void * (*p_ble_npl_event_get_arg)(struct ble_npl_event *);
95     void (*p_ble_npl_event_set_arg)(struct ble_npl_event *, void *);
96     ble_npl_error_t (*p_ble_npl_mutex_init)(struct ble_npl_mutex *);
97     ble_npl_error_t (*p_ble_npl_mutex_deinit)(struct ble_npl_mutex *);
98     ble_npl_error_t (*p_ble_npl_mutex_pend)(struct ble_npl_mutex *, ble_npl_time_t);
99     ble_npl_error_t (*p_ble_npl_mutex_release)(struct ble_npl_mutex *);
100     ble_npl_error_t (*p_ble_npl_sem_init)(struct ble_npl_sem *, uint16_t);
101     ble_npl_error_t (*p_ble_npl_sem_deinit)(struct ble_npl_sem *);
102     ble_npl_error_t (*p_ble_npl_sem_pend)(struct ble_npl_sem *, ble_npl_time_t);
103     ble_npl_error_t (*p_ble_npl_sem_release)(struct ble_npl_sem *);
104     uint16_t (*p_ble_npl_sem_get_count)(struct ble_npl_sem *);
105     int (*p_ble_npl_callout_init)(struct ble_npl_callout *, struct ble_npl_eventq *, ble_npl_event_fn *, void *);
106     ble_npl_error_t (*p_ble_npl_callout_reset)(struct ble_npl_callout *, ble_npl_time_t);
107     void (*p_ble_npl_callout_stop)(struct ble_npl_callout *);
108     void (*p_ble_npl_callout_deinit)(struct ble_npl_callout *);
109     void (*p_ble_npl_callout_mem_reset)(struct ble_npl_callout *);
110     bool (*p_ble_npl_callout_is_active)(struct ble_npl_callout *);
111     ble_npl_time_t (*p_ble_npl_callout_get_ticks)(struct ble_npl_callout *);
112     uint32_t (*p_ble_npl_callout_remaining_ticks)(struct ble_npl_callout *, ble_npl_time_t);
113     void (*p_ble_npl_callout_set_arg)(struct ble_npl_callout *, void *);
114     uint32_t (*p_ble_npl_time_get)(void);
115     ble_npl_error_t (*p_ble_npl_time_ms_to_ticks)(uint32_t ms, ble_npl_time_t *);
116     ble_npl_error_t (*p_ble_npl_time_ticks_to_ms)(ble_npl_time_t, uint32_t *);
117     ble_npl_time_t (*p_ble_npl_time_ms_to_ticks32)(uint32_t);
118     uint32_t (*p_ble_npl_time_ticks_to_ms32)(ble_npl_time_t);
119     void (*p_ble_npl_time_delay)(ble_npl_time_t);
120     void (*p_ble_npl_hw_set_isr)(int, uint32_t);
121     uint32_t (*p_ble_npl_hw_enter_critical)(void);
122     void (*p_ble_npl_hw_exit_critical)(uint32_t);
123     uint32_t (*p_ble_npl_get_time_forever)(void);
124     uint8_t (*p_ble_npl_hw_is_in_critical)(void);
125     void (*p_ble_npl_eventq_put_to_front)(struct ble_npl_eventq *, struct ble_npl_event *);
126 };
127 
128 extern struct npl_funcs_t *npl_funcs;
129 
130 static inline bool
ble_npl_os_started(void)131 IRAM_ATTR ble_npl_os_started(void)
132 {
133     return npl_funcs->p_ble_npl_os_started();
134 }
135 
136 static inline void *
ble_npl_get_current_task_id(void)137 IRAM_ATTR ble_npl_get_current_task_id(void)
138 {
139     return npl_funcs->p_ble_npl_get_current_task_id();
140 }
141 
142 static inline void
ble_npl_eventq_init(struct ble_npl_eventq * evq)143 IRAM_ATTR ble_npl_eventq_init(struct ble_npl_eventq *evq)
144 {
145     return npl_funcs->p_ble_npl_eventq_init(evq);
146 }
147 
148 static inline void
ble_npl_eventq_deinit(struct ble_npl_eventq * evq)149 IRAM_ATTR ble_npl_eventq_deinit(struct ble_npl_eventq *evq)
150 {
151     return npl_funcs->p_ble_npl_eventq_deinit(evq);
152 }
153 
154 static inline struct ble_npl_event *
ble_npl_eventq_get(struct ble_npl_eventq * evq,ble_npl_time_t tmo)155 IRAM_ATTR ble_npl_eventq_get(struct ble_npl_eventq *evq, ble_npl_time_t tmo)
156 {
157     return npl_funcs->p_ble_npl_eventq_get(evq, tmo);
158 }
159 
160 static inline void
ble_npl_eventq_put(struct ble_npl_eventq * evq,struct ble_npl_event * ev)161 IRAM_ATTR ble_npl_eventq_put(struct ble_npl_eventq *evq, struct ble_npl_event *ev)
162 {
163     return npl_funcs->p_ble_npl_eventq_put(evq, ev);
164 }
165 
166 static inline void
ble_npl_eventq_remove(struct ble_npl_eventq * evq,struct ble_npl_event * ev)167 IRAM_ATTR ble_npl_eventq_remove(struct ble_npl_eventq *evq, struct ble_npl_event *ev)
168 {
169     return npl_funcs->p_ble_npl_eventq_remove(evq, ev);
170 }
171 
172 static inline void
ble_npl_event_run(struct ble_npl_event * ev)173 IRAM_ATTR ble_npl_event_run(struct ble_npl_event *ev)
174 {
175     return npl_funcs->p_ble_npl_event_run(ev);
176 }
177 
178 static inline bool
ble_npl_eventq_is_empty(struct ble_npl_eventq * evq)179 IRAM_ATTR ble_npl_eventq_is_empty(struct ble_npl_eventq *evq)
180 {
181     return npl_funcs->p_ble_npl_eventq_is_empty(evq);
182 }
183 
184 static inline void
ble_npl_event_init(struct ble_npl_event * ev,ble_npl_event_fn * fn,void * arg)185 IRAM_ATTR ble_npl_event_init(struct ble_npl_event *ev, ble_npl_event_fn *fn,
186                    void *arg)
187 {
188     return npl_funcs->p_ble_npl_event_init(ev, fn, arg);
189 }
190 
191 static inline bool
ble_npl_event_is_queued(struct ble_npl_event * ev)192 IRAM_ATTR ble_npl_event_is_queued(struct ble_npl_event *ev)
193 {
194     return npl_funcs->p_ble_npl_event_is_queued(ev);
195 }
196 
197 static inline void *
ble_npl_event_get_arg(struct ble_npl_event * ev)198 IRAM_ATTR ble_npl_event_get_arg(struct ble_npl_event *ev)
199 {
200     return npl_funcs->p_ble_npl_event_get_arg(ev);
201 }
202 
203 static inline void
ble_npl_event_set_arg(struct ble_npl_event * ev,void * arg)204 IRAM_ATTR ble_npl_event_set_arg(struct ble_npl_event *ev, void *arg)
205 {
206     return npl_funcs->p_ble_npl_event_set_arg(ev, arg);
207 }
208 
209 static inline ble_npl_error_t
ble_npl_mutex_init(struct ble_npl_mutex * mu)210 IRAM_ATTR ble_npl_mutex_init(struct ble_npl_mutex *mu)
211 {
212     return npl_funcs->p_ble_npl_mutex_init(mu);
213 }
214 
215 static inline ble_npl_error_t
ble_npl_mutex_deinit(struct ble_npl_mutex * mu)216 IRAM_ATTR ble_npl_mutex_deinit(struct ble_npl_mutex *mu)
217 {
218    return npl_funcs->p_ble_npl_mutex_deinit(mu);
219 }
220 
221 static inline ble_npl_error_t
ble_npl_mutex_pend(struct ble_npl_mutex * mu,ble_npl_time_t timeout)222 IRAM_ATTR ble_npl_mutex_pend(struct ble_npl_mutex *mu, ble_npl_time_t timeout)
223 {
224     return npl_funcs->p_ble_npl_mutex_pend(mu, timeout);
225 }
226 
227 static inline ble_npl_error_t
ble_npl_mutex_release(struct ble_npl_mutex * mu)228 IRAM_ATTR ble_npl_mutex_release(struct ble_npl_mutex *mu)
229 {
230     return npl_funcs->p_ble_npl_mutex_release(mu);
231 }
232 
233 static inline ble_npl_error_t
ble_npl_sem_init(struct ble_npl_sem * sem,uint16_t tokens)234 IRAM_ATTR ble_npl_sem_init(struct ble_npl_sem *sem, uint16_t tokens)
235 {
236    return npl_funcs->p_ble_npl_sem_init(sem, tokens);
237 }
238 
239 static inline ble_npl_error_t
ble_npl_sem_deinit(struct ble_npl_sem * sem)240 IRAM_ATTR ble_npl_sem_deinit(struct ble_npl_sem *sem)
241 {
242     return npl_funcs->p_ble_npl_sem_deinit(sem);
243 }
244 
245 static inline ble_npl_error_t
ble_npl_sem_pend(struct ble_npl_sem * sem,ble_npl_time_t timeout)246 IRAM_ATTR ble_npl_sem_pend(struct ble_npl_sem *sem, ble_npl_time_t timeout)
247 {
248     return npl_funcs->p_ble_npl_sem_pend(sem, timeout);
249 }
250 
251 static inline ble_npl_error_t
ble_npl_sem_release(struct ble_npl_sem * sem)252 IRAM_ATTR ble_npl_sem_release(struct ble_npl_sem *sem)
253 {
254     return npl_funcs->p_ble_npl_sem_release(sem);
255 }
256 
257 static inline uint16_t
ble_npl_sem_get_count(struct ble_npl_sem * sem)258 IRAM_ATTR ble_npl_sem_get_count(struct ble_npl_sem *sem)
259 {
260     return npl_funcs->p_ble_npl_sem_get_count(sem);
261 }
262 
263 static inline int
ble_npl_callout_init(struct ble_npl_callout * co,struct ble_npl_eventq * evq,ble_npl_event_fn * ev_cb,void * ev_arg)264 IRAM_ATTR ble_npl_callout_init(struct ble_npl_callout *co, struct ble_npl_eventq *evq,
265                      ble_npl_event_fn *ev_cb, void *ev_arg)
266 {
267     return npl_funcs->p_ble_npl_callout_init(co, evq, ev_cb, ev_arg);
268 }
269 
270 static inline void
ble_npl_callout_deinit(struct ble_npl_callout * co)271 IRAM_ATTR ble_npl_callout_deinit(struct ble_npl_callout *co)
272 {
273     return npl_funcs->p_ble_npl_callout_deinit(co);
274 }
275 
276 static inline ble_npl_error_t
ble_npl_callout_reset(struct ble_npl_callout * co,ble_npl_time_t ticks)277 IRAM_ATTR ble_npl_callout_reset(struct ble_npl_callout *co, ble_npl_time_t ticks)
278 {
279     return npl_funcs->p_ble_npl_callout_reset(co, ticks);
280 }
281 
282 static inline void
ble_npl_callout_stop(struct ble_npl_callout * co)283 IRAM_ATTR ble_npl_callout_stop(struct ble_npl_callout *co)
284 {
285     return npl_funcs->p_ble_npl_callout_stop(co);
286 }
287 
288 static inline bool
ble_npl_callout_is_active(struct ble_npl_callout * co)289 IRAM_ATTR ble_npl_callout_is_active(struct ble_npl_callout *co)
290 {
291     return npl_funcs->p_ble_npl_callout_is_active(co);
292 }
293 
294 static inline ble_npl_time_t
ble_npl_callout_get_ticks(struct ble_npl_callout * co)295 IRAM_ATTR ble_npl_callout_get_ticks(struct ble_npl_callout *co)
296 {
297     return npl_funcs->p_ble_npl_callout_get_ticks(co);
298 }
299 
300 static inline ble_npl_time_t
ble_npl_callout_remaining_ticks(struct ble_npl_callout * co,ble_npl_time_t time)301 IRAM_ATTR ble_npl_callout_remaining_ticks(struct ble_npl_callout *co,
302                                 ble_npl_time_t time)
303 {
304     return npl_funcs->p_ble_npl_callout_remaining_ticks(co, time);
305 }
306 
307 static inline void
ble_npl_callout_set_arg(struct ble_npl_callout * co,void * arg)308 IRAM_ATTR ble_npl_callout_set_arg(struct ble_npl_callout *co, void *arg)
309 {
310     return npl_funcs->p_ble_npl_callout_set_arg(co, arg);
311 }
312 
313 static inline ble_npl_time_t
ble_npl_time_get(void)314 IRAM_ATTR ble_npl_time_get(void)
315 {
316     return npl_funcs->p_ble_npl_time_get();
317 }
318 
319 static inline ble_npl_error_t
ble_npl_time_ms_to_ticks(uint32_t ms,ble_npl_time_t * out_ticks)320 IRAM_ATTR ble_npl_time_ms_to_ticks(uint32_t ms, ble_npl_time_t *out_ticks)
321 {
322     return npl_funcs->p_ble_npl_time_ms_to_ticks(ms, out_ticks);
323 }
324 
325 static inline ble_npl_error_t
ble_npl_time_ticks_to_ms(ble_npl_time_t ticks,uint32_t * out_ms)326 IRAM_ATTR ble_npl_time_ticks_to_ms(ble_npl_time_t ticks, uint32_t *out_ms)
327 {
328     return npl_funcs->p_ble_npl_time_ticks_to_ms(ticks, out_ms);
329 }
330 
331 static inline ble_npl_time_t
ble_npl_time_ms_to_ticks32(uint32_t ms)332 IRAM_ATTR ble_npl_time_ms_to_ticks32(uint32_t ms)
333 {
334     return npl_funcs->p_ble_npl_time_ms_to_ticks32(ms);
335 }
336 
337 static inline uint32_t
ble_npl_time_ticks_to_ms32(ble_npl_time_t ticks)338 IRAM_ATTR ble_npl_time_ticks_to_ms32(ble_npl_time_t ticks)
339 {
340     return npl_funcs->p_ble_npl_time_ticks_to_ms32(ticks);
341 }
342 
343 static inline void
ble_npl_time_delay(ble_npl_time_t ticks)344 IRAM_ATTR ble_npl_time_delay(ble_npl_time_t ticks)
345 {
346     return npl_funcs->p_ble_npl_time_delay(ticks);
347 }
348 
349 #if NIMBLE_CFG_CONTROLLER
350 static inline void
ble_npl_hw_set_isr(int irqn,uint32_t addr)351 IRAM_ATTR ble_npl_hw_set_isr(int irqn, uint32_t addr)
352 {
353     return npl_funcs->p_ble_npl_hw_set_isr(irqn, addr);
354 }
355 #endif
356 
357 static inline uint32_t
ble_npl_hw_enter_critical(void)358 IRAM_ATTR ble_npl_hw_enter_critical(void)
359 {
360     return npl_funcs->p_ble_npl_hw_enter_critical();
361 }
362 
363 static inline void
ble_npl_hw_exit_critical(uint32_t ctx)364 IRAM_ATTR ble_npl_hw_exit_critical(uint32_t ctx)
365 {
366     return npl_funcs->p_ble_npl_hw_exit_critical(ctx);
367 }
368 
ble_npl_hw_is_in_critical(void)369 static inline bool IRAM_ATTR ble_npl_hw_is_in_critical(void)
370 {
371     return npl_funcs->p_ble_npl_hw_is_in_critical();
372 }
373 
374 #define ble_npl_get_time_forever (*npl_funcs->p_ble_npl_get_time_forever)
375 #define ble_npl_callout_mem_reset (*npl_funcs->p_ble_npl_callout_mem_reset)
376 #define ble_npl_event_deinit (*npl_funcs->p_ble_npl_event_deinit)
377 #define ble_npl_event_reset (*npl_funcs->p_ble_npl_event_reset)
378 
379 #ifdef __cplusplus
380 }
381 #endif
382 
383 #endif  /* _NPL_H_ */
384