From 43ad28b9f9b25f2b7369be33dfd1f7db5d34e330 Mon Sep 17 00:00:00 2001 From: Joshua Salzedo Date: Mon, 27 Sep 2021 10:38:55 -0700 Subject: Use unborrow for CRC constructor sort feature gates fix repetition in CRC config names --- embassy-stm32/src/crc/mod.rs | 4 +- embassy-stm32/src/crc/v1.rs | 7 +- embassy-stm32/src/crc/v2.rs | 175 ----------------------------------------- embassy-stm32/src/crc/v2v3.rs | 178 ++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 186 insertions(+), 178 deletions(-) delete mode 100644 embassy-stm32/src/crc/v2.rs create mode 100644 embassy-stm32/src/crc/v2v3.rs diff --git a/embassy-stm32/src/crc/mod.rs b/embassy-stm32/src/crc/mod.rs index 70c87ab53..2ebebc935 100644 --- a/embassy-stm32/src/crc/mod.rs +++ b/embassy-stm32/src/crc/mod.rs @@ -1,6 +1,6 @@ -#[cfg_attr(crc_v2, path = "v2.rs")] #[cfg_attr(crc_v1, path = "v1.rs")] -#[cfg_attr(crc_v3, path = "v2.rs")] +#[cfg_attr(crc_v2, path = "v2v3.rs")] +#[cfg_attr(crc_v3, path = "v2v3.rs")] mod _version; pub use _version::Crc; diff --git a/embassy-stm32/src/crc/v1.rs b/embassy-stm32/src/crc/v1.rs index 09c8eecb6..8431c07f6 100644 --- a/embassy-stm32/src/crc/v1.rs +++ b/embassy-stm32/src/crc/v1.rs @@ -1,6 +1,9 @@ use crate::pac::CRC as PAC_CRC; use crate::peripherals::CRC; use crate::rcc::sealed::RccPeripheral; +use embassy_hal_common::unborrow; +use embassy::util::Unborrow; + pub struct Crc { _peripheral: CRC, @@ -8,12 +11,14 @@ pub struct Crc { impl Crc { /// Instantiates the CRC32 peripheral and initializes it to default values. - pub fn new(peripheral: CRC) -> Self { + pub fn new(peripheral: impl Unborrow) -> Self { // Note: enable and reset come from RccPeripheral. // enable CRC clock in RCC. CRC::enable(); // Reset CRC to default values. CRC::reset(); + // Unborrow the peripheral + unborrow!(peripheral); let mut instance = Self { _peripheral: peripheral, }; diff --git a/embassy-stm32/src/crc/v2.rs b/embassy-stm32/src/crc/v2.rs deleted file mode 100644 index 7705b4285..000000000 --- a/embassy-stm32/src/crc/v2.rs +++ /dev/null @@ -1,175 +0,0 @@ -use crate::pac::crc::vals; -use crate::pac::CRC as PAC_CRC; -use crate::peripherals::CRC; -use crate::rcc::sealed::RccPeripheral; - -pub struct Crc { - _peripheral: CRC, - _config: CrcConfig, -} - -pub enum CrcConfigError { - InvalidPolynomial, -} - -pub struct CrcConfig { - reverse_in: CrcInputReverseConfig, - reverse_out: bool, - #[cfg(crc_v3)] - poly_size: PolySize, - crc_init_value: u32, - #[cfg(crc_v3)] - crc_poly: u32, -} - -pub enum CrcInputReverseConfig { - None, - Byte, - Halfword, - Word, -} - -impl CrcConfig { - pub fn new( - reverse_in: CrcInputReverseConfig, - reverse_out: bool, - #[cfg(crc_v3)] poly_size: PolySize, - crc_init_value: u32, - #[cfg(crc_v3)] crc_poly: u32, - ) -> Result { - // As Per RM0091 (DocID018940 Rev 9), Even polynomials are not supported. - #[cfg(crc_v3)] - if crc_poly % 2 == 0 { - return Err(CrcConfigError::InvalidPolynomial); - } - Ok(CrcConfig { - reverse_in, - reverse_out, - #[cfg(crc_v3)] - poly_size, - crc_init_value, - #[cfg(crc_v3)] - crc_poly, - }) - } -} - -#[cfg(crc_v3)] -pub enum PolySize { - Width7, - Width8, - Width16, - Width32, -} - -impl Crc { - /// Instantiates the CRC32 peripheral and initializes it to default values. - pub fn new(peripheral: CRC, config: CrcConfig) -> Self { - // Note: enable and reset come from RccPeripheral. - // enable CRC clock in RCC. - CRC::enable(); - // Reset CRC to default values. - CRC::reset(); - let mut instance = Self { - _peripheral: peripheral, - _config: config, - }; - CRC::reset(); - instance.reconfigure(); - instance.reset(); - instance - } - - pub fn reset(&mut self) { - unsafe { - PAC_CRC.cr().modify(|w| w.set_reset(true)); - } - } - - /// Reconfigures the CRC peripheral. Doesn't reset. - fn reconfigure(&mut self) { - unsafe { - // Init CRC value - PAC_CRC.init().write_value(self._config.crc_init_value); - #[cfg(crc_v3)] - PAC_CRC.pol().write_value(self._config.crc_poly); - - // configure CR components - // (reverse I/O, polysize, poly) - PAC_CRC.cr().modify(|w| { - // configure reverse output - w.set_rev_out(match self._config.reverse_out { - true => vals::RevOut::REVERSED, - false => vals::RevOut::NORMAL, - }); - // configure reverse input - w.set_rev_in(match self._config.reverse_in { - CrcInputReverseConfig::None => vals::RevIn::NORMAL, - CrcInputReverseConfig::Byte => vals::RevIn::BYTE, - CrcInputReverseConfig::Halfword => vals::RevIn::HALFWORD, - CrcInputReverseConfig::Word => vals::RevIn::WORD, - }); - // configure the polynomial. - #[cfg(crc_v3)] - w.set_polysize(match self._config.poly_size { - PolySize::Width7 => vals::Polysize::POLYSIZE7, - PolySize::Width8 => vals::Polysize::POLYSIZE8, - PolySize::Width16 => vals::Polysize::POLYSIZE16, - PolySize::Width32 => vals::Polysize::POLYSIZE32, - }); - }) - } - - self.reset(); - } - - /// Feeds a byte into the CRC peripheral. Returns the computed checksum. - pub fn feed_byte(&mut self, byte: u8) -> u32 { - unsafe { - PAC_CRC.dr8().write_value(byte as u32); - PAC_CRC.dr().read() - } - } - - /// Feeds an slice of bytes into the CRC peripheral. Returns the computed checksum. - pub fn feed_bytes(&mut self, bytes: &[u8]) -> u32 { - for byte in bytes { - unsafe { - PAC_CRC.dr8().write_value(*byte as u32); - } - } - unsafe { PAC_CRC.dr().read() } - } - /// Feeds a halfword into the CRC peripheral. Returns the computed checksum. - pub fn feed_halfword(&mut self, byte: u16) -> u32 { - unsafe { - PAC_CRC.dr16().write_value(byte as u32); - PAC_CRC.dr().read() - } - } - /// Feeds an slice of halfwords into the CRC peripheral. Returns the computed checksum. - pub fn feed_halfwords(&mut self, bytes: &[u16]) -> u32 { - for byte in bytes { - unsafe { - PAC_CRC.dr16().write_value(*byte as u32); - } - } - unsafe { PAC_CRC.dr().read() } - } - /// Feeds a halfword into the CRC peripheral. Returns the computed checksum. - pub fn feed_word(&mut self, byte: u32) -> u32 { - unsafe { - PAC_CRC.dr().write_value(byte as u32); - PAC_CRC.dr().read() - } - } - /// Feeds an slice of halfwords into the CRC peripheral. Returns the computed checksum. - pub fn feed_words(&mut self, bytes: &[u32]) -> u32 { - for byte in bytes { - unsafe { - PAC_CRC.dr().write_value(*byte as u32); - } - } - unsafe { PAC_CRC.dr().read() } - } -} diff --git a/embassy-stm32/src/crc/v2v3.rs b/embassy-stm32/src/crc/v2v3.rs new file mode 100644 index 000000000..91c24215c --- /dev/null +++ b/embassy-stm32/src/crc/v2v3.rs @@ -0,0 +1,178 @@ +use crate::pac::crc::vals; +use crate::pac::CRC as PAC_CRC; +use crate::peripherals::CRC; +use crate::rcc::sealed::RccPeripheral; +use embassy_hal_common::unborrow; +use embassy::util::Unborrow; + +pub struct Crc { + _peripheral: CRC, + _config: Config, +} + +pub enum ConfigError { + InvalidPolynomial, +} + +pub struct Config { + reverse_in: InputReverseConfig, + reverse_out: bool, + #[cfg(crc_v3)] + poly_size: PolySize, + crc_init_value: u32, + #[cfg(crc_v3)] + crc_poly: u32, +} + +pub enum InputReverseConfig { + None, + Byte, + Halfword, + Word, +} + +impl Config { + pub fn new( + reverse_in: InputReverseConfig, + reverse_out: bool, + #[cfg(crc_v3)] poly_size: PolySize, + crc_init_value: u32, + #[cfg(crc_v3)] crc_poly: u32, + ) -> Result { + // As Per RM0091 (DocID018940 Rev 9), Even polynomials are not supported. + #[cfg(crc_v3)] + if crc_poly % 2 == 0 { + return Err(ConfigError::InvalidPolynomial); + } + Ok(Config { + reverse_in, + reverse_out, + #[cfg(crc_v3)] + poly_size, + crc_init_value, + #[cfg(crc_v3)] + crc_poly, + }) + } +} + +#[cfg(crc_v3)] +pub enum PolySize { + Width7, + Width8, + Width16, + Width32, +} + +impl Crc { + /// Instantiates the CRC32 peripheral and initializes it to default values. + pub fn new(peripheral: impl Unborrow, config: Config) -> Self { + // Note: enable and reset come from RccPeripheral. + // enable CRC clock in RCC. + CRC::enable(); + // Reset CRC to default values. + CRC::reset(); + unborrow!(peripheral); + let mut instance = Self { + _peripheral: peripheral, + _config: config, + }; + CRC::reset(); + instance.reconfigure(); + instance.reset(); + instance + } + + pub fn reset(&mut self) { + unsafe { + PAC_CRC.cr().modify(|w| w.set_reset(true)); + } + } + + /// Reconfigures the CRC peripheral. Doesn't reset. + fn reconfigure(&mut self) { + unsafe { + // Init CRC value + PAC_CRC.init().write_value(self._config.crc_init_value); + #[cfg(crc_v3)] + PAC_CRC.pol().write_value(self._config.crc_poly); + + // configure CR components + // (reverse I/O, polysize, poly) + PAC_CRC.cr().modify(|w| { + // configure reverse output + w.set_rev_out(match self._config.reverse_out { + true => vals::RevOut::REVERSED, + false => vals::RevOut::NORMAL, + }); + // configure reverse input + w.set_rev_in(match self._config.reverse_in { + InputReverseConfig::None => vals::RevIn::NORMAL, + InputReverseConfig::Byte => vals::RevIn::BYTE, + InputReverseConfig::Halfword => vals::RevIn::HALFWORD, + InputReverseConfig::Word => vals::RevIn::WORD, + }); + // configure the polynomial. + #[cfg(crc_v3)] + w.set_polysize(match self._config.poly_size { + PolySize::Width7 => vals::Polysize::POLYSIZE7, + PolySize::Width8 => vals::Polysize::POLYSIZE8, + PolySize::Width16 => vals::Polysize::POLYSIZE16, + PolySize::Width32 => vals::Polysize::POLYSIZE32, + }); + }) + } + + self.reset(); + } + + /// Feeds a byte into the CRC peripheral. Returns the computed checksum. + pub fn feed_byte(&mut self, byte: u8) -> u32 { + unsafe { + PAC_CRC.dr8().write_value(byte as u32); + PAC_CRC.dr().read() + } + } + + /// Feeds an slice of bytes into the CRC peripheral. Returns the computed checksum. + pub fn feed_bytes(&mut self, bytes: &[u8]) -> u32 { + for byte in bytes { + unsafe { + PAC_CRC.dr8().write_value(*byte as u32); + } + } + unsafe { PAC_CRC.dr().read() } + } + /// Feeds a halfword into the CRC peripheral. Returns the computed checksum. + pub fn feed_halfword(&mut self, byte: u16) -> u32 { + unsafe { + PAC_CRC.dr16().write_value(byte as u32); + PAC_CRC.dr().read() + } + } + /// Feeds an slice of halfwords into the CRC peripheral. Returns the computed checksum. + pub fn feed_halfwords(&mut self, bytes: &[u16]) -> u32 { + for byte in bytes { + unsafe { + PAC_CRC.dr16().write_value(*byte as u32); + } + } + unsafe { PAC_CRC.dr().read() } + } + /// Feeds a halfword into the CRC peripheral. Returns the computed checksum. + pub fn feed_word(&mut self, byte: u32) -> u32 { + unsafe { + PAC_CRC.dr().write_value(byte as u32); + PAC_CRC.dr().read() + } + } + /// Feeds an slice of halfwords into the CRC peripheral. Returns the computed checksum. + pub fn feed_words(&mut self, bytes: &[u32]) -> u32 { + for byte in bytes { + unsafe { + PAC_CRC.dr().write_value(*byte as u32); + } + } + unsafe { PAC_CRC.dr().read() } + } +} -- cgit