1use core::ops::{BitAnd, BitOr};
2
3use esp_hal::peripherals::IEEE802154;
4
5use crate::pib::CcaMode;
6
7#[allow(unused)]
8#[derive(Debug, Clone, Copy)]
9pub(crate) enum Event {
10 TxDone = 1 << 0,
11 RxDone = 1 << 1,
12 AckTxDone = 1 << 2,
13 AckRxDone = 1 << 3,
14 RxAbort = 1 << 4,
15 TxAbort = 1 << 5,
16 EdDone = 1 << 6,
17 Timer0Overflow = 1 << 8,
18 Timer1Overflow = 1 << 9,
19 ClockCountMatch = 1 << 10,
20 TxSfdDone = 1 << 11,
21 RxSfdDone = 1 << 12,
22}
23
24impl Event {
25 pub(crate) fn mask() -> u16 {
26 0x0000_1FFF
27 }
28}
29
30impl BitAnd<Event> for u16 {
31 type Output = u16;
32
33 fn bitand(self, rhs: Event) -> Self::Output {
34 self & rhs as u16
35 }
36}
37
38impl BitOr for Event {
39 type Output = u16;
40
41 fn bitor(self, rhs: Self) -> Self::Output {
42 self as u16 | rhs as u16
43 }
44}
45
46impl BitOr<Event> for u16 {
47 type Output = u16;
48
49 fn bitor(self, rhs: Event) -> Self::Output {
50 self | rhs as u16
51 }
52}
53
54#[allow(unused)]
55#[derive(Debug, Clone, Copy)]
56pub(crate) enum TxAbortReason {
57 RxAckStop = 1,
58 RxAckSfdTimeout = 2,
59 RxAckCrcError = 3,
60 RxAckInvalidLen = 4,
61 RxAckFilterFail = 5,
62 RxAckNoRss = 6,
63 RxAckCoexBreak = 7,
64 RxAckTypeNotAck = 8,
65 RxAckRestart = 9,
66 RxAckTimeout = 16,
67 TxStop = 17,
68 TxCoexBreak = 18,
69 TxSecurityError = 19,
70 CcaFailed = 24,
71 CcaBusy = 25,
72}
73
74impl TxAbortReason {
75 pub fn bit(&self) -> u32 {
76 1 << (*self as u32 - 1)
77 }
78}
79
80impl BitOr for TxAbortReason {
81 type Output = u32;
82
83 fn bitor(self, rhs: Self) -> Self::Output {
84 self.bit() | rhs.bit()
85 }
86}
87
88impl BitOr<TxAbortReason> for u32 {
89 type Output = u32;
90
91 fn bitor(self, rhs: TxAbortReason) -> Self::Output {
92 self | rhs.bit()
93 }
94}
95
96#[allow(unused)]
97#[derive(Debug, Clone, Copy)]
98pub(crate) enum RxAbortReason {
99 RxStop = 1,
100 SfdTimeout = 2,
101 CrcError = 3,
102 InvalidLen = 4,
103 FilterFail = 5,
104 NoRss = 6,
105 CoexBreak = 7,
106 UnexpectedAck = 8,
107 RxRestart = 9,
108 TxAckTimeout = 16,
109 TxAckStop = 17,
110 TxAckCoexBreak = 18,
111 EnhackSecurityError = 19,
112 EdAbort = 24,
113 EdStop = 25,
114 EdCoexReject = 26,
115}
116
117impl RxAbortReason {
118 pub fn bit(&self) -> u32 {
119 1 << (*self as u32 - 1)
120 }
121}
122
123impl BitOr for RxAbortReason {
124 type Output = u32;
125
126 fn bitor(self, rhs: Self) -> Self::Output {
127 self.bit() | rhs.bit()
128 }
129}
130
131impl BitOr<RxAbortReason> for u32 {
132 type Output = u32;
133
134 fn bitor(self, rhs: RxAbortReason) -> Self::Output {
135 self | rhs.bit()
136 }
137}
138
139#[allow(unused)]
140#[derive(Debug, Clone, Copy)]
141pub(crate) enum EdSampleMode {
142 Max = 0,
143 Avg = 1,
144}
145
146#[allow(unused)]
147#[derive(Debug, Clone, Copy)]
148pub(crate) enum Command {
149 TxStart = 0x41,
150 RxStart = 0x42,
151 CcaTxStart = 0x43,
152 EdStart = 0x44,
153 Stop = 0x45,
154 DtmTxStart = 0x46,
155 DtmRxStart = 0x47,
156 DtmStop = 0x48,
157 Timer0Start = 0x4C,
158 Timer0Stop = 0x4D,
159 Timer1Start = 0x4E,
160 Timer1Stop = 0x4F,
161}
162
163#[derive(Debug, Clone, Copy)]
164pub(crate) enum MultipanIndex {
165 Multipan0 = 0,
166 Multipan1 = 1,
167 Multipan2 = 2,
168 Multipan3 = 3,
169}
170
171impl From<usize> for MultipanIndex {
172 fn from(value: usize) -> Self {
173 match value {
174 0 => MultipanIndex::Multipan0,
175 1 => MultipanIndex::Multipan1,
176 2 => MultipanIndex::Multipan2,
177 3 => MultipanIndex::Multipan3,
178 _ => panic!(),
179 }
180 }
181}
182
183#[inline(always)]
184pub(crate) fn mac_date() -> u32 {
185 IEEE802154::regs().mac_date().read().bits()
186}
187
188#[inline(always)]
189pub(crate) fn set_rx_on_delay(delay: u16) {
190 IEEE802154::regs()
191 .rxon_delay()
192 .modify(|_, w| unsafe { w.rxon_delay().bits(delay) });
193}
194
195#[inline(always)]
196pub(crate) fn enable_events(events: u16) {
197 IEEE802154::regs()
198 .event_en()
199 .modify(|r, w| unsafe { w.event_en().bits(r.event_en().bits() | events) });
200}
201
202#[inline(always)]
203pub(crate) fn disable_events(events: u16) {
204 IEEE802154::regs()
205 .event_en()
206 .modify(|r, w| unsafe { w.event_en().bits(r.event_en().bits() & !events) });
207}
208
209#[inline(always)]
210pub(crate) fn enable_tx_abort_events(events: u32) {
211 IEEE802154::regs()
212 .tx_abort_interrupt_control()
213 .modify(|r, w| unsafe {
214 w.tx_abort_interrupt_control()
215 .bits(r.tx_abort_interrupt_control().bits() | events)
216 });
217}
218
219#[inline(always)]
220pub(crate) fn enable_rx_abort_events(events: u32) {
221 IEEE802154::regs()
222 .rx_abort_intr_ctrl()
223 .modify(|r, w| unsafe {
224 w.rx_abort_intr_ctrl()
225 .bits(r.rx_abort_intr_ctrl().bits() | events)
226 });
227}
228
229#[inline(always)]
230pub(crate) fn set_ed_sample_mode(ed_sample_mode: EdSampleMode) {
231 IEEE802154::regs()
232 .ed_scan_cfg()
233 .modify(|_, w| unsafe { w.ed_sample_mode().bits(ed_sample_mode as u8) });
234}
235
236#[inline(always)]
237pub(crate) fn set_tx_addr(addr: *const u8) {
238 IEEE802154::regs()
239 .txdma_addr()
240 .modify(|_, w| unsafe { w.txdma_addr().bits(addr as u32) });
241}
242
243#[inline(always)]
244pub(crate) fn set_cmd(cmd: Command) {
245 IEEE802154::regs()
246 .command()
247 .modify(|_, w| unsafe { w.opcode().bits(cmd as u8) });
248}
249
250#[inline(always)]
251pub(crate) fn set_freq(freq: u8) {
252 IEEE802154::regs()
253 .channel()
254 .modify(|_, w| unsafe { w.hop().bits(freq) });
255}
256
257#[inline(always)]
258pub(crate) fn freq() -> u8 {
259 IEEE802154::regs().channel().read().hop().bits()
260}
261
262#[inline(always)]
263pub(crate) fn set_power(power: u8) {
264 IEEE802154::regs()
265 .tx_power()
266 .modify(|_, w| unsafe { w.tx_power().bits(power) });
267}
268
269#[inline(always)]
270pub(crate) fn set_multipan_enable_mask(mask: u8) {
271 IEEE802154::regs()
273 .ctrl_cfg()
274 .modify(|r, w| unsafe { w.bits(r.bits() & !(0b1111 << 29) | ((mask as u32) << 29)) });
275}
276
277#[inline(always)]
278pub(crate) fn set_multipan_panid(index: MultipanIndex, panid: u16) {
279 unsafe {
280 let pan_id = IEEE802154::regs()
281 .inf0_pan_id()
282 .as_ptr()
283 .offset(4 * index as isize);
284 pan_id.write_volatile(panid as u32);
285 }
286}
287
288#[inline(always)]
289pub(crate) fn set_multipan_short_addr(index: MultipanIndex, value: u16) {
290 unsafe {
291 let short_addr = IEEE802154::regs()
292 .inf0_short_addr()
293 .as_ptr()
294 .offset(4 * index as isize);
295 short_addr.write_volatile(value as u32);
296 }
297}
298
299#[inline(always)]
300pub(crate) fn set_multipan_ext_addr(index: MultipanIndex, ext_addr: *const u8) {
301 unsafe {
302 let mut ext_addr_ptr = IEEE802154::regs()
303 .inf0_extend_addr0()
304 .as_ptr()
305 .offset(4 * index as isize);
306
307 ext_addr_ptr.write_volatile(
308 (ext_addr.offset(0).read_volatile() as u32)
309 | ((ext_addr.offset(1).read_volatile() as u32) << 8)
310 | ((ext_addr.offset(2).read_volatile() as u32) << 16)
311 | ((ext_addr.offset(3).read_volatile() as u32) << 24),
312 );
313
314 ext_addr_ptr = ext_addr_ptr.offset(1);
315
316 ext_addr_ptr.write_volatile(
317 (ext_addr.offset(4).read_volatile() as u32)
318 | ((ext_addr.offset(5).read_volatile() as u32) << 8)
319 | ((ext_addr.offset(6).read_volatile() as u32) << 16)
320 | ((ext_addr.offset(7).read_volatile() as u32) << 24),
321 );
322 }
323}
324
325#[inline(always)]
326pub(crate) fn set_cca_mode(cca_mode: CcaMode) {
327 IEEE802154::regs()
328 .ed_scan_cfg()
329 .modify(|_, w| unsafe { w.cca_mode().bits(cca_mode as u8) });
330}
331
332#[inline(always)]
333pub(crate) fn set_cca_threshold(cca_threshold: i8) {
334 IEEE802154::regs()
335 .ed_scan_cfg()
336 .modify(|_, w| unsafe { w.cca_ed_threshold().bits(cca_threshold as u8) });
337}
338
339#[inline(always)]
340pub(crate) fn set_tx_auto_ack(enable: bool) {
341 IEEE802154::regs()
342 .ctrl_cfg()
343 .modify(|_, w| w.hw_auto_ack_tx_en().bit(enable));
344}
345
346#[inline(always)]
347pub(crate) fn tx_auto_ack() -> bool {
348 IEEE802154::regs()
349 .ctrl_cfg()
350 .read()
351 .hw_auto_ack_tx_en()
352 .bit_is_set()
353}
354
355#[inline(always)]
356pub(crate) fn set_rx_auto_ack(enable: bool) {
357 IEEE802154::regs()
358 .ctrl_cfg()
359 .modify(|_, w| w.hw_auto_ack_rx_en().bit(enable));
360}
361
362#[inline(always)]
363pub(crate) fn set_tx_enhance_ack(enable: bool) {
364 IEEE802154::regs()
365 .ctrl_cfg()
366 .modify(|_, w| w.hw_enhance_ack_tx_en().bit(enable));
367}
368
369#[inline(always)]
370pub(crate) fn tx_enhance_ack() -> bool {
371 IEEE802154::regs()
372 .ctrl_cfg()
373 .read()
374 .hw_enhance_ack_tx_en()
375 .bit_is_set()
376}
377
378#[inline(always)]
379pub(crate) fn set_coordinator(enable: bool) {
380 IEEE802154::regs()
381 .ctrl_cfg()
382 .modify(|_, w| w.pan_coordinator().bit(enable));
383}
384
385#[inline(always)]
386pub(crate) fn set_promiscuous(enable: bool) {
387 IEEE802154::regs()
388 .ctrl_cfg()
389 .modify(|_, w| w.promiscuous_mode().bit(enable));
390}
391
392#[inline(always)]
393pub(crate) fn set_pending_mode(enable: bool) {
394 IEEE802154::regs()
395 .ctrl_cfg()
396 .modify(|_, w| w.autopend_enhance().bit(enable));
397}
398
399#[inline(always)]
400pub(crate) fn events() -> u16 {
401 IEEE802154::regs().event_status().read().bits() as u16
402}
403
404#[inline(always)]
405pub(crate) fn clear_events(events: u16) {
406 IEEE802154::regs()
407 .event_status()
408 .modify(|r, w| unsafe { w.event_status().bits(r.event_status().bits() & events) });
409}
410
411#[inline(always)]
412pub(crate) fn set_transmit_security(enable: bool) {
413 IEEE802154::regs()
414 .sec_ctrl()
415 .modify(|_, w| w.sec_en().bit(enable));
416}
417
418#[inline(always)]
419pub(crate) fn set_rx_addr(addr: *mut u8) {
420 IEEE802154::regs()
421 .rxdma_addr()
422 .modify(|_, w| unsafe { w.rxdma_addr().bits(addr as u32) });
423}
424
425#[inline(always)]
426pub(crate) fn abort_tx() {
427 IEEE802154::regs()
428 .tx_status()
429 .modify(|_, w| unsafe { w.tx_abort_status().bits(0) });
430}
431
432#[inline(always)]
433pub(crate) fn abort_rx() {
434 IEEE802154::regs()
435 .rx_status()
436 .modify(|_, w| unsafe { w.rx_abort_status().bits(0) });
437}