diff options
| -rwxr-xr-x | ci.sh | 2 | ||||
| -rw-r--r-- | cyw43-pio/Cargo.toml | 5 | ||||
| -rw-r--r-- | cyw43-pio/src/lib.rs | 139 | ||||
| -rw-r--r-- | examples/rp/src/bin/wifi_ap_tcp_server.rs | 13 | ||||
| -rw-r--r-- | examples/rp/src/bin/wifi_blinky.rs | 13 | ||||
| -rw-r--r-- | examples/rp/src/bin/wifi_scan.rs | 13 | ||||
| -rw-r--r-- | examples/rp/src/bin/wifi_tcp_server.rs | 13 | ||||
| -rw-r--r-- | examples/rp/src/bin/wifi_webrequest.rs | 13 | ||||
| -rw-r--r-- | examples/rp23/src/bin/wifi_blinky_pico_plus_2.rs | 93 | ||||
| -rw-r--r-- | tests/rp/Cargo.toml | 2 | ||||
| -rw-r--r-- | tests/rp/src/bin/cyw43-perf.rs | 13 |
11 files changed, 233 insertions, 86 deletions
| @@ -178,7 +178,7 @@ cargo batch \ | |||
| 178 | --- build --release --manifest-path cyw43/Cargo.toml --target thumbv6m-none-eabi --features 'log,firmware-logs,bluetooth' \ | 178 | --- build --release --manifest-path cyw43/Cargo.toml --target thumbv6m-none-eabi --features 'log,firmware-logs,bluetooth' \ |
| 179 | --- build --release --manifest-path cyw43/Cargo.toml --target thumbv6m-none-eabi --features 'defmt,firmware-logs,bluetooth' \ | 179 | --- build --release --manifest-path cyw43/Cargo.toml --target thumbv6m-none-eabi --features 'defmt,firmware-logs,bluetooth' \ |
| 180 | --- build --release --manifest-path cyw43-pio/Cargo.toml --target thumbv6m-none-eabi --features 'embassy-rp/rp2040' \ | 180 | --- build --release --manifest-path cyw43-pio/Cargo.toml --target thumbv6m-none-eabi --features 'embassy-rp/rp2040' \ |
| 181 | --- build --release --manifest-path cyw43-pio/Cargo.toml --target thumbv6m-none-eabi --features 'embassy-rp/rp2040,overclock' \ | 181 | --- build --release --manifest-path cyw43-pio/Cargo.toml --target thumbv6m-none-eabi --features 'embassy-rp/rp2040' \ |
| 182 | --- build --release --manifest-path embassy-boot-nrf/Cargo.toml --target thumbv7em-none-eabi --features embassy-nrf/nrf52840 \ | 182 | --- build --release --manifest-path embassy-boot-nrf/Cargo.toml --target thumbv7em-none-eabi --features embassy-nrf/nrf52840 \ |
| 183 | --- build --release --manifest-path embassy-boot-nrf/Cargo.toml --target thumbv8m.main-none-eabihf --features embassy-nrf/nrf9160-ns \ | 183 | --- build --release --manifest-path embassy-boot-nrf/Cargo.toml --target thumbv8m.main-none-eabihf --features embassy-nrf/nrf9160-ns \ |
| 184 | --- build --release --manifest-path embassy-boot-nrf/Cargo.toml --target thumbv8m.main-none-eabihf --features embassy-nrf/nrf9120-ns \ | 184 | --- build --release --manifest-path embassy-boot-nrf/Cargo.toml --target thumbv8m.main-none-eabihf --features embassy-nrf/nrf9120-ns \ |
diff --git a/cyw43-pio/Cargo.toml b/cyw43-pio/Cargo.toml index 4e21c255f..e400d95ea 100644 --- a/cyw43-pio/Cargo.toml +++ b/cyw43-pio/Cargo.toml | |||
| @@ -9,11 +9,6 @@ license = "MIT OR Apache-2.0" | |||
| 9 | repository = "https://github.com/embassy-rs/embassy" | 9 | repository = "https://github.com/embassy-rs/embassy" |
| 10 | documentation = "https://docs.embassy.dev/cyw43-pio" | 10 | documentation = "https://docs.embassy.dev/cyw43-pio" |
| 11 | 11 | ||
| 12 | [features] | ||
| 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. | ||
| 15 | overclock = [] | ||
| 16 | |||
| 17 | [dependencies] | 12 | [dependencies] |
| 18 | cyw43 = { version = "0.2.0", path = "../cyw43" } | 13 | cyw43 = { version = "0.2.0", path = "../cyw43" } |
| 19 | embassy-rp = { version = "0.2.0", path = "../embassy-rp" } | 14 | embassy-rp = { version = "0.2.0", path = "../embassy-rp" } |
diff --git a/cyw43-pio/src/lib.rs b/cyw43-pio/src/lib.rs index 40cf63a17..5fe7af95d 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,25 @@ 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 | pub const RM2_CLOCK_DIVIDER: FixedU32<U8> = FixedU32::from_bits(0x0300); | ||
| 44 | |||
| 25 | impl<'d, PIO, const SM: usize, DMA> PioSpi<'d, PIO, SM, DMA> | 45 | impl<'d, PIO, const SM: usize, DMA> PioSpi<'d, PIO, SM, DMA> |
| 26 | where | 46 | where |
| 27 | DMA: Channel, | 47 | DMA: Channel, |
| @@ -31,6 +51,7 @@ where | |||
| 31 | pub fn new<DIO, CLK>( | 51 | pub fn new<DIO, CLK>( |
| 32 | common: &mut Common<'d, PIO>, | 52 | common: &mut Common<'d, PIO>, |
| 33 | mut sm: StateMachine<'d, PIO, SM>, | 53 | mut sm: StateMachine<'d, PIO, SM>, |
| 54 | clock_divider: FixedU32<U8>, | ||
| 34 | irq: Irq<'d, PIO, 0>, | 55 | irq: Irq<'d, PIO, 0>, |
| 35 | cs: Output<'d>, | 56 | cs: Output<'d>, |
| 36 | dio: DIO, | 57 | dio: DIO, |
| @@ -41,53 +62,56 @@ where | |||
| 41 | DIO: PioPin, | 62 | DIO: PioPin, |
| 42 | CLK: PioPin, | 63 | CLK: PioPin, |
| 43 | { | 64 | { |
| 44 | #[cfg(feature = "overclock")] | 65 | let loaded_program = if clock_divider < DEFAULT_CLOCK_DIVIDER { |
| 45 | let program = pio_asm!( | 66 | let overclock_program = pio_asm!( |
| 46 | ".side_set 1" | 67 | ".side_set 1" |
| 47 | 68 | ||
| 48 | ".wrap_target" | 69 | ".wrap_target" |
| 49 | // write out x-1 bits | 70 | // write out x-1 bits |
| 50 | "lp:" | 71 | "lp:" |
| 51 | "out pins, 1 side 0" | 72 | "out pins, 1 side 0" |
| 52 | "jmp x-- lp side 1" | 73 | "jmp x-- lp side 1" |
| 53 | // switch directions | 74 | // switch directions |
| 54 | "set pindirs, 0 side 0" | 75 | "set pindirs, 0 side 0" |
| 55 | "nop side 1" // necessary for clkdiv=1. | 76 | "nop side 1" // necessary for clkdiv=1. |
| 56 | "nop side 0" | 77 | "nop side 0" |
| 57 | // read in y-1 bits | 78 | // read in y-1 bits |
| 58 | "lp2:" | 79 | "lp2:" |
| 59 | "in pins, 1 side 1" | 80 | "in pins, 1 side 1" |
| 60 | "jmp y-- lp2 side 0" | 81 | "jmp y-- lp2 side 0" |
| 61 | 82 | ||
| 62 | // wait for event and irq host | 83 | // wait for event and irq host |
| 63 | "wait 1 pin 0 side 0" | 84 | "wait 1 pin 0 side 0" |
| 64 | "irq 0 side 0" | 85 | "irq 0 side 0" |
| 65 | 86 | ||
| 66 | ".wrap" | 87 | ".wrap" |
| 67 | ); | 88 | ); |
| 68 | #[cfg(not(feature = "overclock"))] | 89 | common.load_program(&overclock_program.program) |
| 69 | let program = pio_asm!( | 90 | } else { |
| 70 | ".side_set 1" | 91 | let default_program = pio_asm!( |
| 71 | 92 | ".side_set 1" | |
| 72 | ".wrap_target" | 93 | |
| 73 | // write out x-1 bits | 94 | ".wrap_target" |
| 74 | "lp:" | 95 | // write out x-1 bits |
| 75 | "out pins, 1 side 0" | 96 | "lp:" |
| 76 | "jmp x-- lp side 1" | 97 | "out pins, 1 side 0" |
| 77 | // switch directions | 98 | "jmp x-- lp side 1" |
| 78 | "set pindirs, 0 side 0" | 99 | // switch directions |
| 79 | "nop side 0" | 100 | "set pindirs, 0 side 0" |
| 80 | // read in y-1 bits | 101 | "nop side 0" |
| 81 | "lp2:" | 102 | // read in y-1 bits |
| 82 | "in pins, 1 side 1" | 103 | "lp2:" |
| 83 | "jmp y-- lp2 side 0" | 104 | "in pins, 1 side 1" |
| 84 | 105 | "jmp y-- lp2 side 0" | |
| 85 | // wait for event and irq host | 106 | |
| 86 | "wait 1 pin 0 side 0" | 107 | // wait for event and irq host |
| 87 | "irq 0 side 0" | 108 | "wait 1 pin 0 side 0" |
| 88 | 109 | "irq 0 side 0" | |
| 89 | ".wrap" | 110 | |
| 90 | ); | 111 | ".wrap" |
| 112 | ); | ||
| 113 | common.load_program(&default_program.program) | ||
| 114 | }; | ||
| 91 | 115 | ||
| 92 | let mut pin_io: embassy_rp::pio::Pin<PIO> = common.make_pio_pin(dio); | 116 | let mut pin_io: embassy_rp::pio::Pin<PIO> = common.make_pio_pin(dio); |
| 93 | pin_io.set_pull(Pull::None); | 117 | pin_io.set_pull(Pull::None); |
| @@ -101,7 +125,6 @@ where | |||
| 101 | pin_clk.set_slew_rate(SlewRate::Fast); | 125 | pin_clk.set_slew_rate(SlewRate::Fast); |
| 102 | 126 | ||
| 103 | let mut cfg = Config::default(); | 127 | let mut cfg = Config::default(); |
| 104 | let loaded_program = common.load_program(&program.program); | ||
| 105 | cfg.use_program(&loaded_program, &[&pin_clk]); | 128 | cfg.use_program(&loaded_program, &[&pin_clk]); |
| 106 | cfg.set_out_pins(&[&pin_io]); | 129 | cfg.set_out_pins(&[&pin_io]); |
| 107 | cfg.set_in_pins(&[&pin_io]); | 130 | cfg.set_in_pins(&[&pin_io]); |
| @@ -112,25 +135,7 @@ where | |||
| 112 | cfg.shift_in.direction = ShiftDirection::Left; | 135 | cfg.shift_in.direction = ShiftDirection::Left; |
| 113 | cfg.shift_in.auto_fill = true; | 136 | cfg.shift_in.auto_fill = true; |
| 114 | //cfg.shift_in.threshold = 32; | 137 | //cfg.shift_in.threshold = 32; |
| 115 | 138 | 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(feature = "overclock"))] | ||
| 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 | 139 | ||
| 135 | sm.set_config(&cfg); | 140 | sm.set_config(&cfg); |
| 136 | 141 | ||
diff --git a/examples/rp/src/bin/wifi_ap_tcp_server.rs b/examples/rp/src/bin/wifi_ap_tcp_server.rs index 4c9651433..e97ddb4c1 100644 --- a/examples/rp/src/bin/wifi_ap_tcp_server.rs +++ b/examples/rp/src/bin/wifi_ap_tcp_server.rs | |||
| @@ -7,7 +7,7 @@ | |||
| 7 | 7 | ||
| 8 | use core::str::from_utf8; | 8 | use core::str::from_utf8; |
| 9 | 9 | ||
| 10 | use cyw43_pio::PioSpi; | 10 | use cyw43_pio::{PioSpi, DEFAULT_CLOCK_DIVIDER}; |
| 11 | use defmt::*; | 11 | use defmt::*; |
| 12 | use embassy_executor::Spawner; | 12 | use embassy_executor::Spawner; |
| 13 | use embassy_net::tcp::TcpSocket; | 13 | use embassy_net::tcp::TcpSocket; |
| @@ -57,7 +57,16 @@ async fn main(spawner: Spawner) { | |||
| 57 | let pwr = Output::new(p.PIN_23, Level::Low); | 57 | let pwr = Output::new(p.PIN_23, Level::Low); |
| 58 | let cs = Output::new(p.PIN_25, Level::High); | 58 | let cs = Output::new(p.PIN_25, Level::High); |
| 59 | let mut pio = Pio::new(p.PIO0, Irqs); | 59 | let mut pio = Pio::new(p.PIO0, Irqs); |
| 60 | let spi = PioSpi::new(&mut pio.common, pio.sm0, pio.irq0, cs, p.PIN_24, p.PIN_29, p.DMA_CH0); | 60 | let spi = PioSpi::new( |
| 61 | &mut pio.common, | ||
| 62 | pio.sm0, | ||
| 63 | DEFAULT_CLOCK_DIVIDER, | ||
| 64 | pio.irq0, | ||
| 65 | cs, | ||
| 66 | p.PIN_24, | ||
| 67 | p.PIN_29, | ||
| 68 | p.DMA_CH0, | ||
| 69 | ); | ||
| 61 | 70 | ||
| 62 | static STATE: StaticCell<cyw43::State> = StaticCell::new(); | 71 | static STATE: StaticCell<cyw43::State> = StaticCell::new(); |
| 63 | let state = STATE.init(cyw43::State::new()); | 72 | let state = STATE.init(cyw43::State::new()); |
diff --git a/examples/rp/src/bin/wifi_blinky.rs b/examples/rp/src/bin/wifi_blinky.rs index 0107a2326..6e91ce167 100644 --- a/examples/rp/src/bin/wifi_blinky.rs +++ b/examples/rp/src/bin/wifi_blinky.rs | |||
| @@ -5,7 +5,7 @@ | |||
| 5 | #![no_std] | 5 | #![no_std] |
| 6 | #![no_main] | 6 | #![no_main] |
| 7 | 7 | ||
| 8 | use cyw43_pio::PioSpi; | 8 | use cyw43_pio::{PioSpi, DEFAULT_CLOCK_DIVIDER}; |
| 9 | use defmt::*; | 9 | use defmt::*; |
| 10 | use embassy_executor::Spawner; | 10 | use embassy_executor::Spawner; |
| 11 | use embassy_rp::bind_interrupts; | 11 | use embassy_rp::bind_interrupts; |
| @@ -41,7 +41,16 @@ async fn main(spawner: Spawner) { | |||
| 41 | let pwr = Output::new(p.PIN_23, Level::Low); | 41 | let pwr = Output::new(p.PIN_23, Level::Low); |
| 42 | let cs = Output::new(p.PIN_25, Level::High); | 42 | let cs = Output::new(p.PIN_25, Level::High); |
| 43 | let mut pio = Pio::new(p.PIO0, Irqs); | 43 | let mut pio = Pio::new(p.PIO0, Irqs); |
| 44 | let spi = PioSpi::new(&mut pio.common, pio.sm0, pio.irq0, cs, p.PIN_24, p.PIN_29, p.DMA_CH0); | 44 | let spi = PioSpi::new( |
| 45 | &mut pio.common, | ||
| 46 | pio.sm0, | ||
| 47 | DEFAULT_CLOCK_DIVIDER, | ||
| 48 | pio.irq0, | ||
| 49 | cs, | ||
| 50 | p.PIN_24, | ||
| 51 | p.PIN_29, | ||
| 52 | p.DMA_CH0, | ||
| 53 | ); | ||
| 45 | 54 | ||
| 46 | static STATE: StaticCell<cyw43::State> = StaticCell::new(); | 55 | static STATE: StaticCell<cyw43::State> = StaticCell::new(); |
| 47 | let state = STATE.init(cyw43::State::new()); | 56 | let state = STATE.init(cyw43::State::new()); |
diff --git a/examples/rp/src/bin/wifi_scan.rs b/examples/rp/src/bin/wifi_scan.rs index 2ef899080..fe9c363d9 100644 --- a/examples/rp/src/bin/wifi_scan.rs +++ b/examples/rp/src/bin/wifi_scan.rs | |||
| @@ -7,7 +7,7 @@ | |||
| 7 | 7 | ||
| 8 | use core::str; | 8 | use core::str; |
| 9 | 9 | ||
| 10 | use cyw43_pio::PioSpi; | 10 | use cyw43_pio::{PioSpi, DEFAULT_CLOCK_DIVIDER}; |
| 11 | use defmt::*; | 11 | use defmt::*; |
| 12 | use embassy_executor::Spawner; | 12 | use embassy_executor::Spawner; |
| 13 | use embassy_rp::bind_interrupts; | 13 | use embassy_rp::bind_interrupts; |
| @@ -45,7 +45,16 @@ async fn main(spawner: Spawner) { | |||
| 45 | let pwr = Output::new(p.PIN_23, Level::Low); | 45 | let pwr = Output::new(p.PIN_23, Level::Low); |
| 46 | let cs = Output::new(p.PIN_25, Level::High); | 46 | let cs = Output::new(p.PIN_25, Level::High); |
| 47 | let mut pio = Pio::new(p.PIO0, Irqs); | 47 | let mut pio = Pio::new(p.PIO0, Irqs); |
| 48 | let spi = PioSpi::new(&mut pio.common, pio.sm0, pio.irq0, cs, p.PIN_24, p.PIN_29, p.DMA_CH0); | 48 | let spi = PioSpi::new( |
| 49 | &mut pio.common, | ||
| 50 | pio.sm0, | ||
| 51 | DEFAULT_CLOCK_DIVIDER, | ||
| 52 | pio.irq0, | ||
| 53 | cs, | ||
| 54 | p.PIN_24, | ||
| 55 | p.PIN_29, | ||
| 56 | p.DMA_CH0, | ||
| 57 | ); | ||
| 49 | 58 | ||
| 50 | static STATE: StaticCell<cyw43::State> = StaticCell::new(); | 59 | static STATE: StaticCell<cyw43::State> = StaticCell::new(); |
| 51 | let state = STATE.init(cyw43::State::new()); | 60 | let state = STATE.init(cyw43::State::new()); |
diff --git a/examples/rp/src/bin/wifi_tcp_server.rs b/examples/rp/src/bin/wifi_tcp_server.rs index 7bf546e01..14dbf4552 100644 --- a/examples/rp/src/bin/wifi_tcp_server.rs +++ b/examples/rp/src/bin/wifi_tcp_server.rs | |||
| @@ -8,7 +8,7 @@ | |||
| 8 | use core::str::from_utf8; | 8 | use core::str::from_utf8; |
| 9 | 9 | ||
| 10 | use cyw43::JoinOptions; | 10 | use cyw43::JoinOptions; |
| 11 | use cyw43_pio::PioSpi; | 11 | use cyw43_pio::{PioSpi, DEFAULT_CLOCK_DIVIDER}; |
| 12 | use defmt::*; | 12 | use defmt::*; |
| 13 | use embassy_executor::Spawner; | 13 | use embassy_executor::Spawner; |
| 14 | use embassy_net::tcp::TcpSocket; | 14 | use embassy_net::tcp::TcpSocket; |
| @@ -61,7 +61,16 @@ async fn main(spawner: Spawner) { | |||
| 61 | let pwr = Output::new(p.PIN_23, Level::Low); | 61 | let pwr = Output::new(p.PIN_23, Level::Low); |
| 62 | let cs = Output::new(p.PIN_25, Level::High); | 62 | let cs = Output::new(p.PIN_25, Level::High); |
| 63 | let mut pio = Pio::new(p.PIO0, Irqs); | 63 | let mut pio = Pio::new(p.PIO0, Irqs); |
| 64 | let spi = PioSpi::new(&mut pio.common, pio.sm0, pio.irq0, cs, p.PIN_24, p.PIN_29, p.DMA_CH0); | 64 | let spi = PioSpi::new( |
| 65 | &mut pio.common, | ||
| 66 | pio.sm0, | ||
| 67 | DEFAULT_CLOCK_DIVIDER, | ||
| 68 | pio.irq0, | ||
| 69 | cs, | ||
| 70 | p.PIN_24, | ||
| 71 | p.PIN_29, | ||
| 72 | p.DMA_CH0, | ||
| 73 | ); | ||
| 65 | 74 | ||
| 66 | static STATE: StaticCell<cyw43::State> = StaticCell::new(); | 75 | static STATE: StaticCell<cyw43::State> = StaticCell::new(); |
| 67 | let state = STATE.init(cyw43::State::new()); | 76 | let state = STATE.init(cyw43::State::new()); |
diff --git a/examples/rp/src/bin/wifi_webrequest.rs b/examples/rp/src/bin/wifi_webrequest.rs index 1ae909917..f1b398b65 100644 --- a/examples/rp/src/bin/wifi_webrequest.rs +++ b/examples/rp/src/bin/wifi_webrequest.rs | |||
| @@ -8,7 +8,7 @@ | |||
| 8 | use core::str::from_utf8; | 8 | use core::str::from_utf8; |
| 9 | 9 | ||
| 10 | use cyw43::JoinOptions; | 10 | use cyw43::JoinOptions; |
| 11 | use cyw43_pio::PioSpi; | 11 | use cyw43_pio::{PioSpi, DEFAULT_CLOCK_DIVIDER}; |
| 12 | use defmt::*; | 12 | use defmt::*; |
| 13 | use embassy_executor::Spawner; | 13 | use embassy_executor::Spawner; |
| 14 | use embassy_net::dns::DnsSocket; | 14 | use embassy_net::dns::DnsSocket; |
| @@ -63,7 +63,16 @@ async fn main(spawner: Spawner) { | |||
| 63 | let pwr = Output::new(p.PIN_23, Level::Low); | 63 | let pwr = Output::new(p.PIN_23, Level::Low); |
| 64 | let cs = Output::new(p.PIN_25, Level::High); | 64 | let cs = Output::new(p.PIN_25, Level::High); |
| 65 | let mut pio = Pio::new(p.PIO0, Irqs); | 65 | let mut pio = Pio::new(p.PIO0, Irqs); |
| 66 | let spi = PioSpi::new(&mut pio.common, pio.sm0, pio.irq0, cs, p.PIN_24, p.PIN_29, p.DMA_CH0); | 66 | let spi = PioSpi::new( |
| 67 | &mut pio.common, | ||
| 68 | pio.sm0, | ||
| 69 | DEFAULT_CLOCK_DIVIDER, | ||
| 70 | pio.irq0, | ||
| 71 | cs, | ||
| 72 | p.PIN_24, | ||
| 73 | p.PIN_29, | ||
| 74 | p.DMA_CH0, | ||
| 75 | ); | ||
| 67 | 76 | ||
| 68 | static STATE: StaticCell<cyw43::State> = StaticCell::new(); | 77 | static STATE: StaticCell<cyw43::State> = StaticCell::new(); |
| 69 | let state = STATE.init(cyw43::State::new()); | 78 | let state = STATE.init(cyw43::State::new()); |
diff --git a/examples/rp23/src/bin/wifi_blinky_pico_plus_2.rs b/examples/rp23/src/bin/wifi_blinky_pico_plus_2.rs new file mode 100644 index 000000000..ebb3c4373 --- /dev/null +++ b/examples/rp23/src/bin/wifi_blinky_pico_plus_2.rs | |||
| @@ -0,0 +1,93 @@ | |||
| 1 | //! This example test the Pimoroni Pico Plus 2 on board LED. | ||
| 2 | //! | ||
| 3 | //! It does not work with the RP Pico board. See blinky.rs. | ||
| 4 | |||
| 5 | #![no_std] | ||
| 6 | #![no_main] | ||
| 7 | |||
| 8 | use cyw43_pio::{PioSpi, RM2_CLOCK_DIVIDER}; | ||
| 9 | use defmt::*; | ||
| 10 | use embassy_executor::Spawner; | ||
| 11 | use embassy_rp::block::ImageDef; | ||
| 12 | use embassy_rp::peripherals::{DMA_CH0, PIO0}; | ||
| 13 | use embassy_rp::pio::{InterruptHandler, Pio}; | ||
| 14 | use embassy_rp::{bind_interrupts, gpio}; | ||
| 15 | use embassy_time::{Duration, Timer}; | ||
| 16 | use gpio::{Level, Output}; | ||
| 17 | use static_cell::StaticCell; | ||
| 18 | use {defmt_rtt as _, panic_probe as _}; | ||
| 19 | |||
| 20 | #[link_section = ".start_block"] | ||
| 21 | #[used] | ||
| 22 | pub static IMAGE_DEF: ImageDef = ImageDef::secure_exe(); | ||
| 23 | |||
| 24 | // Program metadata for `picotool info`. | ||
| 25 | // This isn't needed, but it's recomended to have these minimal entries. | ||
| 26 | #[link_section = ".bi_entries"] | ||
| 27 | #[used] | ||
| 28 | pub static PICOTOOL_ENTRIES: [embassy_rp::binary_info::EntryAddr; 4] = [ | ||
| 29 | embassy_rp::binary_info::rp_program_name!(c"Blinky Example"), | ||
| 30 | embassy_rp::binary_info::rp_program_description!( | ||
| 31 | c"This example tests the RP Pico on board LED, connected to gpio 25" | ||
| 32 | ), | ||
| 33 | embassy_rp::binary_info::rp_cargo_version!(), | ||
| 34 | embassy_rp::binary_info::rp_program_build_attribute!(), | ||
| 35 | ]; | ||
| 36 | |||
| 37 | bind_interrupts!(struct Irqs { | ||
| 38 | PIO0_IRQ_0 => InterruptHandler<PIO0>; | ||
| 39 | }); | ||
| 40 | |||
| 41 | #[embassy_executor::task] | ||
| 42 | async fn cyw43_task(runner: cyw43::Runner<'static, Output<'static>, PioSpi<'static, PIO0, 0, DMA_CH0>>) -> ! { | ||
| 43 | runner.run().await | ||
| 44 | } | ||
| 45 | |||
| 46 | #[embassy_executor::main] | ||
| 47 | async fn main(spawner: Spawner) { | ||
| 48 | let p = embassy_rp::init(Default::default()); | ||
| 49 | let fw = include_bytes!("../../../../cyw43-firmware/43439A0.bin"); | ||
| 50 | let clm = include_bytes!("../../../../cyw43-firmware/43439A0_clm.bin"); | ||
| 51 | |||
| 52 | // To make flashing faster for development, you may want to flash the firmwares independently | ||
| 53 | // at hardcoded addresses, instead of baking them into the program with `include_bytes!`: | ||
| 54 | // probe-rs download ../../cyw43-firmware/43439A0.bin --binary-format bin --chip RP2040 --base-address 0x10100000 | ||
| 55 | // probe-rs download ../../cyw43-firmware/43439A0_clm.bin --binary-format bin --chip RP2040 --base-address 0x10140000 | ||
| 56 | //let fw = unsafe { core::slice::from_raw_parts(0x10100000 as *const u8, 230321) }; | ||
| 57 | //let clm = unsafe { core::slice::from_raw_parts(0x10140000 as *const u8, 4752) }; | ||
| 58 | |||
| 59 | let pwr = Output::new(p.PIN_23, Level::Low); | ||
| 60 | let cs = Output::new(p.PIN_25, Level::High); | ||
| 61 | let mut pio = Pio::new(p.PIO0, Irqs); | ||
| 62 | let spi = PioSpi::new( | ||
| 63 | &mut pio.common, | ||
| 64 | pio.sm0, | ||
| 65 | RM2_CLOCK_DIVIDER, | ||
| 66 | pio.irq0, | ||
| 67 | cs, | ||
| 68 | p.PIN_24, | ||
| 69 | p.PIN_29, | ||
| 70 | p.DMA_CH0, | ||
| 71 | ); | ||
| 72 | |||
| 73 | static STATE: StaticCell<cyw43::State> = StaticCell::new(); | ||
| 74 | let state = STATE.init(cyw43::State::new()); | ||
| 75 | let (_net_device, mut control, runner) = cyw43::new(state, pwr, spi, fw).await; | ||
| 76 | unwrap!(spawner.spawn(cyw43_task(runner))); | ||
| 77 | |||
| 78 | control.init(clm).await; | ||
| 79 | control | ||
| 80 | .set_power_management(cyw43::PowerManagementMode::PowerSave) | ||
| 81 | .await; | ||
| 82 | |||
| 83 | let delay = Duration::from_secs(1); | ||
| 84 | loop { | ||
| 85 | info!("led on!"); | ||
| 86 | control.gpio_set(0, true).await; | ||
| 87 | Timer::after(delay).await; | ||
| 88 | |||
| 89 | info!("led off!"); | ||
| 90 | control.gpio_set(0, false).await; | ||
| 91 | Timer::after(delay).await; | ||
| 92 | } | ||
| 93 | } | ||
diff --git a/tests/rp/Cargo.toml b/tests/rp/Cargo.toml index d5aabc6ac..842cdf51d 100644 --- a/tests/rp/Cargo.toml +++ b/tests/rp/Cargo.toml | |||
| @@ -16,7 +16,7 @@ embassy-net = { version = "0.5.0", path = "../../embassy-net", features = ["defm | |||
| 16 | embassy-net-wiznet = { version = "0.1.0", path = "../../embassy-net-wiznet", features = ["defmt"] } | 16 | embassy-net-wiznet = { version = "0.1.0", path = "../../embassy-net-wiznet", features = ["defmt"] } |
| 17 | embassy-embedded-hal = { version = "0.2.0", path = "../../embassy-embedded-hal/"} | 17 | embassy-embedded-hal = { version = "0.2.0", path = "../../embassy-embedded-hal/"} |
| 18 | cyw43 = { path = "../../cyw43", features = ["defmt", "firmware-logs"] } | 18 | cyw43 = { path = "../../cyw43", features = ["defmt", "firmware-logs"] } |
| 19 | cyw43-pio = { path = "../../cyw43-pio", features = ["defmt", "overclock"] } | 19 | cyw43-pio = { path = "../../cyw43-pio", features = ["defmt"] } |
| 20 | perf-client = { path = "../perf-client" } | 20 | perf-client = { path = "../perf-client" } |
| 21 | 21 | ||
| 22 | defmt = "0.3.0" | 22 | defmt = "0.3.0" |
diff --git a/tests/rp/src/bin/cyw43-perf.rs b/tests/rp/src/bin/cyw43-perf.rs index 30e4afb07..34119722b 100644 --- a/tests/rp/src/bin/cyw43-perf.rs +++ b/tests/rp/src/bin/cyw43-perf.rs | |||
| @@ -3,7 +3,7 @@ | |||
| 3 | teleprobe_meta::target!(b"rpi-pico"); | 3 | teleprobe_meta::target!(b"rpi-pico"); |
| 4 | 4 | ||
| 5 | use cyw43::JoinOptions; | 5 | use cyw43::JoinOptions; |
| 6 | use cyw43_pio::PioSpi; | 6 | use cyw43_pio::{PioSpi, DEFAULT_CLOCK_DIVIDER}; |
| 7 | use defmt::{panic, *}; | 7 | use defmt::{panic, *}; |
| 8 | use embassy_executor::Spawner; | 8 | use embassy_executor::Spawner; |
| 9 | use embassy_net::{Config, StackResources}; | 9 | use embassy_net::{Config, StackResources}; |
| @@ -54,7 +54,16 @@ async fn main(spawner: Spawner) { | |||
| 54 | let pwr = Output::new(p.PIN_23, Level::Low); | 54 | let pwr = Output::new(p.PIN_23, Level::Low); |
| 55 | let cs = Output::new(p.PIN_25, Level::High); | 55 | let cs = Output::new(p.PIN_25, Level::High); |
| 56 | let mut pio = Pio::new(p.PIO0, Irqs); | 56 | let mut pio = Pio::new(p.PIO0, Irqs); |
| 57 | let spi = PioSpi::new(&mut pio.common, pio.sm0, pio.irq0, cs, p.PIN_24, p.PIN_29, p.DMA_CH0); | 57 | let spi = PioSpi::new( |
| 58 | &mut pio.common, | ||
| 59 | pio.sm0, | ||
| 60 | DEFAULT_CLOCK_DIVIDER, | ||
| 61 | pio.irq0, | ||
| 62 | cs, | ||
| 63 | p.PIN_24, | ||
| 64 | p.PIN_29, | ||
| 65 | p.DMA_CH0, | ||
| 66 | ); | ||
| 58 | 67 | ||
| 59 | static STATE: StaticCell<cyw43::State> = StaticCell::new(); | 68 | static STATE: StaticCell<cyw43::State> = StaticCell::new(); |
| 60 | let state = STATE.init(cyw43::State::new()); | 69 | let state = STATE.init(cyw43::State::new()); |
