aboutsummaryrefslogtreecommitdiff
path: root/examples
diff options
context:
space:
mode:
authorbors[bot] <26634292+bors[bot]@users.noreply.github.com>2023-05-08 09:17:51 +0000
committerGitHub <[email protected]>2023-05-08 09:17:51 +0000
commit79c60f4a7d17613269f795df867c3c83ca90cbcc (patch)
tree34d841fd742d6b3e7fa4919a9bd60f5bc67e0afb /examples
parenta9c7263ba02181fc4d54975a63d8a1e92426dff3 (diff)
parentdb9b8eb88f095687ed624171cf79fbacf06c199a (diff)
Merge #1434
1434: rp pio IV (the voyage home) r=Dirbaio a=pennae this should hopefully be the last entry in this series. after this we'll have a reasonably safe interface to pio, both for configuration and at runtime. pio now looks very much like the other peripherals (though not exactly, seeing how state machines can't be constructed from a config but only have it applied to them later). the generated code for `StateMachine::set_config` is still larger than we'd like (almost 300 bytes at Oz), but it's a great step up in safety from the previous interface at approximately the same code space cost. Co-authored-by: pennae <[email protected]>
Diffstat (limited to 'examples')
-rw-r--r--examples/rp/Cargo.toml2
-rw-r--r--examples/rp/src/bin/pio_async.rs62
-rw-r--r--examples/rp/src/bin/pio_dma.rs32
-rw-r--r--examples/rp/src/bin/pio_hd44780.rs66
-rw-r--r--examples/rp/src/bin/ws2812-pio.rs58
5 files changed, 100 insertions, 120 deletions
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
22 22
23defmt = "0.3" 23defmt = "0.3"
24defmt-rtt = "0.4" 24defmt-rtt = "0.4"
25fixed = "1.23.1"
26fixed-macro = "1.2"
25 27
26#cortex-m = { version = "0.7.6", features = ["critical-section-single-core"] } 28#cortex-m = { version = "0.7.6", features = ["critical-section-single-core"] }
27cortex-m = { version = "0.7.6", features = ["inline-asm"] } 29cortex-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 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)]
4use defmt::info; 4use defmt::info;
5use embassy_embedded_hal::SetConfig;
5use embassy_executor::Spawner; 6use embassy_executor::Spawner;
6use embassy_rp::peripherals::PIO0; 7use embassy_rp::peripherals::PIO0;
7use embassy_rp::pio::{Pio, PioCommon, PioIrq, PioPin, PioStateMachine, ShiftDirection}; 8use embassy_rp::pio::{Common, Config, Irq, Pio, PioPin, ShiftDirection, StateMachine};
8use embassy_rp::pio_instr_util;
9use embassy_rp::relocate::RelocatedProgram; 9use embassy_rp::relocate::RelocatedProgram;
10use fixed::traits::ToFixed;
11use fixed_macro::types::U56F8;
10use {defmt_rtt as _, panic_probe as _}; 12use {defmt_rtt as _, panic_probe as _};
11 13
12fn setup_pio_task_sm0(pio: &mut PioCommon<PIO0>, sm: &mut PioStateMachine<PIO0, 0>, pin: impl PioPin) { 14fn 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]
40async fn pio_task_sm0(mut sm: PioStateMachine<'static, PIO0, 0>) { 38async 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
51fn setup_pio_task_sm1(pio: &mut PioCommon<PIO0>, sm: &mut PioStateMachine<PIO0, 1>) { 49fn 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]
70async fn pio_task_sm1(mut sm: PioStateMachine<'static, PIO0, 1>) { 65async 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
78fn setup_pio_task_sm2(pio: &mut PioCommon<PIO0>, sm: &mut PioStateMachine<PIO0, 2>) { 73fn 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]
102async fn pio_task_sm2(mut irq: PioIrq<'static, PIO0, 3>, mut sm: PioStateMachine<'static, PIO0, 2>) { 94async 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)]
4use defmt::info; 4use defmt::info;
5use embassy_embedded_hal::SetConfig;
5use embassy_executor::Spawner; 6use embassy_executor::Spawner;
6use embassy_futures::join::join; 7use embassy_futures::join::join;
7use embassy_rp::pio::{Pio, ShiftDirection}; 8use embassy_rp::pio::{Config, Pio, ShiftConfig, ShiftDirection};
8use embassy_rp::relocate::RelocatedProgram; 9use embassy_rp::relocate::RelocatedProgram;
9use embassy_rp::{pio_instr_util, Peripheral}; 10use embassy_rp::Peripheral;
11use fixed::traits::ToFixed;
12use fixed_macro::types::U56F8;
10use {defmt_rtt as _, panic_probe as _}; 13use {defmt_rtt as _, panic_probe as _};
11 14
12fn swap_nibbles(v: u32) -> u32 { 15fn 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
5use core::fmt::Write; 5use core::fmt::Write;
6 6
7use embassy_embedded_hal::SetConfig;
7use embassy_executor::Spawner; 8use embassy_executor::Spawner;
8use embassy_rp::dma::{AnyChannel, Channel}; 9use embassy_rp::dma::{AnyChannel, Channel};
9use embassy_rp::peripherals::PIO0; 10use embassy_rp::peripherals::PIO0;
10use embassy_rp::pio::{FifoJoin, Pio, PioPin, PioStateMachine, ShiftDirection}; 11use embassy_rp::pio::{Config, Direction, FifoJoin, Pio, PioPin, ShiftConfig, ShiftDirection, StateMachine};
11use embassy_rp::pwm::{Config, Pwm}; 12use embassy_rp::pwm::{self, Pwm};
12use embassy_rp::relocate::RelocatedProgram; 13use embassy_rp::relocate::RelocatedProgram;
13use embassy_rp::{into_ref, Peripheral, PeripheralRef}; 14use embassy_rp::{into_ref, Peripheral, PeripheralRef};
14use embassy_time::{Duration, Instant, Timer}; 15use 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
65pub struct HD44780<'l> { 66pub 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
5use defmt::*; 5use defmt::*;
6use embassy_embedded_hal::SetConfig;
6use embassy_executor::Spawner; 7use embassy_executor::Spawner;
7use embassy_rp::pio::{FifoJoin, Pio, PioCommon, PioInstance, PioPin, PioStateMachine, ShiftDirection}; 8use embassy_rp::pio::{Common, Config, FifoJoin, Instance, Pio, PioPin, ShiftConfig, ShiftDirection, StateMachine};
8use embassy_rp::pio_instr_util;
9use embassy_rp::relocate::RelocatedProgram; 9use embassy_rp::relocate::RelocatedProgram;
10use embassy_time::{Duration, Timer}; 10use embassy_time::{Duration, Timer};
11use fixed_macro::fixed;
11use smart_leds::RGB8; 12use smart_leds::RGB8;
12use {defmt_rtt as _, panic_probe as _}; 13use {defmt_rtt as _, panic_probe as _};
13pub struct Ws2812<'d, P: PioInstance, const S: usize> { 14pub struct Ws2812<'d, P: Instance, const S: usize> {
14 sm: PioStateMachine<'d, P, S>, 15 sm: StateMachine<'d, P, S>,
15} 16}
16 17
17impl<'d, P: PioInstance, const S: usize> Ws2812<'d, P, S> { 18impl<'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 }