aboutsummaryrefslogtreecommitdiff
path: root/examples
diff options
context:
space:
mode:
authorMichael van Niekerk <[email protected]>2023-07-28 12:56:31 +0200
committerMichael van Niekerk <[email protected]>2023-07-28 12:56:31 +0200
commit146c744223056561c6be61dda791993d939d0ae0 (patch)
treeb33254aa39bace0edd09e8ac0ec3641d46bc3022 /examples
parent6b6acc256d163be62e6970d03632eca11a287ec6 (diff)
Fixes as per PR
Diffstat (limited to 'examples')
-rw-r--r--examples/rp/src/bin/pio_uart.rs114
1 files changed, 48 insertions, 66 deletions
diff --git a/examples/rp/src/bin/pio_uart.rs b/examples/rp/src/bin/pio_uart.rs
index eeb213e1b..c978f8f06 100644
--- a/examples/rp/src/bin/pio_uart.rs
+++ b/examples/rp/src/bin/pio_uart.rs
@@ -19,7 +19,7 @@ use embassy_rp::peripherals::{PIO0, USB};
19use embassy_rp::pio::InterruptHandler as PioInterruptHandler; 19use embassy_rp::pio::InterruptHandler as PioInterruptHandler;
20use embassy_rp::usb::{Driver, Instance, InterruptHandler}; 20use embassy_rp::usb::{Driver, Instance, InterruptHandler};
21use embassy_sync::blocking_mutex::raw::ThreadModeRawMutex; 21use embassy_sync::blocking_mutex::raw::ThreadModeRawMutex;
22use embassy_sync::channel::Channel; 22use embassy_sync::pipe::Pipe;
23use embassy_usb::class::cdc_acm::{CdcAcmClass, Receiver, Sender, State}; 23use embassy_usb::class::cdc_acm::{CdcAcmClass, Receiver, Sender, State};
24use embassy_usb::driver::EndpointError; 24use embassy_usb::driver::EndpointError;
25use embassy_usb::{Builder, Config}; 25use embassy_usb::{Builder, Config};
@@ -30,11 +30,8 @@ use crate::uart::PioUart;
30use crate::uart_rx::PioUartRx; 30use crate::uart_rx::PioUartRx;
31use crate::uart_tx::PioUartTx; 31use crate::uart_tx::PioUartTx;
32 32
33bind_interrupts!(struct UsbIrqs { 33bind_interrupts!(struct Irqs {
34 USBCTRL_IRQ => InterruptHandler<USB>; 34 USBCTRL_IRQ => InterruptHandler<USB>;
35});
36
37bind_interrupts!(struct PioIrqs {
38 PIO0_IRQ_0 => PioInterruptHandler<PIO0>; 35 PIO0_IRQ_0 => PioInterruptHandler<PIO0>;
39}); 36});
40 37
@@ -45,7 +42,7 @@ async fn main(_spawner: Spawner) {
45 let p = embassy_rp::init(Default::default()); 42 let p = embassy_rp::init(Default::default());
46 43
47 // Create the driver, from the HAL. 44 // Create the driver, from the HAL.
48 let driver = Driver::new(p.USB, UsbIrqs); 45 let driver = Driver::new(p.USB, Irqs);
49 46
50 // Create embassy-usb Config 47 // Create embassy-usb Config
51 let mut config = Config::new(0xc0de, 0xcafe); 48 let mut config = Config::new(0xc0de, 0xcafe);
@@ -90,17 +87,17 @@ async fn main(_spawner: Spawner) {
90 let usb_fut = usb.run(); 87 let usb_fut = usb.run();
91 88
92 // PIO UART setup 89 // PIO UART setup
93 let uart = PioUart::new(9600, p.PIO0, p.PIN_4, p.PIN_5).await; 90 let uart = PioUart::new(9600, p.PIO0, p.PIN_4, p.PIN_5);
94 let (mut uart_tx, mut uart_rx) = uart.split(); 91 let (mut uart_tx, mut uart_rx) = uart.split();
95 92
96 // Channels setup 93 // Pipe setup
97 static USB_CHANNEL_TX: Channel<ThreadModeRawMutex, u8, 20> = Channel::<ThreadModeRawMutex, u8, 20>::new(); 94 static USB_PIPE: Pipe<ThreadModeRawMutex, 20> = Pipe::new();
98 let mut usb_channel_tx_send = USB_CHANNEL_TX.sender(); 95 let mut usb_pipe_writer = USB_PIPE.writer();
99 let mut usb_channel_tx_recv = USB_CHANNEL_TX.receiver(); 96 let mut usb_pipe_reader = USB_PIPE.reader();
100 97
101 static UART_CHANNEL_TX: Channel<ThreadModeRawMutex, u8, 20> = Channel::<ThreadModeRawMutex, u8, 20>::new(); 98 static UART_PIPE: Pipe<ThreadModeRawMutex, 20> = Pipe::new();
102 let mut uart_channel_tx_send = UART_CHANNEL_TX.sender(); 99 let mut uart_pipe_writer = UART_PIPE.writer();
103 let mut uart_channel_tx_recv = UART_CHANNEL_TX.receiver(); 100 let mut uart_pipe_reader = UART_PIPE.reader();
104 101
105 let (mut usb_tx, mut usb_rx) = class.split(); 102 let (mut usb_tx, mut usb_rx) = class.split();
106 103
@@ -111,8 +108,8 @@ async fn main(_spawner: Spawner) {
111 usb_rx.wait_connection().await; 108 usb_rx.wait_connection().await;
112 info!("Connected"); 109 info!("Connected");
113 let _ = join( 110 let _ = join(
114 usb_read(&mut usb_rx, &mut uart_channel_tx_send), 111 usb_read(&mut usb_rx, &mut uart_pipe_writer),
115 usb_write(&mut usb_tx, &mut usb_channel_tx_recv), 112 usb_write(&mut usb_tx, &mut usb_pipe_reader),
116 ) 113 )
117 .await; 114 .await;
118 info!("Disconnected"); 115 info!("Disconnected");
@@ -120,15 +117,10 @@ async fn main(_spawner: Spawner) {
120 }; 117 };
121 118
122 // Read + write from UART 119 // Read + write from UART
123 let uart_future = async { 120 let uart_future = join(
124 loop { 121 uart_read(&mut uart_rx, &mut usb_pipe_writer),
125 let _ = join( 122 uart_write(&mut uart_tx, &mut uart_pipe_reader),
126 uart_read(&mut uart_rx, &mut usb_channel_tx_send), 123 );
127 uart_write(&mut uart_tx, &mut uart_channel_tx_recv),
128 )
129 .await;
130 }
131 };
132 124
133 // Run everything concurrently. 125 // Run everything concurrently.
134 // If we had made everything `'static` above instead, we could do this using separate tasks instead. 126 // If we had made everything `'static` above instead, we could do this using separate tasks instead.
@@ -146,75 +138,73 @@ impl From<EndpointError> for Disconnected {
146 } 138 }
147} 139}
148 140
149/// Read from the USB and write it to the UART TX send channel 141/// Read from the USB and write it to the UART TX pipe
150async fn usb_read<'d, T: Instance + 'd>( 142async fn usb_read<'d, T: Instance + 'd>(
151 usb_rx: &mut Receiver<'d, Driver<'d, T>>, 143 usb_rx: &mut Receiver<'d, Driver<'d, T>>,
152 uart_tx_send: &mut embassy_sync::channel::Sender<'d, ThreadModeRawMutex, u8, 20>, 144 uart_pipe_writer: &mut embassy_sync::pipe::Writer<'static, ThreadModeRawMutex, 20>,
153) -> Result<(), Disconnected> { 145) -> Result<(), Disconnected> {
154 let mut buf = [0; 64]; 146 let mut buf = [0; 64];
155 loop { 147 loop {
156 let n = usb_rx.read_packet(&mut buf).await?; 148 let n = usb_rx.read_packet(&mut buf).await?;
157 let data = &buf[..n]; 149 let data = &buf[..n];
158 trace!("USB IN: {:x}", data); 150 trace!("USB IN: {:x}", data);
159 for byte in data { 151 uart_pipe_writer.write(data).await;
160 uart_tx_send.send(*byte).await;
161 }
162 } 152 }
163} 153}
164 154
165/// Read from the USB TX receive channel and write it to the USB 155/// Read from the USB TX pipe and write it to the USB
166async fn usb_write<'d, T: Instance + 'd>( 156async fn usb_write<'d, T: Instance + 'd>(
167 usb_tx: &mut Sender<'d, Driver<'d, T>>, 157 usb_tx: &mut Sender<'d, Driver<'d, T>>,
168 usb_tx_recv: &mut embassy_sync::channel::Receiver<'d, ThreadModeRawMutex, u8, 20>, 158 usb_pipe_reader: &mut embassy_sync::pipe::Reader<'d, ThreadModeRawMutex, 20>,
169) -> Result<(), Disconnected> { 159) -> Result<(), Disconnected> {
160 let mut buf = [0; 64];
170 loop { 161 loop {
171 let n = usb_tx_recv.recv().await; 162 let n = usb_pipe_reader.read(&mut buf).await;
172 let data = [n]; 163 let data = &buf[..n];
173 trace!("USB OUT: {:x}", data); 164 trace!("USB OUT: {:x}", data);
174 usb_tx.write_packet(&data).await?; 165 usb_tx.write_packet(&data).await?;
175 } 166 }
176} 167}
177 168
178/// Read from the UART and write it to the USB TX send channel 169/// Read from the UART and write it to the USB TX pipe
179async fn uart_read<'a>( 170async fn uart_read<'a>(
180 uart_rx: &mut PioUartRx<'a>, 171 uart_rx: &mut PioUartRx<'a>,
181 usb_tx_send: &mut embassy_sync::channel::Sender<'a, ThreadModeRawMutex, u8, 20>, 172 usb_pipe_writer: &mut embassy_sync::pipe::Writer<'static, ThreadModeRawMutex, 20>,
182) -> Result<(), Disconnected> { 173) -> ! {
183 let mut buf = [0; 1]; 174 let mut buf = [0; 64];
184 loop { 175 loop {
185 let n = uart_rx.read(&mut buf).await.expect("UART read error"); 176 let n = uart_rx.read(&mut buf).await.expect("UART read error");
186 if n == 0 { 177 if n == 0 {
187 continue; 178 continue;
188 } 179 }
180 let data = &buf[..n];
189 trace!("UART IN: {:x}", buf); 181 trace!("UART IN: {:x}", buf);
190 usb_tx_send.send(buf[0]).await; 182 usb_pipe_writer.write(data).await;
191 } 183 }
192} 184}
193 185
194/// Read from the UART TX receive channel and write it to the UART 186/// Read from the UART TX pipe and write it to the UART
195async fn uart_write<'a>( 187async fn uart_write<'a>(
196 uart_tx: &mut PioUartTx<'a>, 188 uart_tx: &mut PioUartTx<'a>,
197 uart_rx_recv: &mut embassy_sync::channel::Receiver<'a, ThreadModeRawMutex, u8, 20>, 189 uart_pipe_reader: &mut embassy_sync::pipe::Reader<'a, ThreadModeRawMutex, 20>,
198) -> Result<(), Disconnected> { 190) -> ! {
191 let mut buf = [0; 64];
199 loop { 192 loop {
200 let n = uart_rx_recv.recv().await; 193 let n = uart_pipe_reader.read(&mut buf).await;
201 let data = [n]; 194 let data = &buf[..n];
202 trace!("UART OUT: {:x}", data); 195 trace!("UART OUT: {:x}", data);
203 let _ = uart_tx.write(&data).await; 196 let _ = uart_tx.write(&data).await;
204 } 197 }
205} 198}
206 199
207mod uart { 200mod uart {
208 use core::fmt::Debug;
209
210 use embassy_rp::peripherals::PIO0; 201 use embassy_rp::peripherals::PIO0;
211 use embassy_rp::pio::{Pio, PioPin}; 202 use embassy_rp::pio::{Pio, PioPin};
212 use embassy_rp::Peripheral; 203 use embassy_rp::Peripheral;
213 use embedded_io::ErrorKind;
214 204
215 use crate::uart_rx::PioUartRx; 205 use crate::uart_rx::PioUartRx;
216 use crate::uart_tx::PioUartTx; 206 use crate::uart_tx::PioUartTx;
217 use crate::PioIrqs; 207 use crate::Irqs;
218 208
219 pub struct PioUart<'a> { 209 pub struct PioUart<'a> {
220 tx: PioUartTx<'a>, 210 tx: PioUartTx<'a>,
@@ -222,7 +212,7 @@ mod uart {
222 } 212 }
223 213
224 impl<'a> PioUart<'a> { 214 impl<'a> PioUart<'a> {
225 pub async fn new( 215 pub fn new(
226 baud: u64, 216 baud: u64,
227 pio: impl Peripheral<P = PIO0> + 'a, 217 pio: impl Peripheral<P = PIO0> + 'a,
228 tx_pin: impl PioPin, 218 tx_pin: impl PioPin,
@@ -230,7 +220,7 @@ mod uart {
230 ) -> PioUart<'a> { 220 ) -> PioUart<'a> {
231 let Pio { 221 let Pio {
232 mut common, sm0, sm1, .. 222 mut common, sm0, sm1, ..
233 } = Pio::new(pio, PioIrqs); 223 } = Pio::new(pio, Irqs);
234 224
235 let (tx, origin) = PioUartTx::new(&mut common, sm0, tx_pin, baud, None); 225 let (tx, origin) = PioUartTx::new(&mut common, sm0, tx_pin, baud, None);
236 let (rx, _) = PioUartRx::new(&mut common, sm1, rx_pin, baud, Some(origin)); 226 let (rx, _) = PioUartRx::new(&mut common, sm1, rx_pin, baud, Some(origin));
@@ -242,17 +232,11 @@ mod uart {
242 (self.tx, self.rx) 232 (self.tx, self.rx)
243 } 233 }
244 } 234 }
245 #[derive(defmt::Format, Debug)]
246 pub struct PioUartError {}
247
248 impl embedded_io::Error for PioUartError {
249 fn kind(&self) -> ErrorKind {
250 ErrorKind::Other
251 }
252 }
253} 235}
254 236
255mod uart_tx { 237mod uart_tx {
238 use core::convert::Infallible;
239
256 use embassy_rp::gpio::Level; 240 use embassy_rp::gpio::Level;
257 use embassy_rp::peripherals::PIO0; 241 use embassy_rp::peripherals::PIO0;
258 use embassy_rp::pio::{Common, Config, Direction, FifoJoin, PioPin, ShiftDirection, StateMachine}; 242 use embassy_rp::pio::{Common, Config, Direction, FifoJoin, PioPin, ShiftDirection, StateMachine};
@@ -262,8 +246,6 @@ mod uart_tx {
262 use fixed::traits::ToFixed; 246 use fixed::traits::ToFixed;
263 use fixed_macro::types::U56F8; 247 use fixed_macro::types::U56F8;
264 248
265 use crate::uart::PioUartError;
266
267 pub struct PioUartTx<'a> { 249 pub struct PioUartTx<'a> {
268 sm_tx: StateMachine<'a, PIO0, 0>, 250 sm_tx: StateMachine<'a, PIO0, 0>,
269 } 251 }
@@ -328,11 +310,11 @@ mod uart_tx {
328 } 310 }
329 311
330 impl Io for PioUartTx<'_> { 312 impl Io for PioUartTx<'_> {
331 type Error = PioUartError; 313 type Error = Infallible;
332 } 314 }
333 315
334 impl Write for PioUartTx<'_> { 316 impl Write for PioUartTx<'_> {
335 async fn write(&mut self, buf: &[u8]) -> Result<usize, PioUartError> { 317 async fn write(&mut self, buf: &[u8]) -> Result<usize, Infallible> {
336 for byte in buf { 318 for byte in buf {
337 self.write_u8(*byte).await; 319 self.write_u8(*byte).await;
338 } 320 }
@@ -342,6 +324,8 @@ mod uart_tx {
342} 324}
343 325
344mod uart_rx { 326mod uart_rx {
327 use core::convert::Infallible;
328
345 use embassy_rp::gpio::Level; 329 use embassy_rp::gpio::Level;
346 use embassy_rp::peripherals::PIO0; 330 use embassy_rp::peripherals::PIO0;
347 use embassy_rp::pio::{Common, Config, Direction, FifoJoin, PioPin, ShiftDirection, StateMachine}; 331 use embassy_rp::pio::{Common, Config, Direction, FifoJoin, PioPin, ShiftDirection, StateMachine};
@@ -351,8 +335,6 @@ mod uart_rx {
351 use fixed::traits::ToFixed; 335 use fixed::traits::ToFixed;
352 use fixed_macro::types::U56F8; 336 use fixed_macro::types::U56F8;
353 337
354 use crate::uart::PioUartError;
355
356 pub struct PioUartRx<'a> { 338 pub struct PioUartRx<'a> {
357 sm_rx: StateMachine<'a, PIO0, 1>, 339 sm_rx: StateMachine<'a, PIO0, 1>,
358 } 340 }
@@ -415,11 +397,11 @@ mod uart_rx {
415 } 397 }
416 398
417 impl Io for PioUartRx<'_> { 399 impl Io for PioUartRx<'_> {
418 type Error = PioUartError; 400 type Error = Infallible;
419 } 401 }
420 402
421 impl Read for PioUartRx<'_> { 403 impl Read for PioUartRx<'_> {
422 async fn read(&mut self, buf: &mut [u8]) -> Result<usize, PioUartError> { 404 async fn read(&mut self, buf: &mut [u8]) -> Result<usize, Infallible> {
423 let mut i = 0; 405 let mut i = 0;
424 while i < buf.len() { 406 while i < buf.len() {
425 buf[i] = self.read_u8().await; 407 buf[i] = self.read_u8().await;