aboutsummaryrefslogtreecommitdiff
path: root/examples
diff options
context:
space:
mode:
authorpennae <[email protected]>2023-04-25 20:40:18 +0200
committerpennae <[email protected]>2023-05-01 12:58:57 +0200
commitf4ade6af8bb2571ce2de0531d9c9715a7b8b941c (patch)
tree08ae76de328feabf6406e6ad7f79b7d23bbe035e /examples
parentfa1ec29ae61df78a74be4bffb47f400fa35e49f1 (diff)
rp/pio: write instr memory only from common
instruction memory is a shared resource. writing it only from PioCommon clarifies this, and perhaps makes it more obvious that multiple state machines can share the same instructions. this also allows *freeing* of instruction memory to reprogram the system, although this interface is not entirely safe yet. it's safe in the sense rusts understands things, but state machines may misbehave if their instruction memory is freed and rewritten while they are running. fixing this is out of scope for now since it requires some larger changes to how state machines are handled. the interface provided currently is already unsafe in that it lets people execute instruction memory that has never been written, so this isn't much of a drawback for now.
Diffstat (limited to 'examples')
-rw-r--r--examples/rp/src/bin/pio_async.rs28
-rw-r--r--examples/rp/src/bin/pio_dma.rs6
-rw-r--r--examples/rp/src/bin/ws2812-pio.rs4
3 files changed, 23 insertions, 15 deletions
diff --git a/examples/rp/src/bin/pio_async.rs b/examples/rp/src/bin/pio_async.rs
index 3cfeec71f..1b075b8fd 100644
--- a/examples/rp/src/bin/pio_async.rs
+++ b/examples/rp/src/bin/pio_async.rs
@@ -28,7 +28,7 @@ fn setup_pio_task_sm0(pio: &mut PioCommonInstance<Pio0>, sm: &mut PioStateMachin
28 let out_pin = pio.make_pio_pin(pin); 28 let out_pin = pio.make_pio_pin(pin);
29 let pio_pins = [&out_pin]; 29 let pio_pins = [&out_pin];
30 sm.set_out_pins(&pio_pins); 30 sm.set_out_pins(&pio_pins);
31 sm.write_instr(relocated.origin() as usize, relocated.code()); 31 pio.write_instr(relocated.origin() as usize, relocated.code());
32 pio_instr_util::exec_jmp(sm, relocated.origin()); 32 pio_instr_util::exec_jmp(sm, relocated.origin());
33 sm.set_clkdiv((125e6 / 20.0 / 2e2 * 256.0) as u32); 33 sm.set_clkdiv((125e6 / 20.0 / 2e2 * 256.0) as u32);
34 sm.set_set_range(0, 1); 34 sm.set_set_range(0, 1);
@@ -51,16 +51,15 @@ async fn pio_task_sm0(mut sm: PioStateMachineInstance<Pio0, Sm0>) {
51 } 51 }
52} 52}
53 53
54#[embassy_executor::task] 54fn setup_pio_task_sm1(pio: &mut PioCommonInstance<Pio0>, sm: &mut PioStateMachineInstance<Pio0, Sm1>) {
55async fn pio_task_sm1(mut sm: PioStateMachineInstance<Pio0, Sm1>) {
56 // Setupm sm1 55 // Setupm sm1
57 56
58 // Read 0b10101 repeatedly until ISR is full 57 // Read 0b10101 repeatedly until ISR is full
59 let prg = pio_proc::pio_asm!(".origin 8", "set x, 0x15", ".wrap_target", "in x, 5 [31]", ".wrap",); 58 let prg = pio_proc::pio_asm!(".origin 8", "set x, 0x15", ".wrap_target", "in x, 5 [31]", ".wrap",);
60 59
61 let relocated = RelocatedProgram::new(&prg.program); 60 let relocated = RelocatedProgram::new(&prg.program);
62 sm.write_instr(relocated.origin() as usize, relocated.code()); 61 pio.write_instr(relocated.origin() as usize, relocated.code());
63 pio_instr_util::exec_jmp(&mut sm, relocated.origin()); 62 pio_instr_util::exec_jmp(sm, relocated.origin());
64 sm.set_clkdiv((125e6 / 2e3 * 256.0) as u32); 63 sm.set_clkdiv((125e6 / 2e3 * 256.0) as u32);
65 sm.set_set_range(0, 0); 64 sm.set_set_range(0, 0);
66 let pio::Wrap { source, target } = relocated.wrap(); 65 let pio::Wrap { source, target } = relocated.wrap();
@@ -68,6 +67,10 @@ async fn pio_task_sm1(mut sm: PioStateMachineInstance<Pio0, Sm1>) {
68 67
69 sm.set_autopush(true); 68 sm.set_autopush(true);
70 sm.set_in_shift_dir(ShiftDirection::Right); 69 sm.set_in_shift_dir(ShiftDirection::Right);
70}
71
72#[embassy_executor::task]
73async fn pio_task_sm1(mut sm: PioStateMachineInstance<Pio0, Sm1>) {
71 sm.set_enable(true); 74 sm.set_enable(true);
72 loop { 75 loop {
73 let rx = sm.wait_pull().await; 76 let rx = sm.wait_pull().await;
@@ -75,8 +78,7 @@ async fn pio_task_sm1(mut sm: PioStateMachineInstance<Pio0, Sm1>) {
75 } 78 }
76} 79}
77 80
78#[embassy_executor::task] 81fn setup_pio_task_sm2(pio: &mut PioCommonInstance<Pio0>, sm: &mut PioStateMachineInstance<Pio0, Sm2>) {
79async fn pio_task_sm2(mut sm: PioStateMachineInstance<Pio0, Sm2>) {
80 // Setup sm2 82 // Setup sm2
81 83
82 // Repeatedly trigger IRQ 3 84 // Repeatedly trigger IRQ 3
@@ -90,13 +92,17 @@ async fn pio_task_sm2(mut sm: PioStateMachineInstance<Pio0, Sm2>) {
90 ".wrap", 92 ".wrap",
91 ); 93 );
92 let relocated = RelocatedProgram::new(&prg.program); 94 let relocated = RelocatedProgram::new(&prg.program);
93 sm.write_instr(relocated.origin() as usize, relocated.code()); 95 pio.write_instr(relocated.origin() as usize, relocated.code());
94 96
95 let pio::Wrap { source, target } = relocated.wrap(); 97 let pio::Wrap { source, target } = relocated.wrap();
96 sm.set_wrap(source, target); 98 sm.set_wrap(source, target);
97 99
98 pio_instr_util::exec_jmp(&mut sm, relocated.origin()); 100 pio_instr_util::exec_jmp(sm, relocated.origin());
99 sm.set_clkdiv((125e6 / 2e3 * 256.0) as u32); 101 sm.set_clkdiv((125e6 / 2e3 * 256.0) as u32);
102}
103
104#[embassy_executor::task]
105async fn pio_task_sm2(mut sm: PioStateMachineInstance<Pio0, Sm2>) {
100 sm.set_enable(true); 106 sm.set_enable(true);
101 loop { 107 loop {
102 sm.wait_irq(3).await; 108 sm.wait_irq(3).await;
@@ -109,9 +115,11 @@ async fn main(spawner: Spawner) {
109 let p = embassy_rp::init(Default::default()); 115 let p = embassy_rp::init(Default::default());
110 let pio = p.PIO0; 116 let pio = p.PIO0;
111 117
112 let (mut pio0, mut sm0, sm1, sm2, ..) = pio.split(); 118 let (mut pio0, mut sm0, mut sm1, mut sm2, ..) = pio.split();
113 119
114 setup_pio_task_sm0(&mut pio0, &mut sm0, p.PIN_0.degrade()); 120 setup_pio_task_sm0(&mut pio0, &mut sm0, p.PIN_0.degrade());
121 setup_pio_task_sm1(&mut pio0, &mut sm1);
122 setup_pio_task_sm2(&mut pio0, &mut sm2);
115 spawner.spawn(pio_task_sm0(sm0)).unwrap(); 123 spawner.spawn(pio_task_sm0(sm0)).unwrap();
116 spawner.spawn(pio_task_sm1(sm1)).unwrap(); 124 spawner.spawn(pio_task_sm1(sm1)).unwrap();
117 spawner.spawn(pio_task_sm2(sm2)).unwrap(); 125 spawner.spawn(pio_task_sm2(sm2)).unwrap();
diff --git a/examples/rp/src/bin/pio_dma.rs b/examples/rp/src/bin/pio_dma.rs
index 145e4a656..7d4919f75 100644
--- a/examples/rp/src/bin/pio_dma.rs
+++ b/examples/rp/src/bin/pio_dma.rs
@@ -4,7 +4,7 @@
4use defmt::info; 4use defmt::info;
5use embassy_executor::Spawner; 5use embassy_executor::Spawner;
6use embassy_futures::join::join; 6use embassy_futures::join::join;
7use embassy_rp::pio::{PioPeripheral, PioStateMachine, ShiftDirection}; 7use embassy_rp::pio::{PioCommon, PioPeripheral, PioStateMachine, ShiftDirection};
8use embassy_rp::relocate::RelocatedProgram; 8use embassy_rp::relocate::RelocatedProgram;
9use embassy_rp::{pio_instr_util, Peripheral}; 9use embassy_rp::{pio_instr_util, Peripheral};
10use {defmt_rtt as _, panic_probe as _}; 10use {defmt_rtt as _, panic_probe as _};
@@ -19,7 +19,7 @@ fn swap_nibbles(v: u32) -> u32 {
19async fn main(_spawner: Spawner) { 19async fn main(_spawner: Spawner) {
20 let p = embassy_rp::init(Default::default()); 20 let p = embassy_rp::init(Default::default());
21 let pio = p.PIO0; 21 let pio = p.PIO0;
22 let (_, mut sm, ..) = pio.split(); 22 let (mut pio0, mut sm, ..) = pio.split();
23 23
24 let prg = pio_proc::pio_asm!( 24 let prg = pio_proc::pio_asm!(
25 ".origin 0", 25 ".origin 0",
@@ -34,7 +34,7 @@ async fn main(_spawner: Spawner) {
34 ); 34 );
35 35
36 let relocated = RelocatedProgram::new(&prg.program); 36 let relocated = RelocatedProgram::new(&prg.program);
37 sm.write_instr(relocated.origin() as usize, relocated.code()); 37 pio0.write_instr(relocated.origin() as usize, relocated.code());
38 pio_instr_util::exec_jmp(&mut sm, relocated.origin()); 38 pio_instr_util::exec_jmp(&mut sm, relocated.origin());
39 sm.set_clkdiv((125e6 / 10e3 * 256.0) as u32); 39 sm.set_clkdiv((125e6 / 10e3 * 256.0) as u32);
40 let pio::Wrap { source, target } = relocated.wrap(); 40 let pio::Wrap { source, target } = relocated.wrap();
diff --git a/examples/rp/src/bin/ws2812-pio.rs b/examples/rp/src/bin/ws2812-pio.rs
index 211c60c49..041e8ae11 100644
--- a/examples/rp/src/bin/ws2812-pio.rs
+++ b/examples/rp/src/bin/ws2812-pio.rs
@@ -19,7 +19,7 @@ pub struct Ws2812<P: PioInstance, S: SmInstance> {
19} 19}
20 20
21impl<P: PioInstance, S: SmInstance> Ws2812<P, S> { 21impl<P: PioInstance, S: SmInstance> Ws2812<P, S> {
22 pub fn new(pio: PioCommonInstance<P>, mut sm: PioStateMachineInstance<P, S>, pin: gpio::AnyPin) -> Self { 22 pub fn new(mut pio: PioCommonInstance<P>, mut sm: PioStateMachineInstance<P, S>, pin: gpio::AnyPin) -> Self {
23 // Setup sm0 23 // Setup sm0
24 24
25 // prepare the PIO program 25 // prepare the PIO program
@@ -50,7 +50,7 @@ impl<P: PioInstance, S: SmInstance> Ws2812<P, S> {
50 let prg = a.assemble_with_wrap(wrap_source, wrap_target); 50 let prg = a.assemble_with_wrap(wrap_source, wrap_target);
51 51
52 let relocated = RelocatedProgram::new(&prg); 52 let relocated = RelocatedProgram::new(&prg);
53 sm.write_instr(relocated.origin() as usize, relocated.code()); 53 pio.write_instr(relocated.origin() as usize, relocated.code());
54 pio_instr_util::exec_jmp(&mut sm, relocated.origin()); 54 pio_instr_util::exec_jmp(&mut sm, relocated.origin());
55 55
56 // Pin config 56 // Pin config