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/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 a07fd7c816a..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)] 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 5c71abbd647..970e12599ca 100644 --- a/esp-hal/src/dma/mod.rs +++ b/esp-hal/src/dma/mod.rs @@ -2174,13 +2174,11 @@ pub(crate) mod asynch { TX::waker().register(cx.waker()); if self.tx.is_listening_eof() { Poll::Pending + } else if self.tx.has_error() { + self.tx.clear_interrupts(); + Poll::Ready(Err(DmaError::DescriptorError)) } else { - if self.tx.has_error() { - self.tx.clear_interrupts(); - Poll::Ready(Err(DmaError::DescriptorError)) - } else { - Poll::Ready(Ok(())) - } + Poll::Ready(Ok(())) } } } @@ -2220,14 +2218,14 @@ pub(crate) mod asynch { RX::waker().register(cx.waker()); if self.rx.is_listening_eof() { Poll::Pending + } else if self.rx.has_error() + || self.rx.has_dscr_empty_error() + || self.rx.has_eof_error() + { + self.rx.clear_interrupts(); + Poll::Ready(Err(DmaError::DescriptorError)) } else { - if self.rx.has_error() || self.rx.has_dscr_empty_error() || self.rx.has_eof_error() - { - self.rx.clear_interrupts(); - Poll::Ready(Err(DmaError::DescriptorError)) - } else { - Poll::Ready(Ok(())) - } + Poll::Ready(Ok(())) } } } @@ -2264,13 +2262,11 @@ pub(crate) mod asynch { TX::waker().register(cx.waker()); if self.tx.is_listening_ch_out_done() { Poll::Pending + } else if self.tx.has_error() { + self.tx.clear_interrupts(); + Poll::Ready(Err(DmaError::DescriptorError)) } else { - if self.tx.has_error() { - self.tx.clear_interrupts(); - Poll::Ready(Err(DmaError::DescriptorError)) - } else { - Poll::Ready(Ok(())) - } + Poll::Ready(Ok(())) } } } @@ -2309,14 +2305,14 @@ pub(crate) mod asynch { RX::waker().register(cx.waker()); if self.rx.is_listening_ch_in_done() { Poll::Pending + } else if self.rx.has_error() + || self.rx.has_dscr_empty_error() + || self.rx.has_eof_error() + { + self.rx.clear_interrupts(); + Poll::Ready(Err(DmaError::DescriptorError)) } else { - if self.rx.has_error() || self.rx.has_dscr_empty_error() || self.rx.has_eof_error() - { - self.rx.clear_interrupts(); - Poll::Ready(Err(DmaError::DescriptorError)) - } else { - Poll::Ready(Ok(())) - } + Poll::Ready(Ok(())) } } } 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..d617a4be379 100644 --- a/esp-hal/src/parl_io.rs +++ b/esp-hal/src/parl_io.rs @@ -1752,10 +1752,8 @@ 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); 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/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) }