Merge pull request #1707 from pennae/rp-pio-load
rp: relocate programs implicitly during load
This commit is contained in:
@ -8,7 +8,6 @@ use embassy_executor::Spawner;
|
||||
use embassy_rp::bind_interrupts;
|
||||
use embassy_rp::peripherals::PIO0;
|
||||
use embassy_rp::pio::{Common, Config, InterruptHandler, Irq, Pio, PioPin, ShiftDirection, StateMachine};
|
||||
use embassy_rp::relocate::RelocatedProgram;
|
||||
use fixed::traits::ToFixed;
|
||||
use fixed_macro::types::U56F8;
|
||||
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,
|
||||
".wrap",
|
||||
);
|
||||
|
||||
let relocated = RelocatedProgram::new(&prg.program);
|
||||
let mut cfg = Config::default();
|
||||
cfg.use_program(&pio.load_program(&relocated), &[]);
|
||||
cfg.use_program(&pio.load_program(&prg.program), &[]);
|
||||
let out_pin = pio.make_pio_pin(pin);
|
||||
cfg.set_out_pins(&[&out_pin]);
|
||||
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,
|
||||
".wrap",
|
||||
);
|
||||
|
||||
let relocated = RelocatedProgram::new(&prg.program);
|
||||
let mut cfg = Config::default();
|
||||
cfg.use_program(&pio.load_program(&relocated), &[]);
|
||||
cfg.use_program(&pio.load_program(&prg.program), &[]);
|
||||
cfg.clock_divider = (U56F8!(125_000_000) / 2000).to_fixed();
|
||||
cfg.shift_in.auto_fill = true;
|
||||
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,
|
||||
"irq 3 [15]",
|
||||
".wrap",
|
||||
);
|
||||
let relocated = RelocatedProgram::new(&prg.program);
|
||||
let mut cfg = Config::default();
|
||||
cfg.use_program(&pio.load_program(&relocated), &[]);
|
||||
cfg.use_program(&pio.load_program(&prg.program), &[]);
|
||||
cfg.clock_divider = (U56F8!(125_000_000) / 2000).to_fixed();
|
||||
sm.set_config(&cfg);
|
||||
}
|
||||
|
@ -8,7 +8,6 @@ use embassy_executor::Spawner;
|
||||
use embassy_futures::join::join;
|
||||
use embassy_rp::peripherals::PIO0;
|
||||
use embassy_rp::pio::{Config, InterruptHandler, Pio, ShiftConfig, ShiftDirection};
|
||||
use embassy_rp::relocate::RelocatedProgram;
|
||||
use embassy_rp::{bind_interrupts, Peripheral};
|
||||
use fixed::traits::ToFixed;
|
||||
use fixed_macro::types::U56F8;
|
||||
@ -46,9 +45,8 @@ async fn main(_spawner: Spawner) {
|
||||
".wrap",
|
||||
);
|
||||
|
||||
let relocated = RelocatedProgram::new(&prg.program);
|
||||
let mut cfg = Config::default();
|
||||
cfg.use_program(&common.load_program(&relocated), &[]);
|
||||
cfg.use_program(&common.load_program(&prg.program), &[]);
|
||||
cfg.clock_divider = (U56F8!(125_000_000) / U56F8!(10_000)).to_fixed();
|
||||
cfg.shift_in = ShiftConfig {
|
||||
auto_fill: true,
|
||||
|
@ -14,7 +14,6 @@ use embassy_rp::pio::{
|
||||
Config, Direction, FifoJoin, InterruptHandler, Pio, PioPin, ShiftConfig, ShiftDirection, StateMachine,
|
||||
};
|
||||
use embassy_rp::pwm::{self, Pwm};
|
||||
use embassy_rp::relocate::RelocatedProgram;
|
||||
use embassy_rp::{bind_interrupts, into_ref, Peripheral, PeripheralRef};
|
||||
use embassy_time::{Duration, Instant, Timer};
|
||||
use {defmt_rtt as _, panic_probe as _};
|
||||
@ -127,9 +126,8 @@ impl<'l> HD44780<'l> {
|
||||
|
||||
sm0.set_pin_dirs(Direction::Out, &[&rs, &rw, &e, &db4, &db5, &db6, &db7]);
|
||||
|
||||
let relocated = RelocatedProgram::new(&prg.program);
|
||||
let mut cfg = Config::default();
|
||||
cfg.use_program(&common.load_program(&relocated), &[&e]);
|
||||
cfg.use_program(&common.load_program(&prg.program), &[&e]);
|
||||
cfg.clock_divider = 125u8.into();
|
||||
cfg.set_out_pins(&[&db4, &db5, &db6, &db7]);
|
||||
cfg.shift_out = ShiftConfig {
|
||||
@ -201,9 +199,8 @@ impl<'l> HD44780<'l> {
|
||||
"#
|
||||
);
|
||||
|
||||
let relocated = RelocatedProgram::new(&prg.program);
|
||||
let mut cfg = Config::default();
|
||||
cfg.use_program(&common.load_program(&relocated), &[&e]);
|
||||
cfg.use_program(&common.load_program(&prg.program), &[&e]);
|
||||
cfg.clock_divider = 8u8.into(); // ~64ns/insn
|
||||
cfg.set_jmp_pin(&db7);
|
||||
cfg.set_set_pins(&[&rs, &rw]);
|
||||
|
@ -222,8 +222,8 @@ mod uart {
|
||||
mut common, sm0, sm1, ..
|
||||
} = Pio::new(pio, Irqs);
|
||||
|
||||
let (tx, origin) = PioUartTx::new(&mut common, sm0, tx_pin, baud, None);
|
||||
let (rx, _) = PioUartRx::new(&mut common, sm1, rx_pin, baud, Some(origin));
|
||||
let tx = PioUartTx::new(&mut common, sm0, tx_pin, baud);
|
||||
let rx = PioUartRx::new(&mut common, sm1, rx_pin, baud);
|
||||
|
||||
PioUart { tx, rx }
|
||||
}
|
||||
@ -240,7 +240,6 @@ mod uart_tx {
|
||||
use embassy_rp::gpio::Level;
|
||||
use embassy_rp::peripherals::PIO0;
|
||||
use embassy_rp::pio::{Common, Config, Direction, FifoJoin, PioPin, ShiftDirection, StateMachine};
|
||||
use embassy_rp::relocate::RelocatedProgram;
|
||||
use embedded_io::asynch::Write;
|
||||
use embedded_io::Io;
|
||||
use fixed::traits::ToFixed;
|
||||
@ -256,9 +255,8 @@ mod uart_tx {
|
||||
mut sm_tx: StateMachine<'a, PIO0, 0>,
|
||||
tx_pin: impl PioPin,
|
||||
baud: u64,
|
||||
origin: Option<u8>,
|
||||
) -> (Self, u8) {
|
||||
let mut prg = pio_proc::pio_asm!(
|
||||
) -> Self {
|
||||
let prg = pio_proc::pio_asm!(
|
||||
r#"
|
||||
.side_set 1 opt
|
||||
|
||||
@ -272,17 +270,14 @@ mod uart_tx {
|
||||
jmp x-- bitloop [6] ; Each loop iteration is 8 cycles.
|
||||
"#
|
||||
);
|
||||
prg.program.origin = origin;
|
||||
let tx_pin = common.make_pio_pin(tx_pin);
|
||||
sm_tx.set_pins(Level::High, &[&tx_pin]);
|
||||
sm_tx.set_pin_dirs(Direction::Out, &[&tx_pin]);
|
||||
|
||||
let relocated = RelocatedProgram::new(&prg.program);
|
||||
|
||||
let mut cfg = Config::default();
|
||||
|
||||
cfg.set_out_pins(&[&tx_pin]);
|
||||
cfg.use_program(&common.load_program(&relocated), &[&tx_pin]);
|
||||
cfg.use_program(&common.load_program(&prg.program), &[&tx_pin]);
|
||||
cfg.shift_out.auto_fill = false;
|
||||
cfg.shift_out.direction = ShiftDirection::Right;
|
||||
cfg.fifo_join = FifoJoin::TxOnly;
|
||||
@ -290,18 +285,7 @@ mod uart_tx {
|
||||
sm_tx.set_config(&cfg);
|
||||
sm_tx.set_enable(true);
|
||||
|
||||
// The 4 state machines of the PIO each have their own program counter that starts taking
|
||||
// instructions at an offset (origin) of the 32 instruction "space" the PIO device has.
|
||||
// It is up to the programmer to sort out where to place these instructions.
|
||||
// From the pio_asm! macro you get a ProgramWithDefines which has a field .program.origin
|
||||
// which takes an Option<u8>.
|
||||
//
|
||||
// When you load more than one RelocatedProgram into the PIO,
|
||||
// you load your first program at origin = 0.
|
||||
// The RelocatedProgram has .code().count() which returns a usize,
|
||||
// for which you can then use as your next program's origin.
|
||||
let offset = relocated.code().count() as u8 + origin.unwrap_or_default();
|
||||
(Self { sm_tx }, offset)
|
||||
Self { sm_tx }
|
||||
}
|
||||
|
||||
pub async fn write_u8(&mut self, data: u8) {
|
||||
@ -329,7 +313,6 @@ mod uart_rx {
|
||||
use embassy_rp::gpio::Level;
|
||||
use embassy_rp::peripherals::PIO0;
|
||||
use embassy_rp::pio::{Common, Config, Direction, FifoJoin, PioPin, ShiftDirection, StateMachine};
|
||||
use embassy_rp::relocate::RelocatedProgram;
|
||||
use embedded_io::asynch::Read;
|
||||
use embedded_io::Io;
|
||||
use fixed::traits::ToFixed;
|
||||
@ -345,9 +328,8 @@ mod uart_rx {
|
||||
mut sm_rx: StateMachine<'a, PIO0, 1>,
|
||||
rx_pin: impl PioPin,
|
||||
baud: u64,
|
||||
origin: Option<u8>,
|
||||
) -> (Self, u8) {
|
||||
let mut prg = pio_proc::pio_asm!(
|
||||
) -> Self {
|
||||
let prg = pio_proc::pio_asm!(
|
||||
r#"
|
||||
; Slightly more fleshed-out 8n1 UART receiver which handles framing errors and
|
||||
; break conditions more gracefully.
|
||||
@ -369,10 +351,8 @@ mod uart_rx {
|
||||
push ; important in case the TX clock is slightly too fast.
|
||||
"#
|
||||
);
|
||||
prg.program.origin = origin;
|
||||
let relocated = RelocatedProgram::new(&prg.program);
|
||||
let mut cfg = Config::default();
|
||||
cfg.use_program(&common.load_program(&relocated), &[]);
|
||||
cfg.use_program(&common.load_program(&prg.program), &[]);
|
||||
|
||||
let rx_pin = common.make_pio_pin(rx_pin);
|
||||
sm_rx.set_pins(Level::High, &[&rx_pin]);
|
||||
@ -387,8 +367,7 @@ mod uart_rx {
|
||||
sm_rx.set_config(&cfg);
|
||||
sm_rx.set_enable(true);
|
||||
|
||||
let offset = relocated.code().count() as u8 + origin.unwrap_or_default();
|
||||
(Self { sm_rx }, offset)
|
||||
Self { sm_rx }
|
||||
}
|
||||
|
||||
pub async fn read_u8(&mut self) -> u8 {
|
||||
|
@ -12,7 +12,6 @@ use embassy_rp::peripherals::PIO0;
|
||||
use embassy_rp::pio::{
|
||||
Common, Config, FifoJoin, Instance, InterruptHandler, Pio, PioPin, ShiftConfig, ShiftDirection, StateMachine,
|
||||
};
|
||||
use embassy_rp::relocate::RelocatedProgram;
|
||||
use embassy_rp::{bind_interrupts, clocks, into_ref, Peripheral, PeripheralRef};
|
||||
use embassy_time::{Duration, Timer};
|
||||
use fixed::types::U24F8;
|
||||
@ -73,8 +72,7 @@ impl<'d, P: Instance, const S: usize, const N: usize> Ws2812<'d, P, S, N> {
|
||||
cfg.set_out_pins(&[&out_pin]);
|
||||
cfg.set_set_pins(&[&out_pin]);
|
||||
|
||||
let relocated = RelocatedProgram::new(&prg);
|
||||
cfg.use_program(&pio.load_program(&relocated), &[&out_pin]);
|
||||
cfg.use_program(&pio.load_program(&prg), &[&out_pin]);
|
||||
|
||||
// Clock config, measured in kHz to avoid overflows
|
||||
// TODO CLOCK_FREQ should come from embassy_rp
|
||||
|
Reference in New Issue
Block a user