Merge branch 'main' into add-rng

This commit is contained in:
Dario Nieuwenhuis
2025-05-13 22:33:56 +02:00
committed by GitHub
30 changed files with 2146 additions and 337 deletions

190
embassy-imxrt/src/crc.rs Normal file
View File

@@ -0,0 +1,190 @@
//! Cyclic Redundancy Check (CRC)
use core::marker::PhantomData;
use crate::clocks::{enable_and_reset, SysconPeripheral};
pub use crate::pac::crc_engine::mode::CrcPolynomial as Polynomial;
use crate::{peripherals, Peri, PeripheralType};
/// CRC driver.
pub struct Crc<'d> {
info: Info,
_config: Config,
_lifetime: PhantomData<&'d ()>,
}
/// CRC configuration
pub struct Config {
/// Polynomial to be used
pub polynomial: Polynomial,
/// Reverse bit order of input?
pub reverse_in: bool,
/// 1's complement input?
pub complement_in: bool,
/// Reverse CRC bit order?
pub reverse_out: bool,
/// 1's complement CRC?
pub complement_out: bool,
/// CRC Seed
pub seed: u32,
}
impl Config {
/// Create a new CRC config.
#[must_use]
pub fn new(
polynomial: Polynomial,
reverse_in: bool,
complement_in: bool,
reverse_out: bool,
complement_out: bool,
seed: u32,
) -> Self {
Config {
polynomial,
reverse_in,
complement_in,
reverse_out,
complement_out,
seed,
}
}
}
impl Default for Config {
fn default() -> Self {
Self {
polynomial: Polynomial::CrcCcitt,
reverse_in: false,
complement_in: false,
reverse_out: false,
complement_out: false,
seed: 0xffff,
}
}
}
impl<'d> Crc<'d> {
/// Instantiates new CRC peripheral and initializes to default values.
pub fn new<T: Instance>(_peripheral: Peri<'d, T>, config: Config) -> Self {
// enable CRC clock
enable_and_reset::<T>();
let mut instance = Self {
info: T::info(),
_config: config,
_lifetime: PhantomData,
};
instance.reconfigure();
instance
}
/// Reconfigured the CRC peripheral.
fn reconfigure(&mut self) {
self.info.regs.mode().write(|w| {
w.crc_poly()
.variant(self._config.polynomial)
.bit_rvs_wr()
.variant(self._config.reverse_in)
.cmpl_wr()
.variant(self._config.complement_in)
.bit_rvs_sum()
.variant(self._config.reverse_out)
.cmpl_sum()
.variant(self._config.complement_out)
});
// Init CRC value
self.info
.regs
.seed()
.write(|w| unsafe { w.crc_seed().bits(self._config.seed) });
}
/// Feeds a byte into the CRC peripheral. Returns the computed checksum.
pub fn feed_byte(&mut self, byte: u8) -> u32 {
self.info.regs.wr_data8().write(|w| unsafe { w.bits(byte) });
self.info.regs.sum().read().bits()
}
/// Feeds an slice of bytes into the CRC peripheral. Returns the computed checksum.
pub fn feed_bytes(&mut self, bytes: &[u8]) -> u32 {
let (prefix, data, suffix) = unsafe { bytes.align_to::<u32>() };
for b in prefix {
self.info.regs.wr_data8().write(|w| unsafe { w.bits(*b) });
}
for d in data {
self.info.regs.wr_data32().write(|w| unsafe { w.bits(*d) });
}
for b in suffix {
self.info.regs.wr_data8().write(|w| unsafe { w.bits(*b) });
}
self.info.regs.sum().read().bits()
}
/// Feeds a halfword into the CRC peripheral. Returns the computed checksum.
pub fn feed_halfword(&mut self, halfword: u16) -> u32 {
self.info.regs.wr_data16().write(|w| unsafe { w.bits(halfword) });
self.info.regs.sum().read().bits()
}
/// Feeds an slice of halfwords into the CRC peripheral. Returns the computed checksum.
pub fn feed_halfwords(&mut self, halfwords: &[u16]) -> u32 {
for halfword in halfwords {
self.info.regs.wr_data16().write(|w| unsafe { w.bits(*halfword) });
}
self.info.regs.sum().read().bits()
}
/// Feeds a words into the CRC peripheral. Returns the computed checksum.
pub fn feed_word(&mut self, word: u32) -> u32 {
self.info.regs.wr_data32().write(|w| unsafe { w.bits(word) });
self.info.regs.sum().read().bits()
}
/// Feeds an slice of words into the CRC peripheral. Returns the computed checksum.
pub fn feed_words(&mut self, words: &[u32]) -> u32 {
for word in words {
self.info.regs.wr_data32().write(|w| unsafe { w.bits(*word) });
}
self.info.regs.sum().read().bits()
}
}
struct Info {
regs: crate::pac::CrcEngine,
}
trait SealedInstance {
fn info() -> Info;
}
/// CRC instance trait.
#[allow(private_bounds)]
pub trait Instance: SealedInstance + PeripheralType + SysconPeripheral + 'static + Send {}
impl Instance for peripherals::CRC {}
impl SealedInstance for peripherals::CRC {
fn info() -> Info {
// SAFETY: safe from single executor
Info {
regs: unsafe { crate::pac::CrcEngine::steal() },
}
}
}

View File

@@ -18,6 +18,7 @@ compile_error!(
pub(crate) mod fmt;
pub mod clocks;
pub mod crc;
pub mod gpio;
pub mod iopctl;
pub mod rng;