diff options
Diffstat (limited to 'examples/rp/src')
| -rw-r--r-- | examples/rp/src/bin/pio_async.rs | 62 | ||||
| -rw-r--r-- | examples/rp/src/bin/pio_dma.rs | 32 | ||||
| -rw-r--r-- | examples/rp/src/bin/pio_hd44780.rs | 66 | ||||
| -rw-r--r-- | examples/rp/src/bin/ws2812-pio.rs | 58 |
4 files changed, 98 insertions, 120 deletions
diff --git a/examples/rp/src/bin/pio_async.rs b/examples/rp/src/bin/pio_async.rs index 4e0ab5e3c..12484e882 100644 --- a/examples/rp/src/bin/pio_async.rs +++ b/examples/rp/src/bin/pio_async.rs | |||
| @@ -2,14 +2,16 @@ | |||
| 2 | #![no_main] | 2 | #![no_main] |
| 3 | #![feature(type_alias_impl_trait)] | 3 | #![feature(type_alias_impl_trait)] |
| 4 | use defmt::info; | 4 | use defmt::info; |
| 5 | use embassy_embedded_hal::SetConfig; | ||
| 5 | use embassy_executor::Spawner; | 6 | use embassy_executor::Spawner; |
| 6 | use embassy_rp::peripherals::PIO0; | 7 | use embassy_rp::peripherals::PIO0; |
| 7 | use embassy_rp::pio::{Pio, PioCommon, PioIrq, PioPin, PioStateMachine, ShiftDirection}; | 8 | use embassy_rp::pio::{Common, Config, Irq, Pio, PioPin, ShiftDirection, StateMachine}; |
| 8 | use embassy_rp::pio_instr_util; | ||
| 9 | use embassy_rp::relocate::RelocatedProgram; | 9 | use embassy_rp::relocate::RelocatedProgram; |
| 10 | use fixed::traits::ToFixed; | ||
| 11 | use fixed_macro::types::U56F8; | ||
| 10 | use {defmt_rtt as _, panic_probe as _}; | 12 | use {defmt_rtt as _, panic_probe as _}; |
| 11 | 13 | ||
| 12 | fn setup_pio_task_sm0(pio: &mut PioCommon<PIO0>, sm: &mut PioStateMachine<PIO0, 0>, pin: impl PioPin) { | 14 | fn setup_pio_task_sm0<'a>(pio: &mut Common<'a, PIO0>, sm: &mut StateMachine<'a, PIO0, 0>, pin: impl PioPin) { |
| 13 | // Setup sm0 | 15 | // Setup sm0 |
| 14 | 16 | ||
| 15 | // Send data serially to pin | 17 | // Send data serially to pin |
| @@ -22,22 +24,18 @@ fn setup_pio_task_sm0(pio: &mut PioCommon<PIO0>, sm: &mut PioStateMachine<PIO0, | |||
| 22 | ); | 24 | ); |
| 23 | 25 | ||
| 24 | let relocated = RelocatedProgram::new(&prg.program); | 26 | let relocated = RelocatedProgram::new(&prg.program); |
| 27 | let mut cfg = Config::default(); | ||
| 28 | cfg.use_program(&pio.load_program(&relocated), &[]); | ||
| 25 | let out_pin = pio.make_pio_pin(pin); | 29 | let out_pin = pio.make_pio_pin(pin); |
| 26 | let pio_pins = [&out_pin]; | 30 | cfg.set_out_pins(&[&out_pin]); |
| 27 | sm.set_out_pins(&pio_pins); | 31 | cfg.set_set_pins(&[&out_pin]); |
| 28 | pio.write_instr(relocated.origin() as usize, relocated.code()); | 32 | cfg.clock_divider = (U56F8!(125_000_000) / 20 / 200).to_fixed(); |
| 29 | pio_instr_util::exec_jmp(sm, relocated.origin()); | 33 | cfg.shift_out.auto_fill = true; |
| 30 | sm.set_clkdiv((125e6 / 20.0 / 2e2 * 256.0) as u32); | 34 | sm.set_config(&cfg); |
| 31 | sm.set_set_range(0, 1); | ||
| 32 | let pio::Wrap { source, target } = relocated.wrap(); | ||
| 33 | sm.set_wrap(source, target); | ||
| 34 | |||
| 35 | sm.set_autopull(true); | ||
| 36 | sm.set_out_shift_dir(ShiftDirection::Left); | ||
| 37 | } | 35 | } |
| 38 | 36 | ||
| 39 | #[embassy_executor::task] | 37 | #[embassy_executor::task] |
| 40 | async fn pio_task_sm0(mut sm: PioStateMachine<'static, PIO0, 0>) { | 38 | async fn pio_task_sm0(mut sm: StateMachine<'static, PIO0, 0>) { |
| 41 | sm.set_enable(true); | 39 | sm.set_enable(true); |
| 42 | 40 | ||
| 43 | let mut v = 0x0f0caffa; | 41 | let mut v = 0x0f0caffa; |
| @@ -48,26 +46,23 @@ async fn pio_task_sm0(mut sm: PioStateMachine<'static, PIO0, 0>) { | |||
| 48 | } | 46 | } |
| 49 | } | 47 | } |
| 50 | 48 | ||
| 51 | fn setup_pio_task_sm1(pio: &mut PioCommon<PIO0>, sm: &mut PioStateMachine<PIO0, 1>) { | 49 | fn setup_pio_task_sm1<'a>(pio: &mut Common<'a, PIO0>, sm: &mut StateMachine<'a, PIO0, 1>) { |
| 52 | // Setupm sm1 | 50 | // Setupm sm1 |
| 53 | 51 | ||
| 54 | // Read 0b10101 repeatedly until ISR is full | 52 | // Read 0b10101 repeatedly until ISR is full |
| 55 | let prg = pio_proc::pio_asm!(".origin 8", "set x, 0x15", ".wrap_target", "in x, 5 [31]", ".wrap",); | 53 | let prg = pio_proc::pio_asm!(".origin 8", "set x, 0x15", ".wrap_target", "in x, 5 [31]", ".wrap",); |
| 56 | 54 | ||
| 57 | let relocated = RelocatedProgram::new(&prg.program); | 55 | let relocated = RelocatedProgram::new(&prg.program); |
| 58 | pio.write_instr(relocated.origin() as usize, relocated.code()); | 56 | let mut cfg = Config::default(); |
| 59 | pio_instr_util::exec_jmp(sm, relocated.origin()); | 57 | cfg.use_program(&pio.load_program(&relocated), &[]); |
| 60 | sm.set_clkdiv((125e6 / 2e3 * 256.0) as u32); | 58 | cfg.clock_divider = (U56F8!(125_000_000) / 2000).to_fixed(); |
| 61 | sm.set_set_range(0, 0); | 59 | cfg.shift_in.auto_fill = true; |
| 62 | let pio::Wrap { source, target } = relocated.wrap(); | 60 | cfg.shift_in.direction = ShiftDirection::Right; |
| 63 | sm.set_wrap(source, target); | 61 | sm.set_config(&cfg); |
| 64 | |||
| 65 | sm.set_autopush(true); | ||
| 66 | sm.set_in_shift_dir(ShiftDirection::Right); | ||
| 67 | } | 62 | } |
| 68 | 63 | ||
| 69 | #[embassy_executor::task] | 64 | #[embassy_executor::task] |
| 70 | async fn pio_task_sm1(mut sm: PioStateMachine<'static, PIO0, 1>) { | 65 | async fn pio_task_sm1(mut sm: StateMachine<'static, PIO0, 1>) { |
| 71 | sm.set_enable(true); | 66 | sm.set_enable(true); |
| 72 | loop { | 67 | loop { |
| 73 | let rx = sm.rx().wait_pull().await; | 68 | let rx = sm.rx().wait_pull().await; |
| @@ -75,7 +70,7 @@ async fn pio_task_sm1(mut sm: PioStateMachine<'static, PIO0, 1>) { | |||
| 75 | } | 70 | } |
| 76 | } | 71 | } |
| 77 | 72 | ||
| 78 | fn setup_pio_task_sm2(pio: &mut PioCommon<PIO0>, sm: &mut PioStateMachine<PIO0, 2>) { | 73 | fn setup_pio_task_sm2<'a>(pio: &mut Common<'a, PIO0>, sm: &mut StateMachine<'a, PIO0, 2>) { |
| 79 | // Setup sm2 | 74 | // Setup sm2 |
| 80 | 75 | ||
| 81 | // Repeatedly trigger IRQ 3 | 76 | // Repeatedly trigger IRQ 3 |
| @@ -89,17 +84,14 @@ fn setup_pio_task_sm2(pio: &mut PioCommon<PIO0>, sm: &mut PioStateMachine<PIO0, | |||
| 89 | ".wrap", | 84 | ".wrap", |
| 90 | ); | 85 | ); |
| 91 | let relocated = RelocatedProgram::new(&prg.program); | 86 | let relocated = RelocatedProgram::new(&prg.program); |
| 92 | pio.write_instr(relocated.origin() as usize, relocated.code()); | 87 | let mut cfg = Config::default(); |
| 93 | 88 | cfg.use_program(&pio.load_program(&relocated), &[]); | |
| 94 | let pio::Wrap { source, target } = relocated.wrap(); | 89 | cfg.clock_divider = (U56F8!(125_000_000) / 2000).to_fixed(); |
| 95 | sm.set_wrap(source, target); | 90 | sm.set_config(&cfg); |
| 96 | |||
| 97 | pio_instr_util::exec_jmp(sm, relocated.origin()); | ||
| 98 | sm.set_clkdiv((125e6 / 2e3 * 256.0) as u32); | ||
| 99 | } | 91 | } |
| 100 | 92 | ||
| 101 | #[embassy_executor::task] | 93 | #[embassy_executor::task] |
| 102 | async fn pio_task_sm2(mut irq: PioIrq<'static, PIO0, 3>, mut sm: PioStateMachine<'static, PIO0, 2>) { | 94 | async fn pio_task_sm2(mut irq: Irq<'static, PIO0, 3>, mut sm: StateMachine<'static, PIO0, 2>) { |
| 103 | sm.set_enable(true); | 95 | sm.set_enable(true); |
| 104 | loop { | 96 | loop { |
| 105 | irq.wait().await; | 97 | irq.wait().await; |
diff --git a/examples/rp/src/bin/pio_dma.rs b/examples/rp/src/bin/pio_dma.rs index c664482e5..7f85288bf 100644 --- a/examples/rp/src/bin/pio_dma.rs +++ b/examples/rp/src/bin/pio_dma.rs | |||
| @@ -2,11 +2,14 @@ | |||
| 2 | #![no_main] | 2 | #![no_main] |
| 3 | #![feature(type_alias_impl_trait)] | 3 | #![feature(type_alias_impl_trait)] |
| 4 | use defmt::info; | 4 | use defmt::info; |
| 5 | use embassy_embedded_hal::SetConfig; | ||
| 5 | use embassy_executor::Spawner; | 6 | use embassy_executor::Spawner; |
| 6 | use embassy_futures::join::join; | 7 | use embassy_futures::join::join; |
| 7 | use embassy_rp::pio::{Pio, ShiftDirection}; | 8 | use embassy_rp::pio::{Config, Pio, ShiftConfig, ShiftDirection}; |
| 8 | use embassy_rp::relocate::RelocatedProgram; | 9 | use embassy_rp::relocate::RelocatedProgram; |
| 9 | use embassy_rp::{pio_instr_util, Peripheral}; | 10 | use embassy_rp::Peripheral; |
| 11 | use fixed::traits::ToFixed; | ||
| 12 | use fixed_macro::types::U56F8; | ||
| 10 | use {defmt_rtt as _, panic_probe as _}; | 13 | use {defmt_rtt as _, panic_probe as _}; |
| 11 | 14 | ||
| 12 | fn swap_nibbles(v: u32) -> u32 { | 15 | fn swap_nibbles(v: u32) -> u32 { |
| @@ -38,18 +41,21 @@ async fn main(_spawner: Spawner) { | |||
| 38 | ); | 41 | ); |
| 39 | 42 | ||
| 40 | let relocated = RelocatedProgram::new(&prg.program); | 43 | let relocated = RelocatedProgram::new(&prg.program); |
| 41 | common.write_instr(relocated.origin() as usize, relocated.code()); | 44 | let mut cfg = Config::default(); |
| 42 | pio_instr_util::exec_jmp(&mut sm, relocated.origin()); | 45 | cfg.use_program(&common.load_program(&relocated), &[]); |
| 43 | sm.set_clkdiv((125e6 / 10e3 * 256.0) as u32); | 46 | cfg.clock_divider = (U56F8!(125_000_000) / U56F8!(10_000)).to_fixed(); |
| 44 | let pio::Wrap { source, target } = relocated.wrap(); | 47 | cfg.shift_in = ShiftConfig { |
| 45 | sm.set_wrap(source, target); | 48 | auto_fill: true, |
| 46 | sm.set_autopull(true); | 49 | threshold: 32, |
| 47 | sm.set_autopush(true); | 50 | direction: ShiftDirection::Left, |
| 48 | sm.set_pull_threshold(32); | 51 | }; |
| 49 | sm.set_push_threshold(32); | 52 | cfg.shift_out = ShiftConfig { |
| 50 | sm.set_out_shift_dir(ShiftDirection::Right); | 53 | auto_fill: true, |
| 51 | sm.set_in_shift_dir(ShiftDirection::Left); | 54 | threshold: 32, |
| 55 | direction: ShiftDirection::Right, | ||
| 56 | }; | ||
| 52 | 57 | ||
| 58 | sm.set_config(&cfg); | ||
| 53 | sm.set_enable(true); | 59 | sm.set_enable(true); |
| 54 | 60 | ||
| 55 | let mut dma_out_ref = p.DMA_CH0.into_ref(); | 61 | 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 f76d334e7..088fd5649 100644 --- a/examples/rp/src/bin/pio_hd44780.rs +++ b/examples/rp/src/bin/pio_hd44780.rs | |||
| @@ -4,11 +4,12 @@ | |||
| 4 | 4 | ||
| 5 | use core::fmt::Write; | 5 | use core::fmt::Write; |
| 6 | 6 | ||
| 7 | use embassy_embedded_hal::SetConfig; | ||
| 7 | use embassy_executor::Spawner; | 8 | use embassy_executor::Spawner; |
| 8 | use embassy_rp::dma::{AnyChannel, Channel}; | 9 | use embassy_rp::dma::{AnyChannel, Channel}; |
| 9 | use embassy_rp::peripherals::PIO0; | 10 | use embassy_rp::peripherals::PIO0; |
| 10 | use embassy_rp::pio::{FifoJoin, Pio, PioPin, PioStateMachine, ShiftDirection}; | 11 | use embassy_rp::pio::{Config, Direction, FifoJoin, Pio, PioPin, ShiftConfig, ShiftDirection, StateMachine}; |
| 11 | use embassy_rp::pwm::{Config, Pwm}; | 12 | use embassy_rp::pwm::{self, Pwm}; |
| 12 | use embassy_rp::relocate::RelocatedProgram; | 13 | use embassy_rp::relocate::RelocatedProgram; |
| 13 | use embassy_rp::{into_ref, Peripheral, PeripheralRef}; | 14 | use embassy_rp::{into_ref, Peripheral, PeripheralRef}; |
| 14 | use embassy_time::{Duration, Instant, Timer}; | 15 | use embassy_time::{Duration, Instant, Timer}; |
| @@ -29,7 +30,7 @@ async fn main(_spawner: Spawner) { | |||
| 29 | let p = embassy_rp::init(Default::default()); | 30 | let p = embassy_rp::init(Default::default()); |
| 30 | 31 | ||
| 31 | let _pwm = Pwm::new_output_b(p.PWM_CH7, p.PIN_15, { | 32 | let _pwm = Pwm::new_output_b(p.PWM_CH7, p.PIN_15, { |
| 32 | let mut c = Config::default(); | 33 | let mut c = pwm::Config::default(); |
| 33 | c.divider = 125.into(); | 34 | c.divider = 125.into(); |
| 34 | c.top = 100; | 35 | c.top = 100; |
| 35 | c.compare_b = 50; | 36 | c.compare_b = 50; |
| @@ -64,7 +65,7 @@ async fn main(_spawner: Spawner) { | |||
| 64 | 65 | ||
| 65 | pub struct HD44780<'l> { | 66 | pub struct HD44780<'l> { |
| 66 | dma: PeripheralRef<'l, AnyChannel>, | 67 | dma: PeripheralRef<'l, AnyChannel>, |
| 67 | sm: PioStateMachine<'l, PIO0, 0>, | 68 | sm: StateMachine<'l, PIO0, 0>, |
| 68 | 69 | ||
| 69 | buf: [u8; 40], | 70 | buf: [u8; 40], |
| 70 | } | 71 | } |
| @@ -83,7 +84,6 @@ impl<'l> HD44780<'l> { | |||
| 83 | ) -> HD44780<'l> { | 84 | ) -> HD44780<'l> { |
| 84 | into_ref!(dma); | 85 | into_ref!(dma); |
| 85 | 86 | ||
| 86 | let db7pin = db7.pin(); | ||
| 87 | let Pio { | 87 | let Pio { |
| 88 | mut common, | 88 | mut common, |
| 89 | mut irq0, | 89 | mut irq0, |
| @@ -95,6 +95,7 @@ impl<'l> HD44780<'l> { | |||
| 95 | let prg = pio_proc::pio_asm!( | 95 | let prg = pio_proc::pio_asm!( |
| 96 | r#" | 96 | r#" |
| 97 | .side_set 1 opt | 97 | .side_set 1 opt |
| 98 | .origin 20 | ||
| 98 | 99 | ||
| 99 | loop: | 100 | loop: |
| 100 | out x, 24 | 101 | out x, 24 |
| @@ -115,27 +116,20 @@ impl<'l> HD44780<'l> { | |||
| 115 | let db6 = common.make_pio_pin(db6); | 116 | let db6 = common.make_pio_pin(db6); |
| 116 | let db7 = common.make_pio_pin(db7); | 117 | let db7 = common.make_pio_pin(db7); |
| 117 | 118 | ||
| 118 | sm0.set_set_pins(&[&rs, &rw]); | 119 | sm0.set_pin_dirs(Direction::Out, &[&rs, &rw, &e, &db4, &db5, &db6, &db7]); |
| 119 | embassy_rp::pio_instr_util::set_pindir(&mut sm0, 0b11); | ||
| 120 | sm0.set_set_pins(&[&e]); | ||
| 121 | embassy_rp::pio_instr_util::set_pindir(&mut sm0, 0b1); | ||
| 122 | sm0.set_set_pins(&[&db4, &db5, &db6, &db7]); | ||
| 123 | embassy_rp::pio_instr_util::set_pindir(&mut sm0, 0b11111); | ||
| 124 | 120 | ||
| 125 | let relocated = RelocatedProgram::new(&prg.program); | 121 | let relocated = RelocatedProgram::new(&prg.program); |
| 126 | common.write_instr(relocated.origin() as usize, relocated.code()); | 122 | let mut cfg = Config::default(); |
| 127 | embassy_rp::pio_instr_util::exec_jmp(&mut sm0, relocated.origin()); | 123 | cfg.use_program(&common.load_program(&relocated), &[&e]); |
| 128 | sm0.set_clkdiv(125 * 256); | 124 | cfg.clock_divider = 125u8.into(); |
| 129 | let pio::Wrap { source, target } = relocated.wrap(); | 125 | cfg.set_out_pins(&[&db4, &db5, &db6, &db7]); |
| 130 | sm0.set_wrap(source, target); | 126 | cfg.shift_out = ShiftConfig { |
| 131 | sm0.set_side_enable(true); | 127 | auto_fill: true, |
| 132 | sm0.set_out_pins(&[&db4, &db5, &db6, &db7]); | 128 | direction: ShiftDirection::Left, |
| 133 | sm0.set_sideset_base_pin(&e); | 129 | threshold: 32, |
| 134 | sm0.set_sideset_count(2); | 130 | }; |
| 135 | sm0.set_out_shift_dir(ShiftDirection::Left); | 131 | cfg.fifo_join = FifoJoin::TxOnly; |
| 136 | sm0.set_fifo_join(FifoJoin::TxOnly); | 132 | sm0.set_config(&cfg); |
| 137 | sm0.set_autopull(true); | ||
| 138 | sm0.set_pull_threshold(32); | ||
| 139 | 133 | ||
| 140 | sm0.set_enable(true); | 134 | sm0.set_enable(true); |
| 141 | // init to 8 bit thrice | 135 | // init to 8 bit thrice |
| @@ -155,7 +149,7 @@ impl<'l> HD44780<'l> { | |||
| 155 | // many side sets are only there to free up a delay bit! | 149 | // many side sets are only there to free up a delay bit! |
| 156 | let prg = pio_proc::pio_asm!( | 150 | let prg = pio_proc::pio_asm!( |
| 157 | r#" | 151 | r#" |
| 158 | .origin 7 | 152 | .origin 27 |
| 159 | .side_set 1 | 153 | .side_set 1 |
| 160 | 154 | ||
| 161 | .wrap_target | 155 | .wrap_target |
| @@ -199,19 +193,15 @@ impl<'l> HD44780<'l> { | |||
| 199 | ); | 193 | ); |
| 200 | 194 | ||
| 201 | let relocated = RelocatedProgram::new(&prg.program); | 195 | let relocated = RelocatedProgram::new(&prg.program); |
| 202 | common.write_instr(relocated.origin() as usize, relocated.code()); | 196 | let mut cfg = Config::default(); |
| 203 | embassy_rp::pio_instr_util::exec_jmp(&mut sm0, relocated.origin()); | 197 | cfg.use_program(&common.load_program(&relocated), &[&e]); |
| 204 | let pio::Wrap { source, target } = relocated.wrap(); | 198 | cfg.clock_divider = 8u8.into(); // ~64ns/insn |
| 205 | sm0.set_clkdiv(8 * 256); // ~64ns/insn | 199 | cfg.set_jmp_pin(&db7); |
| 206 | sm0.set_side_enable(false); | 200 | cfg.set_set_pins(&[&rs, &rw]); |
| 207 | sm0.set_jmp_pin(db7pin); | 201 | cfg.set_out_pins(&[&db4, &db5, &db6, &db7]); |
| 208 | sm0.set_wrap(source, target); | 202 | cfg.shift_out.direction = ShiftDirection::Left; |
| 209 | sm0.set_set_pins(&[&rs, &rw]); | 203 | cfg.fifo_join = FifoJoin::TxOnly; |
| 210 | sm0.set_out_pins(&[&db4, &db5, &db6, &db7]); | 204 | sm0.set_config(&cfg); |
| 211 | sm0.set_sideset_base_pin(&e); | ||
| 212 | sm0.set_sideset_count(1); | ||
| 213 | sm0.set_out_shift_dir(ShiftDirection::Left); | ||
| 214 | sm0.set_fifo_join(FifoJoin::TxOnly); | ||
| 215 | 205 | ||
| 216 | sm0.set_enable(true); | 206 | sm0.set_enable(true); |
| 217 | 207 | ||
diff --git a/examples/rp/src/bin/ws2812-pio.rs b/examples/rp/src/bin/ws2812-pio.rs index c9c701a70..d7c4742d8 100644 --- a/examples/rp/src/bin/ws2812-pio.rs +++ b/examples/rp/src/bin/ws2812-pio.rs | |||
| @@ -3,19 +3,20 @@ | |||
| 3 | #![feature(type_alias_impl_trait)] | 3 | #![feature(type_alias_impl_trait)] |
| 4 | 4 | ||
| 5 | use defmt::*; | 5 | use defmt::*; |
| 6 | use embassy_embedded_hal::SetConfig; | ||
| 6 | use embassy_executor::Spawner; | 7 | use embassy_executor::Spawner; |
| 7 | use embassy_rp::pio::{FifoJoin, Pio, PioCommon, PioInstance, PioPin, PioStateMachine, ShiftDirection}; | 8 | use embassy_rp::pio::{Common, Config, FifoJoin, Instance, Pio, PioPin, ShiftConfig, ShiftDirection, StateMachine}; |
| 8 | use embassy_rp::pio_instr_util; | ||
| 9 | use embassy_rp::relocate::RelocatedProgram; | 9 | use embassy_rp::relocate::RelocatedProgram; |
| 10 | use embassy_time::{Duration, Timer}; | 10 | use embassy_time::{Duration, Timer}; |
| 11 | use fixed_macro::fixed; | ||
| 11 | use smart_leds::RGB8; | 12 | use smart_leds::RGB8; |
| 12 | use {defmt_rtt as _, panic_probe as _}; | 13 | use {defmt_rtt as _, panic_probe as _}; |
| 13 | pub struct Ws2812<'d, P: PioInstance, const S: usize> { | 14 | pub struct Ws2812<'d, P: Instance, const S: usize> { |
| 14 | sm: PioStateMachine<'d, P, S>, | 15 | sm: StateMachine<'d, P, S>, |
| 15 | } | 16 | } |
| 16 | 17 | ||
| 17 | impl<'d, P: PioInstance, const S: usize> Ws2812<'d, P, S> { | 18 | impl<'d, P: Instance, const S: usize> Ws2812<'d, P, S> { |
| 18 | pub fn new(mut pio: PioCommon<'d, P>, mut sm: PioStateMachine<'d, P, S>, pin: impl PioPin) -> Self { | 19 | pub fn new(mut pio: Common<'d, P>, mut sm: StateMachine<'d, P, S>, pin: impl PioPin) -> Self { |
| 19 | // Setup sm0 | 20 | // Setup sm0 |
| 20 | 21 | ||
| 21 | // prepare the PIO program | 22 | // prepare the PIO program |
| @@ -44,41 +45,30 @@ impl<'d, P: PioInstance, const S: usize> Ws2812<'d, P, S> { | |||
| 44 | a.bind(&mut wrap_source); | 45 | a.bind(&mut wrap_source); |
| 45 | 46 | ||
| 46 | let prg = a.assemble_with_wrap(wrap_source, wrap_target); | 47 | let prg = a.assemble_with_wrap(wrap_source, wrap_target); |
| 47 | 48 | let mut cfg = Config::default(); | |
| 48 | let relocated = RelocatedProgram::new(&prg); | ||
| 49 | pio.write_instr(relocated.origin() as usize, relocated.code()); | ||
| 50 | pio_instr_util::exec_jmp(&mut sm, relocated.origin()); | ||
| 51 | 49 | ||
| 52 | // Pin config | 50 | // Pin config |
| 53 | let out_pin = pio.make_pio_pin(pin); | 51 | let out_pin = pio.make_pio_pin(pin); |
| 54 | sm.set_set_pins(&[&out_pin]); | ||
| 55 | sm.set_sideset_base_pin(&out_pin); | ||
| 56 | sm.set_sideset_count(1); | ||
| 57 | 52 | ||
| 58 | // Clock config | 53 | let relocated = RelocatedProgram::new(&prg); |
| 59 | // TODO CLOCK_FREQ should come from embassy_rp | 54 | cfg.use_program(&pio.load_program(&relocated), &[&out_pin]); |
| 60 | const CLOCK_FREQ: u32 = 125_000_000; | ||
| 61 | const WS2812_FREQ: u32 = 800_000; | ||
| 62 | |||
| 63 | let bit_freq = WS2812_FREQ * CYCLES_PER_BIT; | ||
| 64 | let mut int = CLOCK_FREQ / bit_freq; | ||
| 65 | let rem = CLOCK_FREQ - (int * bit_freq); | ||
| 66 | let frac = (rem * 256) / bit_freq; | ||
| 67 | // 65536.0 is represented as 0 in the pio's clock divider | ||
| 68 | if int == 65536 { | ||
| 69 | int = 0; | ||
| 70 | } | ||
| 71 | 55 | ||
| 72 | sm.set_clkdiv((int << 8) | frac); | 56 | // Clock config, measured in kHz to avoid overflows |
| 73 | let pio::Wrap { source, target } = relocated.wrap(); | 57 | // TODO CLOCK_FREQ should come from embassy_rp |
| 74 | sm.set_wrap(source, target); | 58 | let clock_freq = fixed!(125_000: U24F8); |
| 59 | let ws2812_freq = fixed!(800: U24F8); | ||
| 60 | let bit_freq = ws2812_freq * CYCLES_PER_BIT; | ||
| 61 | cfg.clock_divider = clock_freq / bit_freq; | ||
| 75 | 62 | ||
| 76 | // FIFO config | 63 | // FIFO config |
| 77 | sm.set_autopull(true); | 64 | cfg.fifo_join = FifoJoin::TxOnly; |
| 78 | sm.set_fifo_join(FifoJoin::TxOnly); | 65 | cfg.shift_out = ShiftConfig { |
| 79 | sm.set_pull_threshold(24); | 66 | auto_fill: true, |
| 80 | sm.set_out_shift_dir(ShiftDirection::Left); | 67 | threshold: 24, |
| 81 | 68 | direction: ShiftDirection::Left, | |
| 69 | }; | ||
| 70 | |||
| 71 | sm.set_config(&cfg); | ||
| 82 | sm.set_enable(true); | 72 | sm.set_enable(true); |
| 83 | 73 | ||
| 84 | Self { sm } | 74 | Self { sm } |
