diff options
| -rw-r--r-- | .vscode/settings.json | 2 | ||||
| -rw-r--r-- | Cargo.toml | 3 | ||||
| -rw-r--r-- | examples/rpi-pico-w/src/main.rs | 125 | ||||
| -rw-r--r-- | src/lib.rs | 490 |
4 files changed, 364 insertions, 256 deletions
diff --git a/.vscode/settings.json b/.vscode/settings.json index cc926d04f..748816bb9 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json | |||
| @@ -8,7 +8,7 @@ | |||
| 8 | "rust-analyzer.imports.granularity.enforce": true, | 8 | "rust-analyzer.imports.granularity.enforce": true, |
| 9 | "rust-analyzer.imports.granularity.group": "module", | 9 | "rust-analyzer.imports.granularity.group": "module", |
| 10 | "rust-analyzer.procMacro.attributes.enable": false, | 10 | "rust-analyzer.procMacro.attributes.enable": false, |
| 11 | "rust-analyzer.procMacro.enable": true, | 11 | "rust-analyzer.procMacro.enable": false, |
| 12 | "rust-analyzer.linkedProjects": [ | 12 | "rust-analyzer.linkedProjects": [ |
| 13 | "examples/rpi-pico-w/Cargo.toml", | 13 | "examples/rpi-pico-w/Cargo.toml", |
| 14 | ], | 14 | ], |
diff --git a/Cargo.toml b/Cargo.toml index 31a14f96f..d35e865bf 100644 --- a/Cargo.toml +++ b/Cargo.toml | |||
| @@ -4,11 +4,10 @@ version = "0.1.0" | |||
| 4 | edition = "2021" | 4 | edition = "2021" |
| 5 | 5 | ||
| 6 | [features] | 6 | [features] |
| 7 | defmt = ["dep:defmt", "embassy-rp/defmt", "embassy/defmt"] | 7 | defmt = ["dep:defmt", "embassy/defmt"] |
| 8 | log = ["dep:log"] | 8 | log = ["dep:log"] |
| 9 | [dependencies] | 9 | [dependencies] |
| 10 | embassy = { version = "0.1.0" } | 10 | embassy = { version = "0.1.0" } |
| 11 | embassy-rp = { version = "0.1.0", features = ["unstable-traits", "nightly", "unstable-pac"] } | ||
| 12 | embassy-net = { version = "0.1.0" } | 11 | embassy-net = { version = "0.1.0" } |
| 13 | atomic-polyfill = "0.1.5" | 12 | atomic-polyfill = "0.1.5" |
| 14 | 13 | ||
diff --git a/examples/rpi-pico-w/src/main.rs b/examples/rpi-pico-w/src/main.rs index e08ee8e95..655535f9d 100644 --- a/examples/rpi-pico-w/src/main.rs +++ b/examples/rpi-pico-w/src/main.rs | |||
| @@ -1,8 +1,9 @@ | |||
| 1 | #![no_std] | 1 | #![no_std] |
| 2 | #![no_main] | 2 | #![no_main] |
| 3 | #![feature(type_alias_impl_trait, concat_bytes)] | 3 | #![feature(generic_associated_types, type_alias_impl_trait)] |
| 4 | 4 | ||
| 5 | use core::slice; | 5 | use core::convert::Infallible; |
| 6 | use core::future::Future; | ||
| 6 | 7 | ||
| 7 | use defmt::{assert, assert_eq, panic, *}; | 8 | use defmt::{assert, assert_eq, panic, *}; |
| 8 | use embassy::executor::Spawner; | 9 | use embassy::executor::Spawner; |
| @@ -13,8 +14,9 @@ use embassy_net::{Ipv4Address, Ipv4Cidr, Stack, StackResources}; | |||
| 13 | use embassy_rp::gpio::{Flex, Level, Output, Pin}; | 14 | use embassy_rp::gpio::{Flex, Level, Output, Pin}; |
| 14 | use embassy_rp::peripherals::{PIN_23, PIN_24, PIN_25, PIN_29}; | 15 | use embassy_rp::peripherals::{PIN_23, PIN_24, PIN_25, PIN_29}; |
| 15 | use embassy_rp::Peripherals; | 16 | use embassy_rp::Peripherals; |
| 17 | use embedded_hal_1::spi::ErrorType; | ||
| 18 | use embedded_hal_async::spi::{ExclusiveDevice, SpiBusFlush, SpiBusRead, SpiBusWrite}; | ||
| 16 | use embedded_io::asynch::{Read, Write}; | 19 | use embedded_io::asynch::{Read, Write}; |
| 17 | use heapless::Vec; | ||
| 18 | use {defmt_rtt as _, panic_probe as _}; | 20 | use {defmt_rtt as _, panic_probe as _}; |
| 19 | 21 | ||
| 20 | macro_rules! forever { | 22 | macro_rules! forever { |
| @@ -26,7 +28,9 @@ macro_rules! forever { | |||
| 26 | } | 28 | } |
| 27 | 29 | ||
| 28 | #[embassy::task] | 30 | #[embassy::task] |
| 29 | async fn wifi_task(runner: cyw43::Runner<'static, PIN_23, PIN_25, PIN_29, PIN_24>) -> ! { | 31 | async fn wifi_task( |
| 32 | runner: cyw43::Runner<'static, Output<'static, PIN_23>, ExclusiveDevice<MySpi, Output<'static, PIN_25>>>, | ||
| 33 | ) -> ! { | ||
| 30 | runner.run().await | 34 | runner.run().await |
| 31 | } | 35 | } |
| 32 | 36 | ||
| @@ -39,25 +43,25 @@ async fn net_task(stack: &'static Stack<cyw43::NetDevice<'static>>) -> ! { | |||
| 39 | async fn main(spawner: Spawner, p: Peripherals) { | 43 | async fn main(spawner: Spawner, p: Peripherals) { |
| 40 | info!("Hello World!"); | 44 | info!("Hello World!"); |
| 41 | 45 | ||
| 42 | let (pwr, cs, clk, dio) = (p.PIN_23, p.PIN_25, p.PIN_29, p.PIN_24); | 46 | let pwr = Output::new(p.PIN_23, Level::Low); |
| 43 | //let (pwr, cs, clk, dio) = (p.PIN_23, p.PIN_0, p.PIN_1, p.PIN_2); | 47 | let cs = Output::new(p.PIN_25, Level::High); |
| 48 | let clk = Output::new(p.PIN_29, Level::Low); | ||
| 49 | let mut dio = Flex::new(p.PIN_24); | ||
| 50 | dio.set_low(); | ||
| 51 | dio.set_as_output(); | ||
| 52 | |||
| 53 | let bus = MySpi { clk, dio }; | ||
| 54 | let spi = ExclusiveDevice::new(bus, cs); | ||
| 44 | 55 | ||
| 45 | let state = forever!(cyw43::State::new()); | 56 | let state = forever!(cyw43::State::new()); |
| 46 | let (mut control, runner) = cyw43::new( | 57 | let (mut control, runner) = cyw43::new(state, pwr, spi).await; |
| 47 | state, | ||
| 48 | Output::new(pwr, Level::Low), | ||
| 49 | Output::new(cs, Level::High), | ||
| 50 | Output::new(clk, Level::Low), | ||
| 51 | Flex::new(dio), | ||
| 52 | ) | ||
| 53 | .await; | ||
| 54 | 58 | ||
| 55 | spawner.spawn(wifi_task(runner)).unwrap(); | 59 | spawner.spawn(wifi_task(runner)).unwrap(); |
| 56 | 60 | ||
| 57 | let net_device = control.init().await; | 61 | let net_device = control.init().await; |
| 58 | 62 | ||
| 59 | control.join_open("MikroTik-951589").await; | 63 | //control.join_open("MikroTik-951589").await; |
| 60 | //control.join_wpa2("MikroTik-951589", "asdfasdfasdfasdf").await; | 64 | control.join_wpa2("DirbaioWifi", "HelloWorld").await; |
| 61 | 65 | ||
| 62 | let config = embassy_net::ConfigStrategy::Dhcp; | 66 | let config = embassy_net::ConfigStrategy::Dhcp; |
| 63 | //let config = embassy_net::ConfigStrategy::Static(embassy_net::Config { | 67 | //let config = embassy_net::ConfigStrategy::Static(embassy_net::Config { |
| @@ -122,3 +126,92 @@ async fn main(spawner: Spawner, p: Peripherals) { | |||
| 122 | } | 126 | } |
| 123 | } | 127 | } |
| 124 | } | 128 | } |
| 129 | |||
| 130 | struct MySpi { | ||
| 131 | /// SPI clock | ||
| 132 | clk: Output<'static, PIN_29>, | ||
| 133 | |||
| 134 | /// 4 signals, all in one!! | ||
| 135 | /// - SPI MISO | ||
| 136 | /// - SPI MOSI | ||
| 137 | /// - IRQ | ||
| 138 | /// - strap to set to gSPI mode on boot. | ||
| 139 | dio: Flex<'static, PIN_24>, | ||
| 140 | } | ||
| 141 | |||
| 142 | impl ErrorType for MySpi { | ||
| 143 | type Error = Infallible; | ||
| 144 | } | ||
| 145 | |||
| 146 | impl SpiBusFlush for MySpi { | ||
| 147 | type FlushFuture<'a> = impl Future<Output = Result<(), Self::Error>> | ||
| 148 | where | ||
| 149 | Self: 'a; | ||
| 150 | |||
| 151 | fn flush<'a>(&'a mut self) -> Self::FlushFuture<'a> { | ||
| 152 | async move { Ok(()) } | ||
| 153 | } | ||
| 154 | } | ||
| 155 | |||
| 156 | impl SpiBusRead for MySpi { | ||
| 157 | type ReadFuture<'a> = impl Future<Output = Result<(), Self::Error>> | ||
| 158 | where | ||
| 159 | Self: 'a; | ||
| 160 | |||
| 161 | fn read<'a>(&'a mut self, words: &'a mut [u8]) -> Self::ReadFuture<'a> { | ||
| 162 | async move { | ||
| 163 | self.dio.set_as_input(); | ||
| 164 | for word in words { | ||
| 165 | let mut w = 0; | ||
| 166 | for _ in 0..8 { | ||
| 167 | w = w << 1; | ||
| 168 | |||
| 169 | // rising edge, sample data | ||
| 170 | if self.dio.is_high() { | ||
| 171 | w |= 0x01; | ||
| 172 | } | ||
| 173 | self.clk.set_high(); | ||
| 174 | |||
| 175 | // falling edge | ||
| 176 | self.clk.set_low(); | ||
| 177 | } | ||
| 178 | *word = w | ||
| 179 | } | ||
| 180 | |||
| 181 | Ok(()) | ||
| 182 | } | ||
| 183 | } | ||
| 184 | } | ||
| 185 | |||
| 186 | impl SpiBusWrite for MySpi { | ||
| 187 | type WriteFuture<'a> = impl Future<Output = Result<(), Self::Error>> | ||
| 188 | where | ||
| 189 | Self: 'a; | ||
| 190 | |||
| 191 | fn write<'a>(&'a mut self, words: &'a [u8]) -> Self::WriteFuture<'a> { | ||
| 192 | async move { | ||
| 193 | self.dio.set_as_output(); | ||
| 194 | for word in words { | ||
| 195 | let mut word = *word; | ||
| 196 | for _ in 0..8 { | ||
| 197 | // falling edge, setup data | ||
| 198 | self.clk.set_low(); | ||
| 199 | if word & 0x80 == 0 { | ||
| 200 | self.dio.set_low(); | ||
| 201 | } else { | ||
| 202 | self.dio.set_high(); | ||
| 203 | } | ||
| 204 | |||
| 205 | // rising edge | ||
| 206 | self.clk.set_high(); | ||
| 207 | |||
| 208 | word = word << 1; | ||
| 209 | } | ||
| 210 | } | ||
| 211 | self.clk.set_low(); | ||
| 212 | |||
| 213 | self.dio.set_as_input(); | ||
| 214 | Ok(()) | ||
| 215 | } | ||
| 216 | } | ||
| 217 | } | ||
diff --git a/src/lib.rs b/src/lib.rs index dde9d9c34..fb693c323 100644 --- a/src/lib.rs +++ b/src/lib.rs | |||
| @@ -1,6 +1,6 @@ | |||
| 1 | #![no_std] | 1 | #![no_std] |
| 2 | #![no_main] | 2 | #![no_main] |
| 3 | #![feature(type_alias_impl_trait, concat_bytes, const_slice_from_raw_parts)] | 3 | #![feature(type_alias_impl_trait, concat_bytes)] |
| 4 | #![deny(unused_must_use)] | 4 | #![deny(unused_must_use)] |
| 5 | 5 | ||
| 6 | // This mod MUST go first, so that the others see its macros. | 6 | // This mod MUST go first, so that the others see its macros. |
| @@ -21,7 +21,8 @@ use embassy::channel::mpmc::Channel; | |||
| 21 | use embassy::time::{block_for, Duration, Timer}; | 21 | use embassy::time::{block_for, Duration, Timer}; |
| 22 | use embassy::util::yield_now; | 22 | use embassy::util::yield_now; |
| 23 | use embassy_net::{PacketBoxExt, PacketBuf}; | 23 | use embassy_net::{PacketBoxExt, PacketBuf}; |
| 24 | use embassy_rp::gpio::{Flex, Output, Pin}; | 24 | use embedded_hal_1::digital::blocking::OutputPin; |
| 25 | use embedded_hal_async::spi::{SpiBusRead, SpiBusWrite, SpiDevice}; | ||
| 25 | 26 | ||
| 26 | use self::structs::*; | 27 | use self::structs::*; |
| 27 | use crate::events::Event; | 28 | use crate::events::Event; |
| @@ -514,41 +515,26 @@ impl<'a> embassy_net::Device for NetDevice<'a> { | |||
| 514 | } | 515 | } |
| 515 | } | 516 | } |
| 516 | 517 | ||
| 517 | pub struct Runner<'a, PWR: Pin, CS: Pin, CLK: Pin, DIO: Pin> { | 518 | pub struct Runner<'a, PWR, SPI> { |
| 518 | state: &'a State, | 519 | state: &'a State, |
| 519 | 520 | ||
| 520 | pwr: Output<'a, PWR>, | 521 | pwr: PWR, |
| 521 | 522 | spi: SPI, | |
| 522 | /// SPI chip-select. | ||
| 523 | cs: Output<'a, CS>, | ||
| 524 | |||
| 525 | /// SPI clock | ||
| 526 | clk: Output<'a, CLK>, | ||
| 527 | |||
| 528 | /// 4 signals, all in one!! | ||
| 529 | /// - SPI MISO | ||
| 530 | /// - SPI MOSI | ||
| 531 | /// - IRQ | ||
| 532 | /// - strap to set to gSPI mode on boot. | ||
| 533 | dio: Flex<'a, DIO>, | ||
| 534 | 523 | ||
| 535 | ioctl_seq: u8, | 524 | ioctl_seq: u8, |
| 536 | backplane_window: u32, | 525 | backplane_window: u32, |
| 537 | } | 526 | } |
| 538 | 527 | ||
| 539 | pub async fn new<'a, PWR: Pin, CS: Pin, CLK: Pin, DIO: Pin>( | 528 | pub async fn new<'a, PWR, SPI>(state: &'a State, pwr: PWR, spi: SPI) -> (Control<'a>, Runner<'a, PWR, SPI>) |
| 540 | state: &'a State, | 529 | where |
| 541 | pwr: Output<'a, PWR>, | 530 | PWR: OutputPin, |
| 542 | cs: Output<'a, CS>, | 531 | SPI: SpiDevice, |
| 543 | clk: Output<'a, CLK>, | 532 | SPI::Bus: SpiBusRead + SpiBusWrite, |
| 544 | dio: Flex<'a, DIO>, | 533 | { |
| 545 | ) -> (Control<'a>, Runner<'a, PWR, CS, CLK, DIO>) { | ||
| 546 | let mut runner = Runner { | 534 | let mut runner = Runner { |
| 547 | state, | 535 | state, |
| 548 | pwr, | 536 | pwr, |
| 549 | cs, | 537 | spi, |
| 550 | clk, | ||
| 551 | dio, | ||
| 552 | 538 | ||
| 553 | ioctl_seq: 0, | 539 | ioctl_seq: 0, |
| 554 | backplane_window: 0xAAAA_AAAA, | 540 | backplane_window: 0xAAAA_AAAA, |
| @@ -559,52 +545,53 @@ pub async fn new<'a, PWR: Pin, CS: Pin, CLK: Pin, DIO: Pin>( | |||
| 559 | (Control { state }, runner) | 545 | (Control { state }, runner) |
| 560 | } | 546 | } |
| 561 | 547 | ||
| 562 | impl<'a, PWR: Pin, CS: Pin, CLK: Pin, DIO: Pin> Runner<'a, PWR, CS, CLK, DIO> { | 548 | impl<'a, PWR, SPI> Runner<'a, PWR, SPI> |
| 549 | where | ||
| 550 | PWR: OutputPin, | ||
| 551 | SPI: SpiDevice, | ||
| 552 | SPI::Bus: SpiBusRead + SpiBusWrite, | ||
| 553 | { | ||
| 563 | async fn init(&mut self) { | 554 | async fn init(&mut self) { |
| 564 | // Set strap to select gSPI mode. | ||
| 565 | self.dio.set_as_output(); | ||
| 566 | self.dio.set_low(); | ||
| 567 | |||
| 568 | // Reset | 555 | // Reset |
| 569 | self.pwr.set_low(); | 556 | self.pwr.set_low().unwrap(); |
| 570 | Timer::after(Duration::from_millis(20)).await; | 557 | Timer::after(Duration::from_millis(20)).await; |
| 571 | self.pwr.set_high(); | 558 | self.pwr.set_high().unwrap(); |
| 572 | Timer::after(Duration::from_millis(250)).await; | 559 | Timer::after(Duration::from_millis(250)).await; |
| 573 | 560 | ||
| 574 | info!("waiting for ping..."); | 561 | info!("waiting for ping..."); |
| 575 | while self.read32_swapped(REG_BUS_FEEDBEAD) != FEEDBEAD {} | 562 | while self.read32_swapped(REG_BUS_FEEDBEAD).await != FEEDBEAD {} |
| 576 | info!("ping ok"); | 563 | info!("ping ok"); |
| 577 | 564 | ||
| 578 | self.write32_swapped(0x18, TEST_PATTERN); | 565 | self.write32_swapped(0x18, TEST_PATTERN).await; |
| 579 | let val = self.read32_swapped(REG_BUS_TEST); | 566 | let val = self.read32_swapped(REG_BUS_TEST).await; |
| 580 | assert_eq!(val, TEST_PATTERN); | 567 | assert_eq!(val, TEST_PATTERN); |
| 581 | 568 | ||
| 582 | // 32bit, big endian. | 569 | // 32bit, big endian. |
| 583 | self.write32_swapped(REG_BUS_CTRL, 0x00010033); | 570 | self.write32_swapped(REG_BUS_CTRL, 0x00010033).await; |
| 584 | 571 | ||
| 585 | let val = self.read32(FUNC_BUS, REG_BUS_FEEDBEAD); | 572 | let val = self.read32(FUNC_BUS, REG_BUS_FEEDBEAD).await; |
| 586 | assert_eq!(val, FEEDBEAD); | 573 | assert_eq!(val, FEEDBEAD); |
| 587 | let val = self.read32(FUNC_BUS, REG_BUS_TEST); | 574 | let val = self.read32(FUNC_BUS, REG_BUS_TEST).await; |
| 588 | assert_eq!(val, TEST_PATTERN); | 575 | assert_eq!(val, TEST_PATTERN); |
| 589 | 576 | ||
| 590 | // No response delay in any of the funcs. | 577 | // No response delay in any of the funcs. |
| 591 | // seems to break backplane??? eat the 4-byte delay instead, that's what the vendor drivers do... | 578 | // seems to break backplane??? eat the 4-byte delay instead, that's what the vendor drivers do... |
| 592 | //self.write32(FUNC_BUS, REG_BUS_RESP_DELAY, 0); | 579 | //self.write32(FUNC_BUS, REG_BUS_RESP_DELAY, 0).await; |
| 593 | 580 | ||
| 594 | // Init ALP (no idea what that stands for) clock | 581 | // Init ALP (no idea what that stands for) clock |
| 595 | self.write8(FUNC_BACKPLANE, REG_BACKPLANE_CHIP_CLOCK_CSR, 0x08); | 582 | self.write8(FUNC_BACKPLANE, REG_BACKPLANE_CHIP_CLOCK_CSR, 0x08).await; |
| 596 | info!("waiting for clock..."); | 583 | info!("waiting for clock..."); |
| 597 | while self.read8(FUNC_BACKPLANE, REG_BACKPLANE_CHIP_CLOCK_CSR) & 0x40 == 0 {} | 584 | while self.read8(FUNC_BACKPLANE, REG_BACKPLANE_CHIP_CLOCK_CSR).await & 0x40 == 0 {} |
| 598 | info!("clock ok"); | 585 | info!("clock ok"); |
| 599 | 586 | ||
| 600 | let chip_id = self.bp_read16(0x1800_0000); | 587 | let chip_id = self.bp_read16(0x1800_0000).await; |
| 601 | info!("chip ID: {}", chip_id); | 588 | info!("chip ID: {}", chip_id); |
| 602 | 589 | ||
| 603 | // Upload firmware. | 590 | // Upload firmware. |
| 604 | self.core_disable(Core::WLAN); | 591 | self.core_disable(Core::WLAN).await; |
| 605 | self.core_reset(Core::SOCSRAM); | 592 | self.core_reset(Core::SOCSRAM).await; |
| 606 | self.bp_write32(CHIP.socsram_base_address + 0x10, 3); | 593 | self.bp_write32(CHIP.socsram_base_address + 0x10, 3).await; |
| 607 | self.bp_write32(CHIP.socsram_base_address + 0x44, 0); | 594 | self.bp_write32(CHIP.socsram_base_address + 0x44, 0).await; |
| 608 | 595 | ||
| 609 | let ram_addr = CHIP.atcm_ram_base_address; | 596 | let ram_addr = CHIP.atcm_ram_base_address; |
| 610 | 597 | ||
| @@ -618,42 +605,44 @@ impl<'a, PWR: Pin, CS: Pin, CLK: Pin, DIO: Pin> Runner<'a, PWR, CS, CLK, DIO> { | |||
| 618 | let fw = unsafe { slice::from_raw_parts(0x10100000 as *const u8, 224190) }; | 605 | let fw = unsafe { slice::from_raw_parts(0x10100000 as *const u8, 224190) }; |
| 619 | 606 | ||
| 620 | info!("loading fw"); | 607 | info!("loading fw"); |
| 621 | self.bp_write(ram_addr, fw); | 608 | self.bp_write(ram_addr, fw).await; |
| 622 | 609 | ||
| 623 | info!("verifying fw"); | 610 | info!("verifying fw"); |
| 624 | let mut buf = [0; 1024]; | 611 | let mut buf = [0; 1024]; |
| 625 | for (i, chunk) in fw.chunks(1024).enumerate() { | 612 | for (i, chunk) in fw.chunks(1024).enumerate() { |
| 626 | let buf = &mut buf[..chunk.len()]; | 613 | let buf = &mut buf[..chunk.len()]; |
| 627 | self.bp_read(ram_addr + i as u32 * 1024, buf); | 614 | self.bp_read(ram_addr + i as u32 * 1024, buf).await; |
| 628 | assert_eq!(chunk, buf); | 615 | assert_eq!(chunk, buf); |
| 629 | } | 616 | } |
| 630 | 617 | ||
| 631 | info!("loading nvram"); | 618 | info!("loading nvram"); |
| 632 | // Round up to 4 bytes. | 619 | // Round up to 4 bytes. |
| 633 | let nvram_len = (NVRAM.len() + 3) / 4 * 4; | 620 | let nvram_len = (NVRAM.len() + 3) / 4 * 4; |
| 634 | self.bp_write(ram_addr + CHIP.chip_ram_size - 4 - nvram_len as u32, NVRAM); | 621 | self.bp_write(ram_addr + CHIP.chip_ram_size - 4 - nvram_len as u32, NVRAM) |
| 622 | .await; | ||
| 635 | 623 | ||
| 636 | let nvram_len_words = nvram_len as u32 / 4; | 624 | let nvram_len_words = nvram_len as u32 / 4; |
| 637 | let nvram_len_magic = (!nvram_len_words << 16) | nvram_len_words; | 625 | let nvram_len_magic = (!nvram_len_words << 16) | nvram_len_words; |
| 638 | self.bp_write32(ram_addr + CHIP.chip_ram_size - 4, nvram_len_magic); | 626 | self.bp_write32(ram_addr + CHIP.chip_ram_size - 4, nvram_len_magic) |
| 627 | .await; | ||
| 639 | 628 | ||
| 640 | // Start core! | 629 | // Start core! |
| 641 | info!("starting up core..."); | 630 | info!("starting up core..."); |
| 642 | self.core_reset(Core::WLAN); | 631 | self.core_reset(Core::WLAN).await; |
| 643 | assert!(self.core_is_up(Core::WLAN)); | 632 | assert!(self.core_is_up(Core::WLAN).await); |
| 644 | 633 | ||
| 645 | while self.read8(FUNC_BACKPLANE, REG_BACKPLANE_CHIP_CLOCK_CSR) & 0x80 == 0 {} | 634 | while self.read8(FUNC_BACKPLANE, REG_BACKPLANE_CHIP_CLOCK_CSR).await & 0x80 == 0 {} |
| 646 | 635 | ||
| 647 | // "Set up the interrupt mask and enable interrupts" | 636 | // "Set up the interrupt mask and enable interrupts" |
| 648 | self.bp_write32(CHIP.sdiod_core_base_address + 0x24, 0xF0); | 637 | self.bp_write32(CHIP.sdiod_core_base_address + 0x24, 0xF0).await; |
| 649 | 638 | ||
| 650 | // "Lower F2 Watermark to avoid DMA Hang in F2 when SD Clock is stopped." | 639 | // "Lower F2 Watermark to avoid DMA Hang in F2 when SD Clock is stopped." |
| 651 | // Sounds scary... | 640 | // Sounds scary... |
| 652 | self.write8(FUNC_BACKPLANE, REG_BACKPLANE_FUNCTION2_WATERMARK, 32); | 641 | self.write8(FUNC_BACKPLANE, REG_BACKPLANE_FUNCTION2_WATERMARK, 32).await; |
| 653 | 642 | ||
| 654 | // wait for wifi startup | 643 | // wait for wifi startup |
| 655 | info!("waiting for wifi init..."); | 644 | info!("waiting for wifi init..."); |
| 656 | while self.read32(FUNC_BUS, REG_BUS_STATUS) & STATUS_F2_RX_READY == 0 {} | 645 | while self.read32(FUNC_BUS, REG_BUS_STATUS).await & STATUS_F2_RX_READY == 0 {} |
| 657 | 646 | ||
| 658 | // Some random configs related to sleep. | 647 | // Some random configs related to sleep. |
| 659 | // These aren't needed if we don't want to sleep the bus. | 648 | // These aren't needed if we don't want to sleep the bus. |
| @@ -661,25 +650,25 @@ impl<'a, PWR: Pin, CS: Pin, CLK: Pin, DIO: Pin> Runner<'a, PWR, CS, CLK, DIO> { | |||
| 661 | // being on the same pin as MOSI/MISO? | 650 | // being on the same pin as MOSI/MISO? |
| 662 | 651 | ||
| 663 | /* | 652 | /* |
| 664 | let mut val = self.read8(FUNC_BACKPLANE, REG_BACKPLANE_WAKEUP_CTRL); | 653 | let mut val = self.read8(FUNC_BACKPLANE, REG_BACKPLANE_WAKEUP_CTRL).await; |
| 665 | val |= 0x02; // WAKE_TILL_HT_AVAIL | 654 | val |= 0x02; // WAKE_TILL_HT_AVAIL |
| 666 | self.write8(FUNC_BACKPLANE, REG_BACKPLANE_WAKEUP_CTRL, val); | 655 | self.write8(FUNC_BACKPLANE, REG_BACKPLANE_WAKEUP_CTRL, val).await; |
| 667 | self.write8(FUNC_BUS, 0xF0, 0x08); // SDIOD_CCCR_BRCM_CARDCAP.CMD_NODEC = 1 | 656 | self.write8(FUNC_BUS, 0xF0, 0x08).await; // SDIOD_CCCR_BRCM_CARDCAP.CMD_NODEC = 1 |
| 668 | self.write8(FUNC_BACKPLANE, REG_BACKPLANE_CHIP_CLOCK_CSR, 0x02); // SBSDIO_FORCE_HT | 657 | self.write8(FUNC_BACKPLANE, REG_BACKPLANE_CHIP_CLOCK_CSR, 0x02).await; // SBSDIO_FORCE_HT |
| 669 | 658 | ||
| 670 | let mut val = self.read8(FUNC_BACKPLANE, REG_BACKPLANE_SLEEP_CSR); | 659 | let mut val = self.read8(FUNC_BACKPLANE, REG_BACKPLANE_SLEEP_CSR).await; |
| 671 | val |= 0x01; // SBSDIO_SLPCSR_KEEP_SDIO_ON | 660 | val |= 0x01; // SBSDIO_SLPCSR_KEEP_SDIO_ON |
| 672 | self.write8(FUNC_BACKPLANE, REG_BACKPLANE_SLEEP_CSR, val); | 661 | self.write8(FUNC_BACKPLANE, REG_BACKPLANE_SLEEP_CSR, val).await; |
| 673 | */ | 662 | */ |
| 674 | 663 | ||
| 675 | // clear pulls | 664 | // clear pulls |
| 676 | self.write8(FUNC_BACKPLANE, REG_BACKPLANE_PULL_UP, 0); | 665 | self.write8(FUNC_BACKPLANE, REG_BACKPLANE_PULL_UP, 0).await; |
| 677 | let _ = self.read8(FUNC_BACKPLANE, REG_BACKPLANE_PULL_UP); | 666 | let _ = self.read8(FUNC_BACKPLANE, REG_BACKPLANE_PULL_UP).await; |
| 678 | 667 | ||
| 679 | // start HT clock | 668 | // start HT clock |
| 680 | //self.write8(FUNC_BACKPLANE, REG_BACKPLANE_CHIP_CLOCK_CSR, 0x10); | 669 | //self.write8(FUNC_BACKPLANE, REG_BACKPLANE_CHIP_CLOCK_CSR, 0x10).await; |
| 681 | //info!("waiting for HT clock..."); | 670 | //info!("waiting for HT clock..."); |
| 682 | //while self.read8(FUNC_BACKPLANE, REG_BACKPLANE_CHIP_CLOCK_CSR) & 0x80 == 0 {} | 671 | //while self.read8(FUNC_BACKPLANE, REG_BACKPLANE_CHIP_CLOCK_CSR).await & 0x80 == 0 {} |
| 683 | //info!("clock ok"); | 672 | //info!("clock ok"); |
| 684 | 673 | ||
| 685 | info!("init done "); | 674 | info!("init done "); |
| @@ -691,21 +680,22 @@ impl<'a, PWR: Pin, CS: Pin, CLK: Pin, DIO: Pin> Runner<'a, PWR, CS, CLK, DIO> { | |||
| 691 | // Send stuff | 680 | // Send stuff |
| 692 | // TODO flow control | 681 | // TODO flow control |
| 693 | if let IoctlState::Pending { kind, cmd, iface, buf } = self.state.ioctl_state.get() { | 682 | if let IoctlState::Pending { kind, cmd, iface, buf } = self.state.ioctl_state.get() { |
| 694 | self.send_ioctl(kind, cmd, iface, unsafe { &*buf }, self.state.ioctl_id.get()); | 683 | self.send_ioctl(kind, cmd, iface, unsafe { &*buf }, self.state.ioctl_id.get()) |
| 684 | .await; | ||
| 695 | self.state.ioctl_state.set(IoctlState::Sent { buf }); | 685 | self.state.ioctl_state.set(IoctlState::Sent { buf }); |
| 696 | } | 686 | } |
| 697 | 687 | ||
| 698 | if let Ok(p) = self.state.tx_channel.try_recv() { | 688 | if let Ok(p) = self.state.tx_channel.try_recv() { |
| 699 | self.send_packet(&p); | 689 | self.send_packet(&p).await; |
| 700 | } | 690 | } |
| 701 | 691 | ||
| 702 | // Receive stuff | 692 | // Receive stuff |
| 703 | let irq = self.read16(FUNC_BUS, REG_BUS_INTERRUPT); | 693 | let irq = self.read16(FUNC_BUS, REG_BUS_INTERRUPT).await; |
| 704 | 694 | ||
| 705 | if irq & IRQ_F2_PACKET_AVAILABLE != 0 { | 695 | if irq & IRQ_F2_PACKET_AVAILABLE != 0 { |
| 706 | let mut status = 0xFFFF_FFFF; | 696 | let mut status = 0xFFFF_FFFF; |
| 707 | while status == 0xFFFF_FFFF { | 697 | while status == 0xFFFF_FFFF { |
| 708 | status = self.read32(FUNC_BUS, REG_BUS_STATUS); | 698 | status = self.read32(FUNC_BUS, REG_BUS_STATUS).await; |
| 709 | } | 699 | } |
| 710 | 700 | ||
| 711 | if status & STATUS_F2_PKT_AVAILABLE != 0 { | 701 | if status & STATUS_F2_PKT_AVAILABLE != 0 { |
| @@ -713,15 +703,23 @@ impl<'a, PWR: Pin, CS: Pin, CLK: Pin, DIO: Pin> Runner<'a, PWR, CS, CLK, DIO> { | |||
| 713 | 703 | ||
| 714 | let cmd = cmd_word(false, true, FUNC_WLAN, 0, len); | 704 | let cmd = cmd_word(false, true, FUNC_WLAN, 0, len); |
| 715 | 705 | ||
| 716 | self.cs.set_low(); | 706 | self.spi |
| 717 | self.spi_write(&cmd.to_le_bytes()); | 707 | .transaction(|bus| { |
| 718 | self.spi_read(&mut buf[..len as usize]); | 708 | let bus = unsafe { &mut *bus }; |
| 719 | // pad to 32bit | 709 | async { |
| 720 | let mut junk = [0; 4]; | 710 | bus.write(&cmd.to_le_bytes()).await?; |
| 721 | if len % 4 != 0 { | 711 | bus.read(&mut buf[..len as usize]).await?; |
| 722 | self.spi_read(&mut junk[..(4 - len as usize % 4)]); | 712 | // pad to 32bit |
| 723 | } | 713 | let mut junk = [0; 4]; |
| 724 | self.cs.set_high(); | 714 | if len % 4 != 0 { |
| 715 | bus.read(&mut junk[..(4 - len as usize % 4)]).await?; | ||
| 716 | } | ||
| 717 | |||
| 718 | Ok(()) | ||
| 719 | } | ||
| 720 | }) | ||
| 721 | .await | ||
| 722 | .unwrap(); | ||
| 725 | 723 | ||
| 726 | trace!("rx {:02x}", &buf[..(len as usize).min(48)]); | 724 | trace!("rx {:02x}", &buf[..(len as usize).min(48)]); |
| 727 | 725 | ||
| @@ -734,7 +732,7 @@ impl<'a, PWR: Pin, CS: Pin, CLK: Pin, DIO: Pin> Runner<'a, PWR, CS, CLK, DIO> { | |||
| 734 | } | 732 | } |
| 735 | } | 733 | } |
| 736 | 734 | ||
| 737 | fn send_packet(&mut self, packet: &[u8]) { | 735 | async fn send_packet(&mut self, packet: &[u8]) { |
| 738 | trace!("tx pkt {:02x}", &packet[..packet.len().min(48)]); | 736 | trace!("tx pkt {:02x}", &packet[..packet.len().min(48)]); |
| 739 | 737 | ||
| 740 | let mut buf = [0; 2048]; | 738 | let mut buf = [0; 2048]; |
| @@ -774,10 +772,17 @@ impl<'a, PWR: Pin, CS: Pin, CLK: Pin, DIO: Pin> Runner<'a, PWR, CS, CLK, DIO> { | |||
| 774 | trace!(" {:02x}", &buf[..total_len.min(48)]); | 772 | trace!(" {:02x}", &buf[..total_len.min(48)]); |
| 775 | 773 | ||
| 776 | let cmd = cmd_word(true, true, FUNC_WLAN, 0, total_len as _); | 774 | let cmd = cmd_word(true, true, FUNC_WLAN, 0, total_len as _); |
| 777 | self.cs.set_low(); | 775 | self.spi |
| 778 | self.spi_write(&cmd.to_le_bytes()); | 776 | .transaction(|bus| { |
| 779 | self.spi_write(&buf[..total_len]); | 777 | let bus = unsafe { &mut *bus }; |
| 780 | self.cs.set_high(); | 778 | async { |
| 779 | bus.write(&cmd.to_le_bytes()).await?; | ||
| 780 | bus.write(&buf[..total_len]).await?; | ||
| 781 | Ok(()) | ||
| 782 | } | ||
| 783 | }) | ||
| 784 | .await | ||
| 785 | .unwrap(); | ||
| 781 | } | 786 | } |
| 782 | 787 | ||
| 783 | fn rx(&mut self, packet: &[u8]) { | 788 | fn rx(&mut self, packet: &[u8]) { |
| @@ -869,7 +874,7 @@ impl<'a, PWR: Pin, CS: Pin, CLK: Pin, DIO: Pin> Runner<'a, PWR, CS, CLK, DIO> { | |||
| 869 | } | 874 | } |
| 870 | } | 875 | } |
| 871 | 876 | ||
| 872 | fn send_ioctl(&mut self, kind: u32, cmd: u32, iface: u32, data: &[u8], id: u16) { | 877 | async fn send_ioctl(&mut self, kind: u32, cmd: u32, iface: u32, data: &[u8], id: u16) { |
| 873 | let mut buf = [0; 2048]; | 878 | let mut buf = [0; 2048]; |
| 874 | 879 | ||
| 875 | let total_len = SdpcmHeader::SIZE + CdcHeader::SIZE + data.len(); | 880 | let total_len = SdpcmHeader::SIZE + CdcHeader::SIZE + data.len(); |
| @@ -908,60 +913,69 @@ impl<'a, PWR: Pin, CS: Pin, CLK: Pin, DIO: Pin> Runner<'a, PWR, CS, CLK, DIO> { | |||
| 908 | trace!(" {:02x}", &buf[..total_len.min(48)]); | 913 | trace!(" {:02x}", &buf[..total_len.min(48)]); |
| 909 | 914 | ||
| 910 | let cmd = cmd_word(true, true, FUNC_WLAN, 0, total_len as _); | 915 | let cmd = cmd_word(true, true, FUNC_WLAN, 0, total_len as _); |
| 911 | self.cs.set_low(); | 916 | |
| 912 | self.spi_write(&cmd.to_le_bytes()); | 917 | self.spi |
| 913 | self.spi_write(&buf[..total_len]); | 918 | .transaction(|bus| { |
| 914 | self.cs.set_high(); | 919 | let bus = unsafe { &mut *bus }; |
| 920 | async { | ||
| 921 | bus.write(&cmd.to_le_bytes()).await?; | ||
| 922 | bus.write(&buf[..total_len]).await?; | ||
| 923 | Ok(()) | ||
| 924 | } | ||
| 925 | }) | ||
| 926 | .await | ||
| 927 | .unwrap(); | ||
| 915 | } | 928 | } |
| 916 | 929 | ||
| 917 | fn core_disable(&mut self, core: Core) { | 930 | async fn core_disable(&mut self, core: Core) { |
| 918 | let base = core.base_addr(); | 931 | let base = core.base_addr(); |
| 919 | 932 | ||
| 920 | // Dummy read? | 933 | // Dummy read? |
| 921 | let _ = self.bp_read8(base + AI_RESETCTRL_OFFSET); | 934 | let _ = self.bp_read8(base + AI_RESETCTRL_OFFSET).await; |
| 922 | 935 | ||
| 923 | // Check it isn't already reset | 936 | // Check it isn't already reset |
| 924 | let r = self.bp_read8(base + AI_RESETCTRL_OFFSET); | 937 | let r = self.bp_read8(base + AI_RESETCTRL_OFFSET).await; |
| 925 | if r & AI_RESETCTRL_BIT_RESET != 0 { | 938 | if r & AI_RESETCTRL_BIT_RESET != 0 { |
| 926 | return; | 939 | return; |
| 927 | } | 940 | } |
| 928 | 941 | ||
| 929 | self.bp_write8(base + AI_IOCTRL_OFFSET, 0); | 942 | self.bp_write8(base + AI_IOCTRL_OFFSET, 0).await; |
| 930 | let _ = self.bp_read8(base + AI_IOCTRL_OFFSET); | 943 | let _ = self.bp_read8(base + AI_IOCTRL_OFFSET).await; |
| 931 | 944 | ||
| 932 | block_for(Duration::from_millis(1)); | 945 | block_for(Duration::from_millis(1)); |
| 933 | 946 | ||
| 934 | self.bp_write8(base + AI_RESETCTRL_OFFSET, AI_RESETCTRL_BIT_RESET); | 947 | self.bp_write8(base + AI_RESETCTRL_OFFSET, AI_RESETCTRL_BIT_RESET).await; |
| 935 | let _ = self.bp_read8(base + AI_RESETCTRL_OFFSET); | 948 | let _ = self.bp_read8(base + AI_RESETCTRL_OFFSET).await; |
| 936 | } | 949 | } |
| 937 | 950 | ||
| 938 | fn core_reset(&mut self, core: Core) { | 951 | async fn core_reset(&mut self, core: Core) { |
| 939 | self.core_disable(core); | 952 | self.core_disable(core).await; |
| 940 | 953 | ||
| 941 | let base = core.base_addr(); | 954 | let base = core.base_addr(); |
| 942 | self.bp_write8(base + AI_IOCTRL_OFFSET, AI_IOCTRL_BIT_FGC | AI_IOCTRL_BIT_CLOCK_EN); | 955 | self.bp_write8(base + AI_IOCTRL_OFFSET, AI_IOCTRL_BIT_FGC | AI_IOCTRL_BIT_CLOCK_EN) |
| 943 | let _ = self.bp_read8(base + AI_IOCTRL_OFFSET); | 956 | .await; |
| 957 | let _ = self.bp_read8(base + AI_IOCTRL_OFFSET).await; | ||
| 944 | 958 | ||
| 945 | self.bp_write8(base + AI_RESETCTRL_OFFSET, 0); | 959 | self.bp_write8(base + AI_RESETCTRL_OFFSET, 0).await; |
| 946 | 960 | ||
| 947 | block_for(Duration::from_millis(1)); | 961 | Timer::after(Duration::from_millis(1)).await; |
| 948 | 962 | ||
| 949 | self.bp_write8(base + AI_IOCTRL_OFFSET, AI_IOCTRL_BIT_CLOCK_EN); | 963 | self.bp_write8(base + AI_IOCTRL_OFFSET, AI_IOCTRL_BIT_CLOCK_EN).await; |
| 950 | let _ = self.bp_read8(base + AI_IOCTRL_OFFSET); | 964 | let _ = self.bp_read8(base + AI_IOCTRL_OFFSET).await; |
| 951 | 965 | ||
| 952 | block_for(Duration::from_millis(1)); | 966 | Timer::after(Duration::from_millis(1)).await; |
| 953 | } | 967 | } |
| 954 | 968 | ||
| 955 | fn core_is_up(&mut self, core: Core) -> bool { | 969 | async fn core_is_up(&mut self, core: Core) -> bool { |
| 956 | let base = core.base_addr(); | 970 | let base = core.base_addr(); |
| 957 | 971 | ||
| 958 | let io = self.bp_read8(base + AI_IOCTRL_OFFSET); | 972 | let io = self.bp_read8(base + AI_IOCTRL_OFFSET).await; |
| 959 | if io & (AI_IOCTRL_BIT_FGC | AI_IOCTRL_BIT_CLOCK_EN) != AI_IOCTRL_BIT_CLOCK_EN { | 973 | if io & (AI_IOCTRL_BIT_FGC | AI_IOCTRL_BIT_CLOCK_EN) != AI_IOCTRL_BIT_CLOCK_EN { |
| 960 | debug!("core_is_up: returning false due to bad ioctrl {:02x}", io); | 974 | debug!("core_is_up: returning false due to bad ioctrl {:02x}", io); |
| 961 | return false; | 975 | return false; |
| 962 | } | 976 | } |
| 963 | 977 | ||
| 964 | let r = self.bp_read8(base + AI_RESETCTRL_OFFSET); | 978 | let r = self.bp_read8(base + AI_RESETCTRL_OFFSET).await; |
| 965 | if r & (AI_RESETCTRL_BIT_RESET) != 0 { | 979 | if r & (AI_RESETCTRL_BIT_RESET) != 0 { |
| 966 | debug!("core_is_up: returning false due to bad resetctrl {:02x}", r); | 980 | debug!("core_is_up: returning false due to bad resetctrl {:02x}", r); |
| 967 | return false; | 981 | return false; |
| @@ -970,7 +984,7 @@ impl<'a, PWR: Pin, CS: Pin, CLK: Pin, DIO: Pin> Runner<'a, PWR, CS, CLK, DIO> { | |||
| 970 | true | 984 | true |
| 971 | } | 985 | } |
| 972 | 986 | ||
| 973 | fn bp_read(&mut self, mut addr: u32, mut data: &mut [u8]) { | 987 | async fn bp_read(&mut self, mut addr: u32, mut data: &mut [u8]) { |
| 974 | // It seems the HW force-aligns the addr | 988 | // It seems the HW force-aligns the addr |
| 975 | // to 2 if data.len() >= 2 | 989 | // to 2 if data.len() >= 2 |
| 976 | // to 4 if data.len() >= 4 | 990 | // to 4 if data.len() >= 4 |
| @@ -984,24 +998,32 @@ impl<'a, PWR: Pin, CS: Pin, CLK: Pin, DIO: Pin> Runner<'a, PWR, CS, CLK, DIO> { | |||
| 984 | 998 | ||
| 985 | let len = data.len().min(BACKPLANE_MAX_TRANSFER_SIZE).min(window_remaining); | 999 | let len = data.len().min(BACKPLANE_MAX_TRANSFER_SIZE).min(window_remaining); |
| 986 | 1000 | ||
| 987 | self.backplane_set_window(addr); | 1001 | self.backplane_set_window(addr).await; |
| 988 | 1002 | ||
| 989 | let cmd = cmd_word(false, true, FUNC_BACKPLANE, window_offs, len as u32); | 1003 | let cmd = cmd_word(false, true, FUNC_BACKPLANE, window_offs, len as u32); |
| 990 | self.cs.set_low(); | ||
| 991 | self.spi_write(&cmd.to_le_bytes()); | ||
| 992 | 1004 | ||
| 993 | // 4-byte response delay. | 1005 | self.spi |
| 994 | let mut junk = [0; 4]; | 1006 | .transaction(|bus| { |
| 995 | self.spi_read(&mut junk); | 1007 | let bus = unsafe { &mut *bus }; |
| 1008 | async { | ||
| 1009 | bus.write(&cmd.to_le_bytes()).await?; | ||
| 996 | 1010 | ||
| 997 | // Read data | 1011 | // 4-byte response delay. |
| 998 | self.spi_read(&mut data[..len]); | 1012 | let mut junk = [0; 4]; |
| 1013 | bus.read(&mut junk).await?; | ||
| 999 | 1014 | ||
| 1000 | // pad to 32bit | 1015 | // Read data |
| 1001 | if len % 4 != 0 { | 1016 | bus.read(&mut data[..len]).await?; |
| 1002 | self.spi_read(&mut junk[..(4 - len % 4)]); | 1017 | |
| 1003 | } | 1018 | // pad to 32bit |
| 1004 | self.cs.set_high(); | 1019 | if len % 4 != 0 { |
| 1020 | bus.read(&mut junk[..(4 - len % 4)]).await?; | ||
| 1021 | } | ||
| 1022 | Ok(()) | ||
| 1023 | } | ||
| 1024 | }) | ||
| 1025 | .await | ||
| 1026 | .unwrap(); | ||
| 1005 | 1027 | ||
| 1006 | // Advance ptr. | 1028 | // Advance ptr. |
| 1007 | addr += len as u32; | 1029 | addr += len as u32; |
| @@ -1009,7 +1031,7 @@ impl<'a, PWR: Pin, CS: Pin, CLK: Pin, DIO: Pin> Runner<'a, PWR, CS, CLK, DIO> { | |||
| 1009 | } | 1031 | } |
| 1010 | } | 1032 | } |
| 1011 | 1033 | ||
| 1012 | fn bp_write(&mut self, mut addr: u32, mut data: &[u8]) { | 1034 | async fn bp_write(&mut self, mut addr: u32, mut data: &[u8]) { |
| 1013 | // It seems the HW force-aligns the addr | 1035 | // It seems the HW force-aligns the addr |
| 1014 | // to 2 if data.len() >= 2 | 1036 | // to 2 if data.len() >= 2 |
| 1015 | // to 4 if data.len() >= 4 | 1037 | // to 4 if data.len() >= 4 |
| @@ -1023,18 +1045,26 @@ impl<'a, PWR: Pin, CS: Pin, CLK: Pin, DIO: Pin> Runner<'a, PWR, CS, CLK, DIO> { | |||
| 1023 | 1045 | ||
| 1024 | let len = data.len().min(BACKPLANE_MAX_TRANSFER_SIZE).min(window_remaining); | 1046 | let len = data.len().min(BACKPLANE_MAX_TRANSFER_SIZE).min(window_remaining); |
| 1025 | 1047 | ||
| 1026 | self.backplane_set_window(addr); | 1048 | self.backplane_set_window(addr).await; |
| 1027 | 1049 | ||
| 1028 | let cmd = cmd_word(true, true, FUNC_BACKPLANE, window_offs, len as u32); | 1050 | let cmd = cmd_word(true, true, FUNC_BACKPLANE, window_offs, len as u32); |
| 1029 | self.cs.set_low(); | 1051 | |
| 1030 | self.spi_write(&cmd.to_le_bytes()); | 1052 | self.spi |
| 1031 | self.spi_write(&data[..len]); | 1053 | .transaction(|bus| { |
| 1032 | // pad to 32bit | 1054 | let bus = unsafe { &mut *bus }; |
| 1033 | if len % 4 != 0 { | 1055 | async { |
| 1034 | let zeros = [0; 4]; | 1056 | bus.write(&cmd.to_le_bytes()).await?; |
| 1035 | self.spi_write(&zeros[..(4 - len % 4)]); | 1057 | bus.write(&data[..len]).await?; |
| 1036 | } | 1058 | // pad to 32bit |
| 1037 | self.cs.set_high(); | 1059 | if len % 4 != 0 { |
| 1060 | let zeros = [0; 4]; | ||
| 1061 | bus.write(&zeros[..(4 - len % 4)]).await?; | ||
| 1062 | } | ||
| 1063 | Ok(()) | ||
| 1064 | } | ||
| 1065 | }) | ||
| 1066 | .await | ||
| 1067 | .unwrap(); | ||
| 1038 | 1068 | ||
| 1039 | // Advance ptr. | 1069 | // Advance ptr. |
| 1040 | addr += len as u32; | 1070 | addr += len as u32; |
| @@ -1042,51 +1072,51 @@ impl<'a, PWR: Pin, CS: Pin, CLK: Pin, DIO: Pin> Runner<'a, PWR, CS, CLK, DIO> { | |||
| 1042 | } | 1072 | } |
| 1043 | } | 1073 | } |
| 1044 | 1074 | ||
| 1045 | fn bp_read8(&mut self, addr: u32) -> u8 { | 1075 | async fn bp_read8(&mut self, addr: u32) -> u8 { |
| 1046 | self.backplane_readn(addr, 1) as u8 | 1076 | self.backplane_readn(addr, 1).await as u8 |
| 1047 | } | 1077 | } |
| 1048 | 1078 | ||
| 1049 | fn bp_write8(&mut self, addr: u32, val: u8) { | 1079 | async fn bp_write8(&mut self, addr: u32, val: u8) { |
| 1050 | self.backplane_writen(addr, val as u32, 1) | 1080 | self.backplane_writen(addr, val as u32, 1).await |
| 1051 | } | 1081 | } |
| 1052 | 1082 | ||
| 1053 | fn bp_read16(&mut self, addr: u32) -> u16 { | 1083 | async fn bp_read16(&mut self, addr: u32) -> u16 { |
| 1054 | self.backplane_readn(addr, 2) as u16 | 1084 | self.backplane_readn(addr, 2).await as u16 |
| 1055 | } | 1085 | } |
| 1056 | 1086 | ||
| 1057 | fn bp_write16(&mut self, addr: u32, val: u16) { | 1087 | async fn bp_write16(&mut self, addr: u32, val: u16) { |
| 1058 | self.backplane_writen(addr, val as u32, 2) | 1088 | self.backplane_writen(addr, val as u32, 2).await |
| 1059 | } | 1089 | } |
| 1060 | 1090 | ||
| 1061 | fn bp_read32(&mut self, addr: u32) -> u32 { | 1091 | async fn bp_read32(&mut self, addr: u32) -> u32 { |
| 1062 | self.backplane_readn(addr, 4) | 1092 | self.backplane_readn(addr, 4).await |
| 1063 | } | 1093 | } |
| 1064 | 1094 | ||
| 1065 | fn bp_write32(&mut self, addr: u32, val: u32) { | 1095 | async fn bp_write32(&mut self, addr: u32, val: u32) { |
| 1066 | self.backplane_writen(addr, val, 4) | 1096 | self.backplane_writen(addr, val, 4).await |
| 1067 | } | 1097 | } |
| 1068 | 1098 | ||
| 1069 | fn backplane_readn(&mut self, addr: u32, len: u32) -> u32 { | 1099 | async fn backplane_readn(&mut self, addr: u32, len: u32) -> u32 { |
| 1070 | self.backplane_set_window(addr); | 1100 | self.backplane_set_window(addr).await; |
| 1071 | 1101 | ||
| 1072 | let mut bus_addr = addr & BACKPLANE_ADDRESS_MASK; | 1102 | let mut bus_addr = addr & BACKPLANE_ADDRESS_MASK; |
| 1073 | if len == 4 { | 1103 | if len == 4 { |
| 1074 | bus_addr |= BACKPLANE_ADDRESS_32BIT_FLAG | 1104 | bus_addr |= BACKPLANE_ADDRESS_32BIT_FLAG |
| 1075 | } | 1105 | } |
| 1076 | self.readn(FUNC_BACKPLANE, bus_addr, len) | 1106 | self.readn(FUNC_BACKPLANE, bus_addr, len).await |
| 1077 | } | 1107 | } |
| 1078 | 1108 | ||
| 1079 | fn backplane_writen(&mut self, addr: u32, val: u32, len: u32) { | 1109 | async fn backplane_writen(&mut self, addr: u32, val: u32, len: u32) { |
| 1080 | self.backplane_set_window(addr); | 1110 | self.backplane_set_window(addr).await; |
| 1081 | 1111 | ||
| 1082 | let mut bus_addr = addr & BACKPLANE_ADDRESS_MASK; | 1112 | let mut bus_addr = addr & BACKPLANE_ADDRESS_MASK; |
| 1083 | if len == 4 { | 1113 | if len == 4 { |
| 1084 | bus_addr |= BACKPLANE_ADDRESS_32BIT_FLAG | 1114 | bus_addr |= BACKPLANE_ADDRESS_32BIT_FLAG |
| 1085 | } | 1115 | } |
| 1086 | self.writen(FUNC_BACKPLANE, bus_addr, val, len) | 1116 | self.writen(FUNC_BACKPLANE, bus_addr, val, len).await |
| 1087 | } | 1117 | } |
| 1088 | 1118 | ||
| 1089 | fn backplane_set_window(&mut self, addr: u32) { | 1119 | async fn backplane_set_window(&mut self, addr: u32) { |
| 1090 | let new_window = addr & !BACKPLANE_ADDRESS_MASK; | 1120 | let new_window = addr & !BACKPLANE_ADDRESS_MASK; |
| 1091 | 1121 | ||
| 1092 | if (new_window >> 24) as u8 != (self.backplane_window >> 24) as u8 { | 1122 | if (new_window >> 24) as u8 != (self.backplane_window >> 24) as u8 { |
| @@ -1094,138 +1124,124 @@ impl<'a, PWR: Pin, CS: Pin, CLK: Pin, DIO: Pin> Runner<'a, PWR, CS, CLK, DIO> { | |||
| 1094 | FUNC_BACKPLANE, | 1124 | FUNC_BACKPLANE, |
| 1095 | REG_BACKPLANE_BACKPLANE_ADDRESS_HIGH, | 1125 | REG_BACKPLANE_BACKPLANE_ADDRESS_HIGH, |
| 1096 | (new_window >> 24) as u8, | 1126 | (new_window >> 24) as u8, |
| 1097 | ); | 1127 | ) |
| 1128 | .await; | ||
| 1098 | } | 1129 | } |
| 1099 | if (new_window >> 16) as u8 != (self.backplane_window >> 16) as u8 { | 1130 | if (new_window >> 16) as u8 != (self.backplane_window >> 16) as u8 { |
| 1100 | self.write8( | 1131 | self.write8( |
| 1101 | FUNC_BACKPLANE, | 1132 | FUNC_BACKPLANE, |
| 1102 | REG_BACKPLANE_BACKPLANE_ADDRESS_MID, | 1133 | REG_BACKPLANE_BACKPLANE_ADDRESS_MID, |
| 1103 | (new_window >> 16) as u8, | 1134 | (new_window >> 16) as u8, |
| 1104 | ); | 1135 | ) |
| 1136 | .await; | ||
| 1105 | } | 1137 | } |
| 1106 | if (new_window >> 8) as u8 != (self.backplane_window >> 8) as u8 { | 1138 | if (new_window >> 8) as u8 != (self.backplane_window >> 8) as u8 { |
| 1107 | self.write8( | 1139 | self.write8( |
| 1108 | FUNC_BACKPLANE, | 1140 | FUNC_BACKPLANE, |
| 1109 | REG_BACKPLANE_BACKPLANE_ADDRESS_LOW, | 1141 | REG_BACKPLANE_BACKPLANE_ADDRESS_LOW, |
| 1110 | (new_window >> 8) as u8, | 1142 | (new_window >> 8) as u8, |
| 1111 | ); | 1143 | ) |
| 1144 | .await; | ||
| 1112 | } | 1145 | } |
| 1113 | self.backplane_window = new_window; | 1146 | self.backplane_window = new_window; |
| 1114 | } | 1147 | } |
| 1115 | 1148 | ||
| 1116 | fn read8(&mut self, func: u32, addr: u32) -> u8 { | 1149 | async fn read8(&mut self, func: u32, addr: u32) -> u8 { |
| 1117 | self.readn(func, addr, 1) as u8 | 1150 | self.readn(func, addr, 1).await as u8 |
| 1118 | } | 1151 | } |
| 1119 | 1152 | ||
| 1120 | fn write8(&mut self, func: u32, addr: u32, val: u8) { | 1153 | async fn write8(&mut self, func: u32, addr: u32, val: u8) { |
| 1121 | self.writen(func, addr, val as u32, 1) | 1154 | self.writen(func, addr, val as u32, 1).await |
| 1122 | } | 1155 | } |
| 1123 | 1156 | ||
| 1124 | fn read16(&mut self, func: u32, addr: u32) -> u16 { | 1157 | async fn read16(&mut self, func: u32, addr: u32) -> u16 { |
| 1125 | self.readn(func, addr, 2) as u16 | 1158 | self.readn(func, addr, 2).await as u16 |
| 1126 | } | 1159 | } |
| 1127 | 1160 | ||
| 1128 | fn write16(&mut self, func: u32, addr: u32, val: u16) { | 1161 | async fn write16(&mut self, func: u32, addr: u32, val: u16) { |
| 1129 | self.writen(func, addr, val as u32, 2) | 1162 | self.writen(func, addr, val as u32, 2).await |
| 1130 | } | 1163 | } |
| 1131 | 1164 | ||
| 1132 | fn read32(&mut self, func: u32, addr: u32) -> u32 { | 1165 | async fn read32(&mut self, func: u32, addr: u32) -> u32 { |
| 1133 | self.readn(func, addr, 4) | 1166 | self.readn(func, addr, 4).await |
| 1134 | } | 1167 | } |
| 1135 | 1168 | ||
| 1136 | fn write32(&mut self, func: u32, addr: u32, val: u32) { | 1169 | async fn write32(&mut self, func: u32, addr: u32, val: u32) { |
| 1137 | self.writen(func, addr, val, 4) | 1170 | self.writen(func, addr, val, 4).await |
| 1138 | } | 1171 | } |
| 1139 | 1172 | ||
| 1140 | fn readn(&mut self, func: u32, addr: u32, len: u32) -> u32 { | 1173 | async fn readn(&mut self, func: u32, addr: u32, len: u32) -> u32 { |
| 1141 | let cmd = cmd_word(false, true, func, addr, len); | 1174 | let cmd = cmd_word(false, true, func, addr, len); |
| 1142 | let mut buf = [0; 4]; | 1175 | let mut buf = [0; 4]; |
| 1143 | 1176 | ||
| 1144 | self.cs.set_low(); | 1177 | self.spi |
| 1145 | self.spi_write(&cmd.to_le_bytes()); | 1178 | .transaction(|bus| { |
| 1146 | if func == FUNC_BACKPLANE { | 1179 | let bus = unsafe { &mut *bus }; |
| 1147 | // 4-byte response delay. | 1180 | async { |
| 1148 | self.spi_read(&mut buf); | 1181 | bus.write(&cmd.to_le_bytes()).await?; |
| 1149 | } | 1182 | if func == FUNC_BACKPLANE { |
| 1150 | self.spi_read(&mut buf); | 1183 | // 4-byte response delay. |
| 1151 | self.cs.set_high(); | 1184 | bus.read(&mut buf).await?; |
| 1185 | } | ||
| 1186 | bus.read(&mut buf).await?; | ||
| 1187 | Ok(()) | ||
| 1188 | } | ||
| 1189 | }) | ||
| 1190 | .await | ||
| 1191 | .unwrap(); | ||
| 1152 | 1192 | ||
| 1153 | u32::from_le_bytes(buf) | 1193 | u32::from_le_bytes(buf) |
| 1154 | } | 1194 | } |
| 1155 | 1195 | ||
| 1156 | fn writen(&mut self, func: u32, addr: u32, val: u32, len: u32) { | 1196 | async fn writen(&mut self, func: u32, addr: u32, val: u32, len: u32) { |
| 1157 | let cmd = cmd_word(true, true, func, addr, len); | 1197 | let cmd = cmd_word(true, true, func, addr, len); |
| 1158 | 1198 | ||
| 1159 | self.cs.set_low(); | 1199 | self.spi |
| 1160 | self.spi_write(&cmd.to_le_bytes()); | 1200 | .transaction(|bus| { |
| 1161 | self.spi_write(&val.to_le_bytes()); | 1201 | let bus = unsafe { &mut *bus }; |
| 1162 | self.cs.set_high(); | 1202 | async { |
| 1203 | bus.write(&cmd.to_le_bytes()).await?; | ||
| 1204 | bus.write(&val.to_le_bytes()).await?; | ||
| 1205 | Ok(()) | ||
| 1206 | } | ||
| 1207 | }) | ||
| 1208 | .await | ||
| 1209 | .unwrap(); | ||
| 1163 | } | 1210 | } |
| 1164 | 1211 | ||
| 1165 | fn read32_swapped(&mut self, addr: u32) -> u32 { | 1212 | async fn read32_swapped(&mut self, addr: u32) -> u32 { |
| 1166 | let cmd = cmd_word(false, true, FUNC_BUS, addr, 4); | 1213 | let cmd = cmd_word(false, true, FUNC_BUS, addr, 4); |
| 1167 | let mut buf = [0; 4]; | 1214 | let mut buf = [0; 4]; |
| 1168 | 1215 | ||
| 1169 | self.cs.set_low(); | 1216 | self.spi |
| 1170 | self.spi_write(&swap16(cmd).to_le_bytes()); | 1217 | .transaction(|bus| { |
| 1171 | self.spi_read(&mut buf); | 1218 | let bus = unsafe { &mut *bus }; |
| 1172 | self.cs.set_high(); | 1219 | async { |
| 1220 | bus.write(&swap16(cmd).to_le_bytes()).await?; | ||
| 1221 | bus.read(&mut buf).await?; | ||
| 1222 | Ok(()) | ||
| 1223 | } | ||
| 1224 | }) | ||
| 1225 | .await | ||
| 1226 | .unwrap(); | ||
| 1173 | 1227 | ||
| 1174 | swap16(u32::from_le_bytes(buf)) | 1228 | swap16(u32::from_le_bytes(buf)) |
| 1175 | } | 1229 | } |
| 1176 | 1230 | ||
| 1177 | fn write32_swapped(&mut self, addr: u32, val: u32) { | 1231 | async fn write32_swapped(&mut self, addr: u32, val: u32) { |
| 1178 | let cmd = cmd_word(true, true, FUNC_BUS, addr, 4); | 1232 | let cmd = cmd_word(true, true, FUNC_BUS, addr, 4); |
| 1179 | 1233 | ||
| 1180 | self.cs.set_low(); | 1234 | self.spi |
| 1181 | self.spi_write(&swap16(cmd).to_le_bytes()); | 1235 | .transaction(|bus| { |
| 1182 | self.spi_write(&swap16(val).to_le_bytes()); | 1236 | let bus = unsafe { &mut *bus }; |
| 1183 | self.cs.set_high(); | 1237 | async { |
| 1184 | } | 1238 | bus.write(&swap16(cmd).to_le_bytes()).await?; |
| 1185 | 1239 | bus.write(&swap16(val).to_le_bytes()).await?; | |
| 1186 | fn spi_read(&mut self, words: &mut [u8]) { | 1240 | Ok(()) |
| 1187 | self.dio.set_as_input(); | ||
| 1188 | for word in words { | ||
| 1189 | let mut w = 0; | ||
| 1190 | for _ in 0..8 { | ||
| 1191 | w = w << 1; | ||
| 1192 | |||
| 1193 | // rising edge, sample data | ||
| 1194 | if self.dio.is_high() { | ||
| 1195 | w |= 0x01; | ||
| 1196 | } | ||
| 1197 | self.clk.set_high(); | ||
| 1198 | |||
| 1199 | // falling edge | ||
| 1200 | self.clk.set_low(); | ||
| 1201 | } | ||
| 1202 | *word = w | ||
| 1203 | } | ||
| 1204 | self.clk.set_low(); | ||
| 1205 | } | ||
| 1206 | |||
| 1207 | fn spi_write(&mut self, words: &[u8]) { | ||
| 1208 | self.dio.set_as_output(); | ||
| 1209 | for word in words { | ||
| 1210 | let mut word = *word; | ||
| 1211 | for _ in 0..8 { | ||
| 1212 | // falling edge, setup data | ||
| 1213 | self.clk.set_low(); | ||
| 1214 | if word & 0x80 == 0 { | ||
| 1215 | self.dio.set_low(); | ||
| 1216 | } else { | ||
| 1217 | self.dio.set_high(); | ||
| 1218 | } | 1241 | } |
| 1219 | 1242 | }) | |
| 1220 | // rising edge | 1243 | .await |
| 1221 | self.clk.set_high(); | 1244 | .unwrap(); |
| 1222 | |||
| 1223 | word = word << 1; | ||
| 1224 | } | ||
| 1225 | } | ||
| 1226 | self.clk.set_low(); | ||
| 1227 | |||
| 1228 | self.dio.set_as_input(); | ||
| 1229 | } | 1245 | } |
| 1230 | } | 1246 | } |
| 1231 | 1247 | ||
