aboutsummaryrefslogtreecommitdiff
path: root/examples
diff options
context:
space:
mode:
authorpennae <[email protected]>2023-05-06 11:36:07 +0200
committerpennae <[email protected]>2023-05-06 17:23:41 +0200
commit8e4d65e163bd484efc4fb31d20b14e6ac4a88de7 (patch)
tree0d1623f5b7711993ee549041881601193e782984 /examples
parent2873cb93ee3111d984c35287ea9d98f1218d1024 (diff)
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.
Diffstat (limited to 'examples')
-rw-r--r--examples/rp/Cargo.toml2
-rw-r--r--examples/rp/src/bin/pio_async.rs37
-rw-r--r--examples/rp/src/bin/pio_dma.rs27
-rw-r--r--examples/rp/src/bin/pio_hd44780.rs42
-rw-r--r--examples/rp/src/bin/ws2812-pio.rs39
5 files changed, 83 insertions, 64 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 9f47c2316..12484e882 100644
--- a/examples/rp/src/bin/pio_async.rs
+++ b/examples/rp/src/bin/pio_async.rs
@@ -2,10 +2,13 @@
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::{Common, Irq, Pio, PioPin, ShiftDirection, StateMachine}; 8use embassy_rp::pio::{Common, Config, Irq, Pio, PioPin, ShiftDirection, StateMachine};
8use embassy_rp::relocate::RelocatedProgram; 9use embassy_rp::relocate::RelocatedProgram;
10use fixed::traits::ToFixed;
11use fixed_macro::types::U56F8;
9use {defmt_rtt as _, panic_probe as _}; 12use {defmt_rtt as _, panic_probe as _};
10 13
11fn setup_pio_task_sm0<'a>(pio: &mut Common<'a, PIO0>, sm: &mut StateMachine<'a, 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) {
@@ -21,15 +24,14 @@ fn setup_pio_task_sm0<'a>(pio: &mut Common<'a, PIO0>, sm: &mut StateMachine<'a,
21 ); 24 );
22 25
23 let relocated = RelocatedProgram::new(&prg.program); 26 let relocated = RelocatedProgram::new(&prg.program);
24 sm.use_program(&pio.load_program(&relocated), &[]); 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 sm.set_clkdiv((125e6 / 20.0 / 2e2 * 256.0) as u32); 32 cfg.clock_divider = (U56F8!(125_000_000) / 20 / 200).to_fixed();
29 sm.set_set_range(0, 1); 33 cfg.shift_out.auto_fill = true;
30 34 sm.set_config(&cfg);
31 sm.set_autopull(true);
32 sm.set_out_shift_dir(ShiftDirection::Left);
33} 35}
34 36
35#[embassy_executor::task] 37#[embassy_executor::task]
@@ -51,11 +53,12 @@ fn setup_pio_task_sm1<'a>(pio: &mut Common<'a, PIO0>, sm: &mut StateMachine<'a,
51 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",);
52 54
53 let relocated = RelocatedProgram::new(&prg.program); 55 let relocated = RelocatedProgram::new(&prg.program);
54 sm.use_program(&pio.load_program(&relocated), &[]); 56 let mut cfg = Config::default();
55 sm.set_clkdiv((125e6 / 2e3 * 256.0) as u32); 57 cfg.use_program(&pio.load_program(&relocated), &[]);
56 sm.set_set_range(0, 0); 58 cfg.clock_divider = (U56F8!(125_000_000) / 2000).to_fixed();
57 sm.set_autopush(true); 59 cfg.shift_in.auto_fill = true;
58 sm.set_in_shift_dir(ShiftDirection::Right); 60 cfg.shift_in.direction = ShiftDirection::Right;
61 sm.set_config(&cfg);
59} 62}
60 63
61#[embassy_executor::task] 64#[embassy_executor::task]
@@ -81,8 +84,10 @@ fn setup_pio_task_sm2<'a>(pio: &mut Common<'a, PIO0>, sm: &mut StateMachine<'a,
81 ".wrap", 84 ".wrap",
82 ); 85 );
83 let relocated = RelocatedProgram::new(&prg.program); 86 let relocated = RelocatedProgram::new(&prg.program);
84 sm.use_program(&pio.load_program(&relocated), &[]); 87 let mut cfg = Config::default();
85 sm.set_clkdiv((125e6 / 2e3 * 256.0) as u32); 88 cfg.use_program(&pio.load_program(&relocated), &[]);
89 cfg.clock_divider = (U56F8!(125_000_000) / 2000).to_fixed();
90 sm.set_config(&cfg);
86} 91}
87 92
88#[embassy_executor::task] 93#[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 @@
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::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,15 +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 sm.use_program(&common.load_program(&relocated), &[]); 44 let mut cfg = Config::default();
42 sm.set_clkdiv((125e6 / 10e3 * 256.0) as u32); 45 cfg.use_program(&common.load_program(&relocated), &[]);
43 sm.set_autopull(true); 46 cfg.clock_divider = (U56F8!(125_000_000) / U56F8!(10_000)).to_fixed();
44 sm.set_autopush(true); 47 cfg.shift_in = ShiftConfig {
45 sm.set_pull_threshold(32); 48 auto_fill: true,
46 sm.set_push_threshold(32); 49 threshold: 32,
47 sm.set_out_shift_dir(ShiftDirection::Right); 50 direction: ShiftDirection::Left,
48 sm.set_in_shift_dir(ShiftDirection::Left); 51 };
52 cfg.shift_out = ShiftConfig {
53 auto_fill: true,
54 threshold: 32,
55 direction: ShiftDirection::Right,
56 };
49 57
58 sm.set_config(&cfg);
50 sm.set_enable(true); 59 sm.set_enable(true);
51 60
52 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 40dee1c4d..61c5565d3 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::{Direction, FifoJoin, Pio, PioPin, ShiftDirection, StateMachine}; 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;
@@ -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,
@@ -118,13 +118,17 @@ impl<'l> HD44780<'l> {
118 sm0.set_pin_dirs(Direction::Out, &[&rs, &rw, &e, &db4, &db5, &db6, &db7]); 118 sm0.set_pin_dirs(Direction::Out, &[&rs, &rw, &e, &db4, &db5, &db6, &db7]);
119 119
120 let relocated = RelocatedProgram::new(&prg.program); 120 let relocated = RelocatedProgram::new(&prg.program);
121 sm0.use_program(&common.load_program(&relocated), &[&e]); 121 let mut cfg = Config::default();
122 sm0.set_clkdiv(125 * 256); 122 cfg.use_program(&common.load_program(&relocated), &[&e]);
123 sm0.set_out_pins(&[&db4, &db5, &db6, &db7]); 123 cfg.clock_divider = 125u8.into();
124 sm0.set_out_shift_dir(ShiftDirection::Left); 124 cfg.set_out_pins(&[&db4, &db5, &db6, &db7]);
125 sm0.set_fifo_join(FifoJoin::TxOnly); 125 cfg.shift_out = ShiftConfig {
126 sm0.set_autopull(true); 126 auto_fill: true,
127 sm0.set_pull_threshold(32); 127 direction: ShiftDirection::Left,
128 threshold: 32,
129 };
130 cfg.fifo_join = FifoJoin::TxOnly;
131 sm0.set_config(&cfg);
128 132
129 sm0.set_enable(true); 133 sm0.set_enable(true);
130 // init to 8 bit thrice 134 // init to 8 bit thrice
@@ -188,13 +192,15 @@ impl<'l> HD44780<'l> {
188 ); 192 );
189 193
190 let relocated = RelocatedProgram::new(&prg.program); 194 let relocated = RelocatedProgram::new(&prg.program);
191 sm0.use_program(&common.load_program(&relocated), &[&e]); 195 let mut cfg = Config::default();
192 sm0.set_clkdiv(8 * 256); // ~64ns/insn 196 cfg.use_program(&common.load_program(&relocated), &[&e]);
193 sm0.set_jmp_pin(db7pin); 197 cfg.clock_divider = 8u8.into(); // ~64ns/insn
194 sm0.set_set_pins(&[&rs, &rw]); 198 cfg.set_jmp_pin(&db7);
195 sm0.set_out_pins(&[&db4, &db5, &db6, &db7]); 199 cfg.set_set_pins(&[&rs, &rw]);
196 sm0.set_out_shift_dir(ShiftDirection::Left); 200 cfg.set_out_pins(&[&db4, &db5, &db6, &db7]);
197 sm0.set_fifo_join(FifoJoin::TxOnly); 201 cfg.shift_out.direction = ShiftDirection::Left;
202 cfg.fifo_join = FifoJoin::TxOnly;
203 sm0.set_config(&cfg);
198 204
199 sm0.set_enable(true); 205 sm0.set_enable(true);
200 206
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 @@
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::{Common, FifoJoin, Instance, Pio, PioPin, ShiftDirection, StateMachine}; 8use embassy_rp::pio::{Common, Config, FifoJoin, Instance, Pio, PioPin, ShiftConfig, ShiftDirection, StateMachine};
8use embassy_rp::relocate::RelocatedProgram; 9use embassy_rp::relocate::RelocatedProgram;
9use embassy_time::{Duration, Timer}; 10use embassy_time::{Duration, Timer};
11use fixed_macro::fixed;
10use smart_leds::RGB8; 12use smart_leds::RGB8;
11use {defmt_rtt as _, panic_probe as _}; 13use {defmt_rtt as _, panic_probe as _};
12pub struct Ws2812<'d, P: Instance, const S: usize> { 14pub struct Ws2812<'d, P: Instance, const S: usize> {
@@ -43,35 +45,30 @@ impl<'d, P: Instance, const S: usize> Ws2812<'d, P, S> {
43 a.bind(&mut wrap_source); 45 a.bind(&mut wrap_source);
44 46
45 let prg = a.assemble_with_wrap(wrap_source, wrap_target); 47 let prg = a.assemble_with_wrap(wrap_source, wrap_target);
48 let mut cfg = Config::default();
46 49
47 // Pin config 50 // Pin config
48 let out_pin = pio.make_pio_pin(pin); 51 let out_pin = pio.make_pio_pin(pin);
49 52
50 let relocated = RelocatedProgram::new(&prg); 53 let relocated = RelocatedProgram::new(&prg);
51 sm.use_program(&pio.load_program(&relocated), &[&out_pin]); 54 cfg.use_program(&pio.load_program(&relocated), &[&out_pin]);
52 55
53 // Clock config 56 // Clock config, measured in kHz to avoid overflows
54 // TODO CLOCK_FREQ should come from embassy_rp 57 // TODO CLOCK_FREQ should come from embassy_rp
55 const CLOCK_FREQ: u32 = 125_000_000; 58 let clock_freq = fixed!(125_000: U24F8);
56 const WS2812_FREQ: u32 = 800_000; 59 let ws2812_freq = fixed!(800: U24F8);
57 60 let bit_freq = ws2812_freq * CYCLES_PER_BIT;
58 let bit_freq = WS2812_FREQ * CYCLES_PER_BIT; 61 cfg.clock_divider = clock_freq / bit_freq;
59 let mut int = CLOCK_FREQ / bit_freq;
60 let rem = CLOCK_FREQ - (int * bit_freq);
61 let frac = (rem * 256) / bit_freq;
62 // 65536.0 is represented as 0 in the pio's clock divider
63 if int == 65536 {
64 int = 0;
65 }
66
67 sm.set_clkdiv((int << 8) | frac);
68 62
69 // FIFO config 63 // FIFO config
70 sm.set_autopull(true); 64 cfg.fifo_join = FifoJoin::TxOnly;
71 sm.set_fifo_join(FifoJoin::TxOnly); 65 cfg.shift_out = ShiftConfig {
72 sm.set_pull_threshold(24); 66 auto_fill: true,
73 sm.set_out_shift_dir(ShiftDirection::Left); 67 threshold: 24,
74 68 direction: ShiftDirection::Left,
69 };
70
71 sm.set_config(&cfg);
75 sm.set_enable(true); 72 sm.set_enable(true);
76 73
77 Self { sm } 74 Self { sm }