aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--embassy-stm32/src/spi/mod.rs122
1 files changed, 56 insertions, 66 deletions
diff --git a/embassy-stm32/src/spi/mod.rs b/embassy-stm32/src/spi/mod.rs
index 5d919f923..8befaf529 100644
--- a/embassy-stm32/src/spi/mod.rs
+++ b/embassy-stm32/src/spi/mod.rs
@@ -152,34 +152,43 @@ impl<'d, T: Instance, Tx, Rx> Spi<'d, T, Tx, Rx> {
152 } 152 }
153 153
154 let pclk = T::frequency(); 154 let pclk = T::frequency();
155 let br = Self::compute_baud_rate(pclk, freq.into()); 155 let br = compute_baud_rate(pclk, freq.into());
156
157 let cpha = match config.mode.phase {
158 Phase::CaptureOnSecondTransition => vals::Cpha::SECONDEDGE,
159 Phase::CaptureOnFirstTransition => vals::Cpha::FIRSTEDGE,
160 };
161 let cpol = match config.mode.polarity {
162 Polarity::IdleHigh => vals::Cpol::IDLEHIGH,
163 Polarity::IdleLow => vals::Cpol::IDLELOW,
164 };
165
166 #[cfg(not(spi_v3))]
167 use vals::Lsbfirst;
168 #[cfg(spi_v3)]
169 use vals::Lsbfrst as Lsbfirst;
170
171 let lsbfirst = match config.byte_order {
172 ByteOrder::LsbFirst => Lsbfirst::LSBFIRST,
173 ByteOrder::MsbFirst => Lsbfirst::MSBFIRST,
174 };
175
176 T::enable();
177 T::reset();
156 178
157 #[cfg(any(spi_v1, spi_f1))] 179 #[cfg(any(spi_v1, spi_f1))]
158 unsafe { 180 unsafe {
159 T::enable();
160 T::reset();
161 T::regs().cr2().modify(|w| { 181 T::regs().cr2().modify(|w| {
162 w.set_ssoe(false); 182 w.set_ssoe(false);
163 }); 183 });
164 T::regs().cr1().modify(|w| { 184 T::regs().cr1().modify(|w| {
165 w.set_cpha( 185 w.set_cpha(cpha);
166 match config.mode.phase == Phase::CaptureOnSecondTransition { 186 w.set_cpol(cpol);
167 true => vals::Cpha::SECONDEDGE,
168 false => vals::Cpha::FIRSTEDGE,
169 },
170 );
171 w.set_cpol(match config.mode.polarity == Polarity::IdleHigh {
172 true => vals::Cpol::IDLEHIGH,
173 false => vals::Cpol::IDLELOW,
174 });
175 187
176 w.set_mstr(vals::Mstr::MASTER); 188 w.set_mstr(vals::Mstr::MASTER);
177 w.set_br(vals::Br(br)); 189 w.set_br(br);
178 w.set_spe(true); 190 w.set_spe(true);
179 w.set_lsbfirst(match config.byte_order { 191 w.set_lsbfirst(lsbfirst);
180 ByteOrder::LsbFirst => vals::Lsbfirst::LSBFIRST,
181 ByteOrder::MsbFirst => vals::Lsbfirst::MSBFIRST,
182 });
183 w.set_ssi(true); 192 w.set_ssi(true);
184 w.set_ssm(true); 193 w.set_ssm(true);
185 w.set_crcen(false); 194 w.set_crcen(false);
@@ -192,31 +201,18 @@ impl<'d, T: Instance, Tx, Rx> Spi<'d, T, Tx, Rx> {
192 } 201 }
193 #[cfg(spi_v2)] 202 #[cfg(spi_v2)]
194 unsafe { 203 unsafe {
195 T::enable();
196 T::reset();
197 T::regs().cr2().modify(|w| { 204 T::regs().cr2().modify(|w| {
198 w.set_frxth(WordSize::EightBit.frxth()); 205 w.set_frxth(WordSize::EightBit.frxth());
199 w.set_ds(WordSize::EightBit.ds()); 206 w.set_ds(WordSize::EightBit.ds());
200 w.set_ssoe(false); 207 w.set_ssoe(false);
201 }); 208 });
202 T::regs().cr1().modify(|w| { 209 T::regs().cr1().modify(|w| {
203 w.set_cpha( 210 w.set_cpha(cpha);
204 match config.mode.phase == Phase::CaptureOnSecondTransition { 211 w.set_cpol(cpol);
205 true => vals::Cpha::SECONDEDGE,
206 false => vals::Cpha::FIRSTEDGE,
207 },
208 );
209 w.set_cpol(match config.mode.polarity == Polarity::IdleHigh {
210 true => vals::Cpol::IDLEHIGH,
211 false => vals::Cpol::IDLELOW,
212 });
213 212
214 w.set_mstr(vals::Mstr::MASTER); 213 w.set_mstr(vals::Mstr::MASTER);
215 w.set_br(vals::Br(br)); 214 w.set_br(br);
216 w.set_lsbfirst(match config.byte_order { 215 w.set_lsbfirst(lsbfirst);
217 ByteOrder::LsbFirst => vals::Lsbfirst::LSBFIRST,
218 ByteOrder::MsbFirst => vals::Lsbfirst::MSBFIRST,
219 });
220 w.set_ssi(true); 216 w.set_ssi(true);
221 w.set_ssm(true); 217 w.set_ssm(true);
222 w.set_crcen(false); 218 w.set_crcen(false);
@@ -226,26 +222,13 @@ impl<'d, T: Instance, Tx, Rx> Spi<'d, T, Tx, Rx> {
226 } 222 }
227 #[cfg(spi_v3)] 223 #[cfg(spi_v3)]
228 unsafe { 224 unsafe {
229 T::enable();
230 T::reset();
231 T::regs().ifcr().write(|w| w.0 = 0xffff_ffff); 225 T::regs().ifcr().write(|w| w.0 = 0xffff_ffff);
232 T::regs().cfg2().modify(|w| { 226 T::regs().cfg2().modify(|w| {
233 //w.set_ssoe(true); 227 //w.set_ssoe(true);
234 w.set_ssoe(false); 228 w.set_ssoe(false);
235 w.set_cpha( 229 w.set_cpha(cpha);
236 match config.mode.phase == Phase::CaptureOnSecondTransition { 230 w.set_cpol(cpol);
237 true => vals::Cpha::SECONDEDGE, 231 w.set_lsbfrst(lsbfirst);
238 false => vals::Cpha::FIRSTEDGE,
239 },
240 );
241 w.set_cpol(match config.mode.polarity == Polarity::IdleHigh {
242 true => vals::Cpol::IDLEHIGH,
243 false => vals::Cpol::IDLELOW,
244 });
245 w.set_lsbfrst(match config.byte_order {
246 ByteOrder::LsbFirst => vals::Lsbfrst::LSBFIRST,
247 ByteOrder::MsbFirst => vals::Lsbfrst::MSBFIRST,
248 });
249 w.set_ssm(true); 232 w.set_ssm(true);
250 w.set_master(vals::Master::MASTER); 233 w.set_master(vals::Master::MASTER);
251 w.set_comm(vals::Comm::FULLDUPLEX); 234 w.set_comm(vals::Comm::FULLDUPLEX);
@@ -257,7 +240,7 @@ impl<'d, T: Instance, Tx, Rx> Spi<'d, T, Tx, Rx> {
257 }); 240 });
258 T::regs().cfg1().modify(|w| { 241 T::regs().cfg1().modify(|w| {
259 w.set_crcen(false); 242 w.set_crcen(false);
260 w.set_mbr(vals::Mbr(br)); 243 w.set_mbr(br);
261 w.set_dsize(WordSize::EightBit.dsize()); 244 w.set_dsize(WordSize::EightBit.dsize());
262 }); 245 });
263 T::regs().cr2().modify(|w| { 246 T::regs().cr2().modify(|w| {
@@ -281,20 +264,6 @@ impl<'d, T: Instance, Tx, Rx> Spi<'d, T, Tx, Rx> {
281 } 264 }
282 } 265 }
283 266
284 fn compute_baud_rate(clocks: Hertz, freq: Hertz) -> u8 {
285 match clocks.0 / freq.0 {
286 0 => unreachable!(),
287 1..=2 => 0b000,
288 3..=5 => 0b001,
289 6..=11 => 0b010,
290 12..=23 => 0b011,
291 24..=39 => 0b100,
292 40..=95 => 0b101,
293 96..=191 => 0b110,
294 _ => 0b111,
295 }
296 }
297
298 fn set_word_size(&mut self, word_size: WordSize) { 267 fn set_word_size(&mut self, word_size: WordSize) {
299 if self.current_word_size == word_size { 268 if self.current_word_size == word_size {
300 return; 269 return;
@@ -355,6 +324,27 @@ impl<'d, T: Instance, Tx, Rx> Drop for Spi<'d, T, Tx, Rx> {
355 } 324 }
356} 325}
357 326
327#[cfg(not(spi_v3))]
328use vals::Br;
329#[cfg(spi_v3)]
330use vals::Mbr as Br;
331
332fn compute_baud_rate(clocks: Hertz, freq: Hertz) -> Br {
333 let val = match clocks.0 / freq.0 {
334 0 => unreachable!(),
335 1..=2 => 0b000,
336 3..=5 => 0b001,
337 6..=11 => 0b010,
338 12..=23 => 0b011,
339 24..=39 => 0b100,
340 40..=95 => 0b101,
341 96..=191 => 0b110,
342 _ => 0b111,
343 };
344
345 Br(val)
346}
347
358trait RegsExt { 348trait RegsExt {
359 fn tx_ptr<W>(&self) -> *mut W; 349 fn tx_ptr<W>(&self) -> *mut W;
360 fn rx_ptr<W>(&self) -> *mut W; 350 fn rx_ptr<W>(&self) -> *mut W;