aboutsummaryrefslogtreecommitdiff
path: root/cyw43-pio
diff options
context:
space:
mode:
Diffstat (limited to 'cyw43-pio')
-rw-r--r--cyw43-pio/Cargo.toml2
-rw-r--r--cyw43-pio/src/lib.rs48
2 files changed, 23 insertions, 27 deletions
diff --git a/cyw43-pio/Cargo.toml b/cyw43-pio/Cargo.toml
index 794bf2479..4e21c255f 100644
--- a/cyw43-pio/Cargo.toml
+++ b/cyw43-pio/Cargo.toml
@@ -13,8 +13,6 @@ documentation = "https://docs.embassy.dev/cyw43-pio"
13# If disabled, SPI runs at 31.25MHz 13# If disabled, SPI runs at 31.25MHz
14# If enabled, SPI runs at 62.5MHz, which is 25% higher than 50Mhz which is the maximum according to the CYW43439 datasheet. 14# If enabled, SPI runs at 62.5MHz, which is 25% higher than 50Mhz which is the maximum according to the CYW43439 datasheet.
15overclock = [] 15overclock = []
16# If enabled the PIO runs at a speed that works with the rm2 module
17rm2 = []
18 16
19[dependencies] 17[dependencies]
20cyw43 = { version = "0.2.0", path = "../cyw43" } 18cyw43 = { version = "0.2.0", path = "../cyw43" }
diff --git a/cyw43-pio/src/lib.rs b/cyw43-pio/src/lib.rs
index 1280e2059..abf3830d9 100644
--- a/cyw43-pio/src/lib.rs
+++ b/cyw43-pio/src/lib.rs
@@ -10,6 +10,7 @@ use embassy_rp::dma::Channel;
10use embassy_rp::gpio::{Drive, Level, Output, Pull, SlewRate}; 10use embassy_rp::gpio::{Drive, Level, Output, Pull, SlewRate};
11use embassy_rp::pio::{instr, Common, Config, Direction, Instance, Irq, PioPin, ShiftDirection, StateMachine}; 11use embassy_rp::pio::{instr, Common, Config, Direction, Instance, Irq, PioPin, ShiftDirection, StateMachine};
12use embassy_rp::{Peripheral, PeripheralRef}; 12use embassy_rp::{Peripheral, PeripheralRef};
13use fixed::types::extra::U8;
13use fixed::FixedU32; 14use fixed::FixedU32;
14use pio_proc::pio_asm; 15use pio_proc::pio_asm;
15 16
@@ -22,6 +23,26 @@ pub struct PioSpi<'d, PIO: Instance, const SM: usize, DMA> {
22 wrap_target: u8, 23 wrap_target: u8,
23} 24}
24 25
26/// The default clock divider that works for Pico 1 and 2 W. As well as the RM2 on rp2040 devices.
27/// same speed as pico-sdk, 62.5Mhz
28/// This is actually the fastest we can go without overclocking.
29/// According to data sheet, the theoretical maximum is 100Mhz Pio => 50Mhz SPI Freq.
30/// However, the PIO uses a fractional divider, which works by introducing jitter when
31/// the divider is not an integer. It does some clocks at 125mhz and others at 62.5mhz
32/// so that it averages out to the desired frequency of 100mhz. The 125mhz clock cycles
33/// violate the maximum from the data sheet.
34pub const DEFAULT_CLOCK_DIVIDER: FixedU32<U8> = FixedU32::from_bits(0x0200);
35
36/// The overclock clock divider for the Pico 1 W. Does not work on any known RM2 devices.
37/// 125mhz Pio => 62.5Mhz SPI Freq. 25% higher than theoretical maximum according to
38/// data sheet, but seems to work fine.
39pub const OVERCLOCK_CLOCK_DIVIDER: FixedU32<U8> = FixedU32::from_bits(0x0100);
40
41/// The clock divider for the RM2 module. Found to be needed for the Pimoroni Pico Plus 2 W,
42/// Pico Plus 2 Non w with the RM2 breakout module, and the Pico 2 with the RM2 breakout module.
43/// Does not work with the feature "overclock".
44pub const RM2_CLOCK_DIVIDER: FixedU32<U8> = FixedU32::from_bits(0x0300);
45
25impl<'d, PIO, const SM: usize, DMA> PioSpi<'d, PIO, SM, DMA> 46impl<'d, PIO, const SM: usize, DMA> PioSpi<'d, PIO, SM, DMA>
26where 47where
27 DMA: Channel, 48 DMA: Channel,
@@ -31,6 +52,7 @@ where
31 pub fn new<DIO, CLK>( 52 pub fn new<DIO, CLK>(
32 common: &mut Common<'d, PIO>, 53 common: &mut Common<'d, PIO>,
33 mut sm: StateMachine<'d, PIO, SM>, 54 mut sm: StateMachine<'d, PIO, SM>,
55 clock_divider: FixedU32<U8>,
34 irq: Irq<'d, PIO, 0>, 56 irq: Irq<'d, PIO, 0>,
35 cs: Output<'d>, 57 cs: Output<'d>,
36 dio: DIO, 58 dio: DIO,
@@ -112,31 +134,7 @@ where
112 cfg.shift_in.direction = ShiftDirection::Left; 134 cfg.shift_in.direction = ShiftDirection::Left;
113 cfg.shift_in.auto_fill = true; 135 cfg.shift_in.auto_fill = true;
114 //cfg.shift_in.threshold = 32; 136 //cfg.shift_in.threshold = 32;
115 137 cfg.clock_divider = clock_divider;
116 #[cfg(feature = "overclock")]
117 {
118 // 125mhz Pio => 62.5Mhz SPI Freq. 25% higher than theoretical maximum according to
119 // data sheet, but seems to work fine.
120 cfg.clock_divider = FixedU32::from_bits(0x0100);
121 }
122
123 #[cfg(not(any(feature = "overclock", feature = "rm2")))]
124 {
125 // same speed as pico-sdk, 62.5Mhz
126 // This is actually the fastest we can go without overclocking.
127 // According to data sheet, the theoretical maximum is 100Mhz Pio => 50Mhz SPI Freq.
128 // However, the PIO uses a fractional divider, which works by introducing jitter when
129 // the divider is not an integer. It does some clocks at 125mhz and others at 62.5mhz
130 // so that it averages out to the desired frequency of 100mhz. The 125mhz clock cycles
131 // violate the maximum from the data sheet.
132 cfg.clock_divider = FixedU32::from_bits(0x0200);
133 }
134
135 #[cfg(feature = "rm2")]
136 {
137 // This is found to work better with the RM2 module which is found on the Pimoroni Pico Plus 2 W
138 cfg.clock_divider = FixedU32::from_bits(0x0300);
139 }
140 138
141 sm.set_config(&cfg); 139 sm.set_config(&cfg);
142 140