/
lll.h
311 lines (256 loc) · 7.69 KB
/
lll.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
/*
* Copyright (c) 2018-2019 Nordic Semiconductor ASA
*
* SPDX-License-Identifier: Apache-2.0
*/
#define TICKER_INSTANCE_ID_CTLR 0
#define TICKER_USER_ID_LLL MAYFLY_CALL_ID_0
#define TICKER_USER_ID_ULL_HIGH MAYFLY_CALL_ID_1
#define TICKER_USER_ID_ULL_LOW MAYFLY_CALL_ID_2
#define TICKER_USER_ID_THREAD MAYFLY_CALL_ID_PROGRAM
#define EVENT_PIPELINE_MAX 5
#define HDR_ULL(p) ((void *)((u8_t *)(p) + sizeof(struct evt_hdr)))
#define HDR_ULL2LLL(p) ((struct lll_hdr *)((u8_t *)(p) + \
sizeof(struct ull_hdr)))
#define HDR_LLL2EVT(p) ((struct evt_hdr *)((struct lll_hdr *)(p))->parent)
#if defined(CONFIG_BT_CTLR_XTAL_ADVANCED)
#define XON_BITMASK BIT(31) /* XTAL has been retained from previous prepare */
#endif /* CONFIG_BT_CTLR_XTAL_ADVANCED */
#if defined(CONFIG_BT_BROADCASTER) && defined(CONFIG_BT_ADV_SET)
#define BT_CTLR_ADV_MAX (CONFIG_BT_ADV_SET + 1)
#else
#define BT_CTLR_ADV_MAX 1
#endif
enum {
TICKER_ID_LLL_PREEMPT = 0,
#if defined(CONFIG_BT_TMP)
TICKER_ID_TMP_BASE,
TICKER_ID_TMP_LAST = ((TICKER_ID_TMP_BASE) + (CONFIG_BT_TMP_MAX) - 1),
#endif /* CONFIG_BT_TMP */
#if defined(CONFIG_BT_BROADCASTER)
TICKER_ID_ADV_STOP,
TICKER_ID_ADV_BASE,
#if defined(CONFIG_BT_CTLR_ADV_EXT) || defined(CONFIG_BT_HCI_MESH_EXT)
TICKER_ID_ADV_LAST = ((TICKER_ID_ADV_BASE) + (BT_CTLR_ADV_MAX) - 1),
#endif /* !CONFIG_BT_CTLR_ADV_EXT || !CONFIG_BT_HCI_MESH_EXT */
#endif /* CONFIG_BT_BROADCASTER */
#if defined(CONFIG_BT_OBSERVER)
TICKER_ID_SCAN_STOP,
TICKER_ID_SCAN_BASE,
TICKER_ID_SCAN_LAST = TICKER_ID_SCAN_BASE,
#endif /* CONFIG_BT_OBSERVER */
#if defined(CONFIG_BT_CONN)
TICKER_ID_CONN_BASE,
TICKER_ID_CONN_LAST = ((TICKER_ID_CONN_BASE) + (CONFIG_BT_MAX_CONN) -
1),
#endif /* CONFIG_BT_CONN */
TICKER_ID_MAX,
};
#if defined(CONFIG_BT_BROADCASTER) && !defined(CONFIG_BT_CTLR_ADV_EXT) && \
!defined(CONFIG_BT_HCI_MESH_EXT)
#define TICKER_ID_ADV_LAST TICKER_ID_ADV_BASE
#endif
#define TICKER_ID_ULL_BASE ((TICKER_ID_LLL_PREEMPT) + 1)
enum ull_status {
ULL_STATUS_SUCCESS,
ULL_STATUS_FAILURE,
ULL_STATUS_BUSY,
};
struct evt_hdr {
u32_t ticks_xtal_to_start;
u32_t ticks_active_to_start;
u32_t ticks_preempt_to_start;
u32_t ticks_slot;
};
struct ull_hdr {
u8_t ref; /* Number of ongoing (between Prepare and Done) events */
void (*disabled_cb)(void *param);
void *disabled_param;
};
struct lll_hdr {
void *parent;
u8_t is_stop:1;
};
struct lll_prepare_param {
u32_t ticks_at_expire;
u32_t remainder;
u16_t lazy;
void *param;
};
typedef int (*lll_prepare_cb_t)(struct lll_prepare_param *prepare_param);
typedef int (*lll_is_abort_cb_t)(void *next, int prio, void *curr,
lll_prepare_cb_t *resume_cb, int *resume_prio);
typedef void (*lll_abort_cb_t)(struct lll_prepare_param *prepare_param,
void *param);
struct lll_event {
struct lll_prepare_param prepare_param;
lll_prepare_cb_t prepare_cb;
lll_is_abort_cb_t is_abort_cb;
lll_abort_cb_t abort_cb;
int prio;
u8_t is_resume:1;
u8_t is_aborted:1;
};
enum node_rx_type {
/* Unused */
NODE_RX_TYPE_NONE = 0x00,
/* Signals completion of RX event */
NODE_RX_TYPE_EVENT_DONE = 0x01,
/* Signals arrival of RX Data Channel payload */
NODE_RX_TYPE_DC_PDU = 0x02,
/* Signals release of RX Data Channel payload */
NODE_RX_TYPE_DC_PDU_RELEASE = 0x03,
#if defined(CONFIG_BT_OBSERVER)
/* Advertisement report from scanning */
NODE_RX_TYPE_REPORT = 0x04,
#endif /* CONFIG_BT_OBSERVER */
#if defined(CONFIG_BT_CTLR_ADV_EXT)
NODE_RX_TYPE_EXT_1M_REPORT = 0x05,
NODE_RX_TYPE_EXT_CODED_REPORT = 0x06,
#endif /* CONFIG_BT_CTLR_ADV_EXT */
#if defined(CONFIG_BT_CTLR_SCAN_REQ_NOTIFY)
NODE_RX_TYPE_SCAN_REQ = 0x07,
#endif /* CONFIG_BT_CTLR_SCAN_REQ_NOTIFY */
#if defined(CONFIG_BT_CONN)
NODE_RX_TYPE_CONNECTION = 0x08,
NODE_RX_TYPE_TERMINATE = 0x09,
NODE_RX_TYPE_CONN_UPDATE = 0x0A,
NODE_RX_TYPE_ENC_REFRESH = 0x0B,
#if defined(CONFIG_BT_CTLR_LE_PING)
NODE_RX_TYPE_APTO = 0x0C,
#endif /* CONFIG_BT_CTLR_LE_PING */
NODE_RX_TYPE_CHAN_SEL_ALGO = 0x0D,
#if defined(CONFIG_BT_CTLR_PHY)
NODE_RX_TYPE_PHY_UPDATE = 0x0E,
#endif /* CONFIG_BT_CTLR_PHY */
#if defined(CONFIG_BT_CTLR_CONN_RSSI)
NODE_RX_TYPE_RSSI = 0x0F,
#endif /* CONFIG_BT_CTLR_CONN_RSSI */
#endif /* CONFIG_BT_CONN */
#if defined(CONFIG_BT_CTLR_PROFILE_ISR)
NODE_RX_TYPE_PROFILE = 0x10,
#endif /* CONFIG_BT_CTLR_PROFILE_ISR */
#if defined(CONFIG_BT_CTLR_ADV_INDICATION)
NODE_RX_TYPE_ADV_INDICATION = 0x11,
#endif /* CONFIG_BT_CTLR_ADV_INDICATION */
#if defined(CONFIG_BT_CTLR_SCAN_INDICATION)
NODE_RX_TYPE_SCAN_INDICATION = 0x12,
#endif /* CONFIG_BT_CTLR_SCAN_INDICATION */
#if defined(CONFIG_BT_HCI_MESH_EXT)
NODE_RX_TYPE_MESH_ADV_CPLT = 0x13,
NODE_RX_TYPE_MESH_REPORT = 0x14,
#endif /* CONFIG_BT_HCI_MESH_EXT */
/* Following proprietary defines must be at end of enum range */
#if defined(CONFIG_BT_CTLR_USER_EXT)
NODE_RX_TYPE_USER_START = 0x15,
NODE_RX_TYPE_USER_END = NODE_RX_TYPE_USER_START +
CONFIG_BT_CTLR_USER_EVT_RANGE,
#endif /* CONFIG_BT_CTLR_USER_EXT */
};
/* Footer of node_rx_hdr */
struct node_rx_ftr {
void *param;
void *extra;
u32_t ticks_anchor;
u32_t us_radio_end;
u32_t us_radio_rdy;
u8_t rssi;
#if defined(CONFIG_BT_CTLR_PRIVACY)
u8_t rl_idx;
#endif /* CONFIG_BT_CTLR_PRIVACY */
#if defined(CONFIG_BT_CTLR_EXT_SCAN_FP)
u8_t direct;
#endif /* CONFIG_BT_CTLR_EXT_SCAN_FP */
#if defined(CONFIG_BT_HCI_MESH_EXT)
u8_t chan_idx;
#endif /* CONFIG_BT_HCI_MESH_EXT */
};
/* Header of node_rx_pdu */
struct node_rx_hdr {
union {
void *next;
memq_link_t *link;
u8_t ack_last;
};
enum node_rx_type type;
u16_t handle;
struct node_rx_ftr rx_ftr;
};
struct node_rx_pdu {
struct node_rx_hdr hdr;
u8_t pdu[0];
};
enum {
EVENT_DONE_EXTRA_TYPE_NONE,
EVENT_DONE_EXTRA_TYPE_CONN,
/* Following proprietary defines must be at end of enum range */
#if defined(CONFIG_BT_CTLR_USER_EXT)
EVENT_DONE_EXTRA_TYPE_USER_START,
EVENT_DONE_EXTRA_TYPE_USER_END = EVENT_DONE_EXTRA_TYPE_USER_START +
CONFIG_BT_CTLR_USER_EVT_RANGE,
#endif /* CONFIG_BT_CTLR_USER_EXT */
};
struct event_done_extra_slave {
u32_t start_to_address_actual_us;
u32_t window_widening_event_us;
u32_t preamble_to_addr_us;
};
struct event_done_extra {
u8_t type;
union {
struct {
u16_t trx_cnt;
u8_t crc_valid;
#if defined(CONFIG_BT_CTLR_LE_ENC)
u8_t mic_state;
#endif /* CONFIG_BT_CTLR_LE_ENC */
union {
struct event_done_extra_slave slave;
};
};
};
};
struct node_rx_event_done {
struct node_rx_hdr hdr;
void *param;
struct event_done_extra extra;
};
static inline void lll_hdr_init(void *lll, void *parent)
{
struct lll_hdr *hdr = lll;
hdr->parent = parent;
hdr->is_stop = 0U;
}
static inline int lll_stop(void *lll)
{
struct lll_hdr *hdr = lll;
int ret = !!hdr->is_stop;
hdr->is_stop = 1U;
return ret;
}
static inline int lll_is_stop(void *lll)
{
struct lll_hdr *hdr = lll;
return !!hdr->is_stop;
}
int lll_init(void);
int lll_prepare(lll_is_abort_cb_t is_abort_cb, lll_abort_cb_t abort_cb,
lll_prepare_cb_t prepare_cb, int prio,
struct lll_prepare_param *prepare_param);
void lll_resume(void *param);
void lll_disable(void *param);
u32_t lll_radio_is_idle(void);
int ull_prepare_enqueue(lll_is_abort_cb_t is_abort_cb,
lll_abort_cb_t abort_cb,
struct lll_prepare_param *prepare_param,
lll_prepare_cb_t prepare_cb, int prio,
u8_t is_resume);
void *ull_prepare_dequeue_get(void);
void *ull_prepare_dequeue_iter(u8_t *idx);
void *ull_pdu_rx_alloc_peek(u8_t count);
void *ull_pdu_rx_alloc_peek_iter(u8_t *idx);
void *ull_pdu_rx_alloc(void);
void ull_rx_put(memq_link_t *link, void *rx);
void ull_rx_sched(void);
void *ull_event_done_extra_get(void);
void *ull_event_done(void *param);