diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 8246a54..777cb4a 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -35,6 +35,12 @@ jobs: - name: Build run: cargo build --release --verbose --target ${{ matrix.target }} + - name: Lint + run: cargo clippy --release --verbose --target ${{ matrix.target }} -- -D warnings + + - name: fmt + run: cargo fmt --check + - name: Build examples run: cargo build --verbose --examples --target ${{ matrix.target }} if: matrix.target != 'x86_64-unknown-linux-gnu' diff --git a/examples/flash.rs b/examples/flash.rs index 89edfe4..6bb456a 100644 --- a/examples/flash.rs +++ b/examples/flash.rs @@ -175,12 +175,12 @@ fn main() -> ! { buf[..4].copy_from_slice(&data); flash - .write_native(WHERE, &generic_array::GenericArray::from_slice(&buf)) + .write_native(WHERE, generic_array::GenericArray::from_slice(&buf)) .unwrap(); buf[0] = 37; // // buf[3] = 37; flash - .write_native(WHERE, &generic_array::GenericArray::from_slice(&buf)) + .write_native(WHERE, generic_array::GenericArray::from_slice(&buf)) .unwrap(); flash.write_u8(0x4_000F, 69).ok(); flash.read(WHERE, &mut read_buf); diff --git a/examples/i2c.rs b/examples/i2c.rs index c461fcb..5c84de2 100644 --- a/examples/i2c.rs +++ b/examples/i2c.rs @@ -15,7 +15,6 @@ use hal::{ time::Hertz, }; -use ssd1306; use ssd1306::prelude::*; #[entry] diff --git a/examples/pfr.rs b/examples/pfr.rs index 5cd0a49..bec08fc 100644 --- a/examples/pfr.rs +++ b/examples/pfr.rs @@ -67,7 +67,7 @@ fn main() -> ! { dump_cfpa(&cfpa); heprintln!("Increment the version and write back cfpa!").ok(); - cfpa.version = cfpa.version + 1; + cfpa.version += 1; cfpa.secure_fw_version += 1; cfpa.ns_fw_version += 1; // increment a byte of customer data (with overflow) diff --git a/examples/prince.rs b/examples/prince.rs index 3f4b0f5..b79a50c 100644 --- a/examples/prince.rs +++ b/examples/prince.rs @@ -29,7 +29,7 @@ fn main() -> ! { let mut syscon = hal.syscon; // prince region 2 (128KB) - const DATA_ADDR: usize = 0x00080000 + 0; + const DATA_ADDR: usize = 0x00080000; let _clocks = hal::ClockRequirements::default() .system_frequency(12.MHz()) @@ -47,7 +47,7 @@ fn main() -> ! { hprintln!("writing AA's to flash data.").ok(); - flash.erase_page((DATA_ADDR / 512) + 0).unwrap(); + flash.erase_page((DATA_ADDR / 512)).unwrap(); flash.erase_page((DATA_ADDR / 512) + 1).unwrap(); prince.write_encrypted(|_prince| { @@ -60,7 +60,7 @@ fn main() -> ! { for i in 0..buf.len() { let ptr = DATA_ADDR as *const u8; - buf[i] = unsafe { *ptr.offset(i as isize) }; + buf[i] = unsafe { *ptr.add(i) }; } dump_hex!(&buf[0..32]); @@ -70,7 +70,7 @@ fn main() -> ! { for i in 0..buf.len() { let ptr = DATA_ADDR as *const u8; - buf[i] = unsafe { *ptr.offset(i as isize) }; + buf[i] = unsafe { *ptr.add(i) }; } hprintln!("Read bytes PRINCE OFF:").ok(); diff --git a/examples/pwm.rs b/examples/pwm.rs index 9cbc594..533e05c 100644 --- a/examples/pwm.rs +++ b/examples/pwm.rs @@ -96,7 +96,7 @@ fn main() -> ! { } for i in 0..3 { - let duty = (sin(duties[i] * 3.14159265f32 / 180f32) * 255f32) as u16; + let duty = (sin(duties[i] * 3.141_592_7_f32 / 180f32) * 255f32) as u16; match i { 0 => { // need to tune down red some diff --git a/examples/semihosting.rs b/examples/semihosting.rs index fced6af..3f0d227 100644 --- a/examples/semihosting.rs +++ b/examples/semihosting.rs @@ -28,7 +28,7 @@ fn main() -> ! { // dbg!(UUID); let mut uuid: [u32; 4] = [0; 4]; for i in 0..4 { - uuid[i] = unsafe { dbg!(UUID.offset(i as isize).read_volatile()) }; + uuid[i] = unsafe { dbg!(UUID.add(i).read_volatile()) }; } // dbg!(uuid); diff --git a/examples/touch.rs b/examples/touch.rs index e724877..906a7b7 100644 --- a/examples/touch.rs +++ b/examples/touch.rs @@ -58,7 +58,7 @@ fn main() -> ! { let button_pins = ButtonPins(but1, but2, but3); - let adc = hal::Adc::from(hal.adc).enabled(&mut hal.pmc, &mut hal.syscon); + let adc = hal.adc.enabled(&mut hal.pmc, &mut hal.syscon); let touch_timer = hal .ctimer @@ -70,7 +70,7 @@ fn main() -> ! { .enabled(&mut hal.syscon, clocks.support_1mhz_fro_token().unwrap()); let charge_pin = pins.pio1_16.into_match_output(&mut iocon); - let mut dma = hal::Dma::from(hal.dma).enabled(&mut hal.syscon); + let mut dma = hal.dma.enabled(&mut hal.syscon); let touch_sensor = TouchSensor::new( [13_900, 13_900, 13_900], diff --git a/examples/usb_test_class.rs b/examples/usb_test_class.rs index bf59e34..0022eab 100644 --- a/examples/usb_test_class.rs +++ b/examples/usb_test_class.rs @@ -62,9 +62,9 @@ fn main() -> ! { const VID: u16 = 0x16c0; const PID: u16 = 0x05dc; - const MANUFACTURER: &'static str = "TestClass Manufacturer"; - const PRODUCT: &'static str = "virkkunen.net usb-device TestClass"; - const SERIAL_NUMBER: &'static str = "TestClass Serial"; + const MANUFACTURER: &str = "TestClass Manufacturer"; + const PRODUCT: &str = "virkkunen.net usb-device TestClass"; + const SERIAL_NUMBER: &str = "TestClass Serial"; let mut test = TestClass::new(&usb_bus); let mut usb_dev = UsbDeviceBuilder::new(&usb_bus, UsbVidPid(VID, PID)) diff --git a/src/drivers/aes.rs b/src/drivers/aes.rs index 428d135..ed61bb1 100644 --- a/src/drivers/aes.rs +++ b/src/drivers/aes.rs @@ -162,7 +162,7 @@ impl<'a, Size: KeySize> Aes<'a, Size> { fn one_block(&self, block: &mut Block) { // needs to be word-aligned - let aligned_block: Aligned> = Aligned(block.clone()); + let aligned_block: Aligned> = Aligned(*block); let addr: u32 = &aligned_block as *const _ as _; self.memaddr.write(|w| unsafe { w.bits(addr) }); @@ -182,12 +182,12 @@ impl<'a, Size: KeySize> Aes<'a, Size> { // the `block-cipher` traits -impl<'a, Size: KeySize> BlockCipher for Aes<'a, Size> { +impl BlockCipher for Aes<'_, Size> { type BlockSize = U16; type ParBlocks = U1; } -impl<'a, Size: KeySize> BlockEncrypt for Aes<'a, Size> { +impl BlockEncrypt for Aes<'_, Size> { fn encrypt_block(&self, block: &mut Block) { // unfortunate implementation detail if self.cryptcfg.read().aesdecrypt().is_decrypt() { @@ -197,7 +197,7 @@ impl<'a, Size: KeySize> BlockEncrypt for Aes<'a, Size> { } } -impl<'a, Size: KeySize> BlockDecrypt for Aes<'a, Size> { +impl BlockDecrypt for Aes<'_, Size> { fn decrypt_block(&self, block: &mut Block) { // unfortunate implementation detail if self.cryptcfg.read().aesdecrypt().is_encrypt() { @@ -210,12 +210,12 @@ impl<'a, Size: KeySize> BlockDecrypt for Aes<'a, Size> { impl core::ops::Deref for Aes<'_, Size> { type Target = Hashcrypt; fn deref(&self) -> &Self::Target { - &self.inner + self.inner } } impl core::ops::DerefMut for Aes<'_, Size> { fn deref_mut(&mut self) -> &mut Self::Target { - &mut self.inner + self.inner } } diff --git a/src/drivers/clocks.rs b/src/drivers/clocks.rs index 969ae7a..49d62e9 100644 --- a/src/drivers/clocks.rs +++ b/src/drivers/clocks.rs @@ -1,10 +1,10 @@ -///!* API to configure the clocks. -///! -///! This is very incomplete (e.g., no support for PLL clocks). -///! It is also likely buggy, and more complex than needed -///! -///! It is currently used to prepare for using the USBFSD and -///! Flexcomm peripherals. +//!* API to configure the clocks. +//! +//! This is very incomplete (e.g., no support for PLL clocks). +//! It is also likely buggy, and more complex than needed +//! +//! It is currently used to prepare for using the USBFSD and +//! Flexcomm peripherals. use core::{cmp::min, convert::TryFrom}; use embedded_time::rate::Extensions; @@ -114,6 +114,9 @@ pub struct Pll { impl Pll { // allow user to override if they know better... + /// # Safety + /// + /// Input values must be valid for PLL pub unsafe fn new(n: u8, m: u16, p: u8) -> Pll { // UM 4.6.6.3.2 let selp = min((m >> 2) + 1, 31) as u8; @@ -441,6 +444,9 @@ impl ClockRequirements { } /// Same as above, but allows clock to be changed after an initial configuration. + /// + /// # Safety + /// /// This is unsafe because it's up to the developer to ensure the new configuration is okay for /// the device peripherals being used. pub unsafe fn reconfigure(self, _clocks: Clocks, pmc: &mut Pmc, syscon: &mut Syscon) -> Clocks { diff --git a/src/drivers/i2c.rs b/src/drivers/i2c.rs index ff7448d..397cf9d 100644 --- a/src/drivers/i2c.rs +++ b/src/drivers/i2c.rs @@ -19,6 +19,7 @@ pub mod prelude { /// I2C error #[derive(Debug)] +#[non_exhaustive] pub enum Error { /// Bus error (catch-all) Bus, @@ -30,9 +31,6 @@ pub enum Error { NackData, /// Start/Stop error StartStop, - - #[doc(hidden)] - _Extensible, } pub type Result = core::result::Result; diff --git a/src/drivers/pins.rs b/src/drivers/pins.rs index bae3107..3dc96b1 100644 --- a/src/drivers/pins.rs +++ b/src/drivers/pins.rs @@ -118,6 +118,9 @@ macro_rules! pins { Self::set_all_released(); } + /// # Safety + /// + /// Steals the PIN, must not be called if the PIN is already owned pub unsafe fn steal() -> Self { Self { $( @@ -185,6 +188,9 @@ macro_rules! pins { unsafe { PIN_TAKEN[$port][$number] = false; } } + /// # Safety + /// + /// Steals the PIN, must not be called if the PIN is already owned pub unsafe fn steal() -> Pin { PIN_TAKEN[$port][$number] = true; Pin { diff --git a/src/drivers/pwm.rs b/src/drivers/pwm.rs index f93d6b4..b6bcf2f 100644 --- a/src/drivers/pwm.rs +++ b/src/drivers/pwm.rs @@ -56,7 +56,7 @@ where // Start timer timer.tcr.write(|w| w.crst().clear_bit().cen().set_bit()); - Self { timer: timer } + Self { timer } } pub fn release(self) -> TIMER { @@ -80,7 +80,7 @@ where fn enable(&mut self, channel: Self::Channel) { match channel { - 0 | 1 | 2 => {} + 0..=2 => {} _ => { panic!("Cannot use channel outside 0-2 for PWM."); } diff --git a/src/drivers/rng.rs b/src/drivers/rng.rs index 6177986..197b5db 100644 --- a/src/drivers/rng.rs +++ b/src/drivers/rng.rs @@ -41,7 +41,8 @@ impl rand_core::RngCore for Rng { } fn try_fill_bytes(&mut self, dest: &mut [u8]) -> Result<(), rand_core::Error> { - Ok(self.fill_bytes(dest)) + self.fill_bytes(dest); + Ok(()) } } diff --git a/src/drivers/serial.rs b/src/drivers/serial.rs index 36bc809..58ad4ac 100644 --- a/src/drivers/serial.rs +++ b/src/drivers/serial.rs @@ -19,6 +19,7 @@ pub mod config; /// Serial error #[derive(Debug)] +#[non_exhaustive] pub enum Error { /// Framing error Framing, @@ -28,8 +29,6 @@ pub enum Error { Overrun, /// Parity check error Parity, - #[doc(hidden)] - _Extensible, } // /// Interrupt event @@ -101,7 +100,7 @@ where pub fn new(usart: USART, pins: PINS, config: config::Config) -> Self { use self::config::*; - let speed: Hertz = config.speed.into(); + let speed: Hertz = config.speed; let speed: u32 = speed.0; usart diff --git a/src/drivers/sha.rs b/src/drivers/sha.rs index 435bc10..a2dd540 100644 --- a/src/drivers/sha.rs +++ b/src/drivers/sha.rs @@ -127,7 +127,7 @@ impl Sha<'_, Size> { // relevant code is ~line 800 in fsl_hashcrypt.c fn process_block(peripheral: &mut Hashcrypt, input: &GenericArray) { // input must be word-aligned - let input: Aligned> = Aligned(input.clone()); + let input: Aligned> = Aligned(*input); let addr: u32 = &input[0] as *const _ as _; assert_eq!(addr & 0x3, 0); while peripheral.raw.status.read().waiting().is_not_waiting() { diff --git a/src/drivers/spi.rs b/src/drivers/spi.rs index 6d9e99b..5bf0e2d 100644 --- a/src/drivers/spi.rs +++ b/src/drivers/spi.rs @@ -1,11 +1,10 @@ -///! There are 8 "normal" SPIs and on high-speed SPI. -///! The high-speed SPI is tied to Flexcomm8, which it does not -///! share with any other peripherals. -///! -///! SPI3, SPI4, and this high-speed SPI8 have 4 possible chip selects, -///! whereas the others have two. -/// -/// +//! There are 8 "normal" SPIs and on high-speed SPI. +//! The high-speed SPI is tied to Flexcomm8, which it does not +//! share with any other peripherals. +//! +//! SPI3, SPI4, and this high-speed SPI8 have 4 possible chip selects, +//! whereas the others have two. + use core::marker::PhantomData; use crate::time::Hertz; @@ -29,6 +28,7 @@ pub mod prelude { /// SPI error /// TODO: Use the actual ones from the chip #[derive(Debug)] +#[non_exhaustive] pub enum Error { /// Overrun occurred Overrun, @@ -36,8 +36,6 @@ pub enum Error { ModeFault, /// CRC error Crc, - #[doc(hidden)] - _Extensible, } pub type Result = nb::Result; diff --git a/src/drivers/timer.rs b/src/drivers/timer.rs index 8036a8e..d8b9c10 100644 --- a/src/drivers/timer.rs +++ b/src/drivers/timer.rs @@ -25,7 +25,7 @@ where TIMER: Ctimer, { pub fn new(timer: TIMER) -> Self { - Self { timer: timer } + Self { timer } } pub fn release(self) -> TIMER { diff --git a/src/drivers/touch.rs b/src/drivers/touch.rs index 090e5ae..5bfd1c9 100644 --- a/src/drivers/touch.rs +++ b/src/drivers/touch.rs @@ -202,12 +202,12 @@ where }); Self { - adc: adc, - adc_timer: adc_timer, - sample_timer: sample_timer, + adc, + adc_timer, + sample_timer, _buttons: buttons, - threshold: threshold, - confidence: confidence, + threshold, + confidence, // _state: init_state::Unknown, } } @@ -286,8 +286,8 @@ where } /// For debugging - pub(crate) fn get_results(&self) -> &mut [u32] { - return unsafe { &mut RESULTS }; + pub(crate) fn get_results<'a>(&self) -> &'a mut [u32] { + unsafe { &mut RESULTS } } /// Used after an edge is detected to prevent the same @@ -296,9 +296,9 @@ where let results = unsafe { &mut RESULTS }; // match button { // buttons::ButtonTop => { - for i in 0..RESULTS_LEN { - if (results[i] & (0xf << 24)) == ((channel as u32) << 24) { - results[i] = (results[i] & (!0xffff)) + for item in results { + if (*item & (0xf << 24)) == ((channel as u32) << 24) { + *item = (*item & (!0xffff)) | (self.threshold[(channel as usize) - 3] as i32 + offset) as u32; } } @@ -381,7 +381,9 @@ where let mut streak = 0u32; match ctype { - Compare::AboveThreshold => { + Compare::AboveThreshold => + { + #[allow(clippy::needless_range_loop)] for i in 0..(40 - AVERAGES) { if filtered[i] > self.threshold[(5 - bufsel) as usize] { streak += 1; @@ -394,7 +396,9 @@ where } } } - Compare::BelowThreshold => { + Compare::BelowThreshold => + { + #[allow(clippy::needless_range_loop)] for i in 0..(40 - AVERAGES) { if filtered[i] < self.threshold[(5 - bufsel) as usize] { streak += 1; diff --git a/src/drivers/usbd.rs b/src/drivers/usbd.rs index d46f75a..58a86dd 100644 --- a/src/drivers/usbd.rs +++ b/src/drivers/usbd.rs @@ -83,7 +83,12 @@ where *endpoint = mem::MaybeUninit::new(Endpoint::::new(i as u8)); } - unsafe { mem::transmute::<_, [Endpoint; NUM_ENDPOINTS]>(endpoints) } + unsafe { + mem::transmute::< + [mem::MaybeUninit>; NUM_ENDPOINTS], + [Endpoint; NUM_ENDPOINTS], + >(endpoints) + } }, }; diff --git a/src/drivers/usbd/endpoint.rs b/src/drivers/usbd/endpoint.rs index 8303021..7fd860d 100644 --- a/src/drivers/usbd/endpoint.rs +++ b/src/drivers/usbd/endpoint.rs @@ -1,6 +1,5 @@ use core::cmp::min; -#[cfg(not(feature = "nosync"))] use core::marker::PhantomData; use cortex_m::interrupt::{CriticalSection, Mutex}; @@ -290,7 +289,7 @@ where let nbytes = epl.eps[i].ep_out[0].read().nbytes::().bits() as usize; // let count = min((out_buf.capacity() - nbytes) as usize, buf.len()); - let count = (out_buf.capacity() - nbytes) as usize; + let count = out_buf.capacity() - nbytes; out_buf.read(&mut buf[..count]); @@ -348,7 +347,7 @@ where } else { let out_buf = self.out_buf.as_ref().unwrap().borrow(cs); let nbytes = epl.eps[0].ep_out[0].read().nbytes::().bits() as usize; - let count = min((out_buf.capacity() - nbytes) as usize, buf.len()); + let count = min(out_buf.capacity() - nbytes, buf.len()); out_buf.read(&mut buf[..count]); diff --git a/src/drivers/usbd/endpoint_registers.rs b/src/drivers/usbd/endpoint_registers.rs index fcb4cad..6099eb1 100644 --- a/src/drivers/usbd/endpoint_registers.rs +++ b/src/drivers/usbd/endpoint_registers.rs @@ -79,6 +79,11 @@ pub fn attach() -> Option { } /// Does not zero the memory +/// +/// # Safety +/// +/// Steals the registers instance, must not be called if +/// the registers are owned somewhere pub unsafe fn steal() -> Instance { ENDPOINT_REGISTERS_ATTACHED = true; Instance { @@ -595,7 +600,7 @@ pub mod epr { pub fn addroff>(&self) -> ADDROFFR { let field = AddrOffField::from(USB::SPEED); ADDROFFR { - bits: ((self.bits >> field.offset) & field.mask as u32) as u16, + bits: ((self.bits >> field.offset) & field.mask) as u16, } } #[doc = "Bits 16:25 - Endpoint buffer NBytes while in full speed operation, or bits 11:25 for high speed operation."] @@ -603,7 +608,7 @@ pub mod epr { pub fn nbytes>(&self) -> NBYTESR { let field = NbytesField::from(USB::SPEED); NBYTESR { - bits: ((self.bits >> field.offset) & field.mask as u32) as u16, + bits: ((self.bits >> field.offset) & field.mask) as u16, } } #[doc = "Bit 26 - Endpoint type"] @@ -671,6 +676,8 @@ pub mod epr { W { bits: 1 << 30 } } #[doc = r"Writes raw bits to the register"] + #[doc = r"# Safety"] + #[doc = r"Bit value must be valid"] #[inline] pub unsafe fn bits(&mut self, bits: u32) -> &mut Self { self.bits = bits; diff --git a/src/lib.rs b/src/lib.rs index 2faefc9..e5e883c 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,4 +1,5 @@ #![no_std] +#![allow(static_mut_refs)] //! This HAL takes a layered approach. //! @@ -46,6 +47,8 @@ pub mod time; pub mod traits; pub mod typestates; +use core::ptr::copy_nonoverlapping; + pub use typestates::init_state::Enabled; pub mod peripherals; @@ -446,6 +449,10 @@ impl Peripherals { // } #[cfg(not(feature = "rtic-peripherals"))] + /// # Safety + /// + /// Steals peripherals, must not be used if one of the peripherals + /// is already owned pub unsafe fn steal() -> Self { Self::from((raw::Peripherals::steal(), raw::CorePeripherals::steal())) } @@ -456,7 +463,7 @@ pub fn enable_cycle_counter() { } pub fn get_cycle_count() -> u32 { - raw::DWT::get_cycle_count() + raw::DWT::cycle_count() } pub fn count_cycles(f: impl FnOnce() -> Output) -> (u32, Output) { @@ -502,8 +509,8 @@ pub fn chip_revision() -> &'static str { pub fn uuid() -> [u8; 16] { const UUID: *const u8 = 0x0009_FC70 as _; let mut uuid: [u8; 16] = [0; 16]; - for i in 0..16 { - uuid[i] = unsafe { *UUID.offset(i as isize) }; + unsafe { + copy_nonoverlapping(UUID, uuid.as_mut_ptr(), 16); } uuid } diff --git a/src/macros.rs b/src/macros.rs index 0515183..59746fb 100644 --- a/src/macros.rs +++ b/src/macros.rs @@ -32,7 +32,7 @@ macro_rules! reg_cluster { #[macro_export] macro_rules! wrap_always_on_peripheral { ($hal_name:ident, $pac_name:ident) => { - use crate::raw; + use $crate::raw; // /// Entry point to the $hal_name API pub struct $hal_name { pub(crate) raw: raw::$pac_name, @@ -50,6 +50,9 @@ macro_rules! wrap_always_on_peripheral { $hal_name { raw } } + /// # Safety + /// + /// Must only be called once for the entire duration of the program pub unsafe fn steal() -> Self { // seems a little wastefule to steal the full peripherals but ok.. Self::new(raw::Peripherals::steal().$pac_name) @@ -84,6 +87,9 @@ macro_rules! wrap_stateful_peripheral { } } + /// # Safety + /// + /// Must only be called once for the entire duration of the program pub unsafe fn steal() -> Self { // seems a little wastefule to steal the full peripherals but ok.. Self::new(raw::Peripherals::steal().$pac_name) diff --git a/src/peripherals/adc.rs b/src/peripherals/adc.rs index 6188429..5069fe0 100644 --- a/src/peripherals/adc.rs +++ b/src/peripherals/adc.rs @@ -9,18 +9,11 @@ use crate::{ }; use core::ops::Deref; +#[derive(Default)] pub struct Config { pub conversion_delay: u16, } -impl Default for Config { - fn default() -> Self { - Config { - conversion_delay: 0, - } - } -} - pub enum ChannelType { Comparator = 0, Cancel = 1, @@ -48,6 +41,9 @@ impl Adc { } } + /// # Safety + /// + /// Must only be called once for the entire duration of the program pub unsafe fn steal() -> Self { // seems a little wastefule to steal the full peripherals but ok.. Self::new(raw::Peripherals::steal().ADC0) diff --git a/src/peripherals/dma.rs b/src/peripherals/dma.rs index 2023f34..6d8f1ef 100644 --- a/src/peripherals/dma.rs +++ b/src/peripherals/dma.rs @@ -13,6 +13,7 @@ struct Descriptor { next: u32, } +#[allow(unused)] #[repr(align(512))] struct Align512( Descriptor, diff --git a/src/peripherals/hashcrypt.rs b/src/peripherals/hashcrypt.rs index 0896b5d..65519b9 100644 --- a/src/peripherals/hashcrypt.rs +++ b/src/peripherals/hashcrypt.rs @@ -39,12 +39,12 @@ impl Hashcrypt { impl Hashcrypt { /// SHA-1, as in RustCrypto `digest` trait - pub fn sha1<'a>(&'a mut self) -> Sha1<'a> { + pub fn sha1(&mut self) -> Sha1 { Sha1::from(self) } /// SHA-256, as in RustCrypto `digest` trait - pub fn sha256<'a>(&'a mut self) -> Sha256<'a> { + pub fn sha256(&mut self) -> Sha256 { Sha256::from(self) } @@ -70,7 +70,7 @@ impl Hashcrypt { /// /// DOES NOT PROPERLY CHECK IF PUF AES KEY IS SETUP YET! /// TODO: have user pass in some token signaling PUF AES key is setup - pub fn puf_aes<'a>(&'a mut self) -> aes::Aes256<'a> { + pub fn puf_aes(&mut self) -> aes::Aes256 { Aes::new(self, AesKey::Puf, aes::Mode::Encrypt) } } diff --git a/src/peripherals/pfr.rs b/src/peripherals/pfr.rs index f73a2ef..30157e8 100644 --- a/src/peripherals/pfr.rs +++ b/src/peripherals/pfr.rs @@ -1,6 +1,7 @@ use core::result::Result; // use cortex_m_semihosting::{heprint,heprintln}; use crate::{drivers::clocks::Clocks, typestates::init_state}; +use core::ptr::copy_nonoverlapping; #[derive(Copy, Clone, PartialEq)] pub enum KeyType { @@ -92,13 +93,10 @@ pub struct Cmpa { } // This compile time guarantees that Cmpa and Cfpa are 512 bytes. -#[allow(unreachable_code)] -fn _compile_time_assert() { - unsafe { - core::mem::transmute::(panic!()); - core::mem::transmute::(panic!()); - } -} +const _: () = { + assert!(size_of::() == 512); + assert!(size_of::() == 512); +}; // #define BOOTLOADER_API_TREE_POINTER (bootloader_tree_t*) 0x130010f0 #[repr(C)] @@ -244,7 +242,10 @@ pub struct Pfr { } impl Pfr { fn bootloader_api_tree() -> &'static mut BootloaderTree { - unsafe { core::mem::transmute(0x130010f0u32 as *const ()) } + #[allow(clippy::transmute_ptr_to_ref)] + unsafe { + core::mem::transmute(0x130010f0u32 as *const ()) + } } fn check_error(err: u32) -> Result<(), u32> { if err == 0 { @@ -254,6 +255,12 @@ impl Pfr { } } } + +impl Default for Pfr { + fn default() -> Self { + Self::new() + } +} impl Pfr { pub fn new() -> Self { Self { @@ -263,7 +270,7 @@ impl Pfr { } pub fn enabled(mut self, clock_config: &Clocks) -> Result, u32> { - self.flash_config = FlashConfig::new(clock_config.system_frequency.0 / 1000_000); + self.flash_config = FlashConfig::new(clock_config.system_frequency.0 / 1_000_000); let flash_init = Self::bootloader_api_tree().flash_driver.flash_init; let ffr_init = Self::bootloader_api_tree().flash_driver.ffr_init; @@ -292,7 +299,7 @@ impl Pfr { // heprintln!("cfpa:").ok(); // dump_hex!(cfpa_bytes, 512); - let cmpa: &Cmpa = unsafe { core::mem::transmute(cmpa_bytes.as_ptr()) }; + let cmpa: &Cmpa = unsafe { &*(cmpa_bytes.as_ptr() as *const _) }; Ok(*cmpa) } @@ -310,6 +317,7 @@ impl Pfr { /// - Immediately after CFPA is updated, this method returns the latest CFPA data. /// - After boot/reset, this method will potentially return expected old versions of CFPA. /// - There is a pattern of how to increment VERSION to result in this method returning old CFPA versions or not which is impractical. + /// /// It's almost like there is some other cfpa page storage not documented and this bootrom method mismanages the VERSION. pub fn read_cfpa_with_bootrom(&mut self) -> Result { let mut cfpa_bytes = [0u8; 512]; @@ -324,7 +332,7 @@ impl Pfr { // heprintln!("cfpa:").ok(); // dump_hex!(cfpa_bytes, 512); - let cfpa: &Cfpa = unsafe { core::mem::transmute(cfpa_bytes.as_ptr()) }; + let cfpa: &Cfpa = unsafe { &*(cfpa_bytes.as_ptr() as *const _) }; Ok(*cfpa) } @@ -333,6 +341,7 @@ impl Pfr { /// returns previous versions of the CFPA page (not seen on scratch, ping, or pong pages). /// This method always returns the most recently updated Cfpa from ping or pong pages. pub fn read_latest_cfpa(&mut self) -> Result { + use core::ptr::copy_nonoverlapping; let mut cfpa_bytes = [0u32; 128]; let ping_ptr = (0x0009_DE00 + 512) as *const u32; @@ -347,11 +356,11 @@ impl Pfr { pong_ptr }; - for i in 0..128 { - cfpa_bytes[i] = unsafe { *cfpa_ptr.offset(i as isize) }; + unsafe { + copy_nonoverlapping(cfpa_ptr, cfpa_bytes.as_mut_ptr(), 128); } - let cfpa: &Cfpa = unsafe { core::mem::transmute(cfpa_bytes.as_ptr()) }; + let cfpa: &Cfpa = unsafe { &*(cfpa_bytes.as_ptr() as *const _) }; Ok(*cfpa) } @@ -360,11 +369,11 @@ impl Pfr { let mut cfpa_bytes = [0u32; 128]; const CFPA_PTR: *const u32 = (0x0009_DE00 + 512) as *const u32; - for i in 0..128 { - cfpa_bytes[i] = unsafe { *CFPA_PTR.offset(i as isize) }; + unsafe { + copy_nonoverlapping(CFPA_PTR, cfpa_bytes.as_mut_ptr(), 128); } - let cfpa: &Cfpa = unsafe { core::mem::transmute(cfpa_bytes.as_ptr()) }; + let cfpa: &Cfpa = unsafe { &*(cfpa_bytes.as_ptr() as *const _) }; Ok(*cfpa) } @@ -373,11 +382,11 @@ impl Pfr { let mut cfpa_bytes = [0u32; 128]; const CFPA_PTR: *const u32 = (0x0009_DE00 + 512 + 512) as *const u32; - for i in 0..128 { - cfpa_bytes[i] = unsafe { *CFPA_PTR.offset(i as isize) }; + unsafe { + copy_nonoverlapping(CFPA_PTR, cfpa_bytes.as_mut_ptr(), 128); } - let cfpa: &Cfpa = unsafe { core::mem::transmute(cfpa_bytes.as_ptr()) }; + let cfpa: &Cfpa = unsafe { &*(cfpa_bytes.as_ptr() as *const _) }; Ok(*cfpa) } diff --git a/src/peripherals/pmc.rs b/src/peripherals/pmc.rs index 0f6f5ed..42bfb57 100644 --- a/src/peripherals/pmc.rs +++ b/src/peripherals/pmc.rs @@ -49,7 +49,7 @@ impl Pmc { /// Check if peripheral is powered pub fn is_powered(&self, peripheral: &P) -> bool { - peripheral.is_powered(&self) + peripheral.is_powered(self) } } diff --git a/src/peripherals/prince.rs b/src/peripherals/prince.rs index 2e2d7cc..c8d6d94 100644 --- a/src/peripherals/prince.rs +++ b/src/peripherals/prince.rs @@ -126,13 +126,19 @@ impl Prince { result } + /// # Safety + /// /// marked unsafe to discourage unpaired use; prefer `write_encrypted` + // TODO: Remove unsafe, it's not meant to be used like that pub unsafe fn enable_encrypted_write(&mut self) { // Immediately prior to flash programming, set the ENC_ENABLE.EN bit self.raw.enc_enable.write(|w| w.en().set_bit()); } + /// # Safety + /// /// marked unsafe to discourage unpaired use; prefer `write_encrypted` + // TODO: Remove unsafe, it's not meant to be used like that pub unsafe fn disable_encrypted_write(&mut self) { // After completion of flash programming clear ENC_ENABLE.EN, to prevent // unintended PRINCE encryption of writes diff --git a/src/peripherals/puf.rs b/src/peripherals/puf.rs index 437fe73..6162ab4 100644 --- a/src/peripherals/puf.rs +++ b/src/peripherals/puf.rs @@ -8,11 +8,8 @@ use crate::{peripherals::syscon::Syscon, raw, typestates::init_state}; // 2. The KC is a fixed 4-byte header with formation on key index, length, etc. // 3. Derive a real key using `GetKey` and an input `KC`. The key will be generated and given to the proper // IP via secure bus, or given raw if that was the index in `KC`. -trait PufStates {} pub struct Started; pub struct Enrolled; -impl PufStates for Started {} -impl PufStates for Enrolled {} /// PUF error #[derive(Debug)] @@ -117,13 +114,11 @@ impl Puf> { assert!(key_size >= 64); assert!(key_index < 16); - for i in 0..key_code.len() { - key_code[i] = 0; - } + key_code.fill(0); self.raw .keysize - .write(|w| unsafe { w.bits(((key_size >> 6) & 0x3f) as u32) }); + .write(|w| unsafe { w.bits((key_size >> 6) & 0x3f) }); self.raw .keyindex .write(|w| unsafe { w.bits(((key_index) & 0x0f) as u32) }); @@ -153,7 +148,7 @@ impl Puf> { } // Put PUF into reset state. - pub fn reset(&self) -> () { + pub fn reset(&self) { unimplemented!(); } } @@ -166,9 +161,7 @@ impl Puf { return Err(Error::NotAllowed); } - for i in 0..ac_buffer.len() { - ac_buffer[i] = 0; - } + ac_buffer.fill(0); self.raw.ctrl.write(|w| w.enroll().set_bit()); @@ -280,7 +273,7 @@ impl Puf> { impl core::fmt::Debug for Puf { fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { - writeln!(f, "").unwrap(); + writeln!(f).unwrap(); writeln!(f, " control = x{:X}", self.raw.ctrl.read().bits()).unwrap(); writeln!(f, " ramstatus= x{:X}", self.raw.pwrctrl.read().bits()).unwrap(); writeln!(f, " status = x{:X}", self.raw.stat.read().bits()).unwrap(); diff --git a/src/peripherals/rng.rs b/src/peripherals/rng.rs index 539eb15..d5f55c1 100644 --- a/src/peripherals/rng.rs +++ b/src/peripherals/rng.rs @@ -11,14 +11,12 @@ crate::wrap_stateful_peripheral!(Rng, RNG); #[derive(Debug)] // not sure why this kind of thing is not in `svd2rust`? pub struct ModuleId { - id: u16, - maj_rev: u8, - min_rev: u8, - aperture: u8, + pub id: u16, + pub maj_rev: u8, + pub min_rev: u8, + pub aperture: u8, } -impl Rng {} - impl Rng { pub fn enabled(mut self, syscon: &mut Syscon) -> Rng { syscon.enable_clock(&mut self.raw); diff --git a/src/peripherals/syscon.rs b/src/peripherals/syscon.rs index 0861166..4a1c327 100644 --- a/src/peripherals/syscon.rs +++ b/src/peripherals/syscon.rs @@ -53,7 +53,7 @@ impl Syscon { /// Check if peripheral clock is enabled pub fn is_clock_enabled(&self, peripheral: &P) -> bool { - peripheral.is_clock_enabled(&self) + peripheral.is_clock_enabled(self) } /// Reset a peripheral @@ -64,6 +64,10 @@ impl Syscon { /// Steals syscon and asserts reset to all peripherals that won't immediately cause a crash. /// Flash, Fmc, and AnalogCtrl are not reset. + /// + /// # Safety + /// + /// Steals the syscon, must not be called if Syscon is owned pub unsafe fn reset_all_noncritical_peripherals() -> Syscon { let syscon = Syscon::steal().release(); syscon.presetctrl0.write(|w| { diff --git a/src/peripherals/usbfs.rs b/src/peripherals/usbfs.rs index c40da29..bef251c 100644 --- a/src/peripherals/usbfs.rs +++ b/src/peripherals/usbfs.rs @@ -111,10 +111,10 @@ impl Usbfs Usbhs ()>(&mut self, func: F) { + pub fn borrow(&mut self, func: F) { func(self); } } #[derive(Debug)] pub struct UsbHsDevInfo { - maj_rev: u8, - min_rev: u8, - err_code: u8, - frame_nr: u16, + pub maj_rev: u8, + pub min_rev: u8, + pub err_code: u8, + pub frame_nr: u16, } impl EnabledUsbhsDevice { diff --git a/src/traits.rs b/src/traits.rs index 6eba7f2..e0bd3b3 100644 --- a/src/traits.rs +++ b/src/traits.rs @@ -28,7 +28,8 @@ pub mod reg_proxy { /// Use the `reg!` macro to implement this trait for a register from a crate /// generated by svd2rust. /// - /// Safety: The pointer returned by `get` must be valid for the duration of the program. + /// # Safety + /// The pointer returned by `get` must be valid for the duration of the program. pub unsafe trait Reg { /// The type that `RegProxy` should derefence to /// @@ -43,6 +44,8 @@ pub mod reg_proxy { fn get() -> *const Self::Target; } + /// # Safety + /// The pointer returned by `get` must be valid for the duration of the program. pub unsafe trait RegCluster { /// The type that `RegProxy` should derefence to /// diff --git a/src/typestates/reg_proxy.rs b/src/typestates/reg_proxy.rs index 3a5ae65..7869bc6 100644 --- a/src/typestates/reg_proxy.rs +++ b/src/typestates/reg_proxy.rs @@ -16,6 +16,12 @@ impl RegProxy { } } +impl Default for RegProxy { + fn default() -> Self { + Self::new() + } +} + unsafe impl Send for RegProxy where T: Reg {} impl Deref for RegProxy { @@ -44,6 +50,12 @@ impl RegClusterProxy { } } +impl Default for RegClusterProxy { + fn default() -> Self { + Self::new() + } +} + unsafe impl Send for RegClusterProxy where T: RegCluster {} impl Deref for RegClusterProxy {