nrf52/
ieee802154_radio.rs

1// Licensed under the Apache License, Version 2.0 or the MIT License.
2// SPDX-License-Identifier: Apache-2.0 OR MIT
3// Copyright Tock Contributors 2022.
4
5//! IEEE 802.15.4 radio driver for nRF52
6//!
7//! This driver implements a subset of 802.15.4 sending and receiving for the
8//! nRF52840 chip per the nRF52840_PS_v1.0 spec. Upon calling the initialization
9//! function, the chip is powered on and configured to the fields of the Radio
10//! struct. This driver maintains a state machine between receiving,
11//! transmitting, and sending acknowledgements. Because the nRF52840 15.4 radio
12//! chip does not possess hardware support for ACK, this driver implements
13//! software support for sending ACK when a received packet requests to be
14//! acknowledged. The driver currently lacks support to listen for requested ACK
15//! on packets the radio has sent. As of 8/14/23, the driver is able to send and
16//! receive 15.4 packets as used in the basic 15.4 libtock-c apps.
17//!
18//! ## Driver State Machine
19//!
20//! To aid in future implementations, this describes a simplified and concise
21//! version of the nrf52840 radio state machine specification and the state
22//! machine this driver separately maintains.
23//!
24//! To interact with the radio, tasks are issued to the radio which in turn
25//! trigger interrupt events. To receive, the radio must first "ramp up". The
26//! RXRU state is entered by issuing a RXEN task. Once the radio has ramped up
27//! successfully, it is now in the RXIDLE state and triggers a READY interrupt
28//! event. To optimize the radio's operation, this driver enables hardware
29//! shortcuts such that upon receiving the READY event, the radio chip
30//! immediately triggers a START task. The START task notifies the radio to begin
31//! officially "listening for packets" (RX state). Upon completing receiving the
32//! packet, the radio issues an END event. The driver then determines if the
33//! received packet has requested to be acknowledged (bit flag) and sends an ACK
34//! accordingly. Finally, the received packet buffer and accompanying fields are
35//! passed to the registered radio client. This marks the end of a receive cycle
36//! and a new READY event is issued to once again begin listening for packets.
37//!
38//! When a registered radio client wishes to send a packet. The transmit(...)
39//! method is called. To transmit a packet, the radio must first ramp up for
40//! receiving and then perform a clear channel assessment by listening for a
41//! specified period of time to determine if there is "traffic". If traffic is
42//! detected, the radio sets an alarm and waits to perform another CCA after this
43//! backoff. If the channel is determined to be clear, the radio then begins a TX
44//! ramp up, enters a TX state and then sends the packet. To progress through
45//! these states, hardware shortcuts are once again enabled in this driver. The
46//! driver first issues a DISABLE task. A hardware shortcut is enabled so that
47//! upon receipt of the disable task, the radio automatically issues a RXEN task
48//! to enter the RXRU state. Additionally, a shortcut is enabled such that when
49//! the RXREADY event is received, the radio automatically issues a CCA_START
50//! task. Finally, a shortcut is also enabled such that upon receiving a CCAIDLE
51//! event the radio automatically issues a TXEN event to ramp up the radio. The
52//! driver then handles receiving the READY interrupt event and triggers the
53//! START task to begin sending the packet. Upon completing the sending of the
54//! packet, the radio issues an END event, to which the driver then returns the
55//! radio to a receiving mode as described above. (For a more complete
56//! explanation of the radio's operation, refer to nRF52840_PS_v1.0)
57//!
58//! This radio state machine provides nine possible states the radio can exist
59//! in. For ease of implementation and clarity, this driver also maintains a
60//! simplified state machine. These states consist of the radio being off (OFF),
61//! receiving (RX), transmitting (TX), or acknowledging (ACK).
62
63// Author: Tyler Potyondy
64// 8/21/23
65
66use crate::timer::TimerAlarm;
67use core::cell::Cell;
68use kernel::deferred_call::{DeferredCall, DeferredCallClient};
69use kernel::hil::radio::{self, PowerClient, RadioChannel, RadioConfig, RadioData};
70use kernel::hil::time::{Alarm, AlarmClient, Time};
71use kernel::utilities::cells::{OptionalCell, TakeCell};
72use kernel::utilities::registers::interfaces::{Readable, Writeable};
73use kernel::utilities::registers::{register_bitfields, ReadOnly, ReadWrite, WriteOnly};
74use kernel::utilities::StaticRef;
75use kernel::ErrorCode;
76
77use crate::constants::TxPower;
78
79const RADIO_BASE: StaticRef<RadioRegisters> =
80    unsafe { StaticRef::new(0x40001000 as *const RadioRegisters) };
81
82const ACK_FLAG: u8 = 0b00100000;
83
84pub const IEEE802154_PAYLOAD_LENGTH: usize = 255;
85pub const IEEE802154_BACKOFF_PERIOD: usize = 320; //microseconds = 20 symbols
86pub const IEEE802154_ACK_TIME: usize = 512; //microseconds = 32 symbols
87pub const IEEE802154_MAX_POLLING_ATTEMPTS: u8 = 4;
88pub const IEEE802154_MIN_BE: u8 = 3;
89pub const IEEE802154_MAX_BE: u8 = 5;
90
91// ACK Requires MHR and MFR fields. More explicitly this is composed of:
92// | Frame Control (2 bytes) | Sequence Number (1 byte) | MFR (2 bytes) |.
93// In total the ACK frame is 5 bytes long + 2 PSDU bytes (7 bytes total).
94const SEQ_NUM_LEN: usize = 1;
95pub const ACK_BUF_SIZE: usize =
96    radio::SPI_HEADER_SIZE + radio::PHR_SIZE + radio::MHR_FC_SIZE + SEQ_NUM_LEN + radio::MFR_SIZE;
97
98/// Where the 15.4 packet from the radio is stored in the buffer. The HIL
99/// reserves one byte at the beginning of the buffer for use by the
100/// capsule/hardware. We have no use for this, but the upper layers expect it so
101/// we skip over it.
102// We can't just drop the byte from the buffer because then it would be lost
103// forever when we tried to return the frame buffer.
104const BUF_PREFIX_SIZE: u32 = 1;
105
106#[repr(C)]
107struct RadioRegisters {
108    /// Enable Radio in TX mode
109    /// - Address: 0x000 - 0x004
110    task_txen: WriteOnly<u32, Task::Register>,
111    /// Enable Radio in RX mode
112    /// - Address: 0x004 - 0x008
113    task_rxen: WriteOnly<u32, Task::Register>,
114    /// Start Radio
115    /// - Address: 0x008 - 0x00c
116    task_start: WriteOnly<u32, Task::Register>,
117    /// Stop Radio
118    /// - Address: 0x00c - 0x010
119    task_stop: WriteOnly<u32, Task::Register>,
120    /// Disable Radio
121    /// - Address: 0x010 - 0x014
122    task_disable: WriteOnly<u32, Task::Register>,
123    /// Start the RSSI and take one single sample of the receive signal strength
124    /// - Address: 0x014- 0x018
125    task_rssistart: WriteOnly<u32, Task::Register>,
126    /// Stop the RSSI measurement
127    /// - Address: 0x018 - 0x01c
128    task_rssistop: WriteOnly<u32, Task::Register>,
129    /// Start the bit counter
130    /// - Address: 0x01c - 0x020
131    task_bcstart: WriteOnly<u32, Task::Register>,
132    /// Stop the bit counter
133    /// - Address: 0x020 - 0x024
134    task_bcstop: WriteOnly<u32, Task::Register>,
135    /// Reserved
136    _reserved1: [u32; 2],
137    /// Stop the bit counter
138    /// - Address: 0x02c - 0x030
139    task_ccastart: WriteOnly<u32, Task::Register>,
140    /// Stop the bit counter
141    /// - Address: 0x030 - 0x034
142    task_ccastop: WriteOnly<u32, Task::Register>,
143    /// Reserved
144    _reserved2: [u32; 51],
145    /// Radio has ramped up and is ready to be started
146    /// - Address: 0x100 - 0x104
147    event_ready: ReadWrite<u32, Event::Register>,
148    /// Address sent or received
149    /// - Address: 0x104 - 0x108
150    event_address: ReadWrite<u32, Event::Register>,
151    /// Packet payload sent or received
152    /// - Address: 0x108 - 0x10c
153    event_payload: ReadWrite<u32, Event::Register>,
154    /// Packet sent or received
155    /// - Address: 0x10c - 0x110
156    event_end: ReadWrite<u32, Event::Register>,
157    /// Radio has been disabled
158    /// - Address: 0x110 - 0x114
159    event_disabled: ReadWrite<u32, Event::Register>,
160    /// A device address match occurred on the last received packet
161    /// - Address: 0x114 - 0x118
162    event_devmatch: ReadWrite<u32>,
163    /// No device address match occurred on the last received packet
164    /// - Address: 0x118 - 0x11c
165    event_devmiss: ReadWrite<u32, Event::Register>,
166    /// Sampling of receive signal strength complete
167    /// - Address: 0x11c - 0x120
168    event_rssiend: ReadWrite<u32, Event::Register>,
169    /// Reserved
170    _reserved3: [u32; 2],
171    /// Bit counter reached bit count value
172    /// - Address: 0x128 - 0x12c
173    event_bcmatch: ReadWrite<u32, Event::Register>,
174    /// Reserved
175    _reserved4: [u32; 1],
176    /// Packet received with CRC ok
177    /// - Address: 0x130 - 0x134
178    event_crcok: ReadWrite<u32, Event::Register>,
179    /// Packet received with CRC error
180    /// - Address: 0x134 - 0x138
181    crcerror: ReadWrite<u32, Event::Register>,
182    /// IEEE 802.15.4 length field received
183    /// - Address: 0x138 - 0x13c
184    event_framestart: ReadWrite<u32, Event::Register>,
185    /// Reserved
186    _reserved5: [u32; 2],
187    /// Wireless medium in idle - clear to send
188    /// - Address: 0x144-0x148
189    event_ccaidle: ReadWrite<u32, Event::Register>,
190    /// Wireless medium busy - do not send
191    /// - Address: 0x148-0x14c
192    event_ccabusy: ReadWrite<u32, Event::Register>,
193    /// Reserved
194    _reserved6: [u32; 45],
195    /// Shortcut register
196    /// - Address: 0x200 - 0x204
197    shorts: ReadWrite<u32, Shortcut::Register>,
198    /// Reserved
199    _reserved7: [u32; 64],
200    /// Enable interrupt
201    /// - Address: 0x304 - 0x308
202    intenset: ReadWrite<u32, Interrupt::Register>,
203    /// Disable interrupt
204    /// - Address: 0x308 - 0x30c
205    intenclr: ReadWrite<u32, Interrupt::Register>,
206    /// Reserved
207    _reserved8: [u32; 61],
208    /// CRC status
209    /// - Address: 0x400 - 0x404
210    crcstatus: ReadOnly<u32, Event::Register>,
211    /// Reserved
212    _reserved9: [u32; 1],
213    /// Received address
214    /// - Address: 0x408 - 0x40c
215    rxmatch: ReadOnly<u32, ReceiveMatch::Register>,
216    /// CRC field of previously received packet
217    /// - Address: 0x40c - 0x410
218    rxcrc: ReadOnly<u32, ReceiveCrc::Register>,
219    /// Device address match index
220    /// - Address: 0x410 - 0x414
221    dai: ReadOnly<u32, DeviceAddressIndex::Register>,
222    /// Reserved
223    _reserved10: [u32; 60],
224    /// Packet pointer
225    /// - Address: 0x504 - 0x508
226    packetptr: ReadWrite<u32, PacketPointer::Register>,
227    /// Frequency
228    /// - Address: 0x508 - 0x50c
229    frequency: ReadWrite<u32, Frequency::Register>,
230    /// Output power
231    /// - Address: 0x50c - 0x510
232    txpower: ReadWrite<u32, TransmitPower::Register>,
233    /// Data rate and modulation
234    /// - Address: 0x510 - 0x514
235    mode: ReadWrite<u32, Mode::Register>,
236    /// Packet configuration register 0
237    /// - Address 0x514 - 0x518
238    pcnf0: ReadWrite<u32, PacketConfiguration0::Register>,
239    /// Packet configuration register 1
240    /// - Address: 0x518 - 0x51c
241    pcnf1: ReadWrite<u32, PacketConfiguration1::Register>,
242    /// Base address 0
243    /// - Address: 0x51c - 0x520
244    base0: ReadWrite<u32, BaseAddress::Register>,
245    /// Base address 1
246    /// - Address: 0x520 - 0x524
247    base1: ReadWrite<u32, BaseAddress::Register>,
248    /// Prefix bytes for logical addresses 0-3
249    /// - Address: 0x524 - 0x528
250    prefix0: ReadWrite<u32, Prefix0::Register>,
251    /// Prefix bytes for logical addresses 4-7
252    /// - Address: 0x528 - 0x52c
253    prefix1: ReadWrite<u32, Prefix1::Register>,
254    /// Transmit address select
255    /// - Address: 0x52c - 0x530
256    txaddress: ReadWrite<u32, TransmitAddress::Register>,
257    /// Receive address select
258    /// - Address: 0x530 - 0x534
259    rxaddresses: ReadWrite<u32, ReceiveAddresses::Register>,
260    /// CRC configuration
261    /// - Address: 0x534 - 0x538
262    crccnf: ReadWrite<u32, CrcConfiguration::Register>,
263    /// CRC polynomial
264    /// - Address: 0x538 - 0x53c
265    crcpoly: ReadWrite<u32, CrcPolynomial::Register>,
266    /// CRC initial value
267    /// - Address: 0x53c - 0x540
268    crcinit: ReadWrite<u32, CrcInitialValue::Register>,
269    /// Reserved
270    _reserved11: [u32; 1],
271    /// Interframe spacing in microseconds
272    /// - Address: 0x544 - 0x548
273    tifs: ReadWrite<u32, InterFrameSpacing::Register>,
274    /// RSSI sample
275    /// - Address: 0x548 - 0x54c
276    rssisample: ReadWrite<u32, RssiSample::Register>,
277    /// Reserved
278    _reserved12: [u32; 1],
279    /// Current radio state
280    /// - Address: 0x550 - 0x554
281    state: ReadOnly<u32, State::Register>,
282    /// Data whitening initial value
283    /// - Address: 0x554 - 0x558
284    datawhiteiv: ReadWrite<u32, DataWhiteIv::Register>,
285    /// Reserved
286    _reserved13: [u32; 2],
287    /// Bit counter compare
288    /// - Address: 0x560 - 0x564
289    bcc: ReadWrite<u32, BitCounterCompare::Register>,
290    /// Reserved
291    _reserved14: [u32; 39],
292    /// Device address base segments
293    /// - Address: 0x600 - 0x620
294    dab: [ReadWrite<u32, DeviceAddressBase::Register>; 8],
295    /// Device address prefix
296    /// - Address: 0x620 - 0x640
297    dap: [ReadWrite<u32, DeviceAddressPrefix::Register>; 8],
298    /// Device address match configuration
299    /// - Address: 0x640 - 0x644
300    dacnf: ReadWrite<u32, DeviceAddressMatch::Register>,
301    /// MAC header Search Pattern Configuration
302    /// - Address: 0x644 - 0x648
303    mhrmatchconf: ReadWrite<u32, MACHeaderSearch::Register>,
304    /// MAC Header Search Pattern Mask
305    /// - Address: 0x648 - 0x64C
306    mhrmatchmas: ReadWrite<u32, MACHeaderMask::Register>,
307    /// Reserved
308    _reserved15: [u32; 1],
309    /// Radio mode configuration register
310    /// - Address: 0x650 - 0x654
311    modecnf0: ReadWrite<u32, RadioModeConfig::Register>,
312    /// Reserved
313    _reserved16: [u32; 6],
314    /// Clear Channel Assesment (CCA) control register
315    /// - Address: 0x66C - 0x670
316    ccactrl: ReadWrite<u32, CCAControl::Register>,
317    /// Reserved
318    _reserved17: [u32; 611],
319    /// Peripheral power control
320    /// - Address: 0xFFC - 0x1000
321    power: ReadWrite<u32, Task::Register>,
322}
323
324register_bitfields! [u32,
325    /// Task register
326    Task [
327        /// Enable task
328        ENABLE OFFSET(0) NUMBITS(1)
329    ],
330    /// Event register
331    Event [
332        /// Ready event
333        READY OFFSET(0) NUMBITS(1)
334    ],
335    /// Shortcut register
336    Shortcut [
337        /// Shortcut between READY event and START task
338        READY_START OFFSET(0) NUMBITS(1),
339        /// Shortcut between END event and DISABLE task
340        END_DISABLE OFFSET(1) NUMBITS(1),
341        /// Shortcut between DISABLED event and TXEN task
342        DISABLED_TXEN OFFSET(2) NUMBITS(1),
343        /// Shortcut between DISABLED event and RXEN task
344        DISABLED_RXEN OFFSET(3) NUMBITS(1),
345        /// Shortcut between ADDRESS event and RSSISTART task
346        ADDRESS_RSSISTART OFFSET(4) NUMBITS(1),
347        /// Shortcut between END event and START task
348        END_START OFFSET(5) NUMBITS(1),
349        /// Shortcut between ADDRESS event and BCSTART task
350        ADDRESS_BCSTART OFFSET(6) NUMBITS(1),
351        /// Shortcut between DISABLED event and RSSISTOP task
352        DISABLED_RSSISTOP OFFSET(8) NUMBITS(1),
353        /// Shortcut between CCAIDLE_TXEN
354        CCAIDLE_TXEN OFFSET(12) NUMBITS(1),
355        /// Shortcut between RXREADY_CCASTART
356        RXREADY_CCASTART OFFSET(11) NUMBITS(1),
357        /// Shortcut between TXREADY event and START task
358        TXREADY_START OFFSET(19) NUMBITS(1),
359
360    ],
361    /// Interrupt register
362    Interrupt [
363        /// READY event
364        READY OFFSET(0) NUMBITS(1),
365        /// ADDRESS event
366        ADDRESS OFFSET(1) NUMBITS(1),
367        /// PAYLOAD event
368        PAYLOAD OFFSET(2) NUMBITS(1),
369        /// END event
370        END OFFSET(3) NUMBITS(1),
371        /// DISABLED event
372        DISABLED OFFSET(4) NUMBITS(1),
373        /// DEVMATCH event
374        DEVMATCH OFFSET(5) NUMBITS(1),
375        /// DEVMISS event
376        DEVMISS OFFSET(6) NUMBITS(1),
377        /// RSSIEND event
378        RSSIEND OFFSET(7) NUMBITS(1),
379        /// BCMATCH event
380        BCMATCH OFFSET(10) NUMBITS(1),
381        /// CRCOK event
382        CRCOK OFFSET(12) NUMBITS(1),
383        /// CRCERROR event
384        CRCERROR OFFSET(13) NUMBITS(1),
385        /// CCAIDLE event
386        FRAMESTART OFFSET(14) NUMBITS(1),
387        /// CCAIDLE event
388        CCAIDLE OFFSET(17) NUMBITS(1),
389        /// CCABUSY event
390        CCABUSY OFFSET(18) NUMBITS(1),
391        /// TXREADY event
392        TXREADY OFFSET(21) NUMBITS(1),
393        /// RXREADY event
394        RXREADY OFFSET(22) NUMBITS(1),
395    ],
396    /// Receive match register
397    ReceiveMatch [
398        /// Logical address of which previous packet was received
399        MATCH OFFSET(0) NUMBITS(3)
400    ],
401    /// Received CRC register
402    ReceiveCrc [
403        /// CRC field of previously received packet
404        CRC OFFSET(0) NUMBITS(24)
405    ],
406    /// Device address match index register
407    DeviceAddressIndex [
408        /// Device address match index
409        /// Index (n) of device address, see DAB\[n\] and DAP\[n\], that got an
410        /// address match
411        INDEX OFFSET(0) NUMBITS(3)
412    ],
413    /// Packet pointer register
414    PacketPointer [
415        /// Packet address to be used for the next transmission or reception. When transmitting, the packet pointed to by this
416        /// address will be transmitted and when receiving, the received packet will be written to this address. This address is a byte
417        /// aligned ram address.
418        POINTER OFFSET(0) NUMBITS(32)
419    ],
420    /// Frequency register
421    Frequency [
422        /// Radio channel frequency
423        /// Frequency = 2400 + FREQUENCY (MHz)
424        FREQUENCY OFFSET(0) NUMBITS(7) [],
425        /// Channel map selection.
426        /// Channel map between 2400 MHZ .. 2500 MHZ
427        MAP OFFSET(8) NUMBITS(1) [
428            DEFAULT = 0,
429            LOW = 1
430        ]
431    ],
432    /// Transmitting power register
433    TransmitPower [
434        /// Radio output power
435        POWER OFFSET(0) NUMBITS(8) [
436            POS4DBM = 4,
437            POS3DBM = 3,
438            ODBM = 0,
439            NEG4DBM = 0xfc,
440            NEG8DBM = 0xf8,
441            NEG12DBM = 0xf4,
442            NEG16DBM = 0xf0,
443            NEG20DBM = 0xec,
444            NEG40DBM = 0xd8
445        ]
446    ],
447    /// Data rate and modulation register
448    Mode [
449        /// Radio data rate and modulation setting.
450        /// The radio supports Frequency-shift Keying (FSK) modulation
451        MODE OFFSET(0) NUMBITS(4) [
452            NRF_1MBIT = 0,
453            NRF_2MBIT = 1,
454            NRF_250KBIT = 2,
455            BLE_1MBIT = 3,
456            BLE_2MBIT = 4,
457            BLE_LR125KBIT = 5,
458            BLE_LR500KBIT = 6,
459            IEEE802154_250KBIT = 15
460        ]
461    ],
462    /// Packet configuration register 0
463    PacketConfiguration0 [
464        /// Length on air of LENGTH field in number of bits
465        LFLEN OFFSET(0) NUMBITS(4) [],
466        /// Length on air of S0 field in number of bytes
467        S0LEN OFFSET(8) NUMBITS(1) [],
468        /// Length on air of S1 field in number of bits.
469        S1LEN OFFSET(16) NUMBITS(4) [],
470        /// Include or exclude S1 field in RAM
471        S1INCL OFFSET(20) NUMBITS(1) [
472            AUTOMATIC = 0,
473            INCLUDE = 1
474        ],
475        /// Length of preamble on air. Decision point: TASKS_START task
476        PLEN OFFSET(24) NUMBITS(2) [
477            EIGHT = 0,
478            SIXTEEN = 1,
479            THIRTYTWOZEROS = 2,
480            LONGRANGE = 3
481        ],
482        CRCINC OFFSET(26) NUMBITS(1) [
483            EXCLUDE = 0,
484            INCLUDE = 1
485        ]
486    ],
487    /// Packet configuration register 1
488    PacketConfiguration1 [
489        /// Maximum length of packet payload
490        MAXLEN OFFSET(0) NUMBITS(8) [],
491        /// Static length in number of bytes
492        STATLEN OFFSET(8) NUMBITS(8) [],
493        /// Base address length in number of bytes
494        BALEN OFFSET(16) NUMBITS(3) [],
495        /// On air endianness
496        ENDIAN OFFSET(24) NUMBITS(1) [
497            LITTLE = 0,
498            BIG = 1
499        ],
500        /// Enable or disable packet whitening
501        WHITEEN OFFSET(25) NUMBITS(1) [
502            DISABLED = 0,
503            ENABLED = 1
504        ]
505    ],
506    /// Radio base address register
507    BaseAddress [
508        /// BASE0 or BASE1
509        BASE OFFSET(0) NUMBITS(32)
510    ],
511    /// Radio prefix0 registers
512    Prefix0 [
513        /// Address prefix 0
514        AP0 OFFSET(0) NUMBITS(8),
515        /// Address prefix 1
516        AP1 OFFSET(8) NUMBITS(8),
517        /// Address prefix 2
518        AP2 OFFSET(16) NUMBITS(8),
519        /// Address prefix 3
520        AP3 OFFSET(24) NUMBITS(8)
521    ],
522    /// Radio prefix0 registers
523    Prefix1 [
524        /// Address prefix 4
525        AP4 OFFSET(0) NUMBITS(8),
526        /// Address prefix 5
527        AP5 OFFSET(8) NUMBITS(8),
528        /// Address prefix 6
529        AP6 OFFSET(16) NUMBITS(8),
530        /// Address prefix 7
531        AP7 OFFSET(24) NUMBITS(8)
532    ],
533    /// Transmit address register
534    TransmitAddress [
535        /// Logical address to be used when transmitting a packet
536        ADDRESS OFFSET(0) NUMBITS(3)
537    ],
538    /// Receive addresses register
539    ReceiveAddresses [
540        /// Enable or disable reception on logical address 0-7
541        ADDRESS OFFSET(0) NUMBITS(8)
542    ],
543    /// CRC configuration register
544    CrcConfiguration [
545        /// CRC length in bytes
546        LEN OFFSET(0) NUMBITS(2) [
547            DISABLED = 0,
548            ONE = 1,
549            TWO = 2,
550            THREE = 3
551        ],
552        /// Include or exclude packet field from CRC calculation
553        SKIPADDR OFFSET(8) NUMBITS(2) [
554            INCLUDE = 0,
555            EXCLUDE = 1,
556            IEEE802154 = 2
557        ]
558    ],
559    /// CRC polynomial register
560    CrcPolynomial [
561        /// CRC polynomial
562        CRCPOLY OFFSET(0) NUMBITS(24)
563    ],
564    /// CRC initial value register
565    CrcInitialValue [
566       /// Initial value for CRC calculation
567       CRCINIT OFFSET(0) NUMBITS(24)
568    ],
569    /// Inter Frame Spacing in us register
570    InterFrameSpacing [
571        /// Inter Frame Spacing in us
572        /// Inter frame space is the time interval between two consecutive packets. It is defined as the time, in micro seconds, from the
573        /// end of the last bit of the previous packet to the start of the first bit of the subsequent packet
574        TIFS OFFSET(0) NUMBITS(8)
575    ],
576    /// RSSI sample register
577    RssiSample [
578        /// RSSI sample result
579        RSSISAMPLE OFFSET(0) NUMBITS(7)
580    ],
581    /// Radio state register
582    State [
583        /// Current radio state
584        STATE OFFSET(0) NUMBITS(4) [
585            DISABLED = 0,
586            RXRU = 1,
587            RXIDLE = 2,
588            RX = 3,
589            RXDISABLED = 4,
590            TXRU = 9,
591            TXIDLE = 10,
592            TX = 11,
593            TXDISABLED = 12
594        ]
595    ],
596    /// Data whitening initial value register
597    DataWhiteIv [
598        /// Data whitening initial value. Bit 6 is hard-wired to '1', writing '0'
599        /// to it has no effect, and it will always be read back and used by the device as '1'
600        DATEWHITEIV OFFSET(0) NUMBITS(7)
601    ],
602    /// Bit counter compare register
603    BitCounterCompare [
604        /// Bit counter compare
605        BCC OFFSET(0) NUMBITS(32)
606    ],
607    /// Device address base register
608    DeviceAddressBase [
609        /// Device address base 0-7
610        DAB OFFSET(0) NUMBITS(32)
611    ],
612    /// Device address prefix register
613    DeviceAddressPrefix [
614        /// Device address prefix 0-7
615        DAP OFFSET(0) NUMBITS(32)
616    ],
617    /// Device address match configuration register
618    DeviceAddressMatch [
619        /// Enable or disable device address matching on 0-7
620        ENA OFFSET(0) NUMBITS(8),
621        /// TxAdd for device address 0-7
622        TXADD OFFSET(8) NUMBITS(8)
623    ],
624    MACHeaderSearch [
625        CONFIG OFFSET(0) NUMBITS(32)
626    ],
627    MACHeaderMask [
628        PATTERN OFFSET(0) NUMBITS(32)
629    ],
630    CCAControl [
631        CCAMODE OFFSET(0) NUMBITS(3) [
632            ED_MODE = 0,
633            CARRIER_MODE = 1,
634            CARRIER_AND_ED_MODE = 2,
635            CARRIER_OR_ED_MODE = 3,
636            ED_MODE_TEST_1 = 4
637        ],
638        CCAEDTHRESH OFFSET(8) NUMBITS(8) [],
639        CCACORRTHRESH OFFSET(16) NUMBITS(8) [],
640        CCACORRCNT OFFSET(24) NUMBITS(8) []
641    ],
642    /// Radio mode configuration register
643    RadioModeConfig [
644        /// Radio ramp-up time
645        RU OFFSET(0) NUMBITS(1) [
646            DEFAULT = 0,
647            FAST = 1
648        ],
649        /// Default TX value
650        /// Specifies what the RADIO will transmit when it is not started, i.e. between:
651        /// RADIO.EVENTS_READY and RADIO.TASKS_START
652        /// RADIO.EVENTS_END and RADIO.TASKS_START
653        DTX OFFSET(8) NUMBITS(2) [
654            B1 = 0,
655            B0 = 1,
656            CENTER = 2
657        ]
658    ]
659];
660
661/// Operating mode of the radio.
662#[derive(Debug, Clone, Copy, PartialEq)]
663enum RadioState {
664    /// Radio peripheral is off.
665    OFF,
666    /// Currently transmitting a packet.
667    TX,
668    /// Default state when radio is on. Radio is configured to be in RX mode
669    /// when the radio is turned on but not transmitting.
670    RX,
671    /// Transmitting an acknowledgement packet.
672    ACK,
673}
674
675/// We use a single deferred call for two operations: triggering config clients
676/// and power change clients. This allows us to track which operation we need to
677/// perform when we get the deferred call callback.
678#[derive(Debug, Clone, Copy)]
679enum DeferredOperation {
680    /// Waiting to notify that the configuration operation is complete.
681    ConfigClientCallback,
682    /// Waiting to notify that the power state of the radio changed (ie it
683    /// turned on or off).
684    PowerClientCallback,
685}
686
687pub struct Radio<'a> {
688    registers: StaticRef<RadioRegisters>,
689    rx_client: OptionalCell<&'a dyn radio::RxClient>,
690    tx_client: OptionalCell<&'a dyn radio::TxClient>,
691    config_client: OptionalCell<&'a dyn radio::ConfigClient>,
692    power_client: OptionalCell<&'a dyn radio::PowerClient>,
693    tx_power: Cell<TxPower>,
694    tx_buf: TakeCell<'static, [u8]>,
695    rx_buf: TakeCell<'static, [u8]>,
696    ack_buf: TakeCell<'static, [u8]>,
697    addr: Cell<u16>,
698    addr_long: Cell<[u8; 8]>,
699    pan: Cell<u16>,
700    cca_count: Cell<u8>,
701    cca_be: Cell<u8>,
702    random_nonce: Cell<u32>,
703    channel: Cell<RadioChannel>,
704    timer0: OptionalCell<&'a TimerAlarm<'a>>,
705    state: Cell<RadioState>,
706    deferred_call: DeferredCall,
707    deferred_call_operation: OptionalCell<DeferredOperation>,
708}
709
710impl AlarmClient for Radio<'_> {
711    fn alarm(&self) {
712        // This alarm function is the callback for when the CCA backoff alarm completes
713        // Attempt a new CCA period by issuing CCASTART task
714        self.registers.task_ccastart.write(Task::ENABLE::SET);
715    }
716}
717
718impl<'a> Radio<'a> {
719    pub fn new(ack_buf: &'static mut [u8; ACK_BUF_SIZE]) -> Self {
720        Self {
721            registers: RADIO_BASE,
722            rx_client: OptionalCell::empty(),
723            tx_client: OptionalCell::empty(),
724            config_client: OptionalCell::empty(),
725            power_client: OptionalCell::empty(),
726            tx_power: Cell::new(TxPower::ZerodBm),
727            tx_buf: TakeCell::empty(),
728            rx_buf: TakeCell::empty(),
729            ack_buf: TakeCell::new(ack_buf),
730            addr: Cell::new(0),
731            addr_long: Cell::new([0x00; 8]),
732            pan: Cell::new(0),
733            cca_count: Cell::new(0),
734            cca_be: Cell::new(0),
735            random_nonce: Cell::new(0xDEADBEEF),
736            channel: Cell::new(RadioChannel::Channel26),
737            timer0: OptionalCell::empty(),
738            state: Cell::new(RadioState::OFF),
739            deferred_call: DeferredCall::new(),
740            deferred_call_operation: OptionalCell::empty(),
741        }
742    }
743
744    pub fn set_timer_ref(&self, timer: &'a crate::timer::TimerAlarm<'a>) {
745        self.timer0.set(timer);
746    }
747
748    pub fn is_enabled(&self) -> bool {
749        self.registers
750            .mode
751            .matches_all(Mode::MODE::IEEE802154_250KBIT)
752    }
753
754    fn rx(&self) {
755        self.state.set(RadioState::RX);
756
757        // Unwrap fail = Radio RX Buffer is missing (may be due to receive client not replacing in receive(...) method,
758        // or some instance in  driver taking buffer without properly replacing).
759        let rbuf = self.rx_buf.take().unwrap();
760        self.rx_buf.replace(self.set_dma_ptr(rbuf));
761
762        // Instruct radio hardware to automatically progress from RXIDLE to RX
763        // state upon receipt of internal `READY` signal after radio ramp-up completes.
764        self.registers.shorts.write(Shortcut::READY_START::SET);
765
766        self.registers.task_rxen.write(Task::ENABLE::SET);
767    }
768
769    fn radio_on(&self) {
770        // reset and enable power
771        self.registers.power.write(Task::ENABLE::CLEAR);
772        self.registers.power.write(Task::ENABLE::SET);
773    }
774
775    fn radio_off(&self) {
776        self.state.set(RadioState::OFF);
777
778        self.registers.power.write(Task::ENABLE::CLEAR);
779    }
780
781    fn radio_is_on(&self) -> bool {
782        self.registers.power.is_set(Task::ENABLE)
783    }
784
785    fn set_dma_ptr(&self, buffer: &'static mut [u8]) -> &'static mut [u8] {
786        self.registers
787            .packetptr
788            .set(buffer.as_ptr() as u32 + BUF_PREFIX_SIZE);
789        buffer
790    }
791
792    fn crc_check(&self) -> Result<(), ErrorCode> {
793        if self.registers.crcstatus.is_set(Event::READY) {
794            Ok(())
795        } else {
796            Err(ErrorCode::FAIL)
797        }
798    }
799
800    // TODO: RECEIVING ACK FOR A SENT TX IS NOT IMPLEMENTED
801    //
802    // As a general note for the interrupt handler, event registers must still
803    // be cleared even when hardware shortcuts are enabled.
804    #[inline(never)]
805    pub fn handle_interrupt(&self) {
806        self.disable_all_interrupts();
807
808        let mut start_task = false;
809        let mut rx_init = false;
810
811        match self.state.get() {
812            // It should not be possible to receive an interrupt while the
813            // tracked radio state is OFF.
814            RadioState::OFF => {
815                kernel::debug!("[ERROR]--15.4 state machine");
816                kernel::debug!("Received interrupt while off");
817            }
818            RadioState::RX => {
819                ////////////////////////////////////////////////////////////////
820                // NOTE: This state machine assumes that the READY_START
821                // shortcut is enabled at this point in time. If the READY_START
822                // shortcut is not enabled, the state machine/driver will likely
823                // exhibit undefined behavior.
824                ////////////////////////////////////////////////////////////////
825
826                // Since READY_START shortcut enabled, always clear READY event
827                self.registers.event_ready.write(Event::READY::CLEAR);
828
829                // Completed receiving a packet, now determine if we need to send ACK
830                if self.registers.event_end.is_set(Event::READY) {
831                    self.registers.event_end.write(Event::READY::CLEAR);
832                    let crc = self.crc_check();
833
834                    // Unwrap fail = Radio RX Buffer is missing (may be due to
835                    // receive client not replacing in receive(...) method, or
836                    // some instance in driver taking buffer without properly
837                    // replacing).
838                    let rbuf = self.rx_buf.take().unwrap();
839
840                    // Data buffer format: | PREFIX | PHR | PSDU | LQI |
841                    //
842                    // Retrieve the length of the PSDU (actual frame). The frame
843                    // length is only 7 bits, but of course the field is a byte.
844                    // The nRF52840 product specification says this about the
845                    // PHR byte (Version 1.8, section 6.20.12.1):
846                    //
847                    // > The most significant bit is reserved and is set to zero
848                    // > for frames that are standard compliant. The radio
849                    // > module will report all eight bits and it can
850                    // > potentially be used to carry some information.
851                    //
852                    // We are not using that for any information so we just
853                    // force it to zero. This ensures that `data_len` will not
854                    // be longer than our buffer.
855                    let data_len = (rbuf[radio::PHR_OFFSET] & 0x7F) as usize;
856
857                    // LQI is found just after the data received.
858                    let lqi = rbuf[data_len];
859
860                    // We drop the CRC bytes (the MFR) from our frame.
861                    let frame_len = data_len - radio::MFR_SIZE;
862
863                    // 6th bit in the first byte of the MAC header determines if
864                    // sender requested ACK. If so send ACK first before handing
865                    // packet reception. This optimizes the time taken to send
866                    // an ACK. If we call the receive function here, there is a
867                    // non deterministic time required to complete the function
868                    // as it may be passed up the entirety of the networking
869                    // stack (leading to ACK timeout being exceeded).
870                    if rbuf[radio::PSDU_OFFSET] & ACK_FLAG != 0 && crc.is_ok() {
871                        self.ack_buf
872                            .take()
873                            .map_or(Err(ErrorCode::NOMEM), |ack_buf| {
874                                // Entered ACK state //
875                                self.state.set(RadioState::ACK);
876
877                                // 4th byte of received packet is the 15.4
878                                // sequence number.
879                                let sequence_number = rbuf[radio::PSDU_OFFSET + radio::MHR_FC_SIZE];
880
881                                // The frame control field is hardcoded for now;
882                                // this is the only possible type of ACK
883                                // currently supported so it is reasonable to
884                                // hardcode this.
885                                ack_buf[radio::PSDU_OFFSET] = 2;
886                                ack_buf[radio::PSDU_OFFSET + 1] = 0;
887                                ack_buf[radio::PSDU_OFFSET + radio::MHR_FC_SIZE] = sequence_number;
888
889                                // Ensure we replace our RX buffer for the time
890                                // being.
891                                self.rx_buf.replace(rbuf);
892
893                                // If the transmit function fails, replace the
894                                // buffer and return an error.
895                                if let Err((_, ret_buf)) = self.transmit(ack_buf, 3) {
896                                    self.ack_buf.replace(ret_buf);
897                                    Err(ErrorCode::FAIL)
898                                } else {
899                                    Ok(())
900                                }
901                            })
902                            .unwrap_or_else(|err| {
903                                // The ACK was not sent; we do not need to drop
904                                // the packet, but print msg for debugging
905                                // purposes, notify receive client of packet,
906                                // and reset radio to receiving.
907                                self.rx_client.map(|client| {
908                                    start_task = true;
909                                    client.receive(
910                                        self.rx_buf.take().unwrap(),
911                                        frame_len,
912                                        lqi,
913                                        crc.is_ok(),
914                                        Err(err),
915                                    );
916                                });
917
918                                kernel::debug!(
919                                    "[ACKFail] Failed sending ACK in response to received packet."
920                                );
921                            });
922                    } else {
923                        // Packet received that does not require an ACK. Pass
924                        // received packet to client and return radio to general
925                        // receiving state to listen for new packets.
926                        self.rx_client.map(|client| {
927                            start_task = true;
928                            client.receive(rbuf, frame_len, lqi, crc.is_ok(), Ok(()));
929                        });
930                    }
931                }
932            }
933            RadioState::TX => {
934                ////////////////////////////////////////////////////////////////
935                // NOTE: This state machine assumes that the DISABLED_RXEN,
936                // CCAIDLE_TXEN, RXREADY_CCASTART shortcuts are enabled at this
937                // point in time. If the READY_START shortcut is not enabled,
938                // the state machine/driver will likely exhibit undefined
939                // behavior.
940                ////////////////////////////////////////////////////////////////
941
942                // Handle Event_ready interrupt. The TX path performs both a TX
943                // ramp up and an RX ramp up. This means that there are two
944                // potential cases we must handle. The ready event due to the Rx
945                // Ramp up shortcuts to the CCASTART while the ready event due
946                // to the Tx ramp up requires we issue a start task in response
947                // to progress the state machine.
948                if self.registers.event_ready.is_set(Event::READY) {
949                    // In both cases, we must clear event
950                    self.registers.event_ready.write(Event::READY::CLEAR);
951
952                    // Ready event from Tx ramp up will be in radio internal
953                    // TXIDLE state
954                    if self.registers.state.get() == crate::constants::RADIO_STATE_TXIDLE {
955                        start_task = true;
956                    }
957                }
958
959                // Handle CCA related interrupts.
960                if self.registers.event_ccabusy.is_set(Event::READY) {
961                    self.registers.event_ccabusy.write(Event::READY::CLEAR);
962
963                    // Need to back off for a period of time outlined in the
964                    // IEEE 802.15.4 standard (see Figure 69 in section 7.5.1.4
965                    // The CSMA-CA algorithm of the standard).
966                    if self.cca_count.get() < IEEE802154_MAX_POLLING_ATTEMPTS {
967                        self.cca_count.set(self.cca_count.get() + 1);
968                        self.cca_be.set(self.cca_be.get() + 1);
969                        let backoff_periods = self.random_nonce() & ((1 << self.cca_be.get()) - 1);
970                        let current_time = self.timer0.unwrap_or_panic().now();
971                        self.timer0
972                            .unwrap_or_panic() // Unwrap fail = Missing timer reference for CSMA
973                            .set_alarm(
974                                current_time,
975                                kernel::hil::time::Ticks32::from(
976                                    backoff_periods * (IEEE802154_BACKOFF_PERIOD as u32),
977                                ),
978                            );
979                    } else {
980                        // We have exceeded the IEEE802154_MAX_POLLING_ATTEMPTS
981                        // and should fail the transmission/return buffer to
982                        // sending client.
983
984                        let result = Err(ErrorCode::BUSY);
985                        self.tx_client.map(|client| {
986                            // Unwrap fail = TX Buffer is missing and was
987                            // mistakenly not replaced after completion of
988                            // set_dma_ptr(...)
989                            let tbuf = self.tx_buf.take().unwrap();
990                            client.send_done(tbuf, false, result);
991                        });
992                        rx_init = true;
993                    }
994                }
995
996                // End event received; The TX is now finished and we need to
997                // notify the sending client.
998                if self.registers.event_end.is_set(Event::READY) {
999                    self.registers.event_end.write(Event::READY::CLEAR);
1000                    let result = Ok(());
1001
1002                    // TODO: Acked is hardcoded to always return false; add
1003                    // support to receive tx ACK.
1004                    self.tx_client.map(|client| {
1005                        // Unwrap fail = TX Buffer is missing and was mistakenly
1006                        // not replaced after completion of set_dma_ptr(...)
1007                        let tbuf = self.tx_buf.take().unwrap();
1008                        client.send_done(tbuf, false, result);
1009                    });
1010                    rx_init = true;
1011                }
1012            }
1013            RadioState::ACK => {
1014                ////////////////////////////////////////////////////////////////
1015                // NOTE: This state machine assumes that the READY_START
1016                // shortcut is enabled at this point in time. If the READY_START
1017                // shortcut is not enabled, the state machine/driver will likely
1018                // exhibit undefined behavior.
1019                ////////////////////////////////////////////////////////////////
1020
1021                // Since READY_START shortcut enabled, always clear READY event
1022                self.registers.event_ready.write(Event::READY::CLEAR);
1023
1024                // Completed sending ACK
1025                if self.registers.event_end.is_set(Event::READY) {
1026                    self.registers.event_end.write(Event::READY::CLEAR);
1027
1028                    // Unwrap fail = TX Buffer is missing and was mistakenly not
1029                    // replaced after completion of set_dma_ptr(...)
1030                    let tbuf = self.tx_buf.take().unwrap();
1031
1032                    // We must replace the ACK buffer that was passed to tx_buf
1033                    self.ack_buf.replace(tbuf);
1034
1035                    // Reset radio to proper receiving state
1036                    rx_init = true;
1037
1038                    // Notify receive client of packet that triggered the ACK.
1039                    self.rx_client.map(|client| {
1040                        // Unwrap fail = Radio RX Buffer is missing (may be due
1041                        // to receive client not replacing in receive(...)
1042                        // method, or some instance in  driver taking buffer
1043                        // without properly replacing).
1044                        let rbuf = self.rx_buf.take().unwrap();
1045
1046                        // Data buffer format: | PREFIX | PHR | PSDU | LQI |
1047                        //
1048                        // See the RX case above for how these values are set.
1049                        let data_len = (rbuf[radio::PHR_OFFSET] & 0x7F) as usize;
1050                        let lqi = rbuf[data_len];
1051                        let frame_len = data_len - radio::MFR_SIZE;
1052
1053                        // We know the CRC passed because otherwise we would not
1054                        // have transmitted an ACK.
1055                        client.receive(rbuf, frame_len, lqi, true, Ok(()));
1056                    });
1057                }
1058            }
1059        }
1060
1061        // Enabling hardware shortcuts allows for a much faster operation.
1062        // However, this can also lead to race conditions and strange edge
1063        // cases. Namely, if a task_start or rx_en is set while interrupts are
1064        // disabled, the event_end interrupt can be "missed" and the interrupt
1065        // handler will not be called. If the event is missed, the state machine
1066        // is unable to progress and the driver enters a deadlock.
1067        self.enable_interrupts();
1068        if rx_init {
1069            self.rx();
1070        }
1071        if start_task {
1072            self.registers.task_start.write(Task::ENABLE::SET);
1073        }
1074    }
1075
1076    pub fn enable_interrupts(&self) {
1077        self.registers
1078            .intenset
1079            .write(Interrupt::READY::SET + Interrupt::CCABUSY::SET + Interrupt::END::SET);
1080    }
1081
1082    pub fn enable_interrupt(&self, intr: u32) {
1083        self.registers.intenset.set(intr);
1084    }
1085
1086    pub fn clear_interrupt(&self, intr: u32) {
1087        self.registers.intenclr.set(intr);
1088    }
1089
1090    pub fn disable_all_interrupts(&self) {
1091        // disable all possible interrupts
1092        self.registers.intenclr.set(0xffffffff);
1093    }
1094
1095    pub fn set_ack_buffer(&self, buffer: &'static mut [u8]) {
1096        self.ack_buf.replace(buffer);
1097    }
1098
1099    fn radio_initialize(&self) {
1100        self.radio_on();
1101
1102        // CONFIGURE RADIO //
1103        self.ieee802154_set_channel_rate();
1104
1105        self.ieee802154_set_packet_config();
1106
1107        self.ieee802154_set_crc_config();
1108
1109        self.ieee802154_set_rampup_mode();
1110
1111        self.ieee802154_set_cca_config();
1112
1113        self.ieee802154_set_tx_power();
1114
1115        self.ieee802154_set_channel_freq();
1116
1117        // Begin receiving procedure
1118        self.enable_interrupts();
1119        self.rx();
1120    }
1121
1122    // IEEE802.15.4 SPECIFICATION Section 6.20.12.5 of the NRF52840 Datasheet
1123    fn ieee802154_set_crc_config(&self) {
1124        self.registers
1125            .crccnf
1126            .write(CrcConfiguration::LEN::TWO + CrcConfiguration::SKIPADDR::IEEE802154);
1127        self.registers
1128            .crcinit
1129            .set(crate::constants::RADIO_CRCINIT_IEEE802154);
1130        self.registers
1131            .crcpoly
1132            .set(crate::constants::RADIO_CRCPOLY_IEEE802154);
1133    }
1134
1135    fn ieee802154_set_rampup_mode(&self) {
1136        self.registers
1137            .modecnf0
1138            .write(RadioModeConfig::RU::FAST + RadioModeConfig::DTX::CENTER);
1139    }
1140
1141    fn ieee802154_set_cca_config(&self) {
1142        self.registers.ccactrl.write(
1143            CCAControl::CCAMODE.val(crate::constants::IEEE802154_CCA_MODE)
1144                + CCAControl::CCAEDTHRESH.val(crate::constants::IEEE802154_CCA_ED_THRESH)
1145                + CCAControl::CCACORRTHRESH.val(crate::constants::IEEE802154_CCA_CORR_THRESH)
1146                + CCAControl::CCACORRCNT.val(crate::constants::IEEE802154_CCA_CORR_CNT),
1147        );
1148    }
1149
1150    // Packet configuration
1151    // Settings taken from RiotOS nrf52840 15.4 driver
1152    fn ieee802154_set_packet_config(&self) {
1153        self.registers.pcnf0.write(
1154            PacketConfiguration0::LFLEN.val(8)
1155                + PacketConfiguration0::PLEN::THIRTYTWOZEROS
1156                + PacketConfiguration0::CRCINC::INCLUDE,
1157        );
1158
1159        self.registers
1160            .pcnf1
1161            .write(PacketConfiguration1::MAXLEN.val(crate::constants::RADIO_PAYLOAD_LENGTH as u32));
1162    }
1163
1164    fn ieee802154_set_channel_rate(&self) {
1165        self.registers.mode.write(Mode::MODE::IEEE802154_250KBIT);
1166    }
1167
1168    fn ieee802154_set_channel_freq(&self) {
1169        let channel = self.channel.get();
1170        self.registers
1171            .frequency
1172            .write(Frequency::FREQUENCY.val(channel as u32));
1173    }
1174
1175    fn ieee802154_set_tx_power(&self) {
1176        self.registers.txpower.set(self.tx_power.get() as u32);
1177    }
1178
1179    pub fn startup(&self) -> Result<(), ErrorCode> {
1180        self.radio_initialize();
1181        Ok(())
1182    }
1183
1184    // Returns a new pseudo-random number and updates the randomness state.
1185    //
1186    // Uses the [Xorshift](https://en.wikipedia.org/wiki/Xorshift) algorithm to
1187    // produce pseudo-random numbers. Uses the `random_nonce` field to keep
1188    // state.
1189    fn random_nonce(&self) -> u32 {
1190        let mut next_nonce = ::core::num::Wrapping(self.random_nonce.get());
1191        next_nonce ^= next_nonce << 13;
1192        next_nonce ^= next_nonce >> 17;
1193        next_nonce ^= next_nonce << 5;
1194        self.random_nonce.set(next_nonce.0);
1195        self.random_nonce.get()
1196    }
1197}
1198
1199impl<'a> kernel::hil::radio::RadioConfig<'a> for Radio<'a> {
1200    fn initialize(&self) -> Result<(), ErrorCode> {
1201        Ok(())
1202    }
1203
1204    fn set_power_client(&self, client: &'a dyn PowerClient) {
1205        self.power_client.set(client);
1206    }
1207
1208    fn reset(&self) -> Result<(), ErrorCode> {
1209        self.radio_initialize();
1210        Ok(())
1211    }
1212
1213    fn start(&self) -> Result<(), ErrorCode> {
1214        self.radio_initialize();
1215
1216        // Configure deferred call to trigger callback.
1217        self.deferred_call_operation
1218            .set(DeferredOperation::PowerClientCallback);
1219        self.deferred_call.set();
1220
1221        Ok(())
1222    }
1223
1224    fn stop(&self) -> Result<(), ErrorCode> {
1225        self.radio_off();
1226
1227        // Configure deferred call to trigger callback.
1228        self.deferred_call_operation
1229            .set(DeferredOperation::PowerClientCallback);
1230        self.deferred_call.set();
1231
1232        Ok(())
1233    }
1234
1235    fn is_on(&self) -> bool {
1236        self.radio_is_on()
1237    }
1238
1239    fn busy(&self) -> bool {
1240        // `tx_buf` is only occupied when a transmission is underway.
1241        self.tx_buf.is_some()
1242    }
1243
1244    fn set_config_client(&self, client: &'a dyn radio::ConfigClient) {
1245        self.config_client.set(client);
1246    }
1247
1248    /// Commit the config calls to hardware, changing (in theory):
1249    ///
1250    /// - the RX address
1251    /// - PAN ID
1252    /// - TX power
1253    /// - channel
1254    ///
1255    /// to the specified values. **However**, the nRF52840 IEEE 802.15.4 radio
1256    /// does not support hardware-level address filtering (see
1257    /// [here](https://devzone.nordicsemi.com/f/nordic-q-a/19320/using-nrf52840-for-802-15-4)).
1258    /// So setting the addresses and PAN ID have no meaning for this chip and
1259    /// any filtering must be done in higher layers in software.
1260    ///
1261    /// Issues a callback to the config client when done.
1262    fn config_commit(&self) {
1263        // All we can configure is TX power and channel frequency.
1264        self.ieee802154_set_tx_power();
1265        self.ieee802154_set_channel_freq();
1266
1267        // Enable deferred call so we can generate a `ConfigClient` callback.
1268        self.deferred_call_operation
1269            .set(DeferredOperation::ConfigClientCallback);
1270        self.deferred_call.set();
1271    }
1272
1273    //#################################################
1274    /// Accessors
1275    //#################################################
1276
1277    fn get_address(&self) -> u16 {
1278        self.addr.get()
1279    }
1280
1281    fn get_address_long(&self) -> [u8; 8] {
1282        self.addr_long.get()
1283    }
1284
1285    /// The 16-bit PAN ID
1286    fn get_pan(&self) -> u16 {
1287        self.pan.get()
1288    }
1289
1290    /// The transmit power, in dBm
1291    fn get_tx_power(&self) -> i8 {
1292        self.tx_power.get() as i8
1293    }
1294
1295    /// The 802.15.4 channel
1296    fn get_channel(&self) -> u8 {
1297        self.channel.get().get_channel_number()
1298    }
1299
1300    //#################################################
1301    /// Mutators
1302    //#################################################
1303
1304    fn set_address(&self, addr: u16) {
1305        self.addr.set(addr);
1306    }
1307
1308    fn set_address_long(&self, addr: [u8; 8]) {
1309        self.addr_long.set(addr);
1310    }
1311
1312    fn set_pan(&self, id: u16) {
1313        self.pan.set(id);
1314    }
1315
1316    fn set_channel(&self, chan: RadioChannel) {
1317        self.channel.set(chan);
1318    }
1319
1320    fn set_tx_power(&self, tx_power: i8) -> Result<(), ErrorCode> {
1321        // Convert u8 to TxPower
1322        match crate::constants::TxPower::try_from(tx_power as u8) {
1323            // Invalid transmitting power, propagate error
1324            Err(()) => Err(ErrorCode::NOSUPPORT),
1325            // Valid transmitting power, propagate success
1326            Ok(res) => {
1327                self.tx_power.set(res);
1328                Ok(())
1329            }
1330        }
1331    }
1332}
1333
1334impl<'a> kernel::hil::radio::RadioData<'a> for Radio<'a> {
1335    fn set_receive_client(&self, client: &'a dyn radio::RxClient) {
1336        self.rx_client.set(client);
1337    }
1338
1339    fn set_receive_buffer(&self, buffer: &'static mut [u8]) {
1340        self.rx_buf.replace(buffer);
1341    }
1342
1343    fn set_transmit_client(&self, client: &'a dyn radio::TxClient) {
1344        self.tx_client.set(client);
1345    }
1346
1347    fn transmit(
1348        &self,
1349        buf: &'static mut [u8],
1350        frame_len: usize,
1351    ) -> Result<(), (ErrorCode, &'static mut [u8])> {
1352        if self.state.get() == RadioState::OFF {
1353            return Err((ErrorCode::OFF, buf));
1354        } else if self.busy() {
1355            return Err((ErrorCode::BUSY, buf));
1356        } else if buf.len() < radio::PSDU_OFFSET + frame_len + radio::MFR_SIZE {
1357            // Not enough room for CRC or PHR or reserved byte
1358            return Err((ErrorCode::SIZE, buf));
1359        }
1360
1361        // Insert the PHR which is the PDSU length.
1362        buf[radio::PHR_OFFSET] = (frame_len + radio::MFR_SIZE) as u8;
1363
1364        // The tx_buf does not possess static memory. This buffer only
1365        // temporarily holds a reference to another buffer passed as a function
1366        // argument. The tx_buf holds ownership of this buffer until it is
1367        // returned through the send_done(...) function.
1368        self.tx_buf.replace(self.set_dma_ptr(buf));
1369
1370        // The transmit function handles sending both ACK and standard packets
1371        if let RadioState::ACK = self.state.get() {
1372            self.registers.task_txen.write(Task::ENABLE::SET);
1373        } else {
1374            // Configure radio for standard packet TX
1375            self.state.set(RadioState::TX);
1376
1377            // Instruct radio hardware to automatically progress from:
1378            // - RXDISABLE to RXRU state upon receipt of internal disabled event
1379            // - RXIDLE to RX state upon receipt of ready event and radio ramp
1380            //   up completed, begin CCA backoff
1381            // - RX to TXRU state upon internal receipt CCA completion event
1382            //   (clear to begin transmitting)
1383            self.registers.shorts.write(
1384                Shortcut::DISABLED_RXEN::SET
1385                    + Shortcut::RXREADY_CCASTART::SET
1386                    + Shortcut::CCAIDLE_TXEN::SET,
1387            );
1388
1389            // Radio is in proper shortcut state, disable and begin TX sequence
1390            self.registers.task_disable.write(Task::ENABLE::SET);
1391        }
1392
1393        Ok(())
1394    }
1395}
1396
1397impl DeferredCallClient for Radio<'_> {
1398    fn handle_deferred_call(&self) {
1399        // On deferred call we trigger the config or power callbacks. The
1400        // `.take()` ensures we clear what is pending.
1401        self.deferred_call_operation.take().map(|op| match op {
1402            DeferredOperation::ConfigClientCallback => {
1403                self.config_client.map(|client| {
1404                    client.config_done(Ok(()));
1405                });
1406            }
1407            DeferredOperation::PowerClientCallback => {
1408                self.power_client.map(|client| {
1409                    client.changed(self.radio_is_on());
1410                });
1411            }
1412        });
1413    }
1414
1415    fn register(&'static self) {
1416        self.deferred_call.register(self);
1417    }
1418}