1#![allow(unused_parens)]
17
18use crate::rf233_const::{
19 ExternalState, InteruptFlags, RF233BusCommand, RF233Register, RF233TrxCmd,
20};
21use core::cell::Cell;
22use kernel::hil::gpio;
23use kernel::hil::radio;
24use kernel::hil::spi;
25use kernel::utilities::cells::MapCell;
26use kernel::utilities::cells::OptionalCell;
27use kernel::utilities::leasable_buffer::SubSliceMut;
28use kernel::ErrorCode;
29
30use crate::rf233_const::CSMA_SEED_1;
31use crate::rf233_const::IRQ_MASK;
32use crate::rf233_const::PHY_CC_CCA_MODE_CS_OR_ED;
33use crate::rf233_const::PHY_RSSI_RX_CRC_VALID;
34use crate::rf233_const::PHY_TX_PWR;
35use crate::rf233_const::SHORT_ADDR_0;
36use crate::rf233_const::SHORT_ADDR_1;
37use crate::rf233_const::TRX_CTRL_1;
38use crate::rf233_const::TRX_CTRL_2;
39use crate::rf233_const::TRX_RPC;
40use crate::rf233_const::TRX_TRAC_CHANNEL_ACCESS_FAILURE;
41use crate::rf233_const::TRX_TRAC_MASK;
42use crate::rf233_const::XAH_CTRL_0;
43use crate::rf233_const::XAH_CTRL_1;
44
45#[allow(non_camel_case_types, dead_code)]
46#[derive(Copy, Clone, PartialEq)]
47enum InternalState {
48 START,
56 START_PART_READ,
57 START_STATUS_READ,
58 START_TURNING_OFF,
59 START_CTRL1_SET,
60 START_CCA_SET,
61 START_PWR_SET,
62 START_CTRL2_SET,
63 START_IRQMASK_SET,
64 START_XAH1_SET,
65 START_XAH0_SET,
66 START_PANID0_SET,
67 START_PANID1_SET,
68 START_IEEE0_SET,
69 START_IEEE1_SET,
70 START_IEEE2_SET,
71 START_IEEE3_SET,
72 START_IEEE4_SET,
73 START_IEEE5_SET,
74 START_IEEE6_SET,
75 START_IEEE7_SET,
76 START_SHORT0_SET,
77 START_SHORT1_SET,
78 START_CSMA_0_SEEDED,
79 START_CSMA_1_SEEDED,
80 START_RPC_SET,
81
82 ON_STATUS_READ,
84 ON_PLL_WAITING,
85 ON_PLL_SET,
86
87 READY,
89
90 SLEEP_TRX_OFF,
92 SLEEP,
93 SLEEP_WAKE,
94
95 TX_STATUS_PRECHECK1,
100 TX_WRITING_FRAME,
101 TX_WRITING_FRAME_DONE,
102 TX_STATUS_PRECHECK2,
103 TX_PLL_START,
104 TX_PLL_WAIT,
105 TX_ARET_ON,
106 TX_TRANSMITTING,
107 TX_READ_ACK,
108 TX_DONE,
109 TX_RETURN_TO_RX,
110
111 TX_PENDING,
117
118 CONFIG_SHORT0_SET,
121 CONFIG_SHORT1_SET,
122 CONFIG_PAN0_SET,
123 CONFIG_PAN1_SET,
124 CONFIG_IEEE0_SET,
125 CONFIG_IEEE1_SET,
126 CONFIG_IEEE2_SET,
127 CONFIG_IEEE3_SET,
128 CONFIG_IEEE4_SET,
129 CONFIG_IEEE5_SET,
130 CONFIG_IEEE6_SET,
131 CONFIG_IEEE7_SET,
132 CONFIG_POWER_SET,
133 CONFIG_DONE,
134
135 RX,
140 RX_TURNING_OFF, RX_READY_TO_READ, RX_START_READING, RX_READING_FRAME_LEN, RX_READING_FRAME_LEN_DONE,
146 RX_READING_FRAME, RX_READING_FRAME_DONE, RX_READING_FRAME_FCS_DONE,
149 RX_ENABLING_RECEPTION, }
151
152pub const SPI_REGISTER_TRANSACTION_LENGTH: usize = 2;
195
196pub struct RF233<'a, S: spi::SpiMasterDevice<'a>> {
197 spi: &'a S,
198 radio_on: Cell<bool>,
199 transmitting: Cell<bool>,
200 receiving: Cell<bool>,
201 spi_busy: Cell<bool>,
202 crc_valid: Cell<bool>,
203 interrupt_handling: Cell<bool>,
204 interrupt_pending: Cell<bool>,
205 config_pending: Cell<bool>,
206 sleep_pending: Cell<bool>,
207 wake_pending: Cell<bool>,
208 power_client_pending: Cell<bool>,
209 reset_pin: &'a dyn gpio::Pin,
210 sleep_pin: &'a dyn gpio::Pin,
211 irq_pin: &'a dyn gpio::InterruptPin<'a>,
212 state: Cell<InternalState>,
213 tx_buf: MapCell<SubSliceMut<'static, u8>>,
214 rx_buf: MapCell<SubSliceMut<'static, u8>>,
215 tx_len: Cell<u8>,
216 tx_client: OptionalCell<&'a dyn radio::TxClient>,
217 rx_client: OptionalCell<&'a dyn radio::RxClient>,
218 cfg_client: OptionalCell<&'a dyn radio::ConfigClient>,
219 power_client: OptionalCell<&'a dyn radio::PowerClient>,
220 addr: Cell<u16>,
221 addr_long: Cell<[u8; 8]>,
222 pan: Cell<u16>,
223 tx_power: Cell<i8>,
224 channel: Cell<radio::RadioChannel>,
225 spi_rx: MapCell<SubSliceMut<'static, u8>>,
226 spi_tx: MapCell<SubSliceMut<'static, u8>>,
227 spi_buf: MapCell<SubSliceMut<'static, u8>>,
228}
229
230fn setting_to_power(setting: u8) -> i8 {
231 match setting {
232 0x00 => 4,
233 0x01 => 4,
234 0x02 => 3,
235 0x03 => 3,
236 0x04 => 2,
237 0x05 => 2,
238 0x06 => 1,
239 0x07 => 0,
240 0x08 => -1,
241 0x09 => -2,
242 0x0A => -3,
243 0x0B => -4,
244 0x0C => -6,
245 0x0D => -8,
246 0x0E => -12,
247 0x0F => -17,
248 _ => -127,
249 }
250}
251
252fn power_to_setting(power: i8) -> u8 {
253 if (power >= 4) {
254 0x00
255 } else if (power >= 3) {
256 0x03
257 } else if (power >= 2) {
258 0x05
259 } else if (power >= 1) {
260 0x06
261 } else if (power >= 0) {
262 0x07
263 } else if (power >= -1) {
264 0x08
265 } else if (power >= -2) {
266 0x09
267 } else if (power >= -3) {
268 0x0A
269 } else if (power >= -4) {
270 0x0B
271 } else if (power >= -6) {
272 0x0C
273 } else if (power >= -8) {
274 0x0D
275 } else if (power >= -12) {
276 0x0E
277 } else {
278 0x0F
279 }
280}
281
282fn interrupt_included(mask: u8, interrupt: InteruptFlags) -> bool {
283 let int = interrupt as u8;
284 (mask & int) == int
285}
286
287impl<'a, S: spi::SpiMasterDevice<'a>> spi::SpiMasterClient for RF233<'a, S> {
288 fn read_write_done(
292 &self,
293 mut _write: SubSliceMut<'static, u8>,
294 mut read: Option<SubSliceMut<'static, u8>>,
295 _spi_status: Result<usize, ErrorCode>,
296 ) {
297 self.spi_busy.set(false);
298 let rbuf = read.take().unwrap();
299 let status = rbuf[0] & 0x1f;
300 let result = rbuf[1];
301
302 let state = self.state.get();
317
318 let handling = self.interrupt_handling.get();
319 if !handling && state == InternalState::RX_READING_FRAME_LEN {
320 self.spi_buf.replace(_write);
321 self.rx_buf.replace(rbuf);
322 self.state.set(InternalState::RX_READING_FRAME_LEN_DONE);
323 } else if !handling && state == InternalState::RX_READING_FRAME {
324 self.spi_buf.replace(_write);
325 self.rx_buf.replace(rbuf);
326 self.state.set(InternalState::RX_READING_FRAME_DONE);
327 } else if !handling && state == InternalState::TX_WRITING_FRAME {
328 self.spi_buf.replace(rbuf);
329 self.tx_buf.replace(_write);
330 self.state.set(InternalState::TX_WRITING_FRAME_DONE);
331 } else {
332 self.spi_rx.replace(rbuf);
333 self.spi_tx.replace(_write);
334 }
335
336 let state = self.state.get();
337
338 if handling {
342 self.interrupt_handling.set(false);
343
344 let interrupt = result;
345
346 if state != InternalState::SLEEP_TRX_OFF && state != InternalState::SLEEP {
348 if state == InternalState::ON_PLL_WAITING {
349 if interrupt_included(interrupt, InteruptFlags::IRQ_0_PLL_LOCK) {
350 self.state.set(InternalState::ON_PLL_SET);
351 }
352 } else if state == InternalState::TX_TRANSMITTING
353 && interrupt_included(interrupt, InteruptFlags::IRQ_3_TRX_END)
354 {
355 self.state.set(InternalState::TX_DONE);
356 }
357 if interrupt_included(interrupt, InteruptFlags::IRQ_2_RX_START) {
358 self.receiving.set(true);
360 self.state.set(InternalState::RX);
361 }
362
363 if (interrupt_included(interrupt, InteruptFlags::IRQ_3_TRX_END)
370 && self.receiving.get())
371 {
372 self.receiving.set(false);
373 if self.rx_buf.is_some() {
374 self.state.set(InternalState::RX_START_READING);
375 } else if self.transmitting.get() {
376 self.state_transition_read(
377 RF233Register::MIN,
378 InternalState::TX_STATUS_PRECHECK1,
379 );
380 return;
381 } else {
382 self.state_transition_read(RF233Register::TRX_STATUS, InternalState::READY);
383 return;
384 }
385 }
386 }
387 }
388
389 if self.state.get() == InternalState::READY {
392 self.wake_pending.set(false);
393
394 if !self.radio_on.get() {
396 self.power_client_pending.set(true);
397 }
398 self.radio_on.set(true);
399 }
400
401 if self.interrupt_pending.get() {
408 match self.state.get() {
409 InternalState::RX_TURNING_OFF
410 | InternalState::RX_START_READING
411 | InternalState::RX_READING_FRAME_DONE
412 | InternalState::RX_READING_FRAME_FCS_DONE => {}
413 _ => {
414 self.interrupt_pending.set(false);
415 self.handle_interrupt();
416 return;
417 }
418 }
419 }
420 if self.config_pending.get() && self.state.get() == InternalState::READY {
424 self.state_transition_write(
425 RF233Register::SHORT_ADDR_0,
426 (self.addr.get() & 0xff) as u8,
427 InternalState::CONFIG_SHORT0_SET,
428 );
429 }
430
431 match self.state.get() {
432 InternalState::READY => {
434 if self.sleep_pending.get() {
436 self.sleep_pending.set(false);
437 self.radio_on.set(false);
438 self.state_transition_write(
439 RF233Register::TRX_STATE,
440 RF233TrxCmd::OFF as u8,
441 InternalState::SLEEP_TRX_OFF,
442 );
443 } else if self.power_client_pending.get() {
444 self.power_client_pending.set(false);
446 self.power_client.map(|p| {
447 p.changed(self.radio_on.get());
448 });
449 }
450 }
451 InternalState::START => {
453 self.state_transition_read(
454 RF233Register::IRQ_STATUS,
455 InternalState::START_PART_READ,
456 );
457 }
458 InternalState::START_PART_READ => {
459 self.state_transition_read(
460 RF233Register::TRX_STATUS,
461 InternalState::START_STATUS_READ,
462 );
463 }
464 InternalState::START_STATUS_READ => {
465 if status == ExternalState::ON as u8 {
466 self.state_transition_write(
467 RF233Register::TRX_STATE,
468 RF233TrxCmd::OFF as u8,
469 InternalState::START_TURNING_OFF,
470 );
471 } else {
472 self.state_transition_write(
473 RF233Register::TRX_CTRL_1,
474 TRX_CTRL_1,
475 InternalState::START_CTRL1_SET,
476 );
477 }
478 }
479 InternalState::START_TURNING_OFF => {
480 self.irq_pin.make_input();
481 self.irq_pin.clear();
482 self.irq_pin
483 .set_floating_state(gpio::FloatingState::PullNone);
484 self.irq_pin
485 .enable_interrupts(gpio::InterruptEdge::RisingEdge);
486
487 self.state_transition_write(
488 RF233Register::TRX_CTRL_1,
489 TRX_CTRL_1,
490 InternalState::START_CTRL1_SET,
491 );
492 }
493 InternalState::START_CTRL1_SET => {
494 let val = self.channel.get().get_channel_number() | PHY_CC_CCA_MODE_CS_OR_ED;
495 self.state_transition_write(
496 RF233Register::PHY_CC_CCA,
497 val,
498 InternalState::START_CCA_SET,
499 );
500 }
501 InternalState::START_CCA_SET => {
502 let val = power_to_setting(self.tx_power.get());
503 self.state_transition_write(
504 RF233Register::PHY_TX_PWR,
505 val,
506 InternalState::START_PWR_SET,
507 );
508 }
509 InternalState::START_PWR_SET => self.state_transition_write(
510 RF233Register::TRX_CTRL_2,
511 TRX_CTRL_2,
512 InternalState::START_CTRL2_SET,
513 ),
514 InternalState::START_CTRL2_SET => {
515 self.state_transition_write(
516 RF233Register::IRQ_MASK,
517 IRQ_MASK,
518 InternalState::START_IRQMASK_SET,
519 );
520 }
521
522 InternalState::START_IRQMASK_SET => {
523 self.state_transition_write(
524 RF233Register::XAH_CTRL_1,
525 XAH_CTRL_1,
526 InternalState::START_XAH1_SET,
527 );
528 }
529
530 InternalState::START_XAH1_SET => {
531 self.state_transition_write(
534 RF233Register::XAH_CTRL_0,
535 XAH_CTRL_0,
536 InternalState::START_XAH0_SET,
537 );
538 }
539 InternalState::START_XAH0_SET => {
540 self.state_transition_write(
541 RF233Register::PAN_ID_0,
542 (self.pan.get() >> 8) as u8,
543 InternalState::START_PANID0_SET,
544 );
545 }
546 InternalState::START_PANID0_SET => {
547 self.state_transition_write(
548 RF233Register::PAN_ID_1,
549 (self.pan.get() & 0xff) as u8,
550 InternalState::START_PANID1_SET,
551 );
552 }
553 InternalState::START_PANID1_SET => {
554 self.state_transition_write(
555 RF233Register::IEEE_ADDR_0,
556 self.addr_long.get()[0],
557 InternalState::START_IEEE0_SET,
558 );
559 }
560 InternalState::START_IEEE0_SET => {
561 self.state_transition_write(
562 RF233Register::IEEE_ADDR_1,
563 self.addr_long.get()[1],
564 InternalState::START_IEEE1_SET,
565 );
566 }
567 InternalState::START_IEEE1_SET => {
568 self.state_transition_write(
569 RF233Register::IEEE_ADDR_2,
570 self.addr_long.get()[2],
571 InternalState::START_IEEE2_SET,
572 );
573 }
574 InternalState::START_IEEE2_SET => {
575 self.state_transition_write(
576 RF233Register::IEEE_ADDR_3,
577 self.addr_long.get()[3],
578 InternalState::START_IEEE3_SET,
579 );
580 }
581 InternalState::START_IEEE3_SET => {
582 self.state_transition_write(
583 RF233Register::IEEE_ADDR_4,
584 self.addr_long.get()[4],
585 InternalState::START_IEEE4_SET,
586 );
587 }
588 InternalState::START_IEEE4_SET => {
589 self.state_transition_write(
590 RF233Register::IEEE_ADDR_5,
591 self.addr_long.get()[5],
592 InternalState::START_IEEE5_SET,
593 );
594 }
595 InternalState::START_IEEE5_SET => {
596 self.state_transition_write(
597 RF233Register::IEEE_ADDR_6,
598 self.addr_long.get()[6],
599 InternalState::START_IEEE6_SET,
600 );
601 }
602 InternalState::START_IEEE6_SET => {
603 self.state_transition_write(
604 RF233Register::IEEE_ADDR_7,
605 self.addr_long.get()[7],
606 InternalState::START_IEEE7_SET,
607 );
608 }
609 InternalState::START_IEEE7_SET => {
610 self.state_transition_write(
611 RF233Register::SHORT_ADDR_0,
612 (self.addr.get() & 0xff) as u8,
613 InternalState::START_SHORT0_SET,
614 );
615 }
616 InternalState::START_SHORT0_SET => {
617 self.state_transition_write(
618 RF233Register::SHORT_ADDR_1,
619 (self.addr.get() >> 8) as u8,
620 InternalState::START_SHORT1_SET,
621 );
622 }
623 InternalState::START_SHORT1_SET => {
624 self.state_transition_write(
625 RF233Register::CSMA_SEED_0,
626 SHORT_ADDR_0 + SHORT_ADDR_1,
627 InternalState::START_CSMA_0_SEEDED,
628 );
629 }
630 InternalState::START_CSMA_0_SEEDED => {
631 self.state_transition_write(
632 RF233Register::CSMA_SEED_1,
633 CSMA_SEED_1,
634 InternalState::START_CSMA_1_SEEDED,
635 );
636 }
637 InternalState::START_CSMA_1_SEEDED => {
638 self.state_transition_write(
639 RF233Register::TRX_RPC,
640 TRX_RPC,
641 InternalState::START_RPC_SET,
642 );
643 }
644 InternalState::START_RPC_SET => {
645 self.state_transition_read(
647 RF233Register::TRX_STATUS,
648 InternalState::ON_STATUS_READ,
649 );
650 }
651 InternalState::ON_STATUS_READ => {
652 self.state_transition_write(
653 RF233Register::TRX_STATE,
654 RF233TrxCmd::PLL_ON as u8,
655 InternalState::ON_PLL_WAITING,
656 );
657 }
658 InternalState::ON_PLL_WAITING => {
659 }
661
662 InternalState::ON_PLL_SET => {
664 self.state_transition_write(
669 RF233Register::TRX_STATE,
670 RF233TrxCmd::RX_AACK_ON as u8,
671 InternalState::READY,
672 );
673 }
674 InternalState::SLEEP_TRX_OFF => {
675 self.sleep_pin.set();
677
678 if self.wake_pending.get() {
681 self.state_transition_read(
682 RF233Register::TRX_STATUS,
683 InternalState::SLEEP_WAKE,
684 );
685 } else {
687 self.state.set(InternalState::SLEEP);
688 self.power_client.map(|p| {
689 p.changed(self.radio_on.get());
690 });
691 self.irq_pin.disable_interrupts(); }
693 }
694 InternalState::SLEEP => {}
696
697 InternalState::SLEEP_WAKE => {
698 self.sleep_pin.clear();
701 self.irq_pin
702 .enable_interrupts(gpio::InterruptEdge::RisingEdge);
703 self.state_transition_write(
704 RF233Register::TRX_STATE,
705 RF233TrxCmd::RX_AACK_ON as u8,
706 InternalState::READY,
707 );
708 }
709 InternalState::TX_STATUS_PRECHECK1 => {
710 if (status == ExternalState::BUSY_RX_AACK as u8
711 || status == ExternalState::BUSY_TX_ARET as u8
712 || status == ExternalState::BUSY_RX as u8)
713 {
714 self.state.set(InternalState::TX_PENDING);
715 } else {
716 self.state.set(InternalState::TX_WRITING_FRAME);
718 let wbuf = self.tx_buf.take().unwrap();
719 let _ = self.frame_write(wbuf.take(), self.tx_len.get());
720 }
721 }
722 InternalState::TX_WRITING_FRAME => {} InternalState::TX_WRITING_FRAME_DONE => {
724 self.state_transition_read(
725 RF233Register::TRX_STATUS,
726 InternalState::TX_STATUS_PRECHECK2,
727 );
728 }
729 InternalState::TX_STATUS_PRECHECK2 => {
730 if (status == ExternalState::BUSY_RX_AACK as u8
731 || status == ExternalState::BUSY_TX_ARET as u8
732 || status == ExternalState::BUSY_RX as u8)
733 {
734 self.receiving.set(true);
735 self.state.set(InternalState::RX);
736 } else {
737 self.state_transition_write(
738 RF233Register::TRX_STATE,
739 RF233TrxCmd::PLL_ON as u8,
740 InternalState::TX_PLL_START,
741 );
742 }
743 }
744 InternalState::TX_PLL_START => {
745 self.state_transition_read(RF233Register::TRX_STATUS, InternalState::TX_PLL_WAIT);
746 }
747 InternalState::TX_PLL_WAIT => {
748 self.transmitting.set(true);
749 if status == ExternalState::STATE_TRANSITION_IN_PROGRESS as u8 {
750 self.state_transition_read(
751 RF233Register::TRX_STATUS,
752 InternalState::TX_PLL_WAIT,
753 );
754 } else if status != ExternalState::PLL_ON as u8 {
755 self.state_transition_write(
756 RF233Register::TRX_STATE,
757 RF233TrxCmd::PLL_ON as u8,
758 InternalState::TX_PLL_WAIT,
759 );
760 } else {
761 self.state_transition_write(
762 RF233Register::TRX_STATE,
763 RF233TrxCmd::TX_ARET_ON as u8,
764 InternalState::TX_ARET_ON,
765 );
766 }
767 }
768 InternalState::TX_ARET_ON => {
769 self.state_transition_write(
770 RF233Register::TRX_STATE,
771 RF233TrxCmd::TX_START as u8,
772 InternalState::TX_TRANSMITTING,
773 );
774 }
775 InternalState::TX_TRANSMITTING => {
776 }
780 InternalState::TX_DONE => {
781 self.state_transition_write(
782 RF233Register::TRX_STATE,
783 RF233TrxCmd::RX_AACK_ON as u8,
784 InternalState::TX_READ_ACK,
785 );
786 }
787 InternalState::TX_READ_ACK => {
788 self.state_transition_read(
789 RF233Register::TRX_STATE,
790 InternalState::TX_RETURN_TO_RX,
791 );
792 }
793
794 InternalState::TX_RETURN_TO_RX => {
796 let ack: bool = (result & TRX_TRAC_MASK) == 0;
797 if status == ExternalState::RX_AACK_ON as u8 {
798 let return_code = if (result & TRX_TRAC_MASK) == TRX_TRAC_CHANNEL_ACCESS_FAILURE
799 {
800 Err(ErrorCode::FAIL)
801 } else {
802 Ok(())
803 };
804
805 self.transmitting.set(false);
806 let buf = self.tx_buf.take();
807 self.state_transition_read(RF233Register::TRX_STATUS, InternalState::READY);
808
809 self.tx_client.map(|c| {
810 c.send_done(buf.unwrap().take(), ack, return_code);
811 });
812 } else {
813 let _ = self.register_read(RF233Register::TRX_STATUS);
814 }
815 }
816
817 InternalState::TX_PENDING => {}
823
824 InternalState::RX => {}
827 InternalState::RX_TURNING_OFF => {
828 self.state_transition_read(
833 RF233Register::IRQ_STATUS,
834 InternalState::RX_READY_TO_READ,
835 );
836 self.interrupt_handling.set(true);
837 }
838 InternalState::RX_READY_TO_READ => {}
842
843 InternalState::RX_START_READING => {
845 self.state.set(InternalState::RX_READING_FRAME_LEN);
846 let _ = self.frame_read(self.rx_buf.take().unwrap().take(), 0);
850 }
851
852 InternalState::RX_READING_FRAME_LEN => {} InternalState::RX_READING_FRAME_LEN_DONE => {
854 let frame_len = result;
860 if (frame_len <= radio::MAX_FRAME_SIZE as u8
862 && frame_len >= radio::MIN_FRAME_SIZE as u8)
863 {
864 self.state.set(InternalState::RX_READING_FRAME);
865 let rbuf = self.rx_buf.take().unwrap();
866 let _ = self.frame_read(rbuf.take(), frame_len);
867 } else if self.transmitting.get() {
868 self.state_transition_read(
871 RF233Register::TRX_STATUS,
872 InternalState::TX_STATUS_PRECHECK1,
873 );
874 } else {
875 self.state_transition_read(RF233Register::TRX_STATUS, InternalState::READY);
878 }
879 }
880 InternalState::RX_READING_FRAME => {} InternalState::RX_READING_FRAME_DONE => {
882 self.state_transition_read(
884 RF233Register::PHY_RSSI,
885 InternalState::RX_READING_FRAME_FCS_DONE,
886 );
887 }
888 InternalState::RX_READING_FRAME_FCS_DONE => {
889 self.crc_valid.set((result & PHY_RSSI_RX_CRC_VALID) != 0);
891 self.state_transition_write(
892 RF233Register::TRX_STATE,
893 RF233TrxCmd::RX_AACK_ON as u8,
894 InternalState::RX_ENABLING_RECEPTION,
895 );
896 }
897 InternalState::RX_ENABLING_RECEPTION => {
898 self.receiving.set(false);
899
900 self.sleep_pending.set(false);
906
907 if self.transmitting.get() {
910 self.state_transition_read(
911 RF233Register::TRX_STATUS,
912 InternalState::TX_STATUS_PRECHECK1,
913 );
914 } else {
915 self.state_transition_read(RF233Register::TRX_STATUS, InternalState::READY);
916 }
917 self.rx_client.map(|client| {
918 let rbuf = self.rx_buf.take().unwrap();
919 let frame_len = rbuf[1] as usize - radio::MFR_SIZE;
920
921 client.receive(rbuf.take(), frame_len, 0, self.crc_valid.get(), Ok(()));
923 });
924 }
925
926 InternalState::CONFIG_SHORT0_SET => {
927 self.state_transition_write(
928 RF233Register::SHORT_ADDR_1,
929 (self.addr.get() >> 8) as u8,
930 InternalState::CONFIG_SHORT1_SET,
931 );
932 }
933 InternalState::CONFIG_SHORT1_SET => {
934 self.state_transition_write(
935 RF233Register::PAN_ID_0,
936 (self.pan.get() & 0xff) as u8,
937 InternalState::CONFIG_PAN0_SET,
938 );
939 }
940 InternalState::CONFIG_PAN0_SET => {
941 self.state_transition_write(
942 RF233Register::PAN_ID_1,
943 (self.pan.get() >> 8) as u8,
944 InternalState::CONFIG_PAN1_SET,
945 );
946 }
947 InternalState::CONFIG_PAN1_SET => {
948 self.state_transition_write(
949 RF233Register::IEEE_ADDR_0,
950 self.addr_long.get()[0],
951 InternalState::CONFIG_IEEE0_SET,
952 );
953 }
954 InternalState::CONFIG_IEEE0_SET => {
955 self.state_transition_write(
956 RF233Register::IEEE_ADDR_1,
957 self.addr_long.get()[1],
958 InternalState::CONFIG_IEEE1_SET,
959 );
960 }
961 InternalState::CONFIG_IEEE1_SET => {
962 self.state_transition_write(
963 RF233Register::IEEE_ADDR_2,
964 self.addr_long.get()[2],
965 InternalState::CONFIG_IEEE2_SET,
966 );
967 }
968 InternalState::CONFIG_IEEE2_SET => {
969 self.state_transition_write(
970 RF233Register::IEEE_ADDR_3,
971 self.addr_long.get()[3],
972 InternalState::CONFIG_IEEE3_SET,
973 );
974 }
975 InternalState::CONFIG_IEEE3_SET => {
976 self.state_transition_write(
977 RF233Register::IEEE_ADDR_4,
978 self.addr_long.get()[4],
979 InternalState::CONFIG_IEEE4_SET,
980 );
981 }
982 InternalState::CONFIG_IEEE4_SET => {
983 self.state_transition_write(
984 RF233Register::IEEE_ADDR_5,
985 self.addr_long.get()[5],
986 InternalState::CONFIG_IEEE5_SET,
987 );
988 }
989 InternalState::CONFIG_IEEE5_SET => {
990 self.state_transition_write(
991 RF233Register::IEEE_ADDR_6,
992 self.addr_long.get()[6],
993 InternalState::CONFIG_IEEE6_SET,
994 );
995 }
996 InternalState::CONFIG_IEEE6_SET => {
997 self.state_transition_write(
998 RF233Register::IEEE_ADDR_7,
999 self.addr_long.get()[7],
1000 InternalState::CONFIG_IEEE7_SET,
1001 );
1002 }
1003 InternalState::CONFIG_IEEE7_SET => {
1004 let val = power_to_setting(self.tx_power.get());
1005 self.state_transition_write(
1006 RF233Register::PHY_TX_PWR,
1007 val,
1008 InternalState::CONFIG_POWER_SET,
1009 );
1010 }
1011 InternalState::CONFIG_POWER_SET => {
1012 let val = self.channel.get().get_channel_number() | PHY_CC_CCA_MODE_CS_OR_ED;
1013 self.state_transition_write(
1014 RF233Register::PHY_CC_CCA,
1015 val,
1016 InternalState::CONFIG_DONE,
1017 );
1018 }
1019 InternalState::CONFIG_DONE => {
1020 self.config_pending.set(false);
1021 self.state_transition_read(RF233Register::TRX_STATUS, InternalState::READY);
1022 self.cfg_client.map(|c| {
1023 c.config_done(Ok(()));
1024 });
1025 }
1026 }
1027 }
1028}
1029
1030impl<'a, S: spi::SpiMasterDevice<'a>> gpio::Client for RF233<'a, S> {
1031 fn fired(&self) {
1032 self.handle_interrupt();
1033 }
1034}
1035
1036impl<'a, S: spi::SpiMasterDevice<'a>> RF233<'a, S> {
1037 pub fn new(
1038 spi: &'a S,
1039 spi_buf: &'static mut [u8],
1040 reg_write: &'static mut [u8; SPI_REGISTER_TRANSACTION_LENGTH],
1041 reg_read: &'static mut [u8; SPI_REGISTER_TRANSACTION_LENGTH],
1042 reset: &'a dyn gpio::Pin,
1043 sleep: &'a dyn gpio::Pin,
1044 irq: &'a dyn gpio::InterruptPin<'a>,
1045 channel: radio::RadioChannel,
1046 ) -> RF233<'a, S> {
1047 RF233 {
1048 spi,
1049 reset_pin: reset,
1050 sleep_pin: sleep,
1051 irq_pin: irq,
1052 radio_on: Cell::new(false),
1053 transmitting: Cell::new(false),
1054 receiving: Cell::new(false),
1055 spi_busy: Cell::new(false),
1056 crc_valid: Cell::new(false),
1057 state: Cell::new(InternalState::START),
1058 interrupt_handling: Cell::new(false),
1059 interrupt_pending: Cell::new(false),
1060 config_pending: Cell::new(false),
1061 sleep_pending: Cell::new(false),
1062 wake_pending: Cell::new(false),
1063 power_client_pending: Cell::new(false),
1064 tx_buf: MapCell::empty(),
1065 rx_buf: MapCell::empty(),
1066 tx_len: Cell::new(0),
1067 tx_client: OptionalCell::empty(),
1068 rx_client: OptionalCell::empty(),
1069 cfg_client: OptionalCell::empty(),
1070 power_client: OptionalCell::empty(),
1071 addr: Cell::new(0),
1072 addr_long: Cell::new([0x00; 8]),
1073 pan: Cell::new(0),
1074 tx_power: Cell::new(setting_to_power(PHY_TX_PWR)),
1075 channel: Cell::new(channel),
1076 spi_rx: MapCell::new((&mut reg_read[..]).into()),
1077 spi_tx: MapCell::new((&mut reg_write[..]).into()),
1078 spi_buf: MapCell::new(spi_buf.into()),
1079 }
1080 }
1081
1082 fn handle_interrupt(&self) {
1083 if !self.spi_busy.get() {
1090 if self.state.get() == InternalState::RX {
1091 self.state_transition_write(
1100 RF233Register::TRX_STATE,
1101 RF233TrxCmd::PLL_ON as u8,
1102 InternalState::RX_TURNING_OFF,
1103 );
1104 } else {
1105 self.interrupt_handling.set(true);
1106 let _ = self.register_read(RF233Register::IRQ_STATUS);
1107 }
1108 } else {
1109 self.interrupt_pending.set(true);
1110 }
1111 }
1112
1113 fn register_write(&self, reg: RF233Register, val: u8) -> Result<(), ErrorCode> {
1114 if (self.spi_busy.get() || self.spi_tx.is_none() || self.spi_rx.is_none()) {
1115 return Err(ErrorCode::BUSY);
1116 }
1117 let mut wbuf = self.spi_tx.take().unwrap();
1118 let rbuf = self.spi_rx.take().unwrap();
1119 wbuf[0] = (reg as u8) | RF233BusCommand::REGISTER_WRITE as u8;
1120 wbuf[1] = val;
1121 wbuf.slice(0..2);
1122 let _ = self.spi.read_write_bytes(wbuf, Some(rbuf));
1124 self.spi_busy.set(true);
1125
1126 Ok(())
1127 }
1128
1129 fn register_read(&self, reg: RF233Register) -> Result<(), ErrorCode> {
1130 if (self.spi_busy.get() || self.spi_tx.is_none() || self.spi_rx.is_none()) {
1131 return Err(ErrorCode::BUSY);
1132 }
1133
1134 let mut wbuf = self.spi_tx.take().unwrap();
1135 let rbuf = self.spi_rx.take().unwrap();
1136 wbuf.reset();
1137 wbuf.slice(0..2);
1138 wbuf[0] = (reg as u8) | RF233BusCommand::REGISTER_READ as u8;
1139 wbuf[1] = 0;
1140 let _ = self.spi.read_write_bytes(wbuf, Some(rbuf));
1142 self.spi_busy.set(true);
1143
1144 Ok(())
1145 }
1146
1147 fn frame_write(&self, buf: &'static mut [u8], frame_len: u8) -> Result<(), ErrorCode> {
1148 if self.spi_busy.get() {
1149 return Err(ErrorCode::BUSY);
1150 }
1151
1152 let buf_len = radio::PSDU_OFFSET + frame_len as usize;
1153 buf[0] = RF233BusCommand::FRAME_WRITE as u8;
1154 let mut buf: SubSliceMut<'static, u8> = buf.into();
1155 buf.slice(0..buf_len);
1156 let _ = self.spi.read_write_bytes(buf, self.spi_buf.take());
1158 self.spi_busy.set(true);
1159 Ok(())
1160 }
1161
1162 fn frame_read(&self, buf: &'static mut [u8], frame_len: u8) -> Result<(), ErrorCode> {
1163 if self.spi_busy.get() {
1164 return Err(ErrorCode::BUSY);
1165 }
1166
1167 let buf_len = radio::PSDU_OFFSET + frame_len as usize;
1168 let mut wbuf = self.spi_buf.take().unwrap();
1169 wbuf[0] = RF233BusCommand::FRAME_READ as u8;
1170 wbuf.reset();
1171 wbuf.slice(0..buf_len);
1172 let _ = self.spi.read_write_bytes(wbuf, Some(buf.into()));
1174 self.spi_busy.set(true);
1175 Ok(())
1176 }
1177
1178 fn state_transition_write(&self, reg: RF233Register, val: u8, state: InternalState) {
1179 self.state.set(state);
1180 let _ = self.register_write(reg, val);
1181 }
1182
1183 fn state_transition_read(&self, reg: RF233Register, state: InternalState) {
1184 self.state.set(state);
1185 let _ = self.register_read(reg);
1186 }
1187}
1188
1189impl<'a, S: spi::SpiMasterDevice<'a>> radio::RadioConfig<'a> for RF233<'a, S> {
1190 fn initialize(&self) -> Result<(), ErrorCode> {
1191 Ok(())
1192 }
1193
1194 fn reset(&self) -> Result<(), ErrorCode> {
1195 self.spi.configure(
1196 spi::ClockPolarity::IdleLow,
1197 spi::ClockPhase::SampleLeading,
1198 100000,
1199 )?;
1200 self.reset_pin.make_output();
1201 self.sleep_pin.make_output();
1202 for _i in 0..10000 {
1203 self.reset_pin.clear();
1204 }
1205 self.reset_pin.set();
1206 self.sleep_pin.clear();
1207 self.transmitting.set(false);
1208 Ok(())
1209 }
1210
1211 fn start(&self) -> Result<(), ErrorCode> {
1212 self.sleep_pending.set(false);
1213
1214 if self.state.get() != InternalState::START && self.state.get() != InternalState::SLEEP {
1215 return Err(ErrorCode::ALREADY);
1216 }
1217
1218 if self.state.get() == InternalState::SLEEP {
1219 self.state_transition_read(RF233Register::TRX_STATUS, InternalState::SLEEP_WAKE);
1220 } else {
1221 self.wake_pending.set(true);
1223 let _ = self.register_read(RF233Register::PART_NUM);
1224 }
1225
1226 Ok(())
1227 }
1228
1229 fn stop(&self) -> Result<(), ErrorCode> {
1230 if self.state.get() == InternalState::SLEEP
1231 || self.state.get() == InternalState::SLEEP_TRX_OFF
1232 {
1233 return Err(ErrorCode::ALREADY);
1234 }
1235
1236 match self.state.get() {
1237 InternalState::READY | InternalState::ON_PLL_WAITING => {
1238 self.radio_on.set(false);
1239 self.state_transition_write(
1240 RF233Register::TRX_STATE,
1241 RF233TrxCmd::OFF as u8,
1242 InternalState::SLEEP_TRX_OFF,
1243 );
1244 }
1245 _ => {
1246 self.sleep_pending.set(true);
1247 }
1248 }
1249
1250 Ok(())
1251 }
1252
1253 fn is_on(&self) -> bool {
1254 self.radio_on.get()
1255 }
1256
1257 fn busy(&self) -> bool {
1258 self.state.get() != InternalState::READY && self.state.get() != InternalState::SLEEP
1259 }
1260
1261 fn set_config_client(&self, client: &'a dyn radio::ConfigClient) {
1262 self.cfg_client.set(client);
1263 }
1264
1265 fn set_power_client(&self, client: &'a dyn radio::PowerClient) {
1266 self.power_client.set(client);
1267 }
1268
1269 fn set_address(&self, addr: u16) {
1270 self.addr.set(addr);
1271 }
1272
1273 fn set_address_long(&self, addr: [u8; 8]) {
1274 self.addr_long.set(addr);
1275 }
1276
1277 fn set_pan(&self, id: u16) {
1278 self.pan.set(id);
1279 }
1280
1281 fn set_tx_power(&self, power: i8) -> Result<(), ErrorCode> {
1282 if (power > 4 || power < -17) {
1283 Err(ErrorCode::INVAL)
1284 } else {
1285 self.tx_power.set(power);
1286 Ok(())
1287 }
1288 }
1289
1290 fn set_channel(&self, chan: radio::RadioChannel) {
1291 self.channel.set(chan);
1292 }
1293
1294 fn get_address(&self) -> u16 {
1295 self.addr.get()
1296 }
1297
1298 fn get_address_long(&self) -> [u8; 8] {
1299 self.addr_long.get()
1300 }
1301
1302 fn get_pan(&self) -> u16 {
1304 self.pan.get()
1305 }
1306 fn get_tx_power(&self) -> i8 {
1308 self.tx_power.get()
1309 }
1310 fn get_channel(&self) -> u8 {
1312 self.channel.get().get_channel_number()
1313 }
1314
1315 fn config_commit(&self) {
1316 let pending = self.config_pending.get();
1317 if !pending {
1318 self.config_pending.set(true);
1319 let state = self.state.get();
1320
1321 if state == InternalState::READY {
1322 self.state_transition_write(
1324 RF233Register::SHORT_ADDR_0,
1325 (self.addr.get() & 0xff) as u8,
1326 InternalState::CONFIG_SHORT0_SET,
1327 );
1328 } else {
1329 }
1334 }
1335 }
1336}
1337
1338impl<'a, S: spi::SpiMasterDevice<'a>> radio::RadioData<'a> for RF233<'a, S> {
1339 fn set_transmit_client(&self, client: &'a dyn radio::TxClient) {
1340 self.tx_client.set(client);
1341 }
1342
1343 fn set_receive_client(&self, client: &'a dyn radio::RxClient) {
1344 self.rx_client.set(client);
1345 }
1346
1347 fn set_receive_buffer(&self, buffer: &'static mut [u8]) {
1348 self.rx_buf.replace(buffer.into());
1349 }
1350
1351 fn transmit(
1353 &self,
1354 spi_buf: &'static mut [u8],
1355 frame_len: usize,
1356 ) -> Result<(), (ErrorCode, &'static mut [u8])> {
1357 let state = self.state.get();
1358 let frame_len = frame_len + radio::MFR_SIZE;
1359
1360 if !self.radio_on.get() {
1361 return Err((ErrorCode::OFF, spi_buf));
1362 } else if self.tx_buf.is_some() || self.transmitting.get() {
1363 return Err((ErrorCode::BUSY, spi_buf));
1364 } else if radio::PSDU_OFFSET + frame_len >= spi_buf.len() {
1365 return Err((ErrorCode::SIZE, spi_buf));
1367 }
1368
1369 spi_buf[1] = frame_len as u8;
1371 self.tx_buf.replace(spi_buf.into());
1372 self.tx_len.set(frame_len as u8);
1373 self.transmitting.set(true);
1374
1375 if !self.receiving.get() && state == InternalState::READY {
1376 self.state_transition_read(
1377 RF233Register::TRX_STATUS,
1378 InternalState::TX_STATUS_PRECHECK1,
1379 );
1380 }
1381 Ok(())
1382 }
1383}