embassy_stm32/crc/
v2v3.rs1use embassy_hal_internal::{into_ref, PeripheralRef};
2
3use crate::pac::crc::vals;
4use crate::pac::CRC as PAC_CRC;
5use crate::peripherals::CRC;
6use crate::{rcc, Peripheral};
7
8pub struct Crc<'d> {
10 _peripheral: PeripheralRef<'d, CRC>,
11 _config: Config,
12}
13
14#[derive(Debug)]
16#[cfg_attr(feature = "defmt", derive(defmt::Format))]
17pub enum ConfigError {
18 InvalidPolynomial,
20}
21
22pub struct Config {
24 reverse_in: InputReverseConfig,
25 reverse_out: bool,
26 #[cfg(crc_v3)]
27 poly_size: PolySize,
28 crc_init_value: u32,
29 #[cfg(crc_v3)]
30 crc_poly: u32,
31}
32
33pub enum InputReverseConfig {
35 None,
37 Byte,
39 Halfword,
41 Word,
43}
44
45impl Config {
46 pub fn new(
48 reverse_in: InputReverseConfig,
49 reverse_out: bool,
50 #[cfg(crc_v3)] poly_size: PolySize,
51 crc_init_value: u32,
52 #[cfg(crc_v3)] crc_poly: u32,
53 ) -> Result<Self, ConfigError> {
54 #[cfg(crc_v3)]
56 if crc_poly % 2 == 0 {
57 return Err(ConfigError::InvalidPolynomial);
58 }
59 Ok(Config {
60 reverse_in,
61 reverse_out,
62 #[cfg(crc_v3)]
63 poly_size,
64 crc_init_value,
65 #[cfg(crc_v3)]
66 crc_poly,
67 })
68 }
69}
70
71#[cfg(crc_v3)]
73#[allow(missing_docs)]
74pub enum PolySize {
75 Width7,
76 Width8,
77 Width16,
78 Width32,
79}
80
81impl<'d> Crc<'d> {
82 pub fn new(peripheral: impl Peripheral<P = CRC> + 'd, config: Config) -> Self {
84 rcc::enable_and_reset::<CRC>();
87 into_ref!(peripheral);
88 let mut instance = Self {
89 _peripheral: peripheral,
90 _config: config,
91 };
92 instance.reconfigure();
93 instance.reset();
94 instance
95 }
96
97 pub fn reset(&mut self) {
99 PAC_CRC.cr().modify(|w| w.set_reset(true));
100 }
101
102 fn reconfigure(&mut self) {
104 PAC_CRC.init().write_value(self._config.crc_init_value);
106 #[cfg(crc_v3)]
107 PAC_CRC.pol().write_value(self._config.crc_poly);
108
109 PAC_CRC.cr().write(|w| {
112 w.set_rev_out(match self._config.reverse_out {
114 true => vals::RevOut::REVERSED,
115 false => vals::RevOut::NORMAL,
116 });
117 w.set_rev_in(match self._config.reverse_in {
119 InputReverseConfig::None => vals::RevIn::NORMAL,
120 InputReverseConfig::Byte => vals::RevIn::BYTE,
121 InputReverseConfig::Halfword => vals::RevIn::HALF_WORD,
122 InputReverseConfig::Word => vals::RevIn::WORD,
123 });
124 #[cfg(crc_v3)]
126 w.set_polysize(match self._config.poly_size {
127 PolySize::Width7 => vals::Polysize::POLYSIZE7,
128 PolySize::Width8 => vals::Polysize::POLYSIZE8,
129 PolySize::Width16 => vals::Polysize::POLYSIZE16,
130 PolySize::Width32 => vals::Polysize::POLYSIZE32,
131 });
132 });
133
134 self.reset();
135 }
136
137 pub fn feed_byte(&mut self, byte: u8) -> u32 {
139 PAC_CRC.dr8().write_value(byte);
140 PAC_CRC.dr32().read()
141 }
142
143 pub fn feed_bytes(&mut self, bytes: &[u8]) -> u32 {
145 for byte in bytes {
146 PAC_CRC.dr8().write_value(*byte);
147 }
148 PAC_CRC.dr32().read()
149 }
150 pub fn feed_halfword(&mut self, halfword: u16) -> u32 {
152 PAC_CRC.dr16().write_value(halfword);
153 PAC_CRC.dr32().read()
154 }
155 pub fn feed_halfwords(&mut self, halfwords: &[u16]) -> u32 {
157 for halfword in halfwords {
158 PAC_CRC.dr16().write_value(*halfword);
159 }
160 PAC_CRC.dr32().read()
161 }
162 pub fn feed_word(&mut self, word: u32) -> u32 {
164 PAC_CRC.dr32().write_value(word as u32);
165 PAC_CRC.dr32().read()
166 }
167 pub fn feed_words(&mut self, words: &[u32]) -> u32 {
169 for word in words {
170 PAC_CRC.dr32().write_value(*word as u32);
171 }
172 PAC_CRC.dr32().read()
173 }
174}