diff --git a/.github/workflows/clippy.yaml b/.github/workflows/clippy.yaml new file mode 100644 index 0000000..03996f4 --- /dev/null +++ b/.github/workflows/clippy.yaml @@ -0,0 +1,43 @@ +on: + push: + branches: [ master ] + pull_request: + merge_group: + +name: Lints compliance check + +env: + # Bypass clippy warnings produced by Svd2Rust + CLIPPY_PARAMS: -W clippy::all -D warnings -A clippy::module_inception -A clippy::needless_lifetimes + +jobs: + clippy: + strategy: + matrix: + board: [hifive1, hifive1-revb, redv, lofive, lofive-r1] + toolchain: [ stable, nightly ] + include: + # Nightly is only for reference and allowed to fail + - toolchain: nightly + experimental: true + runs-on: ubuntu-latest + continue-on-error: ${{ matrix.experimental || false }} + steps: + - uses: actions/checkout@v4 + - name: Update Rust toolchain and install Clippy + run: rustup update ${{ matrix.toolchain }} && rustup default ${{ matrix.toolchain }} && rustup component add clippy + - name: Install Rust target + run: rustup target install riscv32imc-unknown-none-elf + - name: Run clippy (direct mode) + run: cargo clippy --features board-${{ matrix.board }} -- $CLIPPY_PARAMS + - name: Run clippy (vectored mode) + run: cargo clippy --features virq,board-${{ matrix.board }} -- $CLIPPY_PARAMS + + # Job to check that all the lint checks succeeded + clippy-check: + needs: + - clippy + runs-on: ubuntu-latest + if: always() + steps: + - run: jq --exit-status 'all(.result == "success")' <<< '${{ toJson(needs) }}' diff --git a/e310x-hal/CHANGELOG.md b/e310x-hal/CHANGELOG.md index 27a341a..dd61301 100644 --- a/e310x-hal/CHANGELOG.md +++ b/e310x-hal/CHANGELOG.md @@ -8,6 +8,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/). ## [Unreleased] ### Changed +- Apply clippy changes - Use `portable-atomic` with `zaamo` feature to use native `amo*` operations. - Official target is now `riscv32imc-unknown-none-elf`, as it does not fully support the A extension. - Update `e310x` dependency and adapt code diff --git a/e310x-hal/src/clock.rs b/e310x-hal/src/clock.rs index 29c359d..79fae5e 100644 --- a/e310x-hal/src/clock.rs +++ b/e310x-hal/src/clock.rs @@ -175,10 +175,10 @@ impl CoreClk { /// The resulting frequency may differ by 0-2% from the requested fn configure_pll(&self, pllref_freq: Hertz, divout_freq: Hertz) -> Hertz { let pllref_freq = pllref_freq.0; - assert!(PLLREF_MIN <= pllref_freq && pllref_freq <= PLLREF_MAX); + assert!((PLLREF_MIN..=PLLREF_MAX).contains(&pllref_freq)); let divout_freq = divout_freq.0; - assert!(DIVOUT_MIN <= divout_freq && divout_freq <= DIVOUT_MAX); + assert!((DIVOUT_MIN..=DIVOUT_MAX).contains(&divout_freq)); // Calculate PLL Output Divider settings let divider_div; @@ -205,7 +205,7 @@ impl CoreClk { 2 * (divider_div + 1) }; let pllout_freq = divout_freq * d; - assert!(PLLOUT_MIN <= pllout_freq && pllout_freq <= PLLOUT_MAX); + assert!((PLLOUT_MIN..=PLLOUT_MAX).contains(&pllout_freq)); // Calculate PLL R ratio let r = match pllref_freq { @@ -218,7 +218,7 @@ impl CoreClk { // Calculate refr frequency let refr_freq = pllref_freq / r; - assert!(REFR_MIN <= refr_freq && refr_freq <= REFR_MAX); + assert!((REFR_MIN..=REFR_MAX).contains(&refr_freq)); // Calculate PLL Q ratio let q = match pllout_freq { @@ -230,7 +230,7 @@ impl CoreClk { // Calculate the desired vco frequency let target_vco_freq = pllout_freq * q; - assert!(VCO_MIN <= target_vco_freq && target_vco_freq <= VCO_MAX); + assert!((VCO_MIN..=VCO_MAX).contains(&target_vco_freq)); // Calculate PLL F ratio let f = target_vco_freq / refr_freq; @@ -249,15 +249,15 @@ impl CoreClk { } else { (f_lo, vco_lo) }; - assert!(VCO_MIN <= vco_freq && vco_freq <= VCO_MAX); + assert!((VCO_MIN..=VCO_MAX).contains(&vco_freq)); // Calculate actual pllout frequency let pllout_freq = vco_freq / q; - assert!(PLLOUT_MIN <= pllout_freq && pllout_freq <= PLLOUT_MAX); + assert!((PLLOUT_MIN..=PLLOUT_MAX).contains(&pllout_freq)); // Calculate actual divout frequency let divout_freq = pllout_freq / d; - assert!(DIVOUT_MIN <= divout_freq && divout_freq <= DIVOUT_MAX); + assert!((DIVOUT_MIN..=DIVOUT_MAX).contains(&divout_freq)); // Calculate bit-values let r: u8 = (r - 1) as u8; diff --git a/e310x-hal/src/core/mod.rs b/e310x-hal/src/core/mod.rs index 43d1483..5b8d03e 100644 --- a/e310x-hal/src/core/mod.rs +++ b/e310x-hal/src/core/mod.rs @@ -26,6 +26,10 @@ impl CorePeripherals { } /// Steal the peripherals + /// + /// # Safety + /// + /// Using this function may break the guarantees of the singleton pattern. pub unsafe fn steal() -> Self { let p = e310x::Peripherals::steal(); Self::new(p.clint, p.plic) diff --git a/e310x-hal/src/core/plic.rs b/e310x-hal/src/core/plic.rs index 3da4167..9f3e0a9 100644 --- a/e310x-hal/src/core/plic.rs +++ b/e310x-hal/src/core/plic.rs @@ -43,11 +43,11 @@ impl Priority { } } -impl Into for Priority { +impl From for u32 { /// Returns the numeric priority for writing to a /// interrupt priority or the plic threshold register. - fn into(self) -> u32 { - match self { + fn from(val: Priority) -> Self { + match val { Priority::P0 => 0, Priority::P1 => 1, Priority::P2 => 2, diff --git a/e310x-hal/src/delay.rs b/e310x-hal/src/delay.rs index 4778bf1..5a89293 100644 --- a/e310x-hal/src/delay.rs +++ b/e310x-hal/src/delay.rs @@ -6,6 +6,7 @@ use embedded_hal::blocking::delay::{DelayMs, DelayUs}; use riscv::register::{mie, mip}; /// Machine timer (mtime) as a busyloop delay provider +#[derive(Default)] pub struct Delay; const TICKS_PER_SECOND: u64 = 32768; diff --git a/e310x-hal/src/device.rs b/e310x-hal/src/device.rs index f1a2f13..da0a63f 100644 --- a/e310x-hal/src/device.rs +++ b/e310x-hal/src/device.rs @@ -173,7 +173,11 @@ impl DeviceResources { e310x::Peripherals::take().map(DeviceResources::from) } - /// Unchecked version of `DeviceResources::take` + /// Unchecked version of [`DeviceResources::take`]. + /// + /// # Safety + /// + /// Using this function may break the guarantees of the singleton pattern. pub unsafe fn steal() -> Self { e310x::Peripherals::steal().into() } diff --git a/e310x-hal/src/i2c.rs b/e310x-hal/src/i2c.rs index c0aac2d..6e03258 100644 --- a/e310x-hal/src/i2c.rs +++ b/e310x-hal/src/i2c.rs @@ -19,12 +19,16 @@ use e310x::{i2c0, I2c0}; use embedded_hal::blocking::i2c::{Read, Write, WriteRead}; /// SDA pin - DO NOT IMPLEMENT THIS TRAIT -pub unsafe trait SdaPin {} -/// SCL pin - DO NOT IMPLEMENT THIS TRAIT -pub unsafe trait SclPin {} +mod sealed { + /// SDA pin + pub trait SdaPin {} -unsafe impl SdaPin for gpio0::Pin12> {} -unsafe impl SclPin for gpio0::Pin13> {} + /// SCL pin + pub trait SclPin {} +} + +impl sealed::SdaPin for gpio0::Pin12> {} +impl sealed::SclPin for gpio0::Pin13> {} /// I2C error #[derive(Debug, Eq, PartialEq)] @@ -61,8 +65,8 @@ impl I2c { /// Configures an I2C peripheral pub fn new(i2c: I2c0, sda: SDA, scl: SCL, speed: Speed, clocks: Clocks) -> Self where - SDA: SdaPin, - SCL: SclPin, + SDA: sealed::SdaPin, + SCL: sealed::SclPin, { // Calculate prescaler value let desired_speed = match speed { @@ -115,13 +119,13 @@ impl, PINS> I2c { { self.i2c.cr().write(|w| unsafe { let mut value: u32 = 0; - f(mem::transmute(&mut value)); + f(mem::transmute::<&mut u32, &mut i2c0::cr::W>(&mut value)); w.bits(value) }); } fn read_sr(&self) -> i2c0::sr::R { - unsafe { mem::transmute(self.i2c.sr().read()) } + self.i2c.sr().read() } fn write_byte(&self, byte: u8) { diff --git a/e310x-hal/src/pmu.rs b/e310x-hal/src/pmu.rs index 21bb422..a55ccac 100644 --- a/e310x-hal/src/pmu.rs +++ b/e310x-hal/src/pmu.rs @@ -132,7 +132,7 @@ pub trait PMUExt { /// /// Stores user data `UD` to backup registers. /// - /// # *WARNING* + /// # Safety /// /// `user_data` value must not contain un-serializable types such as pointers or references. /// @@ -160,7 +160,7 @@ pub trait PMUExt { /// /// Restores user data `UD` from backup registers. /// - /// # *WARNING* + /// # Safety /// /// `user_data` value must not contain un-serializable types such as pointers or references. /// @@ -269,9 +269,9 @@ impl PMUExt for Pmu { let ptr_u32 = ptr as *const u32; let sliced = core::slice::from_raw_parts(ptr_u32, reg_count); - for i in 0..sliced.len() { - backup.backup(i).write(|w| w.bits(sliced[i])); - } + backup.backup_iter().enumerate().for_each(|(i, backup_r)| { + backup_r.write(|w| w.bits(sliced[i])); + }); Ok(()) } @@ -297,9 +297,9 @@ impl PMUExt for Pmu { let ptr_u32 = ptr as *mut u32; let sliced = core::slice::from_raw_parts_mut(ptr_u32, reg_count); - for i in 0..sliced.len() { - sliced[i] = backup.backup(i).read().bits(); - } + backup.backup_iter().enumerate().for_each(|(i, backup_r)| { + sliced[i] = backup_r.read().bits(); + }); Ok(()) } diff --git a/e310x-hal/src/pwm.rs b/e310x-hal/src/pwm.rs index e536c4f..72549e0 100644 --- a/e310x-hal/src/pwm.rs +++ b/e310x-hal/src/pwm.rs @@ -91,6 +91,7 @@ mod pwm2_impl { } /// PWM channel +#[derive(Copy, Clone)] pub struct Channel { _pwm: PhantomData, cmp_index: CmpIndex, @@ -109,17 +110,6 @@ impl Channel { } } -impl Clone for Channel { - fn clone(&self) -> Self { - Self { - _pwm: self._pwm.clone(), - cmp_index: self.cmp_index.clone(), - } - } -} - -impl Copy for Channel {} - #[doc(hidden)] pub trait PwmX: Deref { type CmpWidth: Ord; diff --git a/e310x-hal/src/serial.rs b/e310x-hal/src/serial.rs index 6a284ba..5e5029e 100644 --- a/e310x-hal/src/serial.rs +++ b/e310x-hal/src/serial.rs @@ -26,22 +26,21 @@ use core::mem; #[allow(unused_imports)] use e310x::{uart0, Uart0, Uart1}; -// FIXME these should be "closed" traits -/// TX pin - DO NOT IMPLEMENT THIS TRAIT -pub unsafe trait TxPin {} +mod sealed { + /// TX pin + pub trait TxPin {} -/// RX pin - DO NOT IMPLEMENT THIS TRAIT -pub unsafe trait RxPin {} + /// RX pin + pub trait RxPin {} +} -unsafe impl TxPin for gpio0::Pin17> {} -unsafe impl RxPin for gpio0::Pin16> {} +impl sealed::TxPin for gpio0::Pin17> {} +impl sealed::RxPin for gpio0::Pin16> {} #[cfg(feature = "g002")] -mod g002_ims { - use super::{gpio0, RxPin, TxPin, Uart1, IOF0}; - unsafe impl TxPin for gpio0::Pin18> {} - unsafe impl RxPin for gpio0::Pin23> {} -} +impl sealed::TxPin for gpio0::Pin18> {} +#[cfg(feature = "g002")] +impl sealed::RxPin for gpio0::Pin23> {} #[doc(hidden)] pub trait UartX: Deref {} @@ -68,8 +67,8 @@ impl Serial { /// Configures a UART peripheral to provide serial communication pub fn new(uart: UART, pins: (TX, RX), baud_rate: Bps, clocks: Clocks) -> Self where - TX: TxPin, - RX: RxPin, + TX: sealed::TxPin, + RX: sealed::RxPin, { let div = clocks.tlclk().0 / baud_rate.0 - 1; unsafe { @@ -125,7 +124,7 @@ impl serial::Read for Rx { if rxdata.empty().bit_is_set() { Err(::nb::Error::WouldBlock) } else { - Ok(rxdata.data().bits() as u8) + Ok(rxdata.data().bits()) } } } @@ -162,8 +161,8 @@ impl Serial { #[deprecated(note = "Please use Serial::new function instead")] pub fn uart0(uart: Uart0, pins: (TX, RX), baud_rate: Bps, clocks: Clocks) -> Self where - TX: TxPin, - RX: RxPin, + TX: sealed::TxPin, + RX: sealed::RxPin, { Self::new(uart, pins, baud_rate, clocks) } @@ -175,8 +174,8 @@ impl Serial { #[deprecated(note = "Please use Serial::new function instead")] pub fn uart1(uart: Uart1, pins: (TX, RX), baud_rate: Bps, clocks: Clocks) -> Self where - TX: TxPin, - RX: RxPin, + TX: sealed::TxPin, + RX: sealed::RxPin, { Self::new(uart, pins, baud_rate, clocks) } diff --git a/e310x-hal/src/spi/bus.rs b/e310x-hal/src/spi/bus.rs index 4be10be..3543244 100644 --- a/e310x-hal/src/spi/bus.rs +++ b/e310x-hal/src/spi/bus.rs @@ -210,10 +210,7 @@ where Ok(()) } - pub(crate) fn exec<'op>( - &mut self, - operations: &mut [Operation<'op, u8>], - ) -> Result<(), Infallible> { + pub(crate) fn exec(&mut self, operations: &mut [Operation<'_, u8>]) -> Result<(), Infallible> { for op in operations { match op { Operation::Transfer(words) => { diff --git a/e310x-hal/src/spi/exclusive_device.rs b/e310x-hal/src/spi/exclusive_device.rs index d9e808e..50e01db 100644 --- a/e310x-hal/src/spi/exclusive_device.rs +++ b/e310x-hal/src/spi/exclusive_device.rs @@ -110,7 +110,7 @@ where { type Error = Infallible; - fn exec<'op>(&mut self, operations: &mut [Operation<'op, u8>]) -> Result<(), Infallible> { + fn exec(&mut self, operations: &mut [Operation<'_, u8>]) -> Result<(), Infallible> { self.bus.start_frame(); let result = self.bus.exec(operations); self.bus.end_frame(); diff --git a/e310x-hal/src/spi/shared_device.rs b/e310x-hal/src/spi/shared_device.rs index cbedea9..4612ca7 100644 --- a/e310x-hal/src/spi/shared_device.rs +++ b/e310x-hal/src/spi/shared_device.rs @@ -149,7 +149,7 @@ where { type Error = Infallible; - fn exec<'op>(&mut self, operations: &mut [Operation<'op, u8>]) -> Result<(), Infallible> { + fn exec(&mut self, operations: &mut [Operation<'_, u8>]) -> Result<(), Infallible> { interrupt::free(|| { let mut bus = self.bus.borrow_mut(); diff --git a/e310x-hal/src/spi/traits.rs b/e310x-hal/src/spi/traits.rs index a3b3dfc..f115a5b 100644 --- a/e310x-hal/src/spi/traits.rs +++ b/e310x-hal/src/spi/traits.rs @@ -42,9 +42,9 @@ mod spi1_impl { use crate::gpio::gpio0; use crate::gpio::{NoInvert, IOF0}; - type MOSI = gpio0::Pin3>; - type MISO = gpio0::Pin4>; - type SCK = gpio0::Pin5>; + type Mosi = gpio0::Pin3>; + type Miso = gpio0::Pin4>; + type Sck = gpio0::Pin5>; type CS0 = gpio0::Pin2>; type CS1 = gpio0::Pin8>; type CS2 = gpio0::Pin9>; @@ -64,53 +64,53 @@ mod spi1_impl { const CS_INDEX: u32 = 3; } - impl PinsNoCS for (MOSI, MISO, SCK) {} - impl PinsNoCS for (MOSI, (), SCK) {} - impl PinsNoCS for ((), MISO, SCK) {} + impl PinsNoCS for (Mosi, Miso, Sck) {} + impl PinsNoCS for (Mosi, (), Sck) {} + impl PinsNoCS for ((), Miso, Sck) {} - impl Pins for (MOSI, MISO, SCK) { + impl Pins for (Mosi, Miso, Sck) { const CS_INDEX: Option = None; } - impl Pins for (MOSI, (), SCK) { + impl Pins for (Mosi, (), Sck) { const CS_INDEX: Option = None; } - impl Pins for ((), MISO, SCK) { + impl Pins for ((), Miso, Sck) { const CS_INDEX: Option = None; } - impl Pins for (MOSI, MISO, SCK, CS0) { + impl Pins for (Mosi, Miso, Sck, CS0) { const CS_INDEX: Option = Some(0); } - impl Pins for (MOSI, (), SCK, CS0) { + impl Pins for (Mosi, (), Sck, CS0) { const CS_INDEX: Option = Some(0); } - impl Pins for ((), MISO, SCK, CS0) { + impl Pins for ((), Miso, Sck, CS0) { const CS_INDEX: Option = Some(0); } - impl Pins for (MOSI, MISO, SCK, CS1) { + impl Pins for (Mosi, Miso, Sck, CS1) { const CS_INDEX: Option = Some(1); } - impl Pins for (MOSI, (), SCK, CS1) { + impl Pins for (Mosi, (), Sck, CS1) { const CS_INDEX: Option = Some(1); } - impl Pins for ((), MISO, SCK, CS1) { + impl Pins for ((), Miso, Sck, CS1) { const CS_INDEX: Option = Some(1); } - impl Pins for (MOSI, MISO, SCK, CS2) { + impl Pins for (Mosi, Miso, Sck, CS2) { const CS_INDEX: Option = Some(2); } - impl Pins for (MOSI, (), SCK, CS2) { + impl Pins for (Mosi, (), Sck, CS2) { const CS_INDEX: Option = Some(2); } - impl Pins for ((), MISO, SCK, CS2) { + impl Pins for ((), Miso, Sck, CS2) { const CS_INDEX: Option = Some(2); } - impl Pins for (MOSI, MISO, SCK, CS3) { + impl Pins for (Mosi, Miso, Sck, CS3) { const CS_INDEX: Option = Some(3); } - impl Pins for (MOSI, (), SCK, CS3) { + impl Pins for (Mosi, (), Sck, CS3) { const CS_INDEX: Option = Some(3); } - impl Pins for ((), MISO, SCK, CS3) { + impl Pins for ((), Miso, Sck, CS3) { const CS_INDEX: Option = Some(3); } @@ -123,21 +123,21 @@ mod spi1_impl { impl Sealed for CS1 {} impl Sealed for CS2 {} impl Sealed for CS3 {} - impl Sealed for (MOSI, MISO, SCK) {} - impl Sealed for (MOSI, (), SCK) {} - impl Sealed for ((), MISO, SCK) {} - impl Sealed for (MOSI, MISO, SCK, CS0) {} - impl Sealed for (MOSI, (), SCK, CS0) {} - impl Sealed for ((), MISO, SCK, CS0) {} - impl Sealed for (MOSI, MISO, SCK, CS1) {} - impl Sealed for (MOSI, (), SCK, CS1) {} - impl Sealed for ((), MISO, SCK, CS1) {} - impl Sealed for (MOSI, MISO, SCK, CS2) {} - impl Sealed for (MOSI, (), SCK, CS2) {} - impl Sealed for ((), MISO, SCK, CS2) {} - impl Sealed for (MOSI, MISO, SCK, CS3) {} - impl Sealed for (MOSI, (), SCK, CS3) {} - impl Sealed for ((), MISO, SCK, CS3) {} + impl Sealed for (Mosi, Miso, Sck) {} + impl Sealed for (Mosi, (), Sck) {} + impl Sealed for ((), Miso, Sck) {} + impl Sealed for (Mosi, Miso, Sck, CS0) {} + impl Sealed for (Mosi, (), Sck, CS0) {} + impl Sealed for ((), Miso, Sck, CS0) {} + impl Sealed for (Mosi, Miso, Sck, CS1) {} + impl Sealed for (Mosi, (), Sck, CS1) {} + impl Sealed for ((), Miso, Sck, CS1) {} + impl Sealed for (Mosi, Miso, Sck, CS2) {} + impl Sealed for (Mosi, (), Sck, CS2) {} + impl Sealed for ((), Miso, Sck, CS2) {} + impl Sealed for (Mosi, Miso, Sck, CS3) {} + impl Sealed for (Mosi, (), Sck, CS3) {} + impl Sealed for ((), Miso, Sck, CS3) {} } } @@ -147,35 +147,35 @@ mod spi2_impl { use crate::gpio::gpio0; use crate::gpio::{NoInvert, IOF0}; - type MOSI = gpio0::Pin27>; - type MISO = gpio0::Pin28>; - type SCK = gpio0::Pin29>; + type Mosi = gpio0::Pin27>; + type Miso = gpio0::Pin28>; + type Sck = gpio0::Pin29>; type CS0 = gpio0::Pin26>; impl PinCS for CS0 { const CS_INDEX: u32 = 0; } - impl PinsNoCS for (MOSI, MISO, SCK) {} - impl PinsNoCS for (MOSI, (), SCK) {} - impl PinsNoCS for ((), MISO, SCK) {} + impl PinsNoCS for (Mosi, Miso, Sck) {} + impl PinsNoCS for (Mosi, (), Sck) {} + impl PinsNoCS for ((), Miso, Sck) {} - impl Pins for (MOSI, MISO, SCK) { + impl Pins for (Mosi, Miso, Sck) { const CS_INDEX: Option = None; } - impl Pins for (MOSI, (), SCK) { + impl Pins for (Mosi, (), Sck) { const CS_INDEX: Option = None; } - impl Pins for ((), MISO, SCK) { + impl Pins for ((), Miso, Sck) { const CS_INDEX: Option = None; } - impl Pins for (MOSI, MISO, SCK, CS0) { + impl Pins for (Mosi, Miso, Sck, CS0) { const CS_INDEX: Option = Some(0); } - impl Pins for (MOSI, (), SCK, CS0) { + impl Pins for (Mosi, (), Sck, CS0) { const CS_INDEX: Option = Some(0); } - impl Pins for ((), MISO, SCK, CS0) { + impl Pins for ((), Miso, Sck, CS0) { const CS_INDEX: Option = Some(0); } @@ -185,12 +185,12 @@ mod spi2_impl { use super::*; impl Sealed for CS0 {} - impl Sealed for (MOSI, MISO, SCK) {} - impl Sealed for (MOSI, (), SCK) {} - impl Sealed for ((), MISO, SCK) {} - impl Sealed for (MOSI, MISO, SCK, CS0) {} - impl Sealed for (MOSI, (), SCK, CS0) {} - impl Sealed for ((), MISO, SCK, CS0) {} + impl Sealed for (Mosi, Miso, Sck) {} + impl Sealed for (Mosi, (), Sck) {} + impl Sealed for ((), Miso, Sck) {} + impl Sealed for (Mosi, Miso, Sck, CS0) {} + impl Sealed for (Mosi, (), Sck, CS0) {} + impl Sealed for ((), Miso, Sck, CS0) {} } } diff --git a/e310x-hal/src/time.rs b/e310x-hal/src/time.rs index c21a86f..56cad39 100644 --- a/e310x-hal/src/time.rs +++ b/e310x-hal/src/time.rs @@ -49,20 +49,20 @@ impl U32Ext for u32 { } } -impl Into for KiloHertz { - fn into(self) -> Hertz { - Hertz(self.0 * 1_000) +impl From for Hertz { + fn from(val: KiloHertz) -> Self { + Hertz(val.0 * 1_000) } } -impl Into for MegaHertz { - fn into(self) -> Hertz { - Hertz(self.0 * 1_000_000) +impl From for Hertz { + fn from(val: MegaHertz) -> Self { + Hertz(val.0 * 1_000_000) } } -impl Into for MegaHertz { - fn into(self) -> KiloHertz { - KiloHertz(self.0 * 1_000) +impl From for KiloHertz { + fn from(val: MegaHertz) -> Self { + KiloHertz(val.0 * 1_000) } } diff --git a/hifive1/CHANGELOG.md b/hifive1/CHANGELOG.md index cc719d5..40286ad 100644 --- a/hifive1/CHANGELOG.md +++ b/hifive1/CHANGELOG.md @@ -6,6 +6,8 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/) and this project adheres to [Semantic Versioning](http://semver.org/). ## [Unreleased] +- Replace static muts with Mutexes +- Apply clippy changes - Bump MSRV to 1.72 - Adapt to new Cargo workspace - Use inline assembly instead of binary blobs for flash diff --git a/hifive1/Cargo.toml b/hifive1/Cargo.toml index efa0546..ac01280 100644 --- a/hifive1/Cargo.toml +++ b/hifive1/Cargo.toml @@ -11,6 +11,7 @@ edition = "2021" rust-version = "1.72" [dependencies] +critical-section = { version = "1.1.3" } e310x-hal = { path = "../e310x-hal", version = "0.11.0" } embedded-hal = "0.2.7" riscv = "0.10.1" diff --git a/hifive1/build.rs b/hifive1/build.rs index c16de98..5cf61dd 100644 --- a/hifive1/build.rs +++ b/hifive1/build.rs @@ -16,12 +16,13 @@ fn main() { }) .collect(); - if boards.is_empty() { - panic!("No board features selected"); - } - if boards.len() > 1 { - panic!("More than one board feature selected: {:?}", boards); - } + assert!(!boards.is_empty(), "No board features selected"); + + assert_eq!( + boards.len(), + 1, + "More than one board feature selected: {boards:?}" + ); let board = boards.first().unwrap(); @@ -39,7 +40,7 @@ fn main() { println!("cargo:rerun-if-changed=memory-lofive-r1.x"); } - other => panic!("Unknown board: {}", other), + other => panic!("Unknown board: {other}"), } fs::copy("hifive1-link.x", out_dir.join("hifive1-link.x")).unwrap(); diff --git a/hifive1/src/led.rs b/hifive1/src/led.rs index 5530d19..c06bb3a 100644 --- a/hifive1/src/led.rs +++ b/hifive1/src/led.rs @@ -73,7 +73,8 @@ macro_rules! led_impl { } } -/// Call the macro for each LED +// Call the macro for each LED + #[cfg(any(feature = "board-hifive1", feature = "board-hifive1-revb"))] led_impl!(RED, GREEN); diff --git a/hifive1/src/stdout.rs b/hifive1/src/stdout.rs index 59be531..c325747 100644 --- a/hifive1/src/stdout.rs +++ b/hifive1/src/stdout.rs @@ -1,6 +1,6 @@ //! Stdout based on the UART hooked up to FTDI or J-Link -use core::fmt; +use core::{fmt, ptr}; use e310x_hal::{ clock::Clocks, e310x::Uart0, @@ -10,12 +10,11 @@ use e310x_hal::{ time::Bps, }; use nb::block; -use riscv::interrupt; - -static mut STDOUT: Option = None; struct SerialWrapper(Tx); +static mut STDOUT: Option = None; + impl core::fmt::Write for SerialWrapper { fn write_str(&mut self, s: &str) -> fmt::Result { for byte in s.as_bytes() { @@ -50,28 +49,28 @@ pub fn configure( let serial = Serial::new(uart, (tx, rx), baud_rate, clocks); let (tx, rx) = serial.split(); - interrupt::free(|| unsafe { - STDOUT.replace(SerialWrapper(tx)); + critical_section::with(|_| { + unsafe { &mut *ptr::addr_of_mut!(STDOUT) }.replace(SerialWrapper(tx)); }); rx } /// Writes string to stdout pub fn write_str(s: &str) { - interrupt::free(|| unsafe { - if let Some(stdout) = STDOUT.as_mut() { + critical_section::with(|_| { + if let Some(stdout) = unsafe { &mut *ptr::addr_of_mut!(STDOUT) } { let _ = stdout.write_str(s); } - }) + }); } /// Writes formatted string to stdout pub fn write_fmt(args: fmt::Arguments) { - interrupt::free(|| unsafe { - if let Some(stdout) = STDOUT.as_mut() { + critical_section::with(|_| { + if let Some(stdout) = unsafe { &mut *ptr::addr_of_mut!(STDOUT) } { let _ = stdout.write_fmt(args); } - }) + }); } /// Macro for printing to the serial standard output