diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 4feac24a00d..bb7812c8d86 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -64,33 +64,32 @@ jobs: steps: - uses: actions/checkout@v4 + # Install the Rust toolchain for Xtensa devices: + - uses: esp-rs/xtensa-toolchain@v1.5 + with: + default: true + ldproxy: false # Install the Rust stable and nightly toolchains for RISC-V devices: - - if: ${{ !contains(fromJson('["esp32", "esp32s2", "esp32s3"]'), matrix.device.soc) }} - uses: dtolnay/rust-toolchain@v1 + - uses: dtolnay/rust-toolchain@v1 with: target: riscv32imc-unknown-none-elf,riscv32imac-unknown-none-elf toolchain: stable components: rust-src - - if: ${{ !contains(fromJson('["esp32", "esp32s2", "esp32s3"]'), matrix.device.soc) }} - uses: dtolnay/rust-toolchain@v1 + - uses: dtolnay/rust-toolchain@v1 with: target: riscv32imc-unknown-none-elf,riscv32imac-unknown-none-elf toolchain: nightly components: rust-src - # Install the Rust toolchain for Xtensa devices: - - if: contains(fromJson('["esp32", "esp32s2", "esp32s3"]'), matrix.device.soc) - uses: esp-rs/xtensa-toolchain@v1.5 - with: - buildtargets: ${{ matrix.device.soc }} - default: true - ldproxy: false - uses: Swatinem/rust-cache@v2 # Build all supported examples for the low-power core first (if present): - if: contains(fromJson('["esp32c6", "esp32s2", "esp32s3"]'), matrix.device.soc) - name: Build prerequisites (esp-lp-hal) + name: Build prerequisite examples (esp-lp-hal) run: cargo xtask build-examples esp-lp-hal ${{ matrix.device.soc }} + - if: contains(fromJson('["esp32c6", "esp32s2", "esp32s3"]'), matrix.device.soc) + name: Check esp-lp-hal documentation + run: RUSTDOCFLAGS="-D warnings" cargo xtask build-documentation --packages esp-lp-hal --chips ${{ matrix.device.soc }} # Make sure we're able to build the HAL without the default features # enabled: @@ -106,134 +105,15 @@ jobs: run: cargo xtask build-examples esp-hal ${{ matrix.device.soc }} # Check doc-tests - name: Check doc-tests - run: cargo xtask run-doc-test esp-hal ${{ matrix.device.soc }} + run: cargo +esp xtask run-doc-test esp-hal ${{ matrix.device.soc }} - name: Check documentation - run: RUSTDOCFLAGS="-D warnings" cargo xtask build-documentation --packages esp-hal --chips ${{ matrix.device.soc }} + run: RUSTDOCFLAGS="-D warnings" cargo xtask build-documentation --packages esp-hal --chips ${{ matrix.device.soc }} + # Run clippy + - name: Clippy + # We use the 'esp' toolchain for *all* targets, in order to get a + # semi-stable and consistent set of lints for all targets: + run: cargo +esp xtask lint-packages --chips ${{ matrix.device.soc }} - esp-lp-hal: - runs-on: ubuntu-latest - - strategy: - fail-fast: false - matrix: - soc: ["esp32c6", "esp32s2", "esp32s3"] - - steps: - - uses: actions/checkout@v4 - - # Install the Rust stable and nightly toolchains for RISC-V devices: - - uses: dtolnay/rust-toolchain@v1 - with: - target: riscv32imc-unknown-none-elf,riscv32imac-unknown-none-elf - toolchain: stable - components: rust-src - - uses: dtolnay/rust-toolchain@v1 - if: ${{ !contains(fromJson('["esp32s2", "esp32s3"]'), matrix.soc) }} - with: - target: riscv32imc-unknown-none-elf,riscv32imac-unknown-none-elf - toolchain: nightly - components: rust-src - # Install the Rust toolchain for Xtensa devices: - - if: contains(fromJson('["esp32s2", "esp32s3"]'), matrix.soc) - uses: esp-rs/xtensa-toolchain@v1.5 - with: - buildtargets: ${{ matrix.soc }} - default: true - ldproxy: false - - - - uses: Swatinem/rust-cache@v2 - - # Build all supported examples for the specified device: - - name: Build examples - run: cargo xtask build-examples esp-lp-hal ${{ matrix.soc }} - - name: Check documentation - run: RUSTDOCFLAGS="-D warnings" cargo xtask build-documentation --packages esp-lp-hal --chips ${{ matrix.soc }} - esp-riscv-rt: - runs-on: ubuntu-latest - - steps: - - uses: actions/checkout@v4 - - uses: dtolnay/rust-toolchain@v1 - with: - target: riscv32imc-unknown-none-elf,riscv32imac-unknown-none-elf - toolchain: stable - components: rust-src - - uses: Swatinem/rust-cache@v2 - - # Build for all RISC-V targets (no features): - - name: Build esp-riscv-rt (riscv32imc, no features) - run: cd esp-riscv-rt/ && cargo build --target=riscv32imc-unknown-none-elf - - name: Build esp-riscv-rt (riscv32imac, no features) - run: cd esp-riscv-rt/ && cargo build --target=riscv32imac-unknown-none-elf - # Build for all RISC-V targets (all features): - - name: Build esp-riscv-rt (riscv32imc, all features) - run: cd esp-riscv-rt/ && cargo build --target=riscv32imc-unknown-none-elf --features=ci - - name: Build esp-riscv-rt (riscv32imac, all features) - run: cd esp-riscv-rt/ && cargo build --target=riscv32imac-unknown-none-elf --features=ci - - esp-println: - name: esp-println (${{ matrix.device.soc }}) - runs-on: ubuntu-latest - - strategy: - fail-fast: false - matrix: - device: [ - # RISC-V devices: - { soc: "esp32c2", target: "riscv32imc-unknown-none-elf" }, - { soc: "esp32c3", target: "riscv32imc-unknown-none-elf" }, - { soc: "esp32c6", target: "riscv32imac-unknown-none-elf" }, - { soc: "esp32h2", target: "riscv32imac-unknown-none-elf" }, - # Xtensa devices: - { soc: "esp32", target: "xtensa-esp32-none-elf" }, - { soc: "esp32s2", target: "xtensa-esp32s2-none-elf" }, - { soc: "esp32s3", target: "xtensa-esp32s3-none-elf" }, - ] - - steps: - - uses: actions/checkout@v4 - - # Install the Rust stable and nightly toolchains for RISC-V devices: - - if: ${{ !contains(fromJson('["esp32", "esp32s2", "esp32s3"]'), matrix.device.soc) }} - uses: dtolnay/rust-toolchain@v1 - with: - target: riscv32imc-unknown-none-elf,riscv32imac-unknown-none-elf - toolchain: stable - components: rust-src - - if: ${{ !contains(fromJson('["esp32", "esp32s2", "esp32s3"]'), matrix.device.soc) }} - uses: dtolnay/rust-toolchain@v1 - with: - target: riscv32imc-unknown-none-elf,riscv32imac-unknown-none-elf - toolchain: nightly - components: rust-src - # Install the Rust toolchain for Xtensa devices: - - if: contains(fromJson('["esp32", "esp32s2", "esp32s3"]'), matrix.device.soc) - uses: esp-rs/xtensa-toolchain@v1.5 - with: - buildtargets: ${{ matrix.device.soc }} - default: true - ldproxy: false - - - uses: Swatinem/rust-cache@v2 - - # Make sure we're able to build with the default features and most common features enabled - - name: Build (no features) - run: | - cargo xtask build-package \ - --features=${{ matrix.device.soc }},log \ - --target=${{ matrix.device.target }} \ - esp-println - - # So #1678 doesn't reoccur ('defmt-espflash,auto') - - name: Build (with feature 'defmt-espflash') - run: | - cargo xtask build-package \ - --features=${{ matrix.device.soc }},log,defmt-espflash \ - --target=${{ matrix.device.target }} \ - esp-println - - name: Check documentation - run: RUSTDOCFLAGS="-D warnings" cargo xtask build-documentation --packages esp-println --chips ${{ matrix.device.soc }} extras: runs-on: ubuntu-latest @@ -257,13 +137,19 @@ jobs: # -------------------------------------------------------------------------- # MSRV - msrv-riscv: + msrv: runs-on: ubuntu-latest env: RUSTC_BOOTSTRAP: 1 steps: - uses: actions/checkout@v4 + # install esp toolchain first so it isn't set as the default + - uses: esp-rs/xtensa-toolchain@v1.5 + with: + default: true + ldproxy: false + version: ${{ env.MSRV }} - uses: dtolnay/rust-toolchain@v1 with: target: riscv32imc-unknown-none-elf,riscv32imac-unknown-none-elf @@ -272,56 +158,28 @@ jobs: - uses: Swatinem/rust-cache@v2 # Verify the MSRV for all RISC-V chips. - - name: msrv (esp-hal) + - name: msrv RISCV (esp-hal) run: | cargo xtask build-package --features=esp32c2,ci --target=riscv32imc-unknown-none-elf esp-hal cargo xtask build-package --features=esp32c3,ci --target=riscv32imc-unknown-none-elf esp-hal cargo xtask build-package --features=esp32c6,ci --target=riscv32imac-unknown-none-elf esp-hal cargo xtask build-package --features=esp32h2,ci --target=riscv32imac-unknown-none-elf esp-hal - - name: msrv (esp-lp-hal) - run: | - cargo xtask build-package --features=esp32c6 --target=riscv32imac-unknown-none-elf esp-lp-hal - cargo xtask build-package --features=esp32s2 --target=riscv32imc-unknown-none-elf esp-lp-hal - cargo xtask build-package --features=esp32s3 --target=riscv32imc-unknown-none-elf esp-lp-hal - - msrv-xtensa: - runs-on: ubuntu-latest - env: - RUSTC_BOOTSTRAP: 1 - - steps: - - uses: actions/checkout@v4 - - uses: esp-rs/xtensa-toolchain@v1.5 - with: - ldproxy: false - version: ${{ env.MSRV }} - - uses: Swatinem/rust-cache@v2 # Verify the MSRV for all Xtensa chips: - - name: msrv (esp-hal) + - name: msrv Xtensa (esp-hal) run: | cargo xtask build-package --toolchain=esp --features=esp32,ci --target=xtensa-esp32-none-elf esp-hal cargo xtask build-package --toolchain=esp --features=esp32s2,ci --target=xtensa-esp32s2-none-elf esp-hal cargo xtask build-package --toolchain=esp --features=esp32s3,ci --target=xtensa-esp32s3-none-elf esp-hal - # -------------------------------------------------------------------------- - # Lint & Format - - clippy: - runs-on: ubuntu-latest - - steps: - - uses: actions/checkout@v4 - # We use the 'esp' toolchain for *all* targets, in order to get a - # semi-stable and consistent set of lints for all targets: - - uses: esp-rs/xtensa-toolchain@v1.5 - with: - default: true - ldproxy: false - - uses: Swatinem/rust-cache@v2 + - name: msrv (esp-lp-hal) + run: | + cargo xtask build-package --features=esp32c6 --target=riscv32imac-unknown-none-elf esp-lp-hal + cargo xtask build-package --features=esp32s2 --target=riscv32imc-unknown-none-elf esp-lp-hal + cargo xtask build-package --features=esp32s3 --target=riscv32imc-unknown-none-elf esp-lp-hal - # Lint all packages: - - run: cargo xtask lint-packages + # -------------------------------------------------------------------------- + # Format rustfmt: runs-on: ubuntu-latest diff --git a/.github/workflows/hil.yml b/.github/workflows/hil.yml index 5ae1879da9d..6a805c87004 100644 --- a/.github/workflows/hil.yml +++ b/.github/workflows/hil.yml @@ -103,24 +103,29 @@ jobs: # RISC-V devices: - soc: esp32c2 runner: esp32c2-jtag + usb: ACM0 - soc: esp32c3 runner: esp32c3-usb + usb: ACM0 - soc: esp32c6 runner: esp32c6-usb + usb: ACM0 - soc: esp32h2 runner: esp32h2-usb + usb: ACM0 # Xtensa devices: - soc: esp32s2 runner: esp32s2-jtag + usb: USB0 - soc: esp32s3 runner: esp32s3-usb + usb: USB0 steps: - uses: actions/checkout@v4 - uses: actions/download-artifact@v4 with: name: tests-${{ matrix.target.soc }} path: tests-${{ matrix.target.soc }} - - name: Run Tests id: run-tests run: | @@ -129,4 +134,8 @@ jobs: - name: Erase Flash on Failure if: ${{ failure() && steps.run-tests.conclusion == 'failure' }} - run: espflash erase-flash + env: + ESPFLASH_PORT: /dev/tty${{ matrix.target.usb }} + run: | + export PATH=$PATH:/home/espressif/.cargo/bin + espflash erase-flash diff --git a/esp-backtrace/src/riscv.rs b/esp-backtrace/src/riscv.rs index bc73cbed772..06d666174ee 100644 --- a/esp-backtrace/src/riscv.rs +++ b/esp-backtrace/src/riscv.rs @@ -7,7 +7,7 @@ use crate::MAX_BACKTRACE_ADDRESSES; // we get better results (especially if the caller was the last function in the // calling function) if we report the address of the JALR itself // even if it was a C.JALR we should get good results using RA - 4 -#[allow(unused)] +#[cfg(feature = "panic-handler")] pub(super) const RA_OFFSET: usize = 4; /// Registers saved in trap handler diff --git a/esp-backtrace/src/xtensa.rs b/esp-backtrace/src/xtensa.rs index 23fa3cbc1c5..64b8287ef6d 100644 --- a/esp-backtrace/src/xtensa.rs +++ b/esp-backtrace/src/xtensa.rs @@ -6,6 +6,7 @@ use crate::MAX_BACKTRACE_ADDRESSES; // the return address is the address following the callxN // we get better results (especially if the caller was the last function in the // calling function) if we report the address of callxN itself +#[cfg(feature = "panic-handler")] pub(super) const RA_OFFSET: usize = 3; #[doc(hidden)] @@ -307,7 +308,8 @@ pub(crate) fn backtrace_internal( old_address = address; - if address == 0 { + // the address is 0 but we sanitized the address - then 0 becomes 0x40000000 + if address == 0x40000000 { break; } diff --git a/esp-hal/CHANGELOG.md b/esp-hal/CHANGELOG.md index 40a0756dba6..b545a792d8f 100644 --- a/esp-hal/CHANGELOG.md +++ b/esp-hal/CHANGELOG.md @@ -14,6 +14,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Fixed +- Fix I2S async-tx (#1833) +- Fix PARL_IO async-rx (#1851) + ### Removed - This package no longer re-exports the `esp_hal_procmacros::main` macro (#1828) @@ -40,6 +43,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - uart: Make `rx_timeout` optional in Config struct (#1759) - Add interrupt related functions to `PeriodicTimer`/`OneShotTimer`, added `ErasedTimer` (#1753) - Added blocking `read_bytes` method to `Uart` and `UartRx` (#1784) +- Add method to expose `InputPin::is_interrupt_set` in `Input` for use in interrupt handlers (#1829) ### Fixed diff --git a/esp-hal/Cargo.toml b/esp-hal/Cargo.toml index 31774d21542..62f911358ed 100644 --- a/esp-hal/Cargo.toml +++ b/esp-hal/Cargo.toml @@ -182,7 +182,7 @@ opsram-8m = [] opsram-16m = [] # This feature is intended for testing; you probably don't want to enable it: -ci = ["async", "embedded-hal-02", "embedded-io", "ufmt"] +ci = ["async", "embedded-hal-02", "embedded-io", "ufmt", "defmt", "bluetooth", "place-spi-driver-in-ram"] [lints.clippy] mixed_attributes_style = "allow" diff --git a/esp-hal/src/dma/mod.rs b/esp-hal/src/dma/mod.rs index 74b89e6d42b..289f74ce755 100644 --- a/esp-hal/src/dma/mod.rs +++ b/esp-hal/src/dma/mod.rs @@ -1452,7 +1452,7 @@ where #[cfg(feature = "async")] fn waker() -> &'static embassy_sync::waitqueue::AtomicWaker { - CH::Rx::waker() + CH::Tx::waker() } fn is_listening_out_descriptor_error(&self) -> bool { diff --git a/esp-hal/src/gpio/mod.rs b/esp-hal/src/gpio/mod.rs index 4f1deff0c73..a605027753c 100644 --- a/esp-hal/src/gpio/mod.rs +++ b/esp-hal/src/gpio/mod.rs @@ -1727,6 +1727,12 @@ where self.pin.clear_interrupt(private::Internal); } + /// Checks if the interrupt status bit for this Pin is set + #[inline] + pub fn is_interrupt_set(&self) -> bool { + self.pin.is_interrupt_set(private::Internal) + } + /// Enable as a wake-up source. /// /// This will unlisten for interrupts diff --git a/esp-hal/src/i2c.rs b/esp-hal/src/i2c.rs index 6ae8b6965ff..03fccb93992 100644 --- a/esp-hal/src/i2c.rs +++ b/esp-hal/src/i2c.rs @@ -619,7 +619,7 @@ mod asynch { const NUM_I2C: usize = 1; } } - + #[allow(clippy::declare_interior_mutable_const)] const INIT: AtomicWaker = AtomicWaker::new(); static WAKERS: [AtomicWaker; NUM_I2C] = [INIT; NUM_I2C]; diff --git a/esp-hal/src/i2s.rs b/esp-hal/src/i2s.rs index 9d34d0753ed..5c12e69b3e6 100644 --- a/esp-hal/src/i2s.rs +++ b/esp-hal/src/i2s.rs @@ -2268,7 +2268,7 @@ pub mod asynch { /// Will wait for more than 0 bytes available. pub async fn available(&mut self) -> Result { loop { - self.state.update(&mut self.i2s_tx.tx_channel); + self.state.update(&self.i2s_tx.tx_channel); let res = self.state.available; if res != 0 { diff --git a/esp-hal/src/parl_io.rs b/esp-hal/src/parl_io.rs index 3f0d5eb7b30..8f8b185fc2a 100644 --- a/esp-hal/src/parl_io.rs +++ b/esp-hal/src/parl_io.rs @@ -1664,7 +1664,7 @@ pub mod asynch { use super::{private::Instance, Error, ParlIoRx, ParlIoTx, MAX_DMA_SIZE}; use crate::{ - dma::{asynch::DmaRxDoneChFuture, DmaChannel, ParlIoPeripheral}, + dma::{asynch::DmaRxFuture, DmaChannel, ParlIoPeripheral}, peripherals::Interrupt, }; @@ -1752,13 +1752,11 @@ pub mod asynch { pub async fn read_dma_async(&mut self, words: &mut [u8]) -> Result<(), Error> { let (ptr, len) = (words.as_mut_ptr(), words.len()); - if !Instance::is_suc_eof_generated_externally() { - if len > MAX_DMA_SIZE { - return Err(Error::MaxDmaTransferSizeExceeded); - } + if !Instance::is_suc_eof_generated_externally() && len > MAX_DMA_SIZE { + return Err(Error::MaxDmaTransferSizeExceeded); } - let future = DmaRxDoneChFuture::new(&mut self.rx_channel); + let future = DmaRxFuture::new(&mut self.rx_channel); Self::start_receive_bytes_dma(future.rx, &mut self.rx_chain, ptr, len)?; future.await?; diff --git a/esp-hal/src/rmt.rs b/esp-hal/src/rmt.rs index beaf27ba8cf..569d55e0b79 100644 --- a/esp-hal/src/rmt.rs +++ b/esp-hal/src/rmt.rs @@ -1123,6 +1123,7 @@ pub mod asynch { #[cfg(not(any(esp32, esp32s3)))] const NUM_CHANNELS: usize = 4; + #[allow(clippy::declare_interior_mutable_const)] const INIT: AtomicWaker = AtomicWaker::new(); static WAKER: [AtomicWaker; NUM_CHANNELS] = [INIT; NUM_CHANNELS]; diff --git a/esp-hal/src/rsa/mod.rs b/esp-hal/src/rsa/mod.rs index 7a869e3c7df..8a0afd88364 100644 --- a/esp-hal/src/rsa/mod.rs +++ b/esp-hal/src/rsa/mod.rs @@ -363,7 +363,7 @@ pub(crate) mod asynch { r: &T::InputType, outbuf: &mut T::InputType, ) { - self.start_exponentiation(&base, &r); + self.start_exponentiation(base, r); RsaFuture::new(&self.rsa.rsa).await; self.read_results(outbuf); } diff --git a/esp-hal/src/soc/esp32/psram.rs b/esp-hal/src/soc/esp32/psram.rs index 1914c637acb..fbd23bab397 100644 --- a/esp-hal/src/soc/esp32/psram.rs +++ b/esp-hal/src/soc/esp32/psram.rs @@ -130,7 +130,7 @@ pub(crate) mod utils { const SPI1_USER1_REG: u32 = DR_REG_SPI1_BASE + 0x20; const SPI1_W0_REG: u32 = DR_REG_SPI1_BASE + 0x80; const SPI1_CTRL2_REG: u32 = DR_REG_SPI1_BASE + 0x14; - const SPI1_CMD_REG: u32 = DR_REG_SPI1_BASE + 0x0; + const SPI1_CMD_REG: u32 = DR_REG_SPI1_BASE; const SPI1_USER2_REG: u32 = DR_REG_SPI1_BASE + 0x24; const SPI1_MOSI_DLEN_REG: u32 = DR_REG_SPI1_BASE + 0x28; const SPI1_MISO_DLEN_REG: u32 = DR_REG_SPI1_BASE + 0x2C; @@ -523,17 +523,9 @@ pub(crate) mod utils { psram_set_cs_timing_spi0(mode, clk_mode); // SPI_CACHE_PORT psram_enable_qio_mode_spi1(clk_mode, mode); - info!( - "PS-RAM vaddrmode = {:?}", - PsramVaddrMode::PsramVaddrModeLowhigh - ); + info!("PS-RAM vaddrmode = {:?}", PsramVaddrMode::Lowhigh); - psram_cache_init( - mode, - PsramVaddrMode::PsramVaddrModeLowhigh, - clk_mode, - extra_dummy, - ); + psram_cache_init(mode, PsramVaddrMode::Lowhigh, clk_mode, extra_dummy); } #[allow(unused)] @@ -541,13 +533,13 @@ pub(crate) mod utils { #[cfg_attr(feature = "defmt", derive(defmt::Format))] enum PsramVaddrMode { /// App and pro CPU use their own flash cache for external RAM access - PsramVaddrModeNormal = 0, + Normal = 0, /// App and pro CPU share external RAM caches: pro CPU has low * 2M, app /// CPU has high 2M - PsramVaddrModeLowhigh, + Lowhigh, /// App and pro CPU share external RAM caches: pro CPU does even 32yte /// ranges, app does odd ones. - PsramVaddrModeEvenodd, + Evenodd, } // register initialization for sram cache params and r/w commands @@ -680,14 +672,14 @@ pub(crate) mod utils { dport .app_cache_ctrl() .modify(|_, w| w.app_dram_hl().clear_bit().app_dram_split().clear_bit()); - if vaddrmode == PsramVaddrMode::PsramVaddrModeLowhigh { + if vaddrmode == PsramVaddrMode::Lowhigh { dport .pro_cache_ctrl() .modify(|_, w| w.pro_dram_hl().set_bit()); dport .app_cache_ctrl() .modify(|_, w| w.app_dram_hl().set_bit()); - } else if vaddrmode == PsramVaddrMode::PsramVaddrModeEvenodd { + } else if vaddrmode == PsramVaddrMode::Evenodd { dport .pro_cache_ctrl() .modify(|_, w| w.pro_dram_split().set_bit()); @@ -820,7 +812,7 @@ pub(crate) mod utils { #[ram] fn psram_enable_qio_mode_spi1(clk_mode: PsramClkMode, psram_mode: PsramCacheSpeed) { let mut ps_cmd: PsramCmd = PsramCmd::default(); - let addr: u32 = (PSRAM_ENTER_QMODE << 24) | 0; + let addr: u32 = PSRAM_ENTER_QMODE << 24; ps_cmd.cmd_bit_len = 0; if clk_mode == PsramClkMode::PsramClkModeDclk { diff --git a/esp-hal/src/soc/esp32s2/psram.rs b/esp-hal/src/soc/esp32s2/psram.rs index 0dd575e4e20..daf9c44ea1d 100644 --- a/esp-hal/src/soc/esp32s2/psram.rs +++ b/esp-hal/src/soc/esp32s2/psram.rs @@ -41,11 +41,11 @@ pub const PSRAM_VADDR_START: usize = PSRAM_VADDR as usize; pub fn init_psram(_peripheral: impl crate::peripheral::Peripheral

) { #[allow(unused)] enum CacheLayout { - CacheMemoryInvalid = 0, - CacheMemoryICacheLow = 1 << 0, - CacheMemoryICacheHigh = 1 << 1, - CacheMemoryDCacheLow = 1 << 2, - CacheMemoryDCacheHigh = 1 << 3, + Invalid = 0, + ICacheLow = 1 << 0, + ICacheHigh = 1 << 1, + DCacheLow = 1 << 2, + DCacheHigh = 1 << 3, } const MMU_ACCESS_SPIRAM: u32 = 1 << 16; @@ -102,10 +102,10 @@ pub fn init_psram(_peripheral: impl crate::peripheral::Peripheral

{ - tx_res?; - rx_res?; - } - } + let (tx_res, rx_res) = embassy_futures::join::join(tx_future, rx_future).await; + tx_res?; + rx_res?; self.spi.flush()?; @@ -1663,12 +1660,9 @@ pub mod dma { )?; } - match embassy_futures::join::join(tx_future, rx_future).await { - (tx_res, rx_res) => { - tx_res?; - rx_res?; - } - } + let (tx_res, rx_res) = embassy_futures::join::join(tx_future, rx_future).await; + tx_res?; + rx_res?; self.spi.flush()?; } @@ -1689,16 +1683,15 @@ pub mod dma { } async fn write(&mut self, words: &[u8]) -> Result<(), Self::Error> { - Ok( - if !crate::soc::is_valid_ram_address(&words[0] as *const _ as u32) { - for chunk in words.chunks(SIZE) { - self.buffer[..chunk.len()].copy_from_slice(chunk); - self.inner.write(&self.buffer[..chunk.len()]).await?; - } - } else { - self.inner.write(words).await?; - }, - ) + if !crate::soc::is_valid_ram_address(&words[0] as *const _ as u32) { + for chunk in words.chunks(SIZE) { + self.buffer[..chunk.len()].copy_from_slice(chunk); + self.inner.write(&self.buffer[..chunk.len()]).await?; + } + } else { + self.inner.write(words).await?; + } + Ok(()) } async fn flush(&mut self) -> Result<(), Self::Error> { @@ -1710,18 +1703,17 @@ pub mod dma { } async fn transfer(&mut self, read: &mut [u8], write: &[u8]) -> Result<(), Self::Error> { - Ok( - if !crate::soc::is_valid_ram_address(&write[0] as *const _ as u32) { - for (read, write) in read.chunks_mut(SIZE).zip(write.chunks(SIZE)) { - self.buffer[..write.len()].copy_from_slice(write); - self.inner - .transfer(read, &self.buffer[..write.len()]) - .await?; - } - } else { - self.inner.transfer(read, write).await?; - }, - ) + if !crate::soc::is_valid_ram_address(&write[0] as *const _ as u32) { + for (read, write) in read.chunks_mut(SIZE).zip(write.chunks(SIZE)) { + self.buffer[..write.len()].copy_from_slice(write); + self.inner + .transfer(read, &self.buffer[..write.len()]) + .await?; + } + } else { + self.inner.transfer(read, write).await?; + } + Ok(()) } } } diff --git a/esp-hal/src/timer/systimer.rs b/esp-hal/src/timer/systimer.rs index 156e7afc195..678aead0c55 100644 --- a/esp-hal/src/timer/systimer.rs +++ b/esp-hal/src/timer/systimer.rs @@ -601,6 +601,7 @@ mod asynch { const NUM_ALARMS: usize = 3; + #[allow(clippy::declare_interior_mutable_const)] const INIT: AtomicWaker = AtomicWaker::new(); static WAKERS: [AtomicWaker; NUM_ALARMS] = [INIT; NUM_ALARMS]; diff --git a/esp-hal/src/twai/mod.rs b/esp-hal/src/twai/mod.rs index 8d79af06f42..a157b42aee1 100644 --- a/esp-hal/src/twai/mod.rs +++ b/esp-hal/src/twai/mod.rs @@ -1461,6 +1461,12 @@ mod asynch { pub rx_queue: Channel, 32>, } + impl Default for TwaiAsyncState { + fn default() -> Self { + Self::new() + } + } + impl TwaiAsyncState { pub const fn new() -> Self { Self { @@ -1472,6 +1478,7 @@ mod asynch { } const NUM_TWAI: usize = 2; + #[allow(clippy::declare_interior_mutable_const)] const NEW_STATE: TwaiAsyncState = TwaiAsyncState::new(); pub(crate) static TWAI_STATE: [TwaiAsyncState; NUM_TWAI] = [NEW_STATE; NUM_TWAI]; @@ -1511,7 +1518,7 @@ mod asynch { T::write_frame(frame); - return Poll::Ready(Ok(())); + Poll::Ready(Ok(())) }) .await } diff --git a/esp-hal/src/uart.rs b/esp-hal/src/uart.rs index ce01fcde298..b9f75027a55 100644 --- a/esp-hal/src/uart.rs +++ b/esp-hal/src/uart.rs @@ -1804,6 +1804,7 @@ mod asynch { } } + #[allow(clippy::declare_interior_mutable_const)] const INIT: AtomicWaker = AtomicWaker::new(); static TX_WAKERS: [AtomicWaker; NUM_UART] = [INIT; NUM_UART]; static RX_WAKERS: [AtomicWaker; NUM_UART] = [INIT; NUM_UART]; @@ -1815,13 +1816,13 @@ mod asynch { } #[derive(EnumSetType, Debug)] pub(crate) enum RxEvent { - RxFifoFull, - RxCmdCharDetected, - RxFifoOvf, - RxFifoTout, - RxGlitchDetected, - RxFrameError, - RxParityError, + FifoFull, + CmdCharDetected, + FifoOvf, + FifoTout, + GlitchDetected, + FrameError, + ParityError, } /// A future that resolves when the passed interrupt is triggered, @@ -1854,16 +1855,14 @@ mod asynch { let mut events_triggered = EnumSet::new(); for event in self.events { let event_triggered = match event { - RxEvent::RxFifoFull => interrupts_enabled.rxfifo_full().bit_is_clear(), - RxEvent::RxCmdCharDetected => { - interrupts_enabled.at_cmd_char_det().bit_is_clear() - } - - RxEvent::RxFifoOvf => interrupts_enabled.rxfifo_ovf().bit_is_clear(), - RxEvent::RxFifoTout => interrupts_enabled.rxfifo_tout().bit_is_clear(), - RxEvent::RxGlitchDetected => interrupts_enabled.glitch_det().bit_is_clear(), - RxEvent::RxFrameError => interrupts_enabled.frm_err().bit_is_clear(), - RxEvent::RxParityError => interrupts_enabled.parity_err().bit_is_clear(), + RxEvent::FifoFull => interrupts_enabled.rxfifo_full().bit_is_clear(), + RxEvent::CmdCharDetected => interrupts_enabled.at_cmd_char_det().bit_is_clear(), + + RxEvent::FifoOvf => interrupts_enabled.rxfifo_ovf().bit_is_clear(), + RxEvent::FifoTout => interrupts_enabled.rxfifo_tout().bit_is_clear(), + RxEvent::GlitchDetected => interrupts_enabled.glitch_det().bit_is_clear(), + RxEvent::FrameError => interrupts_enabled.frm_err().bit_is_clear(), + RxEvent::ParityError => interrupts_enabled.parity_err().bit_is_clear(), }; if event_triggered { events_triggered |= event; @@ -1885,13 +1884,13 @@ mod asynch { T::register_block().int_ena().modify(|_, w| { for event in self.events { match event { - RxEvent::RxFifoFull => w.rxfifo_full().set_bit(), - RxEvent::RxCmdCharDetected => w.at_cmd_char_det().set_bit(), - RxEvent::RxFifoOvf => w.rxfifo_ovf().set_bit(), - RxEvent::RxFifoTout => w.rxfifo_tout().set_bit(), - RxEvent::RxGlitchDetected => w.glitch_det().set_bit(), - RxEvent::RxFrameError => w.frm_err().set_bit(), - RxEvent::RxParityError => w.parity_err().set_bit(), + RxEvent::FifoFull => w.rxfifo_full().set_bit(), + RxEvent::CmdCharDetected => w.at_cmd_char_det().set_bit(), + RxEvent::FifoOvf => w.rxfifo_ovf().set_bit(), + RxEvent::FifoTout => w.rxfifo_tout().set_bit(), + RxEvent::GlitchDetected => w.glitch_det().set_bit(), + RxEvent::FrameError => w.frm_err().set_bit(), + RxEvent::ParityError => w.parity_err().set_bit(), }; } w @@ -1915,15 +1914,15 @@ mod asynch { let int_ena = &T::register_block().int_ena(); for event in self.events { match event { - RxEvent::RxFifoFull => int_ena.modify(|_, w| w.rxfifo_full().clear_bit()), - RxEvent::RxCmdCharDetected => { + RxEvent::FifoFull => int_ena.modify(|_, w| w.rxfifo_full().clear_bit()), + RxEvent::CmdCharDetected => { int_ena.modify(|_, w| w.at_cmd_char_det().clear_bit()) } - RxEvent::RxGlitchDetected => int_ena.modify(|_, w| w.glitch_det().clear_bit()), - RxEvent::RxFrameError => int_ena.modify(|_, w| w.frm_err().clear_bit()), - RxEvent::RxParityError => int_ena.modify(|_, w| w.parity_err().clear_bit()), - RxEvent::RxFifoOvf => int_ena.modify(|_, w| w.rxfifo_ovf().clear_bit()), - RxEvent::RxFifoTout => int_ena.modify(|_, w| w.rxfifo_tout().clear_bit()), + RxEvent::GlitchDetected => int_ena.modify(|_, w| w.glitch_det().clear_bit()), + RxEvent::FrameError => int_ena.modify(|_, w| w.frm_err().clear_bit()), + RxEvent::ParityError => int_ena.modify(|_, w| w.parity_err().clear_bit()), + RxEvent::FifoOvf => int_ena.modify(|_, w| w.rxfifo_ovf().clear_bit()), + RxEvent::FifoTout => int_ena.modify(|_, w| w.rxfifo_tout().clear_bit()), } } } @@ -2207,23 +2206,23 @@ mod asynch { /// When successful, returns the number of bytes written to buf. /// This method will never return Ok(0) pub async fn read_async(&mut self, buf: &mut [u8]) -> Result { - if buf.len() == 0 { + if buf.is_empty() { return Err(Error::InvalidArgument); } loop { - let mut events = RxEvent::RxFifoFull - | RxEvent::RxFifoOvf - | RxEvent::RxFrameError - | RxEvent::RxGlitchDetected - | RxEvent::RxParityError; + let mut events = RxEvent::FifoFull + | RxEvent::FifoOvf + | RxEvent::FrameError + | RxEvent::GlitchDetected + | RxEvent::ParityError; if self.at_cmd_config.is_some() { - events |= RxEvent::RxCmdCharDetected; + events |= RxEvent::CmdCharDetected; } if self.rx_timeout_config.is_some() { - events |= RxEvent::RxFifoTout; + events |= RxEvent::FifoTout; } let events_happened = UartRxFuture::::new(events).await; // always drain the fifo, if an error has occurred the data is lost @@ -2231,11 +2230,11 @@ mod asynch { // check error events for event_happened in events_happened { match event_happened { - RxEvent::RxFifoOvf => return Err(Error::RxFifoOvf), - RxEvent::RxGlitchDetected => return Err(Error::RxGlitchDetected), - RxEvent::RxFrameError => return Err(Error::RxFrameError), - RxEvent::RxParityError => return Err(Error::RxParityError), - RxEvent::RxFifoFull | RxEvent::RxCmdCharDetected | RxEvent::RxFifoTout => { + RxEvent::FifoOvf => return Err(Error::RxFifoOvf), + RxEvent::GlitchDetected => return Err(Error::RxGlitchDetected), + RxEvent::FrameError => return Err(Error::RxFrameError), + RxEvent::ParityError => return Err(Error::RxParityError), + RxEvent::FifoFull | RxEvent::CmdCharDetected | RxEvent::FifoTout => { continue } } diff --git a/esp-hal/src/usb_serial_jtag.rs b/esp-hal/src/usb_serial_jtag.rs index 9f53e2793d6..70d6d2f06a3 100644 --- a/esp-hal/src/usb_serial_jtag.rs +++ b/esp-hal/src/usb_serial_jtag.rs @@ -805,7 +805,7 @@ mod asynch { impl UsbSerialJtagRx<'_, Async> { async fn read_bytes_async(&mut self, buf: &mut [u8]) -> Result { - if buf.len() == 0 { + if buf.is_empty() { return Ok(0); } diff --git a/esp-lp-hal/src/uart.rs b/esp-lp-hal/src/uart.rs index 3ca314b5746..9e05c1f120b 100644 --- a/esp-lp-hal/src/uart.rs +++ b/esp-lp-hal/src/uart.rs @@ -284,7 +284,7 @@ impl embedded_io::ErrorType for LpUart { #[cfg(feature = "embedded-io")] impl embedded_io::Read for LpUart { fn read(&mut self, buf: &mut [u8]) -> Result { - if buf.len() == 0 { + if buf.is_empty() { return Ok(0); } diff --git a/esp-metadata/Cargo.toml b/esp-metadata/Cargo.toml index 8172a98f0df..a04eb6ffed1 100644 --- a/esp-metadata/Cargo.toml +++ b/esp-metadata/Cargo.toml @@ -8,6 +8,8 @@ repository = "https://github.com/esp-rs/esp-hal" license = "MIT OR Apache-2.0" [dependencies] +anyhow = "1.0.86" +clap = { version = "4.5.4", features = ["derive"] } basic-toml = "0.1.9" lazy_static = "1.5.0" serde = { version = "1.0.204", features = ["derive"] } diff --git a/esp-metadata/src/lib.rs b/esp-metadata/src/lib.rs index 44db919ad4b..7a5b943278d 100644 --- a/esp-metadata/src/lib.rs +++ b/esp-metadata/src/lib.rs @@ -1,11 +1,12 @@ //! Metadata for Espressif devices, primarily intended for use in build scripts. +use anyhow::{bail, Result}; + const ESP32_TOML: &str = include_str!("../devices/esp32.toml"); const ESP32C2_TOML: &str = include_str!("../devices/esp32c2.toml"); const ESP32C3_TOML: &str = include_str!("../devices/esp32c3.toml"); const ESP32C6_TOML: &str = include_str!("../devices/esp32c6.toml"); const ESP32H2_TOML: &str = include_str!("../devices/esp32h2.toml"); -const ESP32P4_TOML: &str = include_str!("../devices/esp32p4.toml"); const ESP32S2_TOML: &str = include_str!("../devices/esp32s2.toml"); const ESP32S3_TOML: &str = include_str!("../devices/esp32s3.toml"); @@ -15,7 +16,6 @@ lazy_static::lazy_static! { static ref ESP32C3_CFG: Config = basic_toml::from_str(ESP32C3_TOML).unwrap(); static ref ESP32C6_CFG: Config = basic_toml::from_str(ESP32C6_TOML).unwrap(); static ref ESP32H2_CFG: Config = basic_toml::from_str(ESP32H2_TOML).unwrap(); - static ref ESP32P4_CFG: Config = basic_toml::from_str(ESP32P4_TOML).unwrap(); static ref ESP32S2_CFG: Config = basic_toml::from_str(ESP32S2_TOML).unwrap(); static ref ESP32S3_CFG: Config = basic_toml::from_str(ESP32S3_TOML).unwrap(); } @@ -84,9 +84,10 @@ pub enum Cores { strum::Display, strum::EnumIter, strum::EnumString, + clap::ValueEnum, )] -#[serde(rename_all = "lowercase")] -#[strum(serialize_all = "lowercase")] +#[serde(rename_all = "kebab-case")] +#[strum(serialize_all = "kebab-case")] pub enum Chip { /// ESP32 Esp32, @@ -98,14 +99,62 @@ pub enum Chip { Esp32c6, /// ESP32-H2 Esp32h2, - /// ESP32-P4 - Esp32p4, /// ESP32-S2 Esp32s2, /// ESP32-S3 Esp32s3, } +impl Chip { + pub fn target(&self) -> &str { + use Chip::*; + + match self { + Esp32 => "xtensa-esp32-none-elf", + Esp32c2 | Esp32c3 => "riscv32imc-unknown-none-elf", + Esp32c6 | Esp32h2 => "riscv32imac-unknown-none-elf", + Esp32s2 => "xtensa-esp32s2-none-elf", + Esp32s3 => "xtensa-esp32s3-none-elf", + } + } + + pub fn has_lp_core(&self) -> bool { + use Chip::*; + + matches!(self, Esp32c6 | Esp32s2 | Esp32s3) + } + + pub fn lp_target(&self) -> Result<&str> { + use Chip::*; + + match self { + Esp32c6 => Ok("riscv32imac-unknown-none-elf"), + Esp32s2 | Esp32s3 => Ok("riscv32imc-unknown-none-elf"), + _ => bail!("Chip does not contain an LP core: '{}'", self), + } + } + + pub fn pretty_name(&self) -> &str { + match self { + Chip::Esp32 => "ESP32", + Chip::Esp32c2 => "ESP32-C2", + Chip::Esp32c3 => "ESP32-C3", + Chip::Esp32c6 => "ESP32-C6", + Chip::Esp32h2 => "ESP32-H2", + Chip::Esp32s2 => "ESP32-S2", + Chip::Esp32s3 => "ESP32-S3", + } + } + + pub fn is_xtensa(&self) -> bool { + matches!(self, Chip::Esp32 | Chip::Esp32s2 | Chip::Esp32s3) + } + + pub fn is_riscv(&self) -> bool { + !self.is_xtensa() + } +} + #[derive(Debug, Clone, serde::Deserialize, serde::Serialize)] struct Device { pub name: String, @@ -130,7 +179,6 @@ impl Config { Chip::Esp32c3 => ESP32C3_CFG.clone(), Chip::Esp32c6 => ESP32C6_CFG.clone(), Chip::Esp32h2 => ESP32H2_CFG.clone(), - Chip::Esp32p4 => ESP32P4_CFG.clone(), Chip::Esp32s2 => ESP32S2_CFG.clone(), Chip::Esp32s3 => ESP32S3_CFG.clone(), } diff --git a/esp-storage/src/nor_flash.rs b/esp-storage/src/nor_flash.rs index 902dc5ea83b..16190bc8eea 100644 --- a/esp-storage/src/nor_flash.rs +++ b/esp-storage/src/nor_flash.rs @@ -1,7 +1,4 @@ -use core::{ - mem::MaybeUninit, - ops::{Deref, DerefMut}, -}; +use core::mem::MaybeUninit; use embedded_storage::nor_flash::{ ErrorType, @@ -13,6 +10,7 @@ use embedded_storage::nor_flash::{ use crate::{FlashSectorBuffer, FlashStorage, FlashStorageError}; +#[cfg(feature = "bytewise-read")] #[repr(C, align(4))] struct FlashWordBuffer { // NOTE: Ensure that no unaligned fields are added above `data` to maintain its required @@ -20,7 +18,8 @@ struct FlashWordBuffer { data: [u8; FlashStorage::WORD_SIZE as usize], } -impl Deref for FlashWordBuffer { +#[cfg(feature = "bytewise-read")] +impl core::ops::Deref for FlashWordBuffer { type Target = [u8; FlashStorage::WORD_SIZE as usize]; fn deref(&self) -> &Self::Target { @@ -28,7 +27,8 @@ impl Deref for FlashWordBuffer { } } -impl DerefMut for FlashWordBuffer { +#[cfg(feature = "bytewise-read")] +impl core::ops::DerefMut for FlashWordBuffer { fn deref_mut(&mut self) -> &mut Self::Target { &mut self.data } diff --git a/esp-wifi/src/ble/os_adapter_esp32.rs b/esp-wifi/src/ble/os_adapter_esp32.rs index d6bc1d785b6..eb030988059 100644 --- a/esp-wifi/src/ble/os_adapter_esp32.rs +++ b/esp-wifi/src/ble/os_adapter_esp32.rs @@ -475,7 +475,7 @@ pub(crate) unsafe extern "C" fn coex_schm_curr_period_get() -> u8 { debug!("coex_schm_curr_period_get"); #[cfg(coex)] - return crate::binary::include::coex_schm_curr_period_get() as u8; + return crate::binary::include::coex_schm_curr_period_get(); #[cfg(not(coex))] 0 @@ -571,14 +571,13 @@ const BTDM_ASYNC_WAKEUP_REQ_COEX: i32 = 1; #[cfg(coex)] fn async_wakeup_request(event: i32) -> bool { - let request_lock: bool; let mut do_wakeup_request = false; - match event { - e if e == BTDM_ASYNC_WAKEUP_REQ_HCI => request_lock = true, - e if e == BTDM_ASYNC_WAKEUP_REQ_COEX => request_lock = false, + let request_lock = match event { + e if e == BTDM_ASYNC_WAKEUP_REQ_HCI => true, + e if e == BTDM_ASYNC_WAKEUP_REQ_COEX => false, _ => return false, - } + }; extern "C" { fn btdm_power_state_active() -> bool; @@ -590,7 +589,7 @@ fn async_wakeup_request(event: i32) -> bool { unsafe { btdm_wakeup_request(request_lock) }; } - return do_wakeup_request; + do_wakeup_request } /// ************************************************************************** @@ -609,13 +608,11 @@ fn async_wakeup_request(event: i32) -> bool { #[cfg(coex)] fn async_wakeup_request_end(event: i32) { - let request_lock: bool; - - match event { - e if e == BTDM_ASYNC_WAKEUP_REQ_HCI => request_lock = true, - e if e == BTDM_ASYNC_WAKEUP_REQ_COEX => request_lock = false, + let request_lock = match event { + e if e == BTDM_ASYNC_WAKEUP_REQ_HCI => true, + e if e == BTDM_ASYNC_WAKEUP_REQ_COEX => false, _ => return, - } + }; extern "C" { // this isn't found anywhere ... not a ROM function @@ -626,6 +623,4 @@ fn async_wakeup_request_end(event: i32) { if request_lock { // unsafe { btdm_wakeup_request_end() }; } - - return; } diff --git a/esp-wifi/src/common_adapter/common_adapter_esp32.rs b/esp-wifi/src/common_adapter/common_adapter_esp32.rs index 353d806a536..cdc16fa0434 100644 --- a/esp-wifi/src/common_adapter/common_adapter_esp32.rs +++ b/esp-wifi/src/common_adapter/common_adapter_esp32.rs @@ -201,7 +201,9 @@ unsafe extern "C" fn phy_enter_critical() -> u32 { unsafe extern "C" fn phy_exit_critical(level: u32) { trace!("phy_exit_critical {}", level); - critical_section::release(core::mem::transmute(level)); + critical_section::release(core::mem::transmute::( + level, + )); } #[ram] diff --git a/esp-wifi/src/common_adapter/common_adapter_esp32s2.rs b/esp-wifi/src/common_adapter/common_adapter_esp32s2.rs index bfbf1109327..a48a28870f6 100644 --- a/esp-wifi/src/common_adapter/common_adapter_esp32s2.rs +++ b/esp-wifi/src/common_adapter/common_adapter_esp32s2.rs @@ -196,7 +196,9 @@ unsafe extern "C" fn phy_enter_critical() -> u32 { unsafe extern "C" fn phy_exit_critical(level: u32) { trace!("phy_exit_critical {}", level); - critical_section::release(core::mem::transmute(level)); + critical_section::release(core::mem::transmute::( + level, + )); } #[no_mangle] diff --git a/esp-wifi/src/fmt.rs b/esp-wifi/src/fmt.rs index 06697081337..aa009027405 100644 --- a/esp-wifi/src/fmt.rs +++ b/esp-wifi/src/fmt.rs @@ -201,6 +201,7 @@ pub struct NoneError; pub trait Try { type Ok; type Error; + #[allow(unused)] fn into_result(self) -> Result; } diff --git a/esp-wifi/src/timer/xtensa.rs b/esp-wifi/src/timer/xtensa.rs index 37e21ee0f3a..a808566067a 100644 --- a/esp-wifi/src/timer/xtensa.rs +++ b/esp-wifi/src/timer/xtensa.rs @@ -28,7 +28,7 @@ pub fn get_systimer_count() -> u64 { pub fn setup_timer(mut timer1: TimeBase) -> Result<(), esp_hal::timer::Error> { timer1.set_interrupt_handler(InterruptHandler::new( - unsafe { core::mem::transmute(handler as *const ()) }, + unsafe { core::mem::transmute::<*const (), extern "C" fn()>(handler as *const ()) }, interrupt::Priority::Priority2, )); timer1.start(TIMESLICE_FREQUENCY.into_duration())?; diff --git a/esp-wifi/src/wifi/mod.rs b/esp-wifi/src/wifi/mod.rs index 762dd736e18..f93dbc2e94d 100644 --- a/esp-wifi/src/wifi/mod.rs +++ b/esp-wifi/src/wifi/mod.rs @@ -861,6 +861,7 @@ pub(crate) unsafe extern "C" fn coex_init() -> i32 { #[cfg(coex)] { debug!("coex-init"); + #[allow(clippy::needless_return)] return include::coex_init(); } @@ -2687,9 +2688,9 @@ impl Drop for FreeApListOnDrop { mod embedded_svc_compat { use super::*; - impl Into for Capability { - fn into(self) -> embedded_svc::wifi::Capability { - match self { + impl From for embedded_svc::wifi::Capability { + fn from(s: Capability) -> embedded_svc::wifi::Capability { + match s { Capability::Client => embedded_svc::wifi::Capability::Client, Capability::AccessPoint => embedded_svc::wifi::Capability::AccessPoint, Capability::Mixed => embedded_svc::wifi::Capability::Mixed, @@ -2697,9 +2698,9 @@ mod embedded_svc_compat { } } - impl Into for AuthMethod { - fn into(self) -> embedded_svc::wifi::AuthMethod { - match self { + impl From for embedded_svc::wifi::AuthMethod { + fn from(s: AuthMethod) -> embedded_svc::wifi::AuthMethod { + match s { AuthMethod::None => embedded_svc::wifi::AuthMethod::None, AuthMethod::WEP => embedded_svc::wifi::AuthMethod::WEP, AuthMethod::WPA => embedded_svc::wifi::AuthMethod::WPA, @@ -2729,9 +2730,9 @@ mod embedded_svc_compat { } } - impl Into for Protocol { - fn into(self) -> embedded_svc::wifi::Protocol { - match self { + impl From for embedded_svc::wifi::Protocol { + fn from(s: Protocol) -> embedded_svc::wifi::Protocol { + match s { Protocol::P802D11B => embedded_svc::wifi::Protocol::P802D11B, Protocol::P802D11BG => embedded_svc::wifi::Protocol::P802D11BG, Protocol::P802D11BGN => embedded_svc::wifi::Protocol::P802D11BGN, @@ -2755,9 +2756,9 @@ mod embedded_svc_compat { } } - impl Into for Configuration { - fn into(self) -> embedded_svc::wifi::Configuration { - match self { + impl From for embedded_svc::wifi::Configuration { + fn from(s: Configuration) -> embedded_svc::wifi::Configuration { + match s { Configuration::None => embedded_svc::wifi::Configuration::None, Configuration::Client(conf) => embedded_svc::wifi::Configuration::Client( embedded_svc::wifi::ClientConfiguration { @@ -2823,10 +2824,10 @@ mod embedded_svc_compat { embedded_svc::wifi::Configuration::Client(conf) => { Configuration::Client(ClientConfiguration { ssid: conf.ssid.clone(), - bssid: conf.bssid.clone(), + bssid: conf.bssid, auth_method: conf.auth_method.into(), password: conf.password.clone(), - channel: conf.channel.clone(), + channel: conf.channel, }) } embedded_svc::wifi::Configuration::AccessPoint(conf) => { @@ -2850,14 +2851,14 @@ mod embedded_svc_compat { embedded_svc::wifi::Configuration::Mixed(client, ap) => Configuration::Mixed( ClientConfiguration { ssid: client.ssid.clone(), - bssid: client.bssid.clone(), + bssid: client.bssid, auth_method: client.auth_method.into(), password: client.password.clone(), channel: client.channel, }, AccessPointConfiguration { ssid: ap.ssid.clone(), - ssid_hidden: ap.ssid_hidden.clone(), + ssid_hidden: ap.ssid_hidden, channel: ap.channel, secondary_channel: ap.secondary_channel, protocols: { @@ -2876,29 +2877,29 @@ mod embedded_svc_compat { } } - impl Into for AccessPointInfo { - fn into(self) -> embedded_svc::wifi::AccessPointInfo { + impl From for embedded_svc::wifi::AccessPointInfo { + fn from(s: AccessPointInfo) -> embedded_svc::wifi::AccessPointInfo { embedded_svc::wifi::AccessPointInfo { - ssid: self.ssid.clone(), - bssid: self.bssid.clone(), - channel: self.channel, - secondary_channel: self.secondary_channel.into(), - signal_strength: self.signal_strength, + ssid: s.ssid.clone(), + bssid: s.bssid, + channel: s.channel, + secondary_channel: s.secondary_channel.into(), + signal_strength: s.signal_strength, protocols: { let mut res = EnumSet::::new(); - self.protocols.into_iter().for_each(|v| { + s.protocols.into_iter().for_each(|v| { res.insert(v.into()); }); res }, - auth_method: self.auth_method.map(|v| v.into()), + auth_method: s.auth_method.map(|v| v.into()), } } } - impl Into for SecondaryChannel { - fn into(self) -> embedded_svc::wifi::SecondaryChannel { - match self { + impl From for embedded_svc::wifi::SecondaryChannel { + fn from(s: SecondaryChannel) -> embedded_svc::wifi::SecondaryChannel { + match s { SecondaryChannel::None => embedded_svc::wifi::SecondaryChannel::None, SecondaryChannel::Above => embedded_svc::wifi::SecondaryChannel::Above, SecondaryChannel::Below => embedded_svc::wifi::SecondaryChannel::Below, @@ -2906,11 +2907,11 @@ mod embedded_svc_compat { } } - impl Into for crate::wifi::ipv4::Subnet { - fn into(self) -> embedded_svc::ipv4::Subnet { + impl From for embedded_svc::ipv4::Subnet { + fn from(s: crate::wifi::ipv4::Subnet) -> embedded_svc::ipv4::Subnet { embedded_svc::ipv4::Subnet { - gateway: embedded_svc::ipv4::Ipv4Addr::from(self.gateway.octets()), - mask: embedded_svc::ipv4::Mask(self.mask.0), + gateway: embedded_svc::ipv4::Ipv4Addr::from(s.gateway.octets()), + mask: embedded_svc::ipv4::Mask(s.mask.0), } } } @@ -2924,15 +2925,15 @@ mod embedded_svc_compat { } } - impl Into for super::ipv4::IpInfo { - fn into(self) -> embedded_svc::ipv4::IpInfo { + impl From for embedded_svc::ipv4::IpInfo { + fn from(s: super::ipv4::IpInfo) -> embedded_svc::ipv4::IpInfo { embedded_svc::ipv4::IpInfo { - ip: embedded_svc::ipv4::Ipv4Addr::from(self.ip.octets()), - subnet: self.subnet.into(), - dns: self + ip: embedded_svc::ipv4::Ipv4Addr::from(s.ip.octets()), + subnet: s.subnet.into(), + dns: s .dns .map(|v| embedded_svc::ipv4::Ipv4Addr::from(v.octets())), - secondary_dns: self + secondary_dns: s .secondary_dns .map(|v| embedded_svc::ipv4::Ipv4Addr::from(v.octets())), } @@ -2979,9 +2980,9 @@ mod embedded_svc_compat { } } - impl Into for super::ipv4::Configuration { - fn into(self) -> embedded_svc::ipv4::Configuration { - match self { + impl From for embedded_svc::ipv4::Configuration { + fn from(s: super::ipv4::Configuration) -> embedded_svc::ipv4::Configuration { + match s { super::ipv4::Configuration::Client(client) => { let config = match client { super::ipv4::ClientConfiguration::DHCP(dhcp) => { diff --git a/esp-wifi/src/wifi/os_adapter_esp32.rs b/esp-wifi/src/wifi/os_adapter_esp32.rs index 57350837d65..6ef40ee33d1 100644 --- a/esp-wifi/src/wifi/os_adapter_esp32.rs +++ b/esp-wifi/src/wifi/os_adapter_esp32.rs @@ -29,7 +29,9 @@ pub(crate) unsafe extern "C" fn wifi_int_restore( wifi_int_mux: *mut crate::binary::c_types::c_void, tmp: u32, ) { - critical_section::release(core::mem::transmute(tmp)) + critical_section::release(core::mem::transmute::( + tmp, + )) } pub(crate) unsafe extern "C" fn phy_common_clock_disable() { diff --git a/esp-wifi/src/wifi/os_adapter_esp32s2.rs b/esp-wifi/src/wifi/os_adapter_esp32s2.rs index 343160c7460..811e0a79227 100644 --- a/esp-wifi/src/wifi/os_adapter_esp32s2.rs +++ b/esp-wifi/src/wifi/os_adapter_esp32s2.rs @@ -22,7 +22,9 @@ pub(crate) unsafe extern "C" fn wifi_int_restore( wifi_int_mux: *mut crate::binary::c_types::c_void, tmp: u32, ) { - critical_section::release(core::mem::transmute(tmp)) + critical_section::release(core::mem::transmute::( + tmp, + )) } pub(crate) unsafe extern "C" fn set_intr( diff --git a/esp-wifi/src/wifi/os_adapter_esp32s3.rs b/esp-wifi/src/wifi/os_adapter_esp32s3.rs index a3420a8aaad..51ce70299b5 100644 --- a/esp-wifi/src/wifi/os_adapter_esp32s3.rs +++ b/esp-wifi/src/wifi/os_adapter_esp32s3.rs @@ -22,7 +22,9 @@ pub(crate) unsafe extern "C" fn wifi_int_restore( wifi_int_mux: *mut crate::binary::c_types::c_void, tmp: u32, ) { - critical_section::release(core::mem::transmute(tmp)) + critical_section::release(core::mem::transmute::( + tmp, + )) } pub(crate) unsafe extern "C" fn set_intr( diff --git a/examples/src/bin/embassy_multicore.rs b/examples/src/bin/embassy_multicore.rs index b794b3f1f6b..8c46633522c 100644 --- a/examples/src/bin/embassy_multicore.rs +++ b/examples/src/bin/embassy_multicore.rs @@ -24,7 +24,6 @@ use esp_hal::{ get_core, gpio::{AnyOutput, Io, Level}, peripherals::Peripherals, - prelude::*, system::SystemControl, timer::{timg::TimerGroup, ErasedTimer, OneShotTimer}, }; diff --git a/examples/src/bin/embassy_multiprio.rs b/examples/src/bin/embassy_multiprio.rs index a2547914fc9..9a5bb08001f 100644 --- a/examples/src/bin/embassy_multiprio.rs +++ b/examples/src/bin/embassy_multiprio.rs @@ -28,7 +28,7 @@ use esp_hal::{ interrupt::Priority, peripherals::Peripherals, system::SystemControl, - timer::{/*systimer::SystemTimer,*/ timg::TimerGroup, ErasedTimer, OneShotTimer}, + timer::{timg::TimerGroup, ErasedTimer, OneShotTimer}, }; use esp_hal_embassy::InterruptExecutor; use esp_println::println; diff --git a/examples/src/bin/embassy_parl_io_rx.rs b/examples/src/bin/embassy_parl_io_rx.rs index 998338a0881..d1c6ccfe266 100644 --- a/examples/src/bin/embassy_parl_io_rx.rs +++ b/examples/src/bin/embassy_parl_io_rx.rs @@ -74,7 +74,11 @@ async fn main(_spawner: Spawner) { let buffer = rx_buffer; loop { parl_io_rx.read_dma_async(buffer).await.unwrap(); - println!("Received: {:02x?} ...", &buffer[..30]); + println!( + "Received: {:02x?} ... {:02x?}", + &buffer[..30], + &buffer[(buffer.len() - 30)..] + ); Timer::after(Duration::from_millis(500)).await; } diff --git a/examples/src/bin/embassy_usb_serial.rs b/examples/src/bin/embassy_usb_serial.rs index 3c73ffc8ba4..e8a1edb1a11 100644 --- a/examples/src/bin/embassy_usb_serial.rs +++ b/examples/src/bin/embassy_usb_serial.rs @@ -28,7 +28,6 @@ use esp_hal::{ Usb, }, peripherals::Peripherals, - prelude::*, system::SystemControl, timer::{timg::TimerGroup, ErasedTimer, OneShotTimer}, }; diff --git a/examples/src/bin/gpio_interrupt.rs b/examples/src/bin/gpio_interrupt.rs index aa51b43d30f..a4f0cfad313 100644 --- a/examples/src/bin/gpio_interrupt.rs +++ b/examples/src/bin/gpio_interrupt.rs @@ -73,6 +73,18 @@ fn handler() { #[cfg(not(any(feature = "esp32", feature = "esp32s2", feature = "esp32s3")))] esp_println::println!("GPIO Interrupt"); + if critical_section::with(|cs| { + BUTTON + .borrow_ref_mut(cs) + .as_mut() + .unwrap() + .is_interrupt_set() + }) { + esp_println::println!("Button was the source of the interrupt"); + } else { + esp_println::println!("Button was not the source of the interrupt"); + } + critical_section::with(|cs| { BUTTON .borrow_ref_mut(cs) diff --git a/examples/src/bin/usb_serial_jtag.rs b/examples/src/bin/usb_serial_jtag.rs index 803a3e4f69a..d87ab1a7978 100644 --- a/examples/src/bin/usb_serial_jtag.rs +++ b/examples/src/bin/usb_serial_jtag.rs @@ -2,6 +2,10 @@ //! //! You need to connect via the Serial/JTAG interface to see any output. //! Most dev-kits use a USB-UART-bridge - in that case you won't see any output. +//! +//! Windows Users: Flashing and then monitoring via espflash will result in any keypress freezing the application. +//! Please use another serial monitor (e.g. `putty`) on Windows +//! See https://github.com/esp-rs/espflash/issues/654 //% CHIPS: esp32c3 esp32c6 esp32h2 esp32s3 diff --git a/hil-test/Cargo.toml b/hil-test/Cargo.toml index 2e1a042be80..02c1a7c76d3 100644 --- a/hil-test/Cargo.toml +++ b/hil-test/Cargo.toml @@ -52,6 +52,10 @@ harness = false name = "i2s" harness = false +[[test]] +name = "i2s_async" +harness = false + [[test]] name = "spi_full_duplex" harness = false diff --git a/hil-test/tests/i2s_async.rs b/hil-test/tests/i2s_async.rs new file mode 100644 index 00000000000..bc6b816cec1 --- /dev/null +++ b/hil-test/tests/i2s_async.rs @@ -0,0 +1,153 @@ +//! I2S Loopback Test (Async) +//! +//! It's assumed GPIO2 is connected to GPIO3 +//! +//! This test uses I2S TX to transmit known data to I2S RX (forced to slave mode +//! with loopback mode enabled). It's using circular DMA mode + +//% CHIPS: esp32c3 esp32c6 esp32s3 esp32h2 + +#![no_std] +#![no_main] + +use defmt_rtt as _; +use esp_backtrace as _; +use esp_hal::{ + clock::ClockControl, + dma::{Dma, DmaChannel0, DmaPriority}, + gpio::Io, + i2s::{asynch::*, DataFormat, I2s, Standard}, + peripheral::Peripheral, + peripherals::Peripherals, + prelude::*, + system::SystemControl, +}; + +// choose values which DON'T restart on every descriptor buffer's start +const ADD: u8 = 5; +const CUT_OFF: u8 = 113; + +#[embassy_executor::task] +async fn writer( + i: u8, + mut transfer: I2sWriteDmaTransferAsync< + 'static, + esp_hal::peripherals::I2S0, + DmaChannel0, + &'static mut [u8; 2000], + >, +) { + let mut i = i; + loop { + transfer + .push_with(|buffer| { + for b in buffer.iter_mut() { + *b = i; + i = (i + ADD) % CUT_OFF; + } + buffer.len() + }) + .await + .unwrap(); + } +} + +#[cfg(test)] +#[embedded_test::tests(executor = esp_hal_embassy::Executor::new())] +mod tests { + use super::*; + + #[init] + async fn init() {} + + #[test] + async fn test_i2s_loopback() { + let spawner = embassy_executor::Spawner::for_current_executor().await; + + let peripherals = Peripherals::take(); + let system = SystemControl::new(peripherals.SYSTEM); + let clocks = ClockControl::boot_defaults(system.clock_control).freeze(); + + let mut io = Io::new(peripherals.GPIO, peripherals.IO_MUX); + + let dma = Dma::new(peripherals.DMA); + let dma_channel = dma.channel0; + + #[allow(non_upper_case_globals)] + let (tx_buffer, tx_descriptors, rx_buffer, rx_descriptors) = + esp_hal::dma_circular_buffers!(2000, 2000); + + let i2s = I2s::new( + peripherals.I2S0, + Standard::Philips, + DataFormat::Data16Channel16, + 16000.Hz(), + dma_channel.configure_for_async(false, DmaPriority::Priority0), + tx_descriptors, + rx_descriptors, + &clocks, + ); + + let i2s_tx = i2s + .i2s_tx + .with_bclk(unsafe { io.pins.gpio0.clone_unchecked() }) + .with_ws(unsafe { io.pins.gpio1.clone_unchecked() }) + .with_dout(unsafe { io.pins.gpio2.clone_unchecked() }) + .build(); + + let i2s_rx = i2s + .i2s_rx + .with_bclk(io.pins.gpio0) + .with_ws(io.pins.gpio1) + .with_din(io.pins.gpio3) + .build(); + + // enable loopback testing + unsafe { + let i2s = esp_hal::peripherals::I2S0::steal(); + i2s.tx_conf().modify(|_, w| w.sig_loopback().set_bit()); + + i2s.rx_conf().modify(|_, w| w.rx_slave_mod().set_bit()); + + i2s.tx_conf().modify(|_, w| w.tx_update().clear_bit()); + i2s.tx_conf().modify(|_, w| w.tx_update().set_bit()); + + i2s.rx_conf().modify(|_, w| w.rx_update().clear_bit()); + i2s.rx_conf().modify(|_, w| w.rx_update().set_bit()); + } + + let mut iteration = 0; + let mut failed = false; + let mut check_i: u8 = 0; + let mut i = 0; + for b in tx_buffer.iter_mut() { + *b = i; + i = (i + ADD) % CUT_OFF; + } + + let mut rcv = [0u8; 2000]; + + let mut rx_transfer = i2s_rx.read_dma_circular_async(rx_buffer).unwrap(); + let tx_transfer = i2s_tx.write_dma_circular_async(tx_buffer).unwrap(); + + spawner.must_spawn(writer(i, tx_transfer)); + + 'outer: loop { + let len = rx_transfer.pop(&mut rcv).await.unwrap(); + for &b in &rcv[..len] { + if b != check_i { + failed = true; + break 'outer; + } + check_i = (check_i + ADD) % CUT_OFF; + } + iteration += 1; + + if iteration > 30 { + break; + } + } + + assert!(!failed); + } +} diff --git a/xtask/Cargo.toml b/xtask/Cargo.toml index 8384c4487d0..06b9ce793c0 100644 --- a/xtask/Cargo.toml +++ b/xtask/Cargo.toml @@ -17,3 +17,4 @@ semver = { version = "1.0.23", features = ["serde"] } serde = { version = "1.0.203", features = ["derive"] } strum = { version = "0.26.2", features = ["derive"] } toml_edit = "0.22.13" +esp-metadata = { path = "../esp-metadata" } diff --git a/xtask/src/lib.rs b/xtask/src/lib.rs index 126f24a58d1..5740f816f71 100644 --- a/xtask/src/lib.rs +++ b/xtask/src/lib.rs @@ -9,6 +9,7 @@ use std::{ use anyhow::{bail, Result}; use cargo::CargoAction; use clap::ValueEnum; +use esp_metadata::Chip; use strum::{Display, EnumIter, IntoEnumIterator as _}; use self::cargo::CargoArgsBuilder; @@ -52,69 +53,6 @@ pub enum Package { XtensaLxRt, } -#[derive(Debug, Clone, Copy, PartialEq, Eq, Display, EnumIter, ValueEnum, serde::Serialize)] -#[serde(rename_all = "kebab-case")] -#[strum(serialize_all = "kebab-case")] -pub enum Chip { - Esp32, - Esp32c2, - Esp32c3, - Esp32c6, - Esp32h2, - Esp32s2, - Esp32s3, -} - -impl Chip { - pub fn target(&self) -> &str { - use Chip::*; - - match self { - Esp32 => "xtensa-esp32-none-elf", - Esp32c2 | Esp32c3 => "riscv32imc-unknown-none-elf", - Esp32c6 | Esp32h2 => "riscv32imac-unknown-none-elf", - Esp32s2 => "xtensa-esp32s2-none-elf", - Esp32s3 => "xtensa-esp32s3-none-elf", - } - } - - pub fn has_lp_core(&self) -> bool { - use Chip::*; - - matches!(self, Esp32c6 | Esp32s2 | Esp32s3) - } - - pub fn lp_target(&self) -> Result<&str> { - use Chip::*; - - match self { - Esp32c6 => Ok("riscv32imac-unknown-none-elf"), - Esp32s2 | Esp32s3 => Ok("riscv32imc-unknown-none-elf"), - _ => bail!("Chip does not contain an LP core: '{}'", self), - } - } - - pub fn pretty_name(&self) -> &str { - match self { - Chip::Esp32 => "ESP32", - Chip::Esp32c2 => "ESP32-C2", - Chip::Esp32c3 => "ESP32-C3", - Chip::Esp32c6 => "ESP32-C6", - Chip::Esp32h2 => "ESP32-H2", - Chip::Esp32s2 => "ESP32-S2", - Chip::Esp32s3 => "ESP32-S3", - } - } - - pub fn is_xtensa(&self) -> bool { - matches!(self, Chip::Esp32 | Chip::Esp32s2 | Chip::Esp32s3) - } - - pub fn is_riscv(&self) -> bool { - !self.is_xtensa() - } -} - #[derive(Debug, Default, Clone)] pub struct Metadata { example_path: PathBuf, diff --git a/xtask/src/main.rs b/xtask/src/main.rs index a3f4739cafe..e5953ea362e 100644 --- a/xtask/src/main.rs +++ b/xtask/src/main.rs @@ -7,11 +7,11 @@ use std::{ use anyhow::{bail, Result}; use clap::{Args, Parser}; +use esp_metadata::{Arch, Chip, Config}; use minijinja::Value; use strum::IntoEnumIterator; use xtask::{ cargo::{CargoAction, CargoArgsBuilder}, - Chip, Metadata, Package, Version, @@ -130,6 +130,10 @@ struct LintPackagesArgs { /// Package(s) to target. #[arg(value_enum, default_values_t = Package::iter())] packages: Vec, + + /// Lint for a specific chip + #[arg(long, value_enum, default_values_t = Chip::iter())] + chips: Vec, } #[derive(Debug, Args)] @@ -464,103 +468,173 @@ fn lint_packages(workspace: &Path, args: LintPackagesArgs) -> Result<()> { // building, so we need to handle each individually (though there // is *some* overlap) - match package { - Package::EspBacktrace => lint_package( - &path, - &[ - "-Zbuild-std=core", - "--no-default-features", - "--target=riscv32imc-unknown-none-elf", - "--features=esp32c6,defmt", - ], - )?, - - Package::EspHal => { - // Since different files/modules can be included/excluded - // depending on the target, we must lint *all* targets: - for chip in Chip::iter() { + for chip in &args.chips { + let device = Config::for_chip(&chip); + + match package { + Package::EspBacktrace => { lint_package( &path, &[ "-Zbuild-std=core", + "--no-default-features", &format!("--target={}", chip.target()), - &format!("--features={chip}"), + &format!("--features={chip},defmt"), ], )?; } - } - Package::EspHalEmbassy => { - lint_package( - &path, - &[ - "-Zbuild-std=core", - "--target=riscv32imac-unknown-none-elf", - "--features=esp32c6", - ], - )?; - } + Package::EspHal => { + let mut features = format!("--features={chip},ci"); + + // Cover all esp-hal features where a device is supported + if device.contains(&"usb0".to_owned()) { + features.push_str(",usb-otg") + } + if device.contains(&"bt".to_owned()) { + features.push_str(",bluetooth") + } + if device.contains(&"psram".to_owned()) { + // TODO this doesn't test octal psram as it would require a separate build + features.push_str(",psram-4m,psram-80mhz") + } + if matches!(chip, Chip::Esp32c6 | Chip::Esp32h2) { + features.push_str(",flip-link") + } - Package::EspHalProcmacros | Package::EspRiscvRt => lint_package( - &path, - &["-Zbuild-std=core", "--target=riscv32imc-unknown-none-elf"], - )?, - - Package::EspHalSmartled | Package::EspIeee802154 | Package::EspLpHal => lint_package( - &path, - &[ - "-Zbuild-std=core", - "--target=riscv32imac-unknown-none-elf", - "--features=esp32c6", - ], - )?, - - Package::EspPrintln => lint_package( - &path, - &[ - "-Zbuild-std=core", - "--target=riscv32imc-unknown-none-elf", - "--features=esp32c6", - ], - )?, - - Package::EspStorage => lint_package( - &path, - &[ - "-Zbuild-std=core", - "--target=riscv32imc-unknown-none-elf", - "--features=esp32c6", - ], - )?, - - Package::EspWifi => lint_package( - &path, - &[ - "-Zbuild-std=core", - "--target=riscv32imc-unknown-none-elf", - "--features=esp32c3,wifi-default,ble,esp-now,async,embassy-net", - ], - )?, - - Package::XtensaLxRt => { - for chip in [Chip::Esp32, Chip::Esp32s2, Chip::Esp32s3] { lint_package( &path, &[ "-Zbuild-std=core", - &format!("--target=xtensa-{chip}-none-elf"), - &format!("--features={chip}"), + &format!("--target={}", chip.target()), + &features, ], - )? + )?; } - } - // We will *not* check the following packages with `clippy`; this - // may or may not change in the future: - Package::Examples | Package::HilTest => {} + Package::EspHalEmbassy => { + lint_package( + &path, + &[ + "-Zbuild-std=core", + &format!("--target={}", chip.target()), + &format!("--features={chip},executors,defmt,integrated-timers"), + ], + )?; + } - // By default, no `clippy` arguments are required: - _ => lint_package(&path, &[])?, + Package::EspIeee802154 => { + if device.contains(&"ieee802154".to_owned()) { + lint_package( + &path, + &[ + "-Zbuild-std=core", + &format!("--target={}", chip.target()), + &format!("--features={chip}"), + ], + )?; + } + } + Package::EspLpHal => { + if device.contains(&"lp_core".to_owned()) { + lint_package( + &path, + &[ + "-Zbuild-std=core", + &format!("--target={}", chip.lp_target().unwrap()), + &format!("--features={chip},embedded-io,embedded-hal-02"), + ], + )?; + } + } + Package::EspHalSmartled => { + if device.contains(&"rmt".to_owned()) { + lint_package( + &path, + &[ + "-Zbuild-std=core", + &format!("--target={}", chip.target()), + &format!("--features={chip}"), + ], + )?; + } + } + + Package::EspPrintln => { + lint_package( + &path, + &[ + "-Zbuild-std=core", + &format!("--target={}", chip.target()), + &format!("--features={chip},defmt-espflash"), + ], + )?; + } + + Package::EspRiscvRt => { + if matches!(device.arch(), Arch::RiscV) { + lint_package( + &path, + &["-Zbuild-std=core", &format!("--target={}", chip.target())], + )?; + } + } + + Package::EspStorage => { + lint_package( + &path, + &[ + "-Zbuild-std=core", + &format!("--target={}", chip.target()), + &format!("--features={chip},storage,nor-flash,low-level"), + ], + )?; + } + + Package::EspWifi => { + let mut features = format!("--features={chip},async,ps-min-modem,defmt"); + + if device.contains(&"wifi".to_owned()) { + features + .push_str(",wifi-default,esp-now,embedded-svc,embassy-net,dump-packets") + } + if device.contains(&"bt".to_owned()) { + features.push_str(",ble") + } + if device.contains(&"coex".to_owned()) { + features.push_str(",coex") + } + lint_package( + &path, + &[ + "-Zbuild-std=core", + &format!("--target={}", chip.target()), + "--no-default-features", + &features, + ], + )?; + } + + Package::XtensaLxRt => { + if matches!(device.arch(), Arch::Xtensa) { + lint_package( + &path, + &[ + "-Zbuild-std=core", + &format!("--target={}", chip.target()), + &format!("--features={chip}"), + ], + )? + } + } + + // We will *not* check the following packages with `clippy`; this + // may or may not change in the future: + Package::Examples | Package::HilTest => {} + + // By default, no `clippy` arguments are required: + _ => lint_package(&path, &[])?, + } } } @@ -578,7 +652,13 @@ fn lint_package(path: &Path, args: &[&str]) -> Result<()> { builder = builder.arg(arg.to_string()); } - let cargo_args = builder.arg("--").arg("-D").arg("warnings").build(); + // build in release to reuse example artifacts + let cargo_args = builder + .arg("--release") + .arg("--") + .arg("-D") + .arg("warnings") + .build(); xtask::cargo::run(&cargo_args, &path) }