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}