diff options
| author | Bailey Townsend <[email protected]> | 2024-12-27 23:43:38 -0600 |
|---|---|---|
| committer | Bailey Townsend <[email protected]> | 2024-12-27 23:43:38 -0600 |
| commit | dd31ffadfbd145f26b6bb54cf2036cb54149aefe (patch) | |
| tree | 86dadcda4b4dd8dc0d8db65b156099f11b0f7a3c /cyw43-pio/src/lib.rs | |
| parent | 56f9296581800dca70474459debf4a429b312e50 (diff) | |
Work done
Diffstat (limited to 'cyw43-pio/src/lib.rs')
| -rw-r--r-- | cyw43-pio/src/lib.rs | 48 |
1 files changed, 23 insertions, 25 deletions
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; | |||
| 10 | use embassy_rp::gpio::{Drive, Level, Output, Pull, SlewRate}; | 10 | use embassy_rp::gpio::{Drive, Level, Output, Pull, SlewRate}; |
| 11 | use embassy_rp::pio::{instr, Common, Config, Direction, Instance, Irq, PioPin, ShiftDirection, StateMachine}; | 11 | use embassy_rp::pio::{instr, Common, Config, Direction, Instance, Irq, PioPin, ShiftDirection, StateMachine}; |
| 12 | use embassy_rp::{Peripheral, PeripheralRef}; | 12 | use embassy_rp::{Peripheral, PeripheralRef}; |
| 13 | use fixed::types::extra::U8; | ||
| 13 | use fixed::FixedU32; | 14 | use fixed::FixedU32; |
| 14 | use pio_proc::pio_asm; | 15 | use 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. | ||
| 34 | pub 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. | ||
| 39 | pub 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". | ||
| 44 | pub const RM2_CLOCK_DIVIDER: FixedU32<U8> = FixedU32::from_bits(0x0300); | ||
| 45 | |||
| 25 | impl<'d, PIO, const SM: usize, DMA> PioSpi<'d, PIO, SM, DMA> | 46 | impl<'d, PIO, const SM: usize, DMA> PioSpi<'d, PIO, SM, DMA> |
| 26 | where | 47 | where |
| 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 | ||
