From 8ebe6e5f2029026594c703820c11d703da2c0334 Mon Sep 17 00:00:00 2001 From: pennae Date: Wed, 3 May 2023 17:16:35 +0200 Subject: rp/pio: drop Pio prefix from almost all names it's only any good for PioPin because there it follows a pattern of gpio pin alternate functions being named like that, everything else can just as well be referred to as `pio::Thing` --- examples/rp/src/bin/pio_async.rs | 14 +++++++------- examples/rp/src/bin/pio_hd44780.rs | 4 ++-- examples/rp/src/bin/ws2812-pio.rs | 10 +++++----- 3 files changed, 14 insertions(+), 14 deletions(-) (limited to 'examples') diff --git a/examples/rp/src/bin/pio_async.rs b/examples/rp/src/bin/pio_async.rs index 4e0ab5e3c..461ea3ff9 100644 --- a/examples/rp/src/bin/pio_async.rs +++ b/examples/rp/src/bin/pio_async.rs @@ -4,12 +4,12 @@ use defmt::info; use embassy_executor::Spawner; use embassy_rp::peripherals::PIO0; -use embassy_rp::pio::{Pio, PioCommon, PioIrq, PioPin, PioStateMachine, ShiftDirection}; +use embassy_rp::pio::{Common, Irq, Pio, PioPin, ShiftDirection, StateMachine}; use embassy_rp::pio_instr_util; use embassy_rp::relocate::RelocatedProgram; use {defmt_rtt as _, panic_probe as _}; -fn setup_pio_task_sm0(pio: &mut PioCommon, sm: &mut PioStateMachine, pin: impl PioPin) { +fn setup_pio_task_sm0(pio: &mut Common, sm: &mut StateMachine, pin: impl PioPin) { // Setup sm0 // Send data serially to pin @@ -37,7 +37,7 @@ fn setup_pio_task_sm0(pio: &mut PioCommon, sm: &mut PioStateMachine) { +async fn pio_task_sm0(mut sm: StateMachine<'static, PIO0, 0>) { sm.set_enable(true); let mut v = 0x0f0caffa; @@ -48,7 +48,7 @@ async fn pio_task_sm0(mut sm: PioStateMachine<'static, PIO0, 0>) { } } -fn setup_pio_task_sm1(pio: &mut PioCommon, sm: &mut PioStateMachine) { +fn setup_pio_task_sm1(pio: &mut Common, sm: &mut StateMachine) { // Setupm sm1 // Read 0b10101 repeatedly until ISR is full @@ -67,7 +67,7 @@ fn setup_pio_task_sm1(pio: &mut PioCommon, sm: &mut PioStateMachine) { +async fn pio_task_sm1(mut sm: StateMachine<'static, PIO0, 1>) { sm.set_enable(true); loop { let rx = sm.rx().wait_pull().await; @@ -75,7 +75,7 @@ async fn pio_task_sm1(mut sm: PioStateMachine<'static, PIO0, 1>) { } } -fn setup_pio_task_sm2(pio: &mut PioCommon, sm: &mut PioStateMachine) { +fn setup_pio_task_sm2(pio: &mut Common, sm: &mut StateMachine) { // Setup sm2 // Repeatedly trigger IRQ 3 @@ -99,7 +99,7 @@ fn setup_pio_task_sm2(pio: &mut PioCommon, sm: &mut PioStateMachine, mut sm: PioStateMachine<'static, PIO0, 2>) { +async fn pio_task_sm2(mut irq: Irq<'static, PIO0, 3>, mut sm: StateMachine<'static, PIO0, 2>) { sm.set_enable(true); loop { irq.wait().await; diff --git a/examples/rp/src/bin/pio_hd44780.rs b/examples/rp/src/bin/pio_hd44780.rs index f76d334e7..17b2440cf 100644 --- a/examples/rp/src/bin/pio_hd44780.rs +++ b/examples/rp/src/bin/pio_hd44780.rs @@ -7,7 +7,7 @@ use core::fmt::Write; use embassy_executor::Spawner; use embassy_rp::dma::{AnyChannel, Channel}; use embassy_rp::peripherals::PIO0; -use embassy_rp::pio::{FifoJoin, Pio, PioPin, PioStateMachine, ShiftDirection}; +use embassy_rp::pio::{FifoJoin, Pio, PioPin, ShiftDirection, StateMachine}; use embassy_rp::pwm::{Config, Pwm}; use embassy_rp::relocate::RelocatedProgram; use embassy_rp::{into_ref, Peripheral, PeripheralRef}; @@ -64,7 +64,7 @@ async fn main(_spawner: Spawner) { pub struct HD44780<'l> { dma: PeripheralRef<'l, AnyChannel>, - sm: PioStateMachine<'l, PIO0, 0>, + sm: StateMachine<'l, PIO0, 0>, buf: [u8; 40], } diff --git a/examples/rp/src/bin/ws2812-pio.rs b/examples/rp/src/bin/ws2812-pio.rs index c9c701a70..2e6860d8b 100644 --- a/examples/rp/src/bin/ws2812-pio.rs +++ b/examples/rp/src/bin/ws2812-pio.rs @@ -4,18 +4,18 @@ use defmt::*; use embassy_executor::Spawner; -use embassy_rp::pio::{FifoJoin, Pio, PioCommon, PioInstance, PioPin, PioStateMachine, ShiftDirection}; +use embassy_rp::pio::{Common, FifoJoin, Instance, Pio, PioPin, ShiftDirection, StateMachine}; use embassy_rp::pio_instr_util; use embassy_rp::relocate::RelocatedProgram; use embassy_time::{Duration, Timer}; use smart_leds::RGB8; use {defmt_rtt as _, panic_probe as _}; -pub struct Ws2812<'d, P: PioInstance, const S: usize> { - sm: PioStateMachine<'d, P, S>, +pub struct Ws2812<'d, P: Instance, const S: usize> { + sm: StateMachine<'d, P, S>, } -impl<'d, P: PioInstance, const S: usize> Ws2812<'d, P, S> { - pub fn new(mut pio: PioCommon<'d, P>, mut sm: PioStateMachine<'d, P, S>, pin: impl PioPin) -> Self { +impl<'d, P: Instance, const S: usize> Ws2812<'d, P, S> { + pub fn new(mut pio: Common<'d, P>, mut sm: StateMachine<'d, P, S>, pin: impl PioPin) -> Self { // Setup sm0 // prepare the PIO program -- cgit From 41ec4170a5ae9920fe31327252ba1bba754b6d9f Mon Sep 17 00:00:00 2001 From: pennae Date: Fri, 5 May 2023 19:49:34 +0200 Subject: rp/pio: add load_program, use_program programs contain information we could pull from them directly and use to validate other configuration of the state machine instead of asking the user to pull them out and hand them to us bit by bit. unfortunately programs do not specify how many in or out bits they use, so we can only handle side-set and wrapping jumps like this. it's still something though. --- examples/rp/src/bin/pio_async.rs | 25 ++++++------------------- examples/rp/src/bin/pio_dma.rs | 7 ++----- examples/rp/src/bin/pio_hd44780.rs | 16 ++-------------- examples/rp/src/bin/ws2812-pio.rs | 13 +++---------- 4 files changed, 13 insertions(+), 48 deletions(-) (limited to 'examples') diff --git a/examples/rp/src/bin/pio_async.rs b/examples/rp/src/bin/pio_async.rs index 461ea3ff9..9f47c2316 100644 --- a/examples/rp/src/bin/pio_async.rs +++ b/examples/rp/src/bin/pio_async.rs @@ -5,11 +5,10 @@ use defmt::info; use embassy_executor::Spawner; use embassy_rp::peripherals::PIO0; use embassy_rp::pio::{Common, Irq, Pio, PioPin, ShiftDirection, StateMachine}; -use embassy_rp::pio_instr_util; use embassy_rp::relocate::RelocatedProgram; use {defmt_rtt as _, panic_probe as _}; -fn setup_pio_task_sm0(pio: &mut Common, sm: &mut StateMachine, pin: impl PioPin) { +fn setup_pio_task_sm0<'a>(pio: &mut Common<'a, PIO0>, sm: &mut StateMachine<'a, PIO0, 0>, pin: impl PioPin) { // Setup sm0 // Send data serially to pin @@ -22,15 +21,12 @@ fn setup_pio_task_sm0(pio: &mut Common, sm: &mut StateMachine, pi ); let relocated = RelocatedProgram::new(&prg.program); + sm.use_program(&pio.load_program(&relocated), &[]); let out_pin = pio.make_pio_pin(pin); let pio_pins = [&out_pin]; sm.set_out_pins(&pio_pins); - 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(); - sm.set_wrap(source, target); sm.set_autopull(true); sm.set_out_shift_dir(ShiftDirection::Left); @@ -48,20 +44,16 @@ async fn pio_task_sm0(mut sm: StateMachine<'static, PIO0, 0>) { } } -fn setup_pio_task_sm1(pio: &mut Common, sm: &mut StateMachine) { +fn setup_pio_task_sm1<'a>(pio: &mut Common<'a, PIO0>, sm: &mut StateMachine<'a, PIO0, 1>) { // 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); - pio.write_instr(relocated.origin() as usize, relocated.code()); - pio_instr_util::exec_jmp(sm, relocated.origin()); + sm.use_program(&pio.load_program(&relocated), &[]); sm.set_clkdiv((125e6 / 2e3 * 256.0) as u32); sm.set_set_range(0, 0); - let pio::Wrap { source, target } = relocated.wrap(); - sm.set_wrap(source, target); - sm.set_autopush(true); sm.set_in_shift_dir(ShiftDirection::Right); } @@ -75,7 +67,7 @@ async fn pio_task_sm1(mut sm: StateMachine<'static, PIO0, 1>) { } } -fn setup_pio_task_sm2(pio: &mut Common, sm: &mut StateMachine) { +fn setup_pio_task_sm2<'a>(pio: &mut Common<'a, PIO0>, sm: &mut StateMachine<'a, PIO0, 2>) { // Setup sm2 // Repeatedly trigger IRQ 3 @@ -89,12 +81,7 @@ fn setup_pio_task_sm2(pio: &mut Common, sm: &mut StateMachine) { ".wrap", ); let relocated = RelocatedProgram::new(&prg.program); - 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(sm, relocated.origin()); + sm.use_program(&pio.load_program(&relocated), &[]); sm.set_clkdiv((125e6 / 2e3 * 256.0) as u32); } diff --git a/examples/rp/src/bin/pio_dma.rs b/examples/rp/src/bin/pio_dma.rs index c664482e5..1c4e127c7 100644 --- a/examples/rp/src/bin/pio_dma.rs +++ b/examples/rp/src/bin/pio_dma.rs @@ -6,7 +6,7 @@ use embassy_executor::Spawner; use embassy_futures::join::join; use embassy_rp::pio::{Pio, ShiftDirection}; use embassy_rp::relocate::RelocatedProgram; -use embassy_rp::{pio_instr_util, Peripheral}; +use embassy_rp::Peripheral; use {defmt_rtt as _, panic_probe as _}; fn swap_nibbles(v: u32) -> u32 { @@ -38,11 +38,8 @@ async fn main(_spawner: Spawner) { ); let relocated = RelocatedProgram::new(&prg.program); - common.write_instr(relocated.origin() as usize, relocated.code()); - pio_instr_util::exec_jmp(&mut sm, relocated.origin()); + sm.use_program(&common.load_program(&relocated), &[]); sm.set_clkdiv((125e6 / 10e3 * 256.0) as u32); - let pio::Wrap { source, target } = relocated.wrap(); - sm.set_wrap(source, target); sm.set_autopull(true); sm.set_autopush(true); sm.set_pull_threshold(32); diff --git a/examples/rp/src/bin/pio_hd44780.rs b/examples/rp/src/bin/pio_hd44780.rs index 17b2440cf..c3466b554 100644 --- a/examples/rp/src/bin/pio_hd44780.rs +++ b/examples/rp/src/bin/pio_hd44780.rs @@ -123,15 +123,9 @@ impl<'l> HD44780<'l> { embassy_rp::pio_instr_util::set_pindir(&mut sm0, 0b11111); let relocated = RelocatedProgram::new(&prg.program); - common.write_instr(relocated.origin() as usize, relocated.code()); - embassy_rp::pio_instr_util::exec_jmp(&mut sm0, relocated.origin()); + sm0.use_program(&common.load_program(&relocated), &[&e]); sm0.set_clkdiv(125 * 256); - let pio::Wrap { source, target } = relocated.wrap(); - sm0.set_wrap(source, target); - sm0.set_side_enable(true); sm0.set_out_pins(&[&db4, &db5, &db6, &db7]); - sm0.set_sideset_base_pin(&e); - sm0.set_sideset_count(2); sm0.set_out_shift_dir(ShiftDirection::Left); sm0.set_fifo_join(FifoJoin::TxOnly); sm0.set_autopull(true); @@ -199,17 +193,11 @@ impl<'l> HD44780<'l> { ); let relocated = RelocatedProgram::new(&prg.program); - common.write_instr(relocated.origin() as usize, relocated.code()); - embassy_rp::pio_instr_util::exec_jmp(&mut sm0, relocated.origin()); - let pio::Wrap { source, target } = relocated.wrap(); + sm0.use_program(&common.load_program(&relocated), &[&e]); sm0.set_clkdiv(8 * 256); // ~64ns/insn - sm0.set_side_enable(false); sm0.set_jmp_pin(db7pin); - sm0.set_wrap(source, target); sm0.set_set_pins(&[&rs, &rw]); sm0.set_out_pins(&[&db4, &db5, &db6, &db7]); - sm0.set_sideset_base_pin(&e); - sm0.set_sideset_count(1); sm0.set_out_shift_dir(ShiftDirection::Left); sm0.set_fifo_join(FifoJoin::TxOnly); diff --git a/examples/rp/src/bin/ws2812-pio.rs b/examples/rp/src/bin/ws2812-pio.rs index 2e6860d8b..889970541 100644 --- a/examples/rp/src/bin/ws2812-pio.rs +++ b/examples/rp/src/bin/ws2812-pio.rs @@ -5,7 +5,6 @@ use defmt::*; use embassy_executor::Spawner; use embassy_rp::pio::{Common, FifoJoin, Instance, Pio, PioPin, ShiftDirection, StateMachine}; -use embassy_rp::pio_instr_util; use embassy_rp::relocate::RelocatedProgram; use embassy_time::{Duration, Timer}; use smart_leds::RGB8; @@ -45,15 +44,11 @@ impl<'d, P: Instance, const S: usize> Ws2812<'d, P, S> { let prg = a.assemble_with_wrap(wrap_source, wrap_target); - let relocated = RelocatedProgram::new(&prg); - pio.write_instr(relocated.origin() as usize, relocated.code()); - pio_instr_util::exec_jmp(&mut sm, relocated.origin()); - // Pin config 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); + + let relocated = RelocatedProgram::new(&prg); + sm.use_program(&pio.load_program(&relocated), &[&out_pin]); // Clock config // TODO CLOCK_FREQ should come from embassy_rp @@ -70,8 +65,6 @@ impl<'d, P: Instance, const S: usize> Ws2812<'d, P, S> { } sm.set_clkdiv((int << 8) | frac); - let pio::Wrap { source, target } = relocated.wrap(); - sm.set_wrap(source, target); // FIFO config sm.set_autopull(true); -- cgit From 37b460637df0a20885ba8a0fbb0699e2d44ee4ec Mon Sep 17 00:00:00 2001 From: pennae Date: Fri, 5 May 2023 20:45:02 +0200 Subject: rp/pio: add set-pin-{values,dirs} convenience functions these are needed a lot during state machine setup, it makes sense to provide convenience functions for them. --- examples/rp/src/bin/pio_hd44780.rs | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) (limited to 'examples') diff --git a/examples/rp/src/bin/pio_hd44780.rs b/examples/rp/src/bin/pio_hd44780.rs index c3466b554..40dee1c4d 100644 --- a/examples/rp/src/bin/pio_hd44780.rs +++ b/examples/rp/src/bin/pio_hd44780.rs @@ -7,7 +7,7 @@ use core::fmt::Write; use embassy_executor::Spawner; use embassy_rp::dma::{AnyChannel, Channel}; use embassy_rp::peripherals::PIO0; -use embassy_rp::pio::{FifoJoin, Pio, PioPin, ShiftDirection, StateMachine}; +use embassy_rp::pio::{Direction, FifoJoin, Pio, PioPin, ShiftDirection, StateMachine}; use embassy_rp::pwm::{Config, Pwm}; use embassy_rp::relocate::RelocatedProgram; use embassy_rp::{into_ref, Peripheral, PeripheralRef}; @@ -115,12 +115,7 @@ impl<'l> HD44780<'l> { let db6 = common.make_pio_pin(db6); let db7 = common.make_pio_pin(db7); - sm0.set_set_pins(&[&rs, &rw]); - embassy_rp::pio_instr_util::set_pindir(&mut sm0, 0b11); - sm0.set_set_pins(&[&e]); - embassy_rp::pio_instr_util::set_pindir(&mut sm0, 0b1); - sm0.set_set_pins(&[&db4, &db5, &db6, &db7]); - embassy_rp::pio_instr_util::set_pindir(&mut sm0, 0b11111); + sm0.set_pin_dirs(Direction::Out, &[&rs, &rw, &e, &db4, &db5, &db6, &db7]); let relocated = RelocatedProgram::new(&prg.program); sm0.use_program(&common.load_program(&relocated), &[&e]); -- cgit From 8e4d65e163bd484efc4fb31d20b14e6ac4a88de7 Mon Sep 17 00:00:00 2001 From: pennae Date: Sat, 6 May 2023 11:36:07 +0200 Subject: rp/pio: configure state machines with Config struct the many individual sets aren't very efficient, and almost no checks were done to ensure that the configuration written to the hardware was actually valid. this adresses both of these. --- examples/rp/Cargo.toml | 2 ++ examples/rp/src/bin/pio_async.rs | 37 ++++++++++++++++++--------------- examples/rp/src/bin/pio_dma.rs | 27 ++++++++++++++++-------- examples/rp/src/bin/pio_hd44780.rs | 42 ++++++++++++++++++++++---------------- examples/rp/src/bin/ws2812-pio.rs | 39 ++++++++++++++++------------------- 5 files changed, 83 insertions(+), 64 deletions(-) (limited to 'examples') diff --git a/examples/rp/Cargo.toml b/examples/rp/Cargo.toml index 57f6f5c67..d2829df99 100644 --- a/examples/rp/Cargo.toml +++ b/examples/rp/Cargo.toml @@ -22,6 +22,8 @@ lorawan = { version = "0.7.3", default-features = false, features = ["default-cr defmt = "0.3" defmt-rtt = "0.4" +fixed = "1.23.1" +fixed-macro = "1.2" #cortex-m = { version = "0.7.6", features = ["critical-section-single-core"] } cortex-m = { version = "0.7.6", features = ["inline-asm"] } diff --git a/examples/rp/src/bin/pio_async.rs b/examples/rp/src/bin/pio_async.rs index 9f47c2316..12484e882 100644 --- a/examples/rp/src/bin/pio_async.rs +++ b/examples/rp/src/bin/pio_async.rs @@ -2,10 +2,13 @@ #![no_main] #![feature(type_alias_impl_trait)] use defmt::info; +use embassy_embedded_hal::SetConfig; use embassy_executor::Spawner; use embassy_rp::peripherals::PIO0; -use embassy_rp::pio::{Common, Irq, Pio, PioPin, ShiftDirection, StateMachine}; +use embassy_rp::pio::{Common, Config, 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 _}; fn setup_pio_task_sm0<'a>(pio: &mut Common<'a, PIO0>, sm: &mut StateMachine<'a, PIO0, 0>, pin: impl PioPin) { @@ -21,15 +24,14 @@ fn setup_pio_task_sm0<'a>(pio: &mut Common<'a, PIO0>, sm: &mut StateMachine<'a, ); let relocated = RelocatedProgram::new(&prg.program); - sm.use_program(&pio.load_program(&relocated), &[]); + let mut cfg = Config::default(); + cfg.use_program(&pio.load_program(&relocated), &[]); let out_pin = pio.make_pio_pin(pin); - let pio_pins = [&out_pin]; - sm.set_out_pins(&pio_pins); - sm.set_clkdiv((125e6 / 20.0 / 2e2 * 256.0) as u32); - sm.set_set_range(0, 1); - - sm.set_autopull(true); - sm.set_out_shift_dir(ShiftDirection::Left); + cfg.set_out_pins(&[&out_pin]); + cfg.set_set_pins(&[&out_pin]); + cfg.clock_divider = (U56F8!(125_000_000) / 20 / 200).to_fixed(); + cfg.shift_out.auto_fill = true; + sm.set_config(&cfg); } #[embassy_executor::task] @@ -51,11 +53,12 @@ fn setup_pio_task_sm1<'a>(pio: &mut Common<'a, PIO0>, sm: &mut StateMachine<'a, 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.use_program(&pio.load_program(&relocated), &[]); - sm.set_clkdiv((125e6 / 2e3 * 256.0) as u32); - sm.set_set_range(0, 0); - sm.set_autopush(true); - sm.set_in_shift_dir(ShiftDirection::Right); + let mut cfg = Config::default(); + cfg.use_program(&pio.load_program(&relocated), &[]); + cfg.clock_divider = (U56F8!(125_000_000) / 2000).to_fixed(); + cfg.shift_in.auto_fill = true; + cfg.shift_in.direction = ShiftDirection::Right; + sm.set_config(&cfg); } #[embassy_executor::task] @@ -81,8 +84,10 @@ fn setup_pio_task_sm2<'a>(pio: &mut Common<'a, PIO0>, sm: &mut StateMachine<'a, ".wrap", ); let relocated = RelocatedProgram::new(&prg.program); - sm.use_program(&pio.load_program(&relocated), &[]); - sm.set_clkdiv((125e6 / 2e3 * 256.0) as u32); + let mut cfg = Config::default(); + cfg.use_program(&pio.load_program(&relocated), &[]); + cfg.clock_divider = (U56F8!(125_000_000) / 2000).to_fixed(); + sm.set_config(&cfg); } #[embassy_executor::task] diff --git a/examples/rp/src/bin/pio_dma.rs b/examples/rp/src/bin/pio_dma.rs index 1c4e127c7..7f85288bf 100644 --- a/examples/rp/src/bin/pio_dma.rs +++ b/examples/rp/src/bin/pio_dma.rs @@ -2,11 +2,14 @@ #![no_main] #![feature(type_alias_impl_trait)] use defmt::info; +use embassy_embedded_hal::SetConfig; use embassy_executor::Spawner; use embassy_futures::join::join; -use embassy_rp::pio::{Pio, ShiftDirection}; +use embassy_rp::pio::{Config, Pio, ShiftConfig, ShiftDirection}; use embassy_rp::relocate::RelocatedProgram; use embassy_rp::Peripheral; +use fixed::traits::ToFixed; +use fixed_macro::types::U56F8; use {defmt_rtt as _, panic_probe as _}; fn swap_nibbles(v: u32) -> u32 { @@ -38,15 +41,21 @@ async fn main(_spawner: Spawner) { ); let relocated = RelocatedProgram::new(&prg.program); - sm.use_program(&common.load_program(&relocated), &[]); - sm.set_clkdiv((125e6 / 10e3 * 256.0) as u32); - sm.set_autopull(true); - sm.set_autopush(true); - sm.set_pull_threshold(32); - sm.set_push_threshold(32); - sm.set_out_shift_dir(ShiftDirection::Right); - sm.set_in_shift_dir(ShiftDirection::Left); + let mut cfg = Config::default(); + cfg.use_program(&common.load_program(&relocated), &[]); + cfg.clock_divider = (U56F8!(125_000_000) / U56F8!(10_000)).to_fixed(); + cfg.shift_in = ShiftConfig { + auto_fill: true, + threshold: 32, + direction: ShiftDirection::Left, + }; + cfg.shift_out = ShiftConfig { + auto_fill: true, + threshold: 32, + direction: ShiftDirection::Right, + }; + sm.set_config(&cfg); sm.set_enable(true); let mut dma_out_ref = p.DMA_CH0.into_ref(); diff --git a/examples/rp/src/bin/pio_hd44780.rs b/examples/rp/src/bin/pio_hd44780.rs index 40dee1c4d..61c5565d3 100644 --- a/examples/rp/src/bin/pio_hd44780.rs +++ b/examples/rp/src/bin/pio_hd44780.rs @@ -4,11 +4,12 @@ use core::fmt::Write; +use embassy_embedded_hal::SetConfig; use embassy_executor::Spawner; use embassy_rp::dma::{AnyChannel, Channel}; use embassy_rp::peripherals::PIO0; -use embassy_rp::pio::{Direction, FifoJoin, Pio, PioPin, ShiftDirection, StateMachine}; -use embassy_rp::pwm::{Config, Pwm}; +use embassy_rp::pio::{Config, Direction, FifoJoin, Pio, PioPin, ShiftConfig, ShiftDirection, StateMachine}; +use embassy_rp::pwm::{self, Pwm}; use embassy_rp::relocate::RelocatedProgram; use embassy_rp::{into_ref, Peripheral, PeripheralRef}; use embassy_time::{Duration, Instant, Timer}; @@ -29,7 +30,7 @@ async fn main(_spawner: Spawner) { let p = embassy_rp::init(Default::default()); let _pwm = Pwm::new_output_b(p.PWM_CH7, p.PIN_15, { - let mut c = Config::default(); + let mut c = pwm::Config::default(); c.divider = 125.into(); c.top = 100; c.compare_b = 50; @@ -83,7 +84,6 @@ impl<'l> HD44780<'l> { ) -> HD44780<'l> { into_ref!(dma); - let db7pin = db7.pin(); let Pio { mut common, mut irq0, @@ -118,13 +118,17 @@ impl<'l> HD44780<'l> { sm0.set_pin_dirs(Direction::Out, &[&rs, &rw, &e, &db4, &db5, &db6, &db7]); let relocated = RelocatedProgram::new(&prg.program); - sm0.use_program(&common.load_program(&relocated), &[&e]); - sm0.set_clkdiv(125 * 256); - sm0.set_out_pins(&[&db4, &db5, &db6, &db7]); - sm0.set_out_shift_dir(ShiftDirection::Left); - sm0.set_fifo_join(FifoJoin::TxOnly); - sm0.set_autopull(true); - sm0.set_pull_threshold(32); + let mut cfg = Config::default(); + cfg.use_program(&common.load_program(&relocated), &[&e]); + cfg.clock_divider = 125u8.into(); + cfg.set_out_pins(&[&db4, &db5, &db6, &db7]); + cfg.shift_out = ShiftConfig { + auto_fill: true, + direction: ShiftDirection::Left, + threshold: 32, + }; + cfg.fifo_join = FifoJoin::TxOnly; + sm0.set_config(&cfg); sm0.set_enable(true); // init to 8 bit thrice @@ -188,13 +192,15 @@ impl<'l> HD44780<'l> { ); let relocated = RelocatedProgram::new(&prg.program); - sm0.use_program(&common.load_program(&relocated), &[&e]); - sm0.set_clkdiv(8 * 256); // ~64ns/insn - sm0.set_jmp_pin(db7pin); - sm0.set_set_pins(&[&rs, &rw]); - sm0.set_out_pins(&[&db4, &db5, &db6, &db7]); - sm0.set_out_shift_dir(ShiftDirection::Left); - sm0.set_fifo_join(FifoJoin::TxOnly); + let mut cfg = Config::default(); + cfg.use_program(&common.load_program(&relocated), &[&e]); + cfg.clock_divider = 8u8.into(); // ~64ns/insn + cfg.set_jmp_pin(&db7); + cfg.set_set_pins(&[&rs, &rw]); + cfg.set_out_pins(&[&db4, &db5, &db6, &db7]); + cfg.shift_out.direction = ShiftDirection::Left; + cfg.fifo_join = FifoJoin::TxOnly; + sm0.set_config(&cfg); sm0.set_enable(true); diff --git a/examples/rp/src/bin/ws2812-pio.rs b/examples/rp/src/bin/ws2812-pio.rs index 889970541..d7c4742d8 100644 --- a/examples/rp/src/bin/ws2812-pio.rs +++ b/examples/rp/src/bin/ws2812-pio.rs @@ -3,10 +3,12 @@ #![feature(type_alias_impl_trait)] use defmt::*; +use embassy_embedded_hal::SetConfig; use embassy_executor::Spawner; -use embassy_rp::pio::{Common, FifoJoin, Instance, Pio, PioPin, ShiftDirection, StateMachine}; +use embassy_rp::pio::{Common, Config, FifoJoin, Instance, Pio, PioPin, ShiftConfig, ShiftDirection, StateMachine}; use embassy_rp::relocate::RelocatedProgram; use embassy_time::{Duration, Timer}; +use fixed_macro::fixed; use smart_leds::RGB8; use {defmt_rtt as _, panic_probe as _}; pub struct Ws2812<'d, P: Instance, const S: usize> { @@ -43,35 +45,30 @@ impl<'d, P: Instance, const S: usize> Ws2812<'d, P, S> { a.bind(&mut wrap_source); let prg = a.assemble_with_wrap(wrap_source, wrap_target); + let mut cfg = Config::default(); // Pin config let out_pin = pio.make_pio_pin(pin); let relocated = RelocatedProgram::new(&prg); - sm.use_program(&pio.load_program(&relocated), &[&out_pin]); + cfg.use_program(&pio.load_program(&relocated), &[&out_pin]); - // Clock config + // Clock config, measured in kHz to avoid overflows // TODO CLOCK_FREQ should come from embassy_rp - const CLOCK_FREQ: u32 = 125_000_000; - const WS2812_FREQ: u32 = 800_000; - - let bit_freq = WS2812_FREQ * CYCLES_PER_BIT; - let mut int = CLOCK_FREQ / bit_freq; - let rem = CLOCK_FREQ - (int * bit_freq); - let frac = (rem * 256) / bit_freq; - // 65536.0 is represented as 0 in the pio's clock divider - if int == 65536 { - int = 0; - } - - sm.set_clkdiv((int << 8) | frac); + let clock_freq = fixed!(125_000: U24F8); + let ws2812_freq = fixed!(800: U24F8); + let bit_freq = ws2812_freq * CYCLES_PER_BIT; + cfg.clock_divider = clock_freq / bit_freq; // FIFO config - sm.set_autopull(true); - sm.set_fifo_join(FifoJoin::TxOnly); - sm.set_pull_threshold(24); - sm.set_out_shift_dir(ShiftDirection::Left); - + cfg.fifo_join = FifoJoin::TxOnly; + cfg.shift_out = ShiftConfig { + auto_fill: true, + threshold: 24, + direction: ShiftDirection::Left, + }; + + sm.set_config(&cfg); sm.set_enable(true); Self { sm } -- cgit From b38d496d519f87d7f455e6c6b32f5d6379af44a5 Mon Sep 17 00:00:00 2001 From: pennae Date: Sat, 6 May 2023 20:53:06 +0200 Subject: rp/pio: allow wrap-around program loading execution wraps around after the end of instruction memory and wrapping works with this, so we may as well allow program loading across this boundary. could be useful for reusing chunks of instruction memory. --- examples/rp/src/bin/pio_hd44780.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'examples') diff --git a/examples/rp/src/bin/pio_hd44780.rs b/examples/rp/src/bin/pio_hd44780.rs index 61c5565d3..088fd5649 100644 --- a/examples/rp/src/bin/pio_hd44780.rs +++ b/examples/rp/src/bin/pio_hd44780.rs @@ -95,6 +95,7 @@ impl<'l> HD44780<'l> { let prg = pio_proc::pio_asm!( r#" .side_set 1 opt + .origin 20 loop: out x, 24 @@ -148,7 +149,7 @@ impl<'l> HD44780<'l> { // many side sets are only there to free up a delay bit! let prg = pio_proc::pio_asm!( r#" - .origin 7 + .origin 27 .side_set 1 .wrap_target -- cgit