1395: rp/pio: bit of a rework r=Dirbaio a=pennae

the pio module is currently in a Bit of a State. this is far from all that's needed to make it more useful, but it's a start.

Co-authored-by: pennae <github@quasiparticle.net>
This commit is contained in:
bors[bot] 2023-05-01 11:00:48 +00:00 committed by GitHub
commit ac0ea406f9
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 287 additions and 446 deletions

View file

@ -156,6 +156,7 @@ pub fn init(_config: config::Config) -> Peripherals {
#[cfg(feature = "time-driver")]
timer::init();
dma::init();
pio::init();
}
peripherals

File diff suppressed because it is too large Load diff

View file

@ -4,13 +4,15 @@
use defmt::info;
use embassy_executor::Spawner;
use embassy_rp::gpio::{AnyPin, Pin};
use embassy_rp::pio::{Pio0, PioPeripheral, PioStateMachine, PioStateMachineInstance, ShiftDirection, Sm0, Sm1, Sm2};
use embassy_rp::pio::{
Pio0, PioCommon, PioCommonInstance, PioPeripheral, PioStateMachine, PioStateMachineInstance, ShiftDirection, Sm0,
Sm1, Sm2,
};
use embassy_rp::pio_instr_util;
use embassy_rp::relocate::RelocatedProgram;
use {defmt_rtt as _, panic_probe as _};
#[embassy_executor::task]
async fn pio_task_sm0(mut sm: PioStateMachineInstance<Pio0, Sm0>, pin: AnyPin) {
fn setup_pio_task_sm0(pio: &mut PioCommonInstance<Pio0>, sm: &mut PioStateMachineInstance<Pio0, Sm0>, pin: AnyPin) {
// Setup sm0
// Send data serially to pin
@ -23,11 +25,11 @@ async fn pio_task_sm0(mut sm: PioStateMachineInstance<Pio0, Sm0>, pin: AnyPin) {
);
let relocated = RelocatedProgram::new(&prg.program);
let out_pin = sm.make_pio_pin(pin);
let out_pin = pio.make_pio_pin(pin);
let pio_pins = [&out_pin];
sm.set_out_pins(&pio_pins);
sm.write_instr(relocated.origin() as usize, relocated.code());
pio_instr_util::exec_jmp(&mut sm, relocated.origin());
pio.write_instr(relocated.origin() as usize, relocated.code());
pio_instr_util::exec_jmp(sm, relocated.origin());
sm.set_clkdiv((125e6 / 20.0 / 2e2 * 256.0) as u32);
sm.set_set_range(0, 1);
let pio::Wrap { source, target } = relocated.wrap();
@ -35,7 +37,10 @@ async fn pio_task_sm0(mut sm: PioStateMachineInstance<Pio0, Sm0>, pin: AnyPin) {
sm.set_autopull(true);
sm.set_out_shift_dir(ShiftDirection::Left);
}
#[embassy_executor::task]
async fn pio_task_sm0(mut sm: PioStateMachineInstance<Pio0, Sm0>) {
sm.set_enable(true);
let mut v = 0x0f0caffa;
@ -46,16 +51,15 @@ async fn pio_task_sm0(mut sm: PioStateMachineInstance<Pio0, Sm0>, pin: AnyPin) {
}
}
#[embassy_executor::task]
async fn pio_task_sm1(mut sm: PioStateMachineInstance<Pio0, Sm1>) {
fn setup_pio_task_sm1(pio: &mut PioCommonInstance<Pio0>, sm: &mut PioStateMachineInstance<Pio0, Sm1>) {
// Setupm sm1
// Read 0b10101 repeatedly until ISR is full
let prg = pio_proc::pio_asm!(".origin 8", "set x, 0x15", ".wrap_target", "in x, 5 [31]", ".wrap",);
let relocated = RelocatedProgram::new(&prg.program);
sm.write_instr(relocated.origin() as usize, relocated.code());
pio_instr_util::exec_jmp(&mut sm, relocated.origin());
pio.write_instr(relocated.origin() as usize, relocated.code());
pio_instr_util::exec_jmp(sm, relocated.origin());
sm.set_clkdiv((125e6 / 2e3 * 256.0) as u32);
sm.set_set_range(0, 0);
let pio::Wrap { source, target } = relocated.wrap();
@ -63,6 +67,10 @@ async fn pio_task_sm1(mut sm: PioStateMachineInstance<Pio0, Sm1>) {
sm.set_autopush(true);
sm.set_in_shift_dir(ShiftDirection::Right);
}
#[embassy_executor::task]
async fn pio_task_sm1(mut sm: PioStateMachineInstance<Pio0, Sm1>) {
sm.set_enable(true);
loop {
let rx = sm.wait_pull().await;
@ -70,8 +78,7 @@ async fn pio_task_sm1(mut sm: PioStateMachineInstance<Pio0, Sm1>) {
}
}
#[embassy_executor::task]
async fn pio_task_sm2(mut sm: PioStateMachineInstance<Pio0, Sm2>) {
fn setup_pio_task_sm2(pio: &mut PioCommonInstance<Pio0>, sm: &mut PioStateMachineInstance<Pio0, Sm2>) {
// Setup sm2
// Repeatedly trigger IRQ 3
@ -85,13 +92,17 @@ async fn pio_task_sm2(mut sm: PioStateMachineInstance<Pio0, Sm2>) {
".wrap",
);
let relocated = RelocatedProgram::new(&prg.program);
sm.write_instr(relocated.origin() as usize, relocated.code());
pio.write_instr(relocated.origin() as usize, relocated.code());
let pio::Wrap { source, target } = relocated.wrap();
sm.set_wrap(source, target);
pio_instr_util::exec_jmp(&mut sm, relocated.origin());
pio_instr_util::exec_jmp(sm, relocated.origin());
sm.set_clkdiv((125e6 / 2e3 * 256.0) as u32);
}
#[embassy_executor::task]
async fn pio_task_sm2(mut sm: PioStateMachineInstance<Pio0, Sm2>) {
sm.set_enable(true);
loop {
sm.wait_irq(3).await;
@ -104,9 +115,12 @@ async fn main(spawner: Spawner) {
let p = embassy_rp::init(Default::default());
let pio = p.PIO0;
let (_, sm0, sm1, sm2, ..) = pio.split();
let (mut pio0, mut sm0, mut sm1, mut sm2, ..) = pio.split();
spawner.spawn(pio_task_sm0(sm0, p.PIN_0.degrade())).unwrap();
setup_pio_task_sm0(&mut pio0, &mut sm0, p.PIN_0.degrade());
setup_pio_task_sm1(&mut pio0, &mut sm1);
setup_pio_task_sm2(&mut pio0, &mut sm2);
spawner.spawn(pio_task_sm0(sm0)).unwrap();
spawner.spawn(pio_task_sm1(sm1)).unwrap();
spawner.spawn(pio_task_sm2(sm2)).unwrap();
}

View file

@ -4,7 +4,7 @@
use defmt::info;
use embassy_executor::Spawner;
use embassy_futures::join::join;
use embassy_rp::pio::{PioPeripheral, PioStateMachine, ShiftDirection};
use embassy_rp::pio::{PioCommon, PioPeripheral, PioStateMachine, ShiftDirection};
use embassy_rp::relocate::RelocatedProgram;
use embassy_rp::{pio_instr_util, Peripheral};
use {defmt_rtt as _, panic_probe as _};
@ -19,7 +19,7 @@ fn swap_nibbles(v: u32) -> u32 {
async fn main(_spawner: Spawner) {
let p = embassy_rp::init(Default::default());
let pio = p.PIO0;
let (_, mut sm, ..) = pio.split();
let (mut pio0, mut sm, ..) = pio.split();
let prg = pio_proc::pio_asm!(
".origin 0",
@ -34,7 +34,7 @@ async fn main(_spawner: Spawner) {
);
let relocated = RelocatedProgram::new(&prg.program);
sm.write_instr(relocated.origin() as usize, relocated.code());
pio0.write_instr(relocated.origin() as usize, relocated.code());
pio_instr_util::exec_jmp(&mut sm, relocated.origin());
sm.set_clkdiv((125e6 / 10e3 * 256.0) as u32);
let pio::Wrap { source, target } = relocated.wrap();

View file

@ -6,7 +6,8 @@ use defmt::*;
use embassy_executor::Spawner;
use embassy_rp::gpio::{self, Pin};
use embassy_rp::pio::{
FifoJoin, PioInstance, PioPeripheral, PioStateMachine, PioStateMachineInstance, ShiftDirection, SmInstance,
FifoJoin, PioCommon, PioCommonInstance, PioInstance, PioPeripheral, PioStateMachine, PioStateMachineInstance,
ShiftDirection, SmInstance,
};
use embassy_rp::pio_instr_util;
use embassy_rp::relocate::RelocatedProgram;
@ -18,7 +19,7 @@ pub struct Ws2812<P: PioInstance, S: SmInstance> {
}
impl<P: PioInstance, S: SmInstance> Ws2812<P, S> {
pub fn new(mut sm: PioStateMachineInstance<P, S>, pin: gpio::AnyPin) -> Self {
pub fn new(mut pio: PioCommonInstance<P>, mut sm: PioStateMachineInstance<P, S>, pin: gpio::AnyPin) -> Self {
// Setup sm0
// prepare the PIO program
@ -49,11 +50,11 @@ impl<P: PioInstance, S: SmInstance> Ws2812<P, S> {
let prg = a.assemble_with_wrap(wrap_source, wrap_target);
let relocated = RelocatedProgram::new(&prg);
sm.write_instr(relocated.origin() as usize, relocated.code());
pio.write_instr(relocated.origin() as usize, relocated.code());
pio_instr_util::exec_jmp(&mut sm, relocated.origin());
// Pin config
let out_pin = sm.make_pio_pin(pin);
let out_pin = pio.make_pio_pin(pin);
sm.set_set_pins(&[&out_pin]);
sm.set_sideset_base_pin(&out_pin);
sm.set_sideset_count(1);
@ -115,7 +116,7 @@ async fn main(_spawner: Spawner) {
info!("Start");
let p = embassy_rp::init(Default::default());
let (_pio0, sm0, _sm1, _sm2, _sm3) = p.PIO0.split();
let (pio0, sm0, _sm1, _sm2, _sm3) = p.PIO0.split();
// This is the number of leds in the string. Helpfully, the sparkfun thing plus and adafruit
// feather boards for the 2040 both have one built in.
@ -124,7 +125,7 @@ async fn main(_spawner: Spawner) {
// For the thing plus, use pin 8
// For the feather, use pin 16
let mut ws2812 = Ws2812::new(sm0, p.PIN_8.degrade());
let mut ws2812 = Ws2812::new(pio0, sm0, p.PIN_8.degrade());
// Loop forever making RGB values and pushing them out to the WS2812.
loop {