diff options
| author | pennae <[email protected]> | 2023-07-28 18:45:57 +0200 |
|---|---|---|
| committer | pennae <[email protected]> | 2023-07-28 19:33:02 +0200 |
| commit | cbc8871a0bb40eb5fec82e7c27ed4c0127844c3c (patch) | |
| tree | 333ab4bc2d1893d42529c6a378ea51c42f8c8d22 /examples | |
| parent | d752a3f9808ec9be64c720d3f80f152f0b7507df (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')
| -rw-r--r-- | examples/rp/src/bin/pio_async.rs | 10 | ||||
| -rw-r--r-- | examples/rp/src/bin/pio_dma.rs | 4 | ||||
| -rw-r--r-- | examples/rp/src/bin/pio_hd44780.rs | 7 | ||||
| -rw-r--r-- | examples/rp/src/bin/pio_uart.rs | 41 | ||||
| -rw-r--r-- | examples/rp/src/bin/pio_ws2812.rs | 4 |
5 files changed, 17 insertions, 49 deletions
diff --git a/examples/rp/src/bin/pio_async.rs b/examples/rp/src/bin/pio_async.rs index c001d6440..a6d6144be 100644 --- a/examples/rp/src/bin/pio_async.rs +++ b/examples/rp/src/bin/pio_async.rs | |||
| @@ -8,7 +8,6 @@ use embassy_executor::Spawner; | |||
| 8 | use embassy_rp::bind_interrupts; | 8 | use embassy_rp::bind_interrupts; |
| 9 | use embassy_rp::peripherals::PIO0; | 9 | use embassy_rp::peripherals::PIO0; |
| 10 | use embassy_rp::pio::{Common, Config, InterruptHandler, Irq, Pio, PioPin, ShiftDirection, StateMachine}; | 10 | use embassy_rp::pio::{Common, Config, InterruptHandler, Irq, Pio, PioPin, ShiftDirection, StateMachine}; |
| 11 | use embassy_rp::relocate::RelocatedProgram; | ||
| 12 | use fixed::traits::ToFixed; | 11 | use fixed::traits::ToFixed; |
| 13 | use fixed_macro::types::U56F8; | 12 | use fixed_macro::types::U56F8; |
| 14 | use {defmt_rtt as _, panic_probe as _}; | 13 | use {defmt_rtt as _, panic_probe as _}; |
| @@ -29,9 +28,8 @@ fn setup_pio_task_sm0<'a>(pio: &mut Common<'a, PIO0>, sm: &mut StateMachine<'a, | |||
| 29 | ".wrap", | 28 | ".wrap", |
| 30 | ); | 29 | ); |
| 31 | 30 | ||
| 32 | let relocated = RelocatedProgram::new(&prg.program); | ||
| 33 | let mut cfg = Config::default(); | 31 | let mut cfg = Config::default(); |
| 34 | cfg.use_program(&pio.load_program(&relocated), &[]); | 32 | cfg.use_program(&pio.load_program(&prg.program), &[]); |
| 35 | let out_pin = pio.make_pio_pin(pin); | 33 | let out_pin = pio.make_pio_pin(pin); |
| 36 | cfg.set_out_pins(&[&out_pin]); | 34 | cfg.set_out_pins(&[&out_pin]); |
| 37 | cfg.set_set_pins(&[&out_pin]); | 35 | cfg.set_set_pins(&[&out_pin]); |
| @@ -65,9 +63,8 @@ fn setup_pio_task_sm1<'a>(pio: &mut Common<'a, PIO0>, sm: &mut StateMachine<'a, | |||
| 65 | ".wrap", | 63 | ".wrap", |
| 66 | ); | 64 | ); |
| 67 | 65 | ||
| 68 | let relocated = RelocatedProgram::new(&prg.program); | ||
| 69 | let mut cfg = Config::default(); | 66 | let mut cfg = Config::default(); |
| 70 | cfg.use_program(&pio.load_program(&relocated), &[]); | 67 | cfg.use_program(&pio.load_program(&prg.program), &[]); |
| 71 | cfg.clock_divider = (U56F8!(125_000_000) / 2000).to_fixed(); | 68 | cfg.clock_divider = (U56F8!(125_000_000) / 2000).to_fixed(); |
| 72 | cfg.shift_in.auto_fill = true; | 69 | cfg.shift_in.auto_fill = true; |
| 73 | cfg.shift_in.direction = ShiftDirection::Right; | 70 | cfg.shift_in.direction = ShiftDirection::Right; |
| @@ -96,9 +93,8 @@ fn setup_pio_task_sm2<'a>(pio: &mut Common<'a, PIO0>, sm: &mut StateMachine<'a, | |||
| 96 | "irq 3 [15]", | 93 | "irq 3 [15]", |
| 97 | ".wrap", | 94 | ".wrap", |
| 98 | ); | 95 | ); |
| 99 | let relocated = RelocatedProgram::new(&prg.program); | ||
| 100 | let mut cfg = Config::default(); | 96 | let mut cfg = Config::default(); |
| 101 | cfg.use_program(&pio.load_program(&relocated), &[]); | 97 | cfg.use_program(&pio.load_program(&prg.program), &[]); |
| 102 | cfg.clock_divider = (U56F8!(125_000_000) / 2000).to_fixed(); | 98 | cfg.clock_divider = (U56F8!(125_000_000) / 2000).to_fixed(); |
| 103 | sm.set_config(&cfg); | 99 | sm.set_config(&cfg); |
| 104 | } | 100 | } |
diff --git a/examples/rp/src/bin/pio_dma.rs b/examples/rp/src/bin/pio_dma.rs index 9ab72e1f3..86e5017ac 100644 --- a/examples/rp/src/bin/pio_dma.rs +++ b/examples/rp/src/bin/pio_dma.rs | |||
| @@ -8,7 +8,6 @@ use embassy_executor::Spawner; | |||
| 8 | use embassy_futures::join::join; | 8 | use embassy_futures::join::join; |
| 9 | use embassy_rp::peripherals::PIO0; | 9 | use embassy_rp::peripherals::PIO0; |
| 10 | use embassy_rp::pio::{Config, InterruptHandler, Pio, ShiftConfig, ShiftDirection}; | 10 | use embassy_rp::pio::{Config, InterruptHandler, Pio, ShiftConfig, ShiftDirection}; |
| 11 | use embassy_rp::relocate::RelocatedProgram; | ||
| 12 | use embassy_rp::{bind_interrupts, Peripheral}; | 11 | use embassy_rp::{bind_interrupts, Peripheral}; |
| 13 | use fixed::traits::ToFixed; | 12 | use fixed::traits::ToFixed; |
| 14 | use fixed_macro::types::U56F8; | 13 | use fixed_macro::types::U56F8; |
| @@ -46,9 +45,8 @@ async fn main(_spawner: Spawner) { | |||
| 46 | ".wrap", | 45 | ".wrap", |
| 47 | ); | 46 | ); |
| 48 | 47 | ||
| 49 | let relocated = RelocatedProgram::new(&prg.program); | ||
| 50 | let mut cfg = Config::default(); | 48 | let mut cfg = Config::default(); |
| 51 | cfg.use_program(&common.load_program(&relocated), &[]); | 49 | cfg.use_program(&common.load_program(&prg.program), &[]); |
| 52 | cfg.clock_divider = (U56F8!(125_000_000) / U56F8!(10_000)).to_fixed(); | 50 | cfg.clock_divider = (U56F8!(125_000_000) / U56F8!(10_000)).to_fixed(); |
| 53 | cfg.shift_in = ShiftConfig { | 51 | cfg.shift_in = ShiftConfig { |
| 54 | auto_fill: true, | 52 | auto_fill: true, |
diff --git a/examples/rp/src/bin/pio_hd44780.rs b/examples/rp/src/bin/pio_hd44780.rs index 8aedd24b6..d80c5c24b 100644 --- a/examples/rp/src/bin/pio_hd44780.rs +++ b/examples/rp/src/bin/pio_hd44780.rs | |||
| @@ -14,7 +14,6 @@ use embassy_rp::pio::{ | |||
| 14 | Config, Direction, FifoJoin, InterruptHandler, Pio, PioPin, ShiftConfig, ShiftDirection, StateMachine, | 14 | Config, Direction, FifoJoin, InterruptHandler, Pio, PioPin, ShiftConfig, ShiftDirection, StateMachine, |
| 15 | }; | 15 | }; |
| 16 | use embassy_rp::pwm::{self, Pwm}; | 16 | use embassy_rp::pwm::{self, Pwm}; |
| 17 | use embassy_rp::relocate::RelocatedProgram; | ||
| 18 | use embassy_rp::{bind_interrupts, into_ref, Peripheral, PeripheralRef}; | 17 | use embassy_rp::{bind_interrupts, into_ref, Peripheral, PeripheralRef}; |
| 19 | use embassy_time::{Duration, Instant, Timer}; | 18 | use embassy_time::{Duration, Instant, Timer}; |
| 20 | use {defmt_rtt as _, panic_probe as _}; | 19 | use {defmt_rtt as _, panic_probe as _}; |
| @@ -127,9 +126,8 @@ impl<'l> HD44780<'l> { | |||
| 127 | 126 | ||
| 128 | sm0.set_pin_dirs(Direction::Out, &[&rs, &rw, &e, &db4, &db5, &db6, &db7]); | 127 | sm0.set_pin_dirs(Direction::Out, &[&rs, &rw, &e, &db4, &db5, &db6, &db7]); |
| 129 | 128 | ||
| 130 | let relocated = RelocatedProgram::new(&prg.program); | ||
| 131 | let mut cfg = Config::default(); | 129 | let mut cfg = Config::default(); |
| 132 | cfg.use_program(&common.load_program(&relocated), &[&e]); | 130 | cfg.use_program(&common.load_program(&prg.program), &[&e]); |
| 133 | cfg.clock_divider = 125u8.into(); | 131 | cfg.clock_divider = 125u8.into(); |
| 134 | cfg.set_out_pins(&[&db4, &db5, &db6, &db7]); | 132 | cfg.set_out_pins(&[&db4, &db5, &db6, &db7]); |
| 135 | cfg.shift_out = ShiftConfig { | 133 | cfg.shift_out = ShiftConfig { |
| @@ -201,9 +199,8 @@ impl<'l> HD44780<'l> { | |||
| 201 | "# | 199 | "# |
| 202 | ); | 200 | ); |
| 203 | 201 | ||
| 204 | let relocated = RelocatedProgram::new(&prg.program); | ||
| 205 | let mut cfg = Config::default(); | 202 | let mut cfg = Config::default(); |
| 206 | cfg.use_program(&common.load_program(&relocated), &[&e]); | 203 | cfg.use_program(&common.load_program(&prg.program), &[&e]); |
| 207 | cfg.clock_divider = 8u8.into(); // ~64ns/insn | 204 | cfg.clock_divider = 8u8.into(); // ~64ns/insn |
| 208 | cfg.set_jmp_pin(&db7); | 205 | cfg.set_jmp_pin(&db7); |
| 209 | cfg.set_set_pins(&[&rs, &rw]); | 206 | cfg.set_set_pins(&[&rs, &rw]); |
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 { |
diff --git a/examples/rp/src/bin/pio_ws2812.rs b/examples/rp/src/bin/pio_ws2812.rs index 3de2bd48d..bc87016ec 100644 --- a/examples/rp/src/bin/pio_ws2812.rs +++ b/examples/rp/src/bin/pio_ws2812.rs | |||
| @@ -12,7 +12,6 @@ use embassy_rp::peripherals::PIO0; | |||
| 12 | use embassy_rp::pio::{ | 12 | use embassy_rp::pio::{ |
| 13 | Common, Config, FifoJoin, Instance, InterruptHandler, Pio, PioPin, ShiftConfig, ShiftDirection, StateMachine, | 13 | Common, Config, FifoJoin, Instance, InterruptHandler, Pio, PioPin, ShiftConfig, ShiftDirection, StateMachine, |
| 14 | }; | 14 | }; |
| 15 | use embassy_rp::relocate::RelocatedProgram; | ||
| 16 | use embassy_rp::{bind_interrupts, clocks, into_ref, Peripheral, PeripheralRef}; | 15 | use embassy_rp::{bind_interrupts, clocks, into_ref, Peripheral, PeripheralRef}; |
| 17 | use embassy_time::{Duration, Timer}; | 16 | use embassy_time::{Duration, Timer}; |
| 18 | use fixed::types::U24F8; | 17 | use fixed::types::U24F8; |
| @@ -73,8 +72,7 @@ impl<'d, P: Instance, const S: usize, const N: usize> Ws2812<'d, P, S, N> { | |||
| 73 | cfg.set_out_pins(&[&out_pin]); | 72 | cfg.set_out_pins(&[&out_pin]); |
| 74 | cfg.set_set_pins(&[&out_pin]); | 73 | cfg.set_set_pins(&[&out_pin]); |
| 75 | 74 | ||
| 76 | let relocated = RelocatedProgram::new(&prg); | 75 | cfg.use_program(&pio.load_program(&prg), &[&out_pin]); |
| 77 | cfg.use_program(&pio.load_program(&relocated), &[&out_pin]); | ||
| 78 | 76 | ||
| 79 | // Clock config, measured in kHz to avoid overflows | 77 | // Clock config, measured in kHz to avoid overflows |
| 80 | // TODO CLOCK_FREQ should come from embassy_rp | 78 | // TODO CLOCK_FREQ should come from embassy_rp |
