1use crate::command::{FlushTx, WriteTxPayload};
2use crate::config::Configuration;
3use crate::device::Device;
4use crate::registers::{FifoStatus, ObserveTx, Status};
5use crate::standby::StandbyMode;
6use core::fmt;
7
8pub struct TxMode<D: Device> {
20 device: D,
21}
22
23impl<D: Device> fmt::Debug for TxMode<D> {
24 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
25 write!(f, "TxMode")
26 }
27}
28
29impl<D: Device> TxMode<D> {
30 pub(crate) fn new(device: D) -> Self {
33 TxMode { device }
34 }
35
36 pub fn standby(mut self) -> Result<StandbyMode<D>, D::Error> {
38 self.wait_empty()?;
39
40 Ok(StandbyMode::from_rx_tx(self.device))
41 }
42
43 pub fn is_empty(&mut self) -> Result<bool, D::Error> {
45 let (_, fifo_status) = self.device.read_register::<FifoStatus>()?;
46 Ok(fifo_status.tx_empty())
47 }
48
49 pub fn is_full(&mut self) -> Result<bool, D::Error> {
51 let (_, fifo_status) = self.device.read_register::<FifoStatus>()?;
52 Ok(fifo_status.tx_full())
53 }
54
55 pub fn can_send(&mut self) -> Result<bool, D::Error> {
57 let full = self.is_full()?;
58 Ok(!full)
59 }
60
61 pub fn send(&mut self, packet: &[u8]) -> Result<(), D::Error> {
63 self.device.send_command(&WriteTxPayload::new(packet))?;
64 self.device.ce_enable();
65 Ok(())
66 }
67
68 pub fn poll_send(&mut self) -> nb::Result<bool, D::Error> {
74 let (status, fifo_status) = self.device.read_register::<FifoStatus>()?;
75 if status.max_rt() {
78 self.device.send_command(&FlushTx)?;
81 self.clear_interrupts_and_ce()?;
82 Ok(false)
83 } else if fifo_status.tx_empty() {
84 self.clear_interrupts_and_ce()?;
85 Ok(true)
86 } else {
87 self.device.ce_enable();
88 Err(nb::Error::WouldBlock)
89 }
90 }
91
92 fn clear_interrupts_and_ce(&mut self) -> nb::Result<(), D::Error> {
93 let mut clear = Status(0);
94 clear.set_tx_ds(true);
95 clear.set_max_rt(true);
96 self.device.write_register(clear)?;
97
98 self.device.ce_disable();
100
101 Ok(())
102 }
103
104 pub fn wait_empty(&mut self) -> Result<(), D::Error> {
110 let mut empty = false;
111 while !empty {
112 let (status, fifo_status) = self.device.read_register::<FifoStatus>()?;
113 empty = fifo_status.tx_empty();
114 if !empty {
115 self.device.ce_enable();
116 }
117
118 if status.max_rt() {
120 let mut clear = Status(0);
121 self.device.send_command(&FlushTx)?;
124 clear.set_tx_ds(true);
126 clear.set_max_rt(true);
127 self.device.write_register(clear)?;
128 }
129 }
130 self.device.ce_disable();
132
133 Ok(())
134 }
135
136 pub fn observe(&mut self) -> Result<ObserveTx, D::Error> {
138 let (_, observe_tx) = self.device.read_register()?;
139 Ok(observe_tx)
140 }
141}
142
143impl<D: Device> Configuration for TxMode<D> {
144 type Inner = D;
145 fn device(&mut self) -> &mut Self::Inner {
146 &mut self.device
147 }
148}