1use embassy_nrf::{
8 Peri,
9 buffered_uarte::{BufferedUarteRx, BufferedUarteTx, InterruptHandler},
10 gpio::{Flex, Pin},
11 interrupt,
12 uarte::{Baudrate, Instance, Parity},
13};
14use embedded_io_async::{Read as _, Write};
15use rktk::drivers::interface::split::SplitDriver;
16
17#[derive(Debug)]
18#[cfg_attr(feature = "defmt", derive(defmt::Format))]
19pub enum UartHalfDuplexSplitDriverError {
20 GeneralError(&'static str),
21}
22
23impl rktk::drivers::interface::Error for UartHalfDuplexSplitDriverError {}
24
25pub struct UartHalfDuplexSplitDriver<
26 PIN: Pin,
27 UARTE: Instance,
28 IRQ: interrupt::typelevel::Binding<UARTE::Interrupt, InterruptHandler<UARTE>>,
29 TIMER: embassy_nrf::timer::Instance,
30 CH1: embassy_nrf::ppi::ConfigurableChannel,
31 CH2: embassy_nrf::ppi::ConfigurableChannel,
32 GROUP: embassy_nrf::ppi::Group,
33> {
34 pin: Peri<'static, PIN>,
35 uarte: Peri<'static, UARTE>,
36 irq: IRQ,
37 timer: Peri<'static, TIMER>,
38 ppi_ch1: Peri<'static, CH1>,
39 ppi_ch2: Peri<'static, CH2>,
40 ppi_group: Peri<'static, GROUP>,
41 read_buffer: [u8; 256],
42 write_buffer: [u8; 256],
43}
44
45impl<
46 PIN: Pin,
47 UARTE: Instance,
48 IRQ: interrupt::typelevel::Binding<UARTE::Interrupt, InterruptHandler<UARTE>> + Clone,
49 TIMER: embassy_nrf::timer::Instance,
50 CH1: embassy_nrf::ppi::ConfigurableChannel,
51 CH2: embassy_nrf::ppi::ConfigurableChannel,
52 GROUP: embassy_nrf::ppi::Group,
53> UartHalfDuplexSplitDriver<PIN, UARTE, IRQ, TIMER, CH1, CH2, GROUP>
54{
55 pub fn new(
56 mut pin: Peri<'static, PIN>,
57 uarte: Peri<'static, UARTE>,
58 irq: IRQ,
59 timer: Peri<'static, TIMER>,
60 ppi_ch1: Peri<'static, CH1>,
61 ppi_ch2: Peri<'static, CH2>,
62 ppi_group: Peri<'static, GROUP>,
63 ) -> Self {
64 {
65 let mut pin = Flex::new(pin.reborrow());
66 pin.set_as_input_output(
67 embassy_nrf::gpio::Pull::Up,
68 embassy_nrf::gpio::OutputDrive::HighDrive0Disconnect1,
69 );
70 }
71 Self {
72 pin,
73 uarte,
74 irq,
75 timer,
76 ppi_ch1,
77 ppi_ch2,
78 ppi_group,
79 read_buffer: [0; 256],
80 write_buffer: [0; 256],
81 }
82 }
83}
84
85impl<
86 PIN: Pin,
87 UARTE: Instance,
88 IRQ: interrupt::typelevel::Binding<UARTE::Interrupt, InterruptHandler<UARTE>> + Clone + 'static,
89 TIMER: embassy_nrf::timer::Instance,
90 CH1: embassy_nrf::ppi::ConfigurableChannel,
91 CH2: embassy_nrf::ppi::ConfigurableChannel,
92 GROUP: embassy_nrf::ppi::Group,
93> SplitDriver for UartHalfDuplexSplitDriver<PIN, UARTE, IRQ, TIMER, CH1, CH2, GROUP>
94{
95 type Error = UartHalfDuplexSplitDriverError;
96
97 async fn recv(&mut self, buf: &mut [u8], _is_master: bool) -> Result<usize, Self::Error> {
98 let mut config = embassy_nrf::uarte::Config::default();
99 config.baudrate = Baudrate::BAUD1M;
100 config.parity = Parity::EXCLUDED;
101 let mut rx = BufferedUarteRx::new(
102 self.uarte.reborrow(),
103 self.timer.reborrow(),
104 self.ppi_ch1.reborrow(),
105 self.ppi_ch2.reborrow(),
106 self.ppi_group.reborrow(),
107 self.irq.clone(),
108 self.pin.reborrow(),
109 config,
110 &mut self.read_buffer,
111 );
112 let mut reader = [0u8];
113 let mut i = 0;
114 loop {
115 rx.read_exact(&mut reader)
116 .await
117 .map_err(|_| UartHalfDuplexSplitDriverError::GeneralError("read error"))?;
118 if reader[0] == 0 {
119 buf[i] = reader[0];
120 break;
121 } else {
122 buf[i] = reader[0];
123 i += 1;
124 }
125 }
126 drop(rx);
127
128 Ok(i)
129 }
130
131 async fn send_all(&mut self, buf: &[u8], _is_master: bool) -> Result<(), Self::Error> {
132 let mut config = embassy_nrf::uarte::Config::default();
133 config.baudrate = Baudrate::BAUD1M;
134 config.parity = Parity::EXCLUDED;
135 let mut tx = BufferedUarteTx::new(
136 self.uarte.reborrow(),
137 self.pin.reborrow(),
138 self.irq.clone(),
139 config,
140 &mut self.write_buffer,
141 );
142
143 tx.write_all(buf)
144 .await
145 .map_err(|_| UartHalfDuplexSplitDriverError::GeneralError("write error"))?;
146 tx.flush()
147 .await
148 .map_err(|_| UartHalfDuplexSplitDriverError::GeneralError("flush error"))?;
149 drop(tx);
150
151 embassy_time::Timer::after_micros(50).await;
152
153 Ok(())
154 }
155}