aboutsummaryrefslogtreecommitdiff
path: root/examples/rp/src/bin/pio_uart.rs
diff options
context:
space:
mode:
authorpennae <[email protected]>2023-07-28 18:45:57 +0200
committerpennae <[email protected]>2023-07-28 19:33:02 +0200
commitcbc8871a0bb40eb5fec82e7c27ed4c0127844c3c (patch)
tree333ab4bc2d1893d42529c6a378ea51c42f8c8d22 /examples/rp/src/bin/pio_uart.rs
parentd752a3f9808ec9be64c720d3f80f152f0b7507df (diff)
rp: relocate programs implicitly during load
this removed the RelocatedProgram construction step from pio uses. there's not all that much to be said for the extra step because the origin can be set on the input program itself, and the remaining information exposed by RelocatedProgram can be exposed from LoadedProgram instead (even though it's already available on the pio_asm programs, albeit perhaps less convenient). we do lose access to the relocated instruction iterator, but we also cannot think of anything this iterator would actually be useful for outside of program loading.
Diffstat (limited to 'examples/rp/src/bin/pio_uart.rs')
-rw-r--r--examples/rp/src/bin/pio_uart.rs41
1 files changed, 10 insertions, 31 deletions
diff --git a/examples/rp/src/bin/pio_uart.rs b/examples/rp/src/bin/pio_uart.rs
index ca1c7f394..5fddbe292 100644
--- a/examples/rp/src/bin/pio_uart.rs
+++ b/examples/rp/src/bin/pio_uart.rs
@@ -222,8 +222,8 @@ mod uart {
222 mut common, sm0, sm1, .. 222 mut common, sm0, sm1, ..
223 } = Pio::new(pio, Irqs); 223 } = Pio::new(pio, Irqs);
224 224
225 let (tx, origin) = PioUartTx::new(&mut common, sm0, tx_pin, baud, None); 225 let tx = PioUartTx::new(&mut common, sm0, tx_pin, baud);
226 let (rx, _) = PioUartRx::new(&mut common, sm1, rx_pin, baud, Some(origin)); 226 let rx = PioUartRx::new(&mut common, sm1, rx_pin, baud);
227 227
228 PioUart { tx, rx } 228 PioUart { tx, rx }
229 } 229 }
@@ -240,7 +240,6 @@ mod uart_tx {
240 use embassy_rp::gpio::Level; 240 use embassy_rp::gpio::Level;
241 use embassy_rp::peripherals::PIO0; 241 use embassy_rp::peripherals::PIO0;
242 use embassy_rp::pio::{Common, Config, Direction, FifoJoin, PioPin, ShiftDirection, StateMachine}; 242 use embassy_rp::pio::{Common, Config, Direction, FifoJoin, PioPin, ShiftDirection, StateMachine};
243 use embassy_rp::relocate::RelocatedProgram;
244 use embedded_io::asynch::Write; 243 use embedded_io::asynch::Write;
245 use embedded_io::Io; 244 use embedded_io::Io;
246 use fixed::traits::ToFixed; 245 use fixed::traits::ToFixed;
@@ -256,9 +255,8 @@ mod uart_tx {
256 mut sm_tx: StateMachine<'a, PIO0, 0>, 255 mut sm_tx: StateMachine<'a, PIO0, 0>,
257 tx_pin: impl PioPin, 256 tx_pin: impl PioPin,
258 baud: u64, 257 baud: u64,
259 origin: Option<u8>, 258 ) -> Self {
260 ) -> (Self, u8) { 259 let prg = pio_proc::pio_asm!(
261 let mut prg = pio_proc::pio_asm!(
262 r#" 260 r#"
263 .side_set 1 opt 261 .side_set 1 opt
264 262
@@ -272,17 +270,14 @@ mod uart_tx {
272 jmp x-- bitloop [6] ; Each loop iteration is 8 cycles. 270 jmp x-- bitloop [6] ; Each loop iteration is 8 cycles.
273 "# 271 "#
274 ); 272 );
275 prg.program.origin = origin;
276 let tx_pin = common.make_pio_pin(tx_pin); 273 let tx_pin = common.make_pio_pin(tx_pin);
277 sm_tx.set_pins(Level::High, &[&tx_pin]); 274 sm_tx.set_pins(Level::High, &[&tx_pin]);
278 sm_tx.set_pin_dirs(Direction::Out, &[&tx_pin]); 275 sm_tx.set_pin_dirs(Direction::Out, &[&tx_pin]);
279 276
280 let relocated = RelocatedProgram::new(&prg.program);
281
282 let mut cfg = Config::default(); 277 let mut cfg = Config::default();
283 278
284 cfg.set_out_pins(&[&tx_pin]); 279 cfg.set_out_pins(&[&tx_pin]);
285 cfg.use_program(&common.load_program(&relocated), &[&tx_pin]); 280 cfg.use_program(&common.load_program(&prg.program), &[&tx_pin]);
286 cfg.shift_out.auto_fill = false; 281 cfg.shift_out.auto_fill = false;
287 cfg.shift_out.direction = ShiftDirection::Right; 282 cfg.shift_out.direction = ShiftDirection::Right;
288 cfg.fifo_join = FifoJoin::TxOnly; 283 cfg.fifo_join = FifoJoin::TxOnly;
@@ -290,18 +285,7 @@ mod uart_tx {
290 sm_tx.set_config(&cfg); 285 sm_tx.set_config(&cfg);
291 sm_tx.set_enable(true); 286 sm_tx.set_enable(true);
292 287
293 // The 4 state machines of the PIO each have their own program counter that starts taking 288 Self { sm_tx }
294 // instructions at an offset (origin) of the 32 instruction "space" the PIO device has.
295 // It is up to the programmer to sort out where to place these instructions.
296 // From the pio_asm! macro you get a ProgramWithDefines which has a field .program.origin
297 // which takes an Option<u8>.
298 //
299 // When you load more than one RelocatedProgram into the PIO,
300 // you load your first program at origin = 0.
301 // The RelocatedProgram has .code().count() which returns a usize,
302 // for which you can then use as your next program's origin.
303 let offset = relocated.code().count() as u8 + origin.unwrap_or_default();
304 (Self { sm_tx }, offset)
305 } 289 }
306 290
307 pub async fn write_u8(&mut self, data: u8) { 291 pub async fn write_u8(&mut self, data: u8) {
@@ -329,7 +313,6 @@ mod uart_rx {
329 use embassy_rp::gpio::Level; 313 use embassy_rp::gpio::Level;
330 use embassy_rp::peripherals::PIO0; 314 use embassy_rp::peripherals::PIO0;
331 use embassy_rp::pio::{Common, Config, Direction, FifoJoin, PioPin, ShiftDirection, StateMachine}; 315 use embassy_rp::pio::{Common, Config, Direction, FifoJoin, PioPin, ShiftDirection, StateMachine};
332 use embassy_rp::relocate::RelocatedProgram;
333 use embedded_io::asynch::Read; 316 use embedded_io::asynch::Read;
334 use embedded_io::Io; 317 use embedded_io::Io;
335 use fixed::traits::ToFixed; 318 use fixed::traits::ToFixed;
@@ -345,9 +328,8 @@ mod uart_rx {
345 mut sm_rx: StateMachine<'a, PIO0, 1>, 328 mut sm_rx: StateMachine<'a, PIO0, 1>,
346 rx_pin: impl PioPin, 329 rx_pin: impl PioPin,
347 baud: u64, 330 baud: u64,
348 origin: Option<u8>, 331 ) -> Self {
349 ) -> (Self, u8) { 332 let prg = pio_proc::pio_asm!(
350 let mut prg = pio_proc::pio_asm!(
351 r#" 333 r#"
352 ; Slightly more fleshed-out 8n1 UART receiver which handles framing errors and 334 ; Slightly more fleshed-out 8n1 UART receiver which handles framing errors and
353 ; break conditions more gracefully. 335 ; break conditions more gracefully.
@@ -369,10 +351,8 @@ mod uart_rx {
369 push ; important in case the TX clock is slightly too fast. 351 push ; important in case the TX clock is slightly too fast.
370 "# 352 "#
371 ); 353 );
372 prg.program.origin = origin;
373 let relocated = RelocatedProgram::new(&prg.program);
374 let mut cfg = Config::default(); 354 let mut cfg = Config::default();
375 cfg.use_program(&common.load_program(&relocated), &[]); 355 cfg.use_program(&common.load_program(&prg.program), &[]);
376 356
377 let rx_pin = common.make_pio_pin(rx_pin); 357 let rx_pin = common.make_pio_pin(rx_pin);
378 sm_rx.set_pins(Level::High, &[&rx_pin]); 358 sm_rx.set_pins(Level::High, &[&rx_pin]);
@@ -387,8 +367,7 @@ mod uart_rx {
387 sm_rx.set_config(&cfg); 367 sm_rx.set_config(&cfg);
388 sm_rx.set_enable(true); 368 sm_rx.set_enable(true);
389 369
390 let offset = relocated.code().count() as u8 + origin.unwrap_or_default(); 370 Self { sm_rx }
391 (Self { sm_rx }, offset)
392 } 371 }
393 372
394 pub async fn read_u8(&mut self) -> u8 { 373 pub async fn read_u8(&mut self) -> u8 {