aboutsummaryrefslogtreecommitdiff
path: root/examples
diff options
context:
space:
mode:
authorkbleeke <[email protected]>2023-03-27 18:04:48 +0200
committerkbleeke <[email protected]>2023-03-27 19:00:20 +0200
commit20ea35fc9639487eaa21f1dcee6c32d8a66a0fbb (patch)
tree20b44e30e4bce17d3c5c6cc342c0888bf60c3bbe /examples
parentd918919cb20a3b8139013638193c22b3744b0f1d (diff)
Move pio driver to separate crate
Diffstat (limited to 'examples')
-rw-r--r--examples/rpi-pico-w/Cargo.toml3
-rw-r--r--examples/rpi-pico-w/src/main.rs5
-rw-r--r--examples/rpi-pico-w/src/pio.rs179
3 files changed, 2 insertions, 185 deletions
diff --git a/examples/rpi-pico-w/Cargo.toml b/examples/rpi-pico-w/Cargo.toml
index 4a531c88c..41ee8a3c4 100644
--- a/examples/rpi-pico-w/Cargo.toml
+++ b/examples/rpi-pico-w/Cargo.toml
@@ -6,6 +6,7 @@ edition = "2021"
6 6
7[dependencies] 7[dependencies]
8cyw43 = { path = "../../", features = ["defmt", "firmware-logs"] } 8cyw43 = { path = "../../", features = ["defmt", "firmware-logs"] }
9cyw43-pio = { path = "../../cyw43-pio" }
9embassy-executor = { version = "0.1.0", features = ["defmt", "integrated-timers"] } 10embassy-executor = { version = "0.1.0", features = ["defmt", "integrated-timers"] }
10embassy-time = { version = "0.1.0", features = ["defmt", "defmt-timestamp-uptime"] } 11embassy-time = { version = "0.1.0", features = ["defmt", "defmt-timestamp-uptime"] }
11embassy-rp = { version = "0.1.0", features = ["defmt", "unstable-traits", "nightly", "unstable-pac", "time-driver", "pio"] } 12embassy-rp = { version = "0.1.0", features = ["defmt", "unstable-traits", "nightly", "unstable-pac", "time-driver", "pio"] }
@@ -20,8 +21,6 @@ panic-probe = { version = "0.3", features = ["print-defmt"] }
20cortex-m = { version = "0.7.6", features = ["critical-section-single-core"] } 21cortex-m = { version = "0.7.6", features = ["critical-section-single-core"] }
21cortex-m-rt = "0.7.0" 22cortex-m-rt = "0.7.0"
22futures = { version = "0.3.17", default-features = false, features = ["async-await", "cfg-target-has-atomic", "unstable"] } 23futures = { version = "0.3.17", default-features = false, features = ["async-await", "cfg-target-has-atomic", "unstable"] }
23pio-proc = "0.2"
24pio = "0.2.1"
25 24
26embedded-io = { version = "0.4.0", features = ["async", "defmt"] } 25embedded-io = { version = "0.4.0", features = ["async", "defmt"] }
27heapless = "0.7.15" 26heapless = "0.7.15"
diff --git a/examples/rpi-pico-w/src/main.rs b/examples/rpi-pico-w/src/main.rs
index e3c59223b..4b1623be7 100644
--- a/examples/rpi-pico-w/src/main.rs
+++ b/examples/rpi-pico-w/src/main.rs
@@ -4,11 +4,10 @@
4#![feature(async_fn_in_trait)] 4#![feature(async_fn_in_trait)]
5#![allow(incomplete_features)] 5#![allow(incomplete_features)]
6 6
7mod pio;
8
9use core::slice; 7use core::slice;
10use core::str::from_utf8; 8use core::str::from_utf8;
11 9
10use cyw43_pio::PioSpi;
12use defmt::*; 11use defmt::*;
13use embassy_executor::Spawner; 12use embassy_executor::Spawner;
14use embassy_net::tcp::TcpSocket; 13use embassy_net::tcp::TcpSocket;
@@ -20,8 +19,6 @@ use embedded_io::asynch::Write;
20use static_cell::StaticCell; 19use static_cell::StaticCell;
21use {defmt_rtt as _, panic_probe as _}; 20use {defmt_rtt as _, panic_probe as _};
22 21
23use crate::pio::PioSpi;
24
25macro_rules! singleton { 22macro_rules! singleton {
26 ($val:expr) => {{ 23 ($val:expr) => {{
27 type T = impl Sized; 24 type T = impl Sized;
diff --git a/examples/rpi-pico-w/src/pio.rs b/examples/rpi-pico-w/src/pio.rs
deleted file mode 100644
index 846113060..000000000
--- a/examples/rpi-pico-w/src/pio.rs
+++ /dev/null
@@ -1,179 +0,0 @@
1use core::slice;
2
3use cyw43::SpiBusCyw43;
4use embassy_rp::dma::Channel;
5use embassy_rp::gpio::{Drive, Output, Pin, Pull, SlewRate};
6use embassy_rp::pio::{PioStateMachine, ShiftDirection};
7use embassy_rp::relocate::RelocatedProgram;
8use embassy_rp::{pio_instr_util, Peripheral};
9use pio::Wrap;
10use pio_proc::pio_asm;
11
12pub struct PioSpi<CS: Pin, SM, DMA> {
13 cs: Output<'static, CS>,
14 sm: SM,
15 dma: DMA,
16 wrap_target: u8,
17}
18
19impl<CS, SM, DMA> PioSpi<CS, SM, DMA>
20where
21 SM: PioStateMachine,
22 DMA: Channel,
23 CS: Pin,
24{
25 pub fn new<DIO, CLK>(mut sm: SM, cs: Output<'static, CS>, dio: DIO, clk: CLK, dma: DMA) -> Self
26 where
27 DIO: Pin,
28 CLK: Pin,
29 {
30 let program = pio_asm!(
31 ".side_set 1"
32 // "set pindirs, 1 side 0"
33 // "set pins, 0 side 0"
34 ".wrap_target"
35 "lp:",
36 "out pins, 1 side 0"
37 "jmp x-- lp side 1"
38 "set pindirs, 0 side 0"
39 "nop side 1"
40 "lp2:"
41 "in pins, 1 side 1"
42 "jmp y-- lp2 side 0"
43
44 "wait 1 pin 0 side 0"
45 "irq 0 side 0"
46
47 ".wrap"
48 );
49
50 let relocated = RelocatedProgram::new(&program.program);
51
52 let mut pin_io = sm.make_pio_pin(dio);
53 pin_io.set_pull(Pull::Down);
54 pin_io.set_schmitt(true);
55 pin_io.set_input_sync_bypass(true);
56
57 let mut pin_clk = sm.make_pio_pin(clk);
58 pin_clk.set_drive_strength(Drive::_12mA);
59 pin_clk.set_slew_rate(SlewRate::Fast);
60
61 sm.write_instr(relocated.origin() as usize, relocated.code());
62
63 // 32 Mhz
64 sm.set_clkdiv(0x03E8);
65
66 // 16 Mhz
67 // sm.set_clkdiv(0x07d0);
68
69 // 8Mhz
70 // sm.set_clkdiv(0x0a_00);
71
72 // 1Mhz
73 // sm.set_clkdiv(0x7d_00);
74
75 // slowest possible
76 // sm.set_clkdiv(0xffff_00);
77
78 sm.set_autopull(true);
79 // sm.set_pull_threshold(32);
80 sm.set_autopush(true);
81 // sm.set_push_threshold(32);
82
83 sm.set_out_pins(&[&pin_io]);
84 sm.set_in_base_pin(&pin_io);
85
86 sm.set_set_pins(&[&pin_clk]);
87 pio_instr_util::set_pindir(&mut sm, 0b1);
88 sm.set_set_pins(&[&pin_io]);
89 pio_instr_util::set_pindir(&mut sm, 0b1);
90
91 sm.set_sideset_base_pin(&pin_clk);
92 sm.set_sideset_count(1);
93
94 sm.set_out_shift_dir(ShiftDirection::Left);
95 sm.set_in_shift_dir(ShiftDirection::Left);
96
97 let Wrap { source, target } = relocated.wrap();
98 sm.set_wrap(source, target);
99
100 // pull low for startup
101 pio_instr_util::set_pin(&mut sm, 0);
102
103 Self {
104 cs,
105 sm,
106 dma,
107 wrap_target: target,
108 }
109 }
110
111 pub async fn write(&mut self, write: &[u32]) -> u32 {
112 self.sm.set_enable(false);
113 let write_bits = write.len() * 32 - 1;
114 let read_bits = 31;
115
116 defmt::trace!("write={} read={}", write_bits, read_bits);
117
118 let mut dma = Peripheral::into_ref(&mut self.dma);
119 pio_instr_util::set_x(&mut self.sm, write_bits as u32);
120 pio_instr_util::set_y(&mut self.sm, read_bits as u32);
121 pio_instr_util::set_pindir(&mut self.sm, 0b1);
122 pio_instr_util::exec_jmp(&mut self.sm, self.wrap_target);
123
124 self.sm.set_enable(true);
125
126 self.sm.dma_push(dma.reborrow(), write).await;
127
128 let status = self.sm.wait_pull().await;
129 status
130 }
131
132 pub async fn cmd_read(&mut self, cmd: u32, read: &mut [u32]) -> u32 {
133 self.sm.set_enable(false);
134 let write_bits = 31;
135 let read_bits = read.len() * 32 + 32 - 1;
136
137 defmt::trace!("write={} read={}", write_bits, read_bits);
138
139 let mut dma = Peripheral::into_ref(&mut self.dma);
140 pio_instr_util::set_y(&mut self.sm, read_bits as u32);
141 pio_instr_util::set_x(&mut self.sm, write_bits as u32);
142 pio_instr_util::set_pindir(&mut self.sm, 0b1);
143 pio_instr_util::exec_jmp(&mut self.sm, self.wrap_target);
144 // self.cs.set_low();
145 self.sm.set_enable(true);
146
147 self.sm.dma_push(dma.reborrow(), slice::from_ref(&cmd)).await;
148 self.sm.dma_pull(dma, read).await;
149
150 let status = self.sm.wait_pull().await;
151 status
152 }
153}
154
155impl<CS, SM, DMA> SpiBusCyw43 for PioSpi<CS, SM, DMA>
156where
157 CS: Pin,
158 SM: PioStateMachine,
159 DMA: Channel,
160{
161 async fn cmd_write(&mut self, write: &[u32]) -> u32 {
162 self.cs.set_low();
163 let status = self.write(write).await;
164 self.cs.set_high();
165 status
166 }
167
168 async fn cmd_read(&mut self, write: u32, read: &mut [u32]) -> u32 {
169 self.cs.set_low();
170 let status = self.cmd_read(write, read).await;
171 self.cs.set_high();
172 status
173 }
174
175 async fn wait_for_event(&mut self) {
176 self.sm.wait_irq(0).await;
177 self.sm.clear_irq(0);
178 }
179}