embassy_stm32/crc/
v2v3.rs1use crate::pac::crc::vals;
2use crate::pac::CRC as PAC_CRC;
3use crate::peripherals::CRC;
4use crate::{rcc, Peri};
5
6pub struct Crc<'d> {
8 _peripheral: Peri<'d, CRC>,
9 _config: Config,
10}
11
12#[derive(Debug)]
14#[cfg_attr(feature = "defmt", derive(defmt::Format))]
15pub enum ConfigError {
16 InvalidPolynomial,
18}
19
20pub struct Config {
22 reverse_in: InputReverseConfig,
23 reverse_out: bool,
24 #[cfg(crc_v3)]
25 poly_size: PolySize,
26 crc_init_value: u32,
27 #[cfg(crc_v3)]
28 crc_poly: u32,
29}
30
31pub enum InputReverseConfig {
33 None,
35 Byte,
37 Halfword,
39 Word,
41}
42
43impl Config {
44 pub fn new(
46 reverse_in: InputReverseConfig,
47 reverse_out: bool,
48 #[cfg(crc_v3)] poly_size: PolySize,
49 crc_init_value: u32,
50 #[cfg(crc_v3)] crc_poly: u32,
51 ) -> Result<Self, ConfigError> {
52 #[cfg(crc_v3)]
54 if crc_poly % 2 == 0 {
55 return Err(ConfigError::InvalidPolynomial);
56 }
57 Ok(Config {
58 reverse_in,
59 reverse_out,
60 #[cfg(crc_v3)]
61 poly_size,
62 crc_init_value,
63 #[cfg(crc_v3)]
64 crc_poly,
65 })
66 }
67}
68
69#[cfg(crc_v3)]
71#[allow(missing_docs)]
72pub enum PolySize {
73 Width7,
74 Width8,
75 Width16,
76 Width32,
77}
78
79impl<'d> Crc<'d> {
80 pub fn new(peripheral: Peri<'d, CRC>, config: Config) -> Self {
82 rcc::enable_and_reset::<CRC>();
85 let mut instance = Self {
86 _peripheral: peripheral,
87 _config: config,
88 };
89 instance.reconfigure();
90 instance.reset();
91 instance
92 }
93
94 pub fn reset(&mut self) {
96 PAC_CRC.cr().modify(|w| w.set_reset(true));
97 }
98
99 fn reconfigure(&mut self) {
101 PAC_CRC.init().write_value(self._config.crc_init_value);
103 #[cfg(crc_v3)]
104 PAC_CRC.pol().write_value(self._config.crc_poly);
105
106 PAC_CRC.cr().write(|w| {
109 w.set_rev_out(match self._config.reverse_out {
111 true => vals::RevOut::REVERSED,
112 false => vals::RevOut::NORMAL,
113 });
114 w.set_rev_in(match self._config.reverse_in {
116 InputReverseConfig::None => vals::RevIn::NORMAL,
117 InputReverseConfig::Byte => vals::RevIn::BYTE,
118 InputReverseConfig::Halfword => vals::RevIn::HALF_WORD,
119 InputReverseConfig::Word => vals::RevIn::WORD,
120 });
121 #[cfg(crc_v3)]
123 w.set_polysize(match self._config.poly_size {
124 PolySize::Width7 => vals::Polysize::POLYSIZE7,
125 PolySize::Width8 => vals::Polysize::POLYSIZE8,
126 PolySize::Width16 => vals::Polysize::POLYSIZE16,
127 PolySize::Width32 => vals::Polysize::POLYSIZE32,
128 });
129 });
130 }
131
132 pub fn read(&self) -> u32 {
134 PAC_CRC.dr32().read()
135 }
136
137 pub fn feed_byte(&mut self, byte: u8) -> u32 {
139 PAC_CRC.dr8().write_value(byte);
140 self.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 self.read()
149 }
150
151 pub fn feed_halfword(&mut self, halfword: u16) -> u32 {
153 PAC_CRC.dr16().write_value(halfword);
154 self.read()
155 }
156
157 pub fn feed_halfwords(&mut self, halfwords: &[u16]) -> u32 {
159 for halfword in halfwords {
160 PAC_CRC.dr16().write_value(*halfword);
161 }
162 self.read()
163 }
164
165 pub fn feed_word(&mut self, word: u32) -> u32 {
167 PAC_CRC.dr32().write_value(word as u32);
168 self.read()
169 }
170
171 pub fn feed_words(&mut self, words: &[u32]) -> u32 {
173 for word in words {
174 PAC_CRC.dr32().write_value(*word as u32);
175 }
176 self.read()
177 }
178}