Add embassy-imxrt CRC driver
This commit is contained in:
parent
64a2b9b2a3
commit
d4c378e059
@ -9,5 +9,5 @@ The link: link:https://github.com/embassy-rs/embassy/tree/main/embassy-imxrt[Emb
|
|||||||
|
|
||||||
The following peripherals have a HAL implementation at present
|
The following peripherals have a HAL implementation at present
|
||||||
|
|
||||||
|
* CRC
|
||||||
* GPIO
|
* GPIO
|
||||||
|
|
||||||
|
|||||||
190
embassy-imxrt/src/crc.rs
Normal file
190
embassy-imxrt/src/crc.rs
Normal 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() },
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -18,6 +18,7 @@ compile_error!(
|
|||||||
pub(crate) mod fmt;
|
pub(crate) mod fmt;
|
||||||
|
|
||||||
pub mod clocks;
|
pub mod clocks;
|
||||||
|
pub mod crc;
|
||||||
pub mod gpio;
|
pub mod gpio;
|
||||||
pub mod iopctl;
|
pub mod iopctl;
|
||||||
|
|
||||||
|
|||||||
175
examples/mimxrt6/src/bin/crc.rs
Normal file
175
examples/mimxrt6/src/bin/crc.rs
Normal file
@ -0,0 +1,175 @@
|
|||||||
|
#![no_std]
|
||||||
|
#![no_main]
|
||||||
|
|
||||||
|
extern crate embassy_imxrt_examples;
|
||||||
|
|
||||||
|
use defmt::*;
|
||||||
|
use embassy_executor::Spawner;
|
||||||
|
use embassy_imxrt::crc::{Config, Crc, Polynomial};
|
||||||
|
use {defmt_rtt as _, panic_probe as _};
|
||||||
|
|
||||||
|
#[embassy_executor::main]
|
||||||
|
async fn main(_spawner: Spawner) {
|
||||||
|
let mut p = embassy_imxrt::init(Default::default());
|
||||||
|
let data = b"123456789";
|
||||||
|
|
||||||
|
info!("Initializing CRC");
|
||||||
|
|
||||||
|
// CRC-CCITT
|
||||||
|
let mut crc = Crc::new(p.CRC.reborrow(), Default::default());
|
||||||
|
let output = crc.feed_bytes(data);
|
||||||
|
defmt::assert_eq!(output, 0x29b1);
|
||||||
|
|
||||||
|
// CRC16-ARC
|
||||||
|
let mut crc = Crc::new(
|
||||||
|
p.CRC.reborrow(),
|
||||||
|
Config {
|
||||||
|
polynomial: Polynomial::Crc16,
|
||||||
|
reverse_in: true,
|
||||||
|
reverse_out: true,
|
||||||
|
complement_out: false,
|
||||||
|
seed: 0,
|
||||||
|
..Default::default()
|
||||||
|
},
|
||||||
|
);
|
||||||
|
let output = crc.feed_bytes(data);
|
||||||
|
defmt::assert_eq!(output, 0xbb3d);
|
||||||
|
|
||||||
|
// CRC16-CMS
|
||||||
|
let mut crc = Crc::new(
|
||||||
|
p.CRC.reborrow(),
|
||||||
|
Config {
|
||||||
|
polynomial: Polynomial::Crc16,
|
||||||
|
reverse_in: false,
|
||||||
|
reverse_out: false,
|
||||||
|
complement_out: false,
|
||||||
|
seed: 0xffff,
|
||||||
|
..Default::default()
|
||||||
|
},
|
||||||
|
);
|
||||||
|
let output = crc.feed_bytes(data);
|
||||||
|
defmt::assert_eq!(output, 0xaee7);
|
||||||
|
|
||||||
|
// CRC16-DDS-110
|
||||||
|
let mut crc = Crc::new(
|
||||||
|
p.CRC.reborrow(),
|
||||||
|
Config {
|
||||||
|
polynomial: Polynomial::Crc16,
|
||||||
|
reverse_in: false,
|
||||||
|
reverse_out: false,
|
||||||
|
complement_out: false,
|
||||||
|
seed: 0x800d,
|
||||||
|
..Default::default()
|
||||||
|
},
|
||||||
|
);
|
||||||
|
let output = crc.feed_bytes(data);
|
||||||
|
defmt::assert_eq!(output, 0x9ecf);
|
||||||
|
|
||||||
|
// CRC16-MAXIM-DOW
|
||||||
|
let mut crc = Crc::new(
|
||||||
|
p.CRC.reborrow(),
|
||||||
|
Config {
|
||||||
|
polynomial: Polynomial::Crc16,
|
||||||
|
reverse_in: true,
|
||||||
|
reverse_out: true,
|
||||||
|
complement_out: true,
|
||||||
|
seed: 0,
|
||||||
|
..Default::default()
|
||||||
|
},
|
||||||
|
);
|
||||||
|
let output = crc.feed_bytes(data);
|
||||||
|
defmt::assert_eq!(output, 0x44c2);
|
||||||
|
|
||||||
|
// CRC16-MODBUS
|
||||||
|
let mut crc = Crc::new(
|
||||||
|
p.CRC.reborrow(),
|
||||||
|
Config {
|
||||||
|
polynomial: Polynomial::Crc16,
|
||||||
|
reverse_in: true,
|
||||||
|
reverse_out: true,
|
||||||
|
complement_out: false,
|
||||||
|
seed: 0xffff,
|
||||||
|
..Default::default()
|
||||||
|
},
|
||||||
|
);
|
||||||
|
let output = crc.feed_bytes(data);
|
||||||
|
defmt::assert_eq!(output, 0x4b37);
|
||||||
|
|
||||||
|
// CRC32-BZIP2
|
||||||
|
let mut crc = Crc::new(
|
||||||
|
p.CRC.reborrow(),
|
||||||
|
Config {
|
||||||
|
polynomial: Polynomial::Crc32,
|
||||||
|
reverse_in: false,
|
||||||
|
reverse_out: false,
|
||||||
|
complement_out: true,
|
||||||
|
seed: 0xffff_ffff,
|
||||||
|
..Default::default()
|
||||||
|
},
|
||||||
|
);
|
||||||
|
let output = crc.feed_bytes(data);
|
||||||
|
defmt::assert_eq!(output, 0xfc89_1918);
|
||||||
|
|
||||||
|
// CRC32-CKSUM
|
||||||
|
let mut crc = Crc::new(
|
||||||
|
p.CRC.reborrow(),
|
||||||
|
Config {
|
||||||
|
polynomial: Polynomial::Crc32,
|
||||||
|
reverse_in: false,
|
||||||
|
reverse_out: false,
|
||||||
|
complement_out: true,
|
||||||
|
seed: 0,
|
||||||
|
..Default::default()
|
||||||
|
},
|
||||||
|
);
|
||||||
|
let output = crc.feed_bytes(data);
|
||||||
|
defmt::assert_eq!(output, 0x765e_7680);
|
||||||
|
|
||||||
|
// CRC32-ISO-HDLC
|
||||||
|
let mut crc = Crc::new(
|
||||||
|
p.CRC.reborrow(),
|
||||||
|
Config {
|
||||||
|
polynomial: Polynomial::Crc32,
|
||||||
|
reverse_in: true,
|
||||||
|
reverse_out: true,
|
||||||
|
complement_out: true,
|
||||||
|
seed: 0xffff_ffff,
|
||||||
|
..Default::default()
|
||||||
|
},
|
||||||
|
);
|
||||||
|
let output = crc.feed_bytes(data);
|
||||||
|
defmt::assert_eq!(output, 0xcbf4_3926);
|
||||||
|
|
||||||
|
// CRC32-JAMCRC
|
||||||
|
let mut crc = Crc::new(
|
||||||
|
p.CRC.reborrow(),
|
||||||
|
Config {
|
||||||
|
polynomial: Polynomial::Crc32,
|
||||||
|
reverse_in: true,
|
||||||
|
reverse_out: true,
|
||||||
|
complement_out: false,
|
||||||
|
seed: 0xffff_ffff,
|
||||||
|
..Default::default()
|
||||||
|
},
|
||||||
|
);
|
||||||
|
let output = crc.feed_bytes(data);
|
||||||
|
defmt::assert_eq!(output, 0x340b_c6d9);
|
||||||
|
|
||||||
|
// CRC32-MPEG-2
|
||||||
|
let mut crc = Crc::new(
|
||||||
|
p.CRC.reborrow(),
|
||||||
|
Config {
|
||||||
|
polynomial: Polynomial::Crc32,
|
||||||
|
reverse_in: false,
|
||||||
|
reverse_out: false,
|
||||||
|
complement_out: false,
|
||||||
|
seed: 0xffff_ffff,
|
||||||
|
..Default::default()
|
||||||
|
},
|
||||||
|
);
|
||||||
|
let output = crc.feed_bytes(data);
|
||||||
|
defmt::assert_eq!(output, 0x0376_e6e7);
|
||||||
|
|
||||||
|
info!("end program");
|
||||||
|
cortex_m::asm::bkpt();
|
||||||
|
}
|
||||||
Loading…
x
Reference in New Issue
Block a user