aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--embassy-stm32/src/dma/bdma.rs9
-rw-r--r--embassy-stm32/src/dma/dma.rs11
-rw-r--r--embassy-stm32/src/dma/gpdma.rs9
-rw-r--r--embassy-stm32/src/dma/mod.rs49
-rw-r--r--embassy-stm32/src/dma/word.rs79
-rw-r--r--embassy-stm32/src/spi/mod.rs166
6 files changed, 190 insertions, 133 deletions
diff --git a/embassy-stm32/src/dma/bdma.rs b/embassy-stm32/src/dma/bdma.rs
index cf1222c46..a23bb8cd7 100644
--- a/embassy-stm32/src/dma/bdma.rs
+++ b/embassy-stm32/src/dma/bdma.rs
@@ -9,7 +9,8 @@ use embassy_cortex_m::interrupt::Priority;
9use embassy_hal_common::{into_ref, Peripheral, PeripheralRef}; 9use embassy_hal_common::{into_ref, Peripheral, PeripheralRef};
10use embassy_sync::waitqueue::AtomicWaker; 10use embassy_sync::waitqueue::AtomicWaker;
11 11
12use super::{Dir, Word, WordSize}; 12use super::word::{Word, WordSize};
13use super::Dir;
13use crate::_generated::BDMA_CHANNEL_COUNT; 14use crate::_generated::BDMA_CHANNEL_COUNT;
14use crate::interrupt::{Interrupt, InterruptExt}; 15use crate::interrupt::{Interrupt, InterruptExt};
15use crate::pac; 16use crate::pac;
@@ -167,7 +168,7 @@ impl<'a, C: Channel> Transfer<'a, C> {
167 ptr as *mut u32, 168 ptr as *mut u32,
168 len, 169 len,
169 true, 170 true,
170 W::bits(), 171 W::size(),
171 options, 172 options,
172 ) 173 )
173 } 174 }
@@ -202,7 +203,7 @@ impl<'a, C: Channel> Transfer<'a, C> {
202 ptr as *mut u32, 203 ptr as *mut u32,
203 len, 204 len,
204 true, 205 true,
205 W::bits(), 206 W::size(),
206 options, 207 options,
207 ) 208 )
208 } 209 }
@@ -225,7 +226,7 @@ impl<'a, C: Channel> Transfer<'a, C> {
225 repeated as *const W as *mut u32, 226 repeated as *const W as *mut u32,
226 count, 227 count,
227 false, 228 false,
228 W::bits(), 229 W::size(),
229 options, 230 options,
230 ) 231 )
231 } 232 }
diff --git a/embassy-stm32/src/dma/dma.rs b/embassy-stm32/src/dma/dma.rs
index 62c092241..ef1d27573 100644
--- a/embassy-stm32/src/dma/dma.rs
+++ b/embassy-stm32/src/dma/dma.rs
@@ -9,7 +9,8 @@ use embassy_hal_common::{into_ref, Peripheral, PeripheralRef};
9use embassy_sync::waitqueue::AtomicWaker; 9use embassy_sync::waitqueue::AtomicWaker;
10use pac::dma::regs; 10use pac::dma::regs;
11 11
12use super::{Dir, Word, WordSize}; 12use super::word::{Word, WordSize};
13use super::Dir;
13use crate::_generated::DMA_CHANNEL_COUNT; 14use crate::_generated::DMA_CHANNEL_COUNT;
14use crate::interrupt::{Interrupt, InterruptExt}; 15use crate::interrupt::{Interrupt, InterruptExt};
15use crate::pac::dma::vals; 16use crate::pac::dma::vals;
@@ -246,7 +247,7 @@ impl<'a, C: Channel> Transfer<'a, C> {
246 ptr as *mut u32, 247 ptr as *mut u32,
247 len, 248 len,
248 true, 249 true,
249 W::bits(), 250 W::size(),
250 options, 251 options,
251 ) 252 )
252 } 253 }
@@ -281,7 +282,7 @@ impl<'a, C: Channel> Transfer<'a, C> {
281 ptr as *mut u32, 282 ptr as *mut u32,
282 len, 283 len,
283 true, 284 true,
284 W::bits(), 285 W::size(),
285 options, 286 options,
286 ) 287 )
287 } 288 }
@@ -304,7 +305,7 @@ impl<'a, C: Channel> Transfer<'a, C> {
304 repeated as *const W as *mut u32, 305 repeated as *const W as *mut u32,
305 count, 306 count,
306 false, 307 false,
307 W::bits(), 308 W::size(),
308 options, 309 options,
309 ) 310 )
310 } 311 }
@@ -464,7 +465,7 @@ impl<'a, C: Channel, W: Word> DoubleBuffered<'a, C, W> {
464 assert!(len > 0 && len <= 0xFFFF); 465 assert!(len > 0 && len <= 0xFFFF);
465 466
466 let dir = Dir::PeripheralToMemory; 467 let dir = Dir::PeripheralToMemory;
467 let data_size = W::bits(); 468 let data_size = W::size();
468 469
469 let channel_number = channel.num(); 470 let channel_number = channel.num();
470 let dma = channel.regs(); 471 let dma = channel.regs();
diff --git a/embassy-stm32/src/dma/gpdma.rs b/embassy-stm32/src/dma/gpdma.rs
index 5c6676a5f..5a516ccda 100644
--- a/embassy-stm32/src/dma/gpdma.rs
+++ b/embassy-stm32/src/dma/gpdma.rs
@@ -9,7 +9,8 @@ use embassy_cortex_m::interrupt::Priority;
9use embassy_hal_common::{into_ref, Peripheral, PeripheralRef}; 9use embassy_hal_common::{into_ref, Peripheral, PeripheralRef};
10use embassy_sync::waitqueue::AtomicWaker; 10use embassy_sync::waitqueue::AtomicWaker;
11 11
12use super::{Dir, Word, WordSize}; 12use super::word::{Word, WordSize};
13use super::Dir;
13use crate::_generated::GPDMA_CHANNEL_COUNT; 14use crate::_generated::GPDMA_CHANNEL_COUNT;
14use crate::interrupt::{Interrupt, InterruptExt}; 15use crate::interrupt::{Interrupt, InterruptExt};
15use crate::pac; 16use crate::pac;
@@ -165,7 +166,7 @@ impl<'a, C: Channel> Transfer<'a, C> {
165 ptr as *mut u32, 166 ptr as *mut u32,
166 len, 167 len,
167 true, 168 true,
168 W::bits(), 169 W::size(),
169 options, 170 options,
170 ) 171 )
171 } 172 }
@@ -200,7 +201,7 @@ impl<'a, C: Channel> Transfer<'a, C> {
200 ptr as *mut u32, 201 ptr as *mut u32,
201 len, 202 len,
202 true, 203 true,
203 W::bits(), 204 W::size(),
204 options, 205 options,
205 ) 206 )
206 } 207 }
@@ -223,7 +224,7 @@ impl<'a, C: Channel> Transfer<'a, C> {
223 repeated as *const W as *mut u32, 224 repeated as *const W as *mut u32,
224 count, 225 count,
225 false, 226 false,
226 W::bits(), 227 W::size(),
227 options, 228 options,
228 ) 229 )
229 } 230 }
diff --git a/embassy-stm32/src/dma/mod.rs b/embassy-stm32/src/dma/mod.rs
index d29ef4a1f..3312ca752 100644
--- a/embassy-stm32/src/dma/mod.rs
+++ b/embassy-stm32/src/dma/mod.rs
@@ -21,6 +21,8 @@ pub use gpdma::*;
21#[cfg(dmamux)] 21#[cfg(dmamux)]
22mod dmamux; 22mod dmamux;
23 23
24pub mod word;
25
24use core::mem; 26use core::mem;
25 27
26use embassy_cortex_m::interrupt::Priority; 28use embassy_cortex_m::interrupt::Priority;
@@ -36,53 +38,6 @@ enum Dir {
36 PeripheralToMemory, 38 PeripheralToMemory,
37} 39}
38 40
39#[derive(Debug, Copy, Clone, PartialEq, Eq)]
40#[cfg_attr(feature = "defmt", derive(defmt::Format))]
41pub enum WordSize {
42 OneByte,
43 TwoBytes,
44 FourBytes,
45}
46
47impl WordSize {
48 pub fn bytes(&self) -> usize {
49 match self {
50 Self::OneByte => 1,
51 Self::TwoBytes => 2,
52 Self::FourBytes => 4,
53 }
54 }
55}
56
57mod word_sealed {
58 pub trait Word {}
59}
60
61pub trait Word: word_sealed::Word {
62 fn bits() -> WordSize;
63}
64
65impl word_sealed::Word for u8 {}
66impl Word for u8 {
67 fn bits() -> WordSize {
68 WordSize::OneByte
69 }
70}
71
72impl word_sealed::Word for u16 {}
73impl Word for u16 {
74 fn bits() -> WordSize {
75 WordSize::TwoBytes
76 }
77}
78
79impl word_sealed::Word for u32 {}
80impl Word for u32 {
81 fn bits() -> WordSize {
82 WordSize::FourBytes
83 }
84}
85
86pub struct NoDma; 41pub struct NoDma;
87 42
88impl_peripheral!(NoDma); 43impl_peripheral!(NoDma);
diff --git a/embassy-stm32/src/dma/word.rs b/embassy-stm32/src/dma/word.rs
new file mode 100644
index 000000000..aef6e9700
--- /dev/null
+++ b/embassy-stm32/src/dma/word.rs
@@ -0,0 +1,79 @@
1#[derive(Debug, Copy, Clone, PartialEq, Eq)]
2#[cfg_attr(feature = "defmt", derive(defmt::Format))]
3pub enum WordSize {
4 OneByte,
5 TwoBytes,
6 FourBytes,
7}
8
9impl WordSize {
10 pub fn bytes(&self) -> usize {
11 match self {
12 Self::OneByte => 1,
13 Self::TwoBytes => 2,
14 Self::FourBytes => 4,
15 }
16 }
17}
18
19mod sealed {
20 pub trait Word {}
21}
22
23pub trait Word: sealed::Word + Default + Copy + 'static {
24 fn size() -> WordSize;
25 fn bits() -> usize;
26}
27
28macro_rules! impl_word {
29 (_, $T:ident, $bits:literal, $size:ident) => {
30 impl sealed::Word for $T {}
31 impl Word for $T {
32 fn bits() -> usize {
33 $bits
34 }
35 fn size() -> WordSize {
36 WordSize::$size
37 }
38 }
39 };
40 ($T:ident, $uX:ident, $bits:literal, $size:ident) => {
41 #[repr(transparent)]
42 #[derive(Copy, Clone, Default)]
43 pub struct $T(pub $uX);
44 impl_word!(_, $T, $bits, $size);
45 };
46}
47
48impl_word!(U1, u8, 1, OneByte);
49impl_word!(U2, u8, 2, OneByte);
50impl_word!(U3, u8, 3, OneByte);
51impl_word!(U4, u8, 4, OneByte);
52impl_word!(U5, u8, 5, OneByte);
53impl_word!(U6, u8, 6, OneByte);
54impl_word!(U7, u8, 7, OneByte);
55impl_word!(_, u8, 8, OneByte);
56impl_word!(U9, u16, 9, TwoBytes);
57impl_word!(U10, u16, 10, TwoBytes);
58impl_word!(U11, u16, 11, TwoBytes);
59impl_word!(U12, u16, 12, TwoBytes);
60impl_word!(U13, u16, 13, TwoBytes);
61impl_word!(U14, u16, 14, TwoBytes);
62impl_word!(U15, u16, 15, TwoBytes);
63impl_word!(_, u16, 16, TwoBytes);
64impl_word!(U17, u32, 17, FourBytes);
65impl_word!(U18, u32, 18, FourBytes);
66impl_word!(U19, u32, 19, FourBytes);
67impl_word!(U20, u32, 20, FourBytes);
68impl_word!(U21, u32, 21, FourBytes);
69impl_word!(U22, u32, 22, FourBytes);
70impl_word!(U23, u32, 23, FourBytes);
71impl_word!(U24, u32, 24, FourBytes);
72impl_word!(U25, u32, 25, FourBytes);
73impl_word!(U26, u32, 26, FourBytes);
74impl_word!(U27, u32, 27, FourBytes);
75impl_word!(U28, u32, 28, FourBytes);
76impl_word!(U29, u32, 29, FourBytes);
77impl_word!(U30, u32, 30, FourBytes);
78impl_word!(U31, u32, 31, FourBytes);
79impl_word!(_, u32, 32, FourBytes);
diff --git a/embassy-stm32/src/spi/mod.rs b/embassy-stm32/src/spi/mod.rs
index 7858cb3e8..9ce0cebfe 100644
--- a/embassy-stm32/src/spi/mod.rs
+++ b/embassy-stm32/src/spi/mod.rs
@@ -7,8 +7,7 @@ use embassy_futures::join::join;
7use embassy_hal_common::{into_ref, PeripheralRef}; 7use embassy_hal_common::{into_ref, PeripheralRef};
8pub use embedded_hal_02::spi::{Mode, Phase, Polarity, MODE_0, MODE_1, MODE_2, MODE_3}; 8pub use embedded_hal_02::spi::{Mode, Phase, Polarity, MODE_0, MODE_1, MODE_2, MODE_3};
9 9
10use self::sealed::WordSize; 10use crate::dma::{slice_ptr_parts, word, Transfer};
11use crate::dma::{slice_ptr_parts, Transfer};
12use crate::gpio::sealed::{AFType, Pin as _}; 11use crate::gpio::sealed::{AFType, Pin as _};
13use crate::gpio::{AnyPin, Pull}; 12use crate::gpio::{AnyPin, Pull};
14use crate::pac::spi::{regs, vals, Spi as Regs}; 13use crate::pac::spi::{regs, vals, Spi as Regs};
@@ -78,7 +77,7 @@ pub struct Spi<'d, T: Instance, Tx, Rx> {
78 miso: Option<PeripheralRef<'d, AnyPin>>, 77 miso: Option<PeripheralRef<'d, AnyPin>>,
79 txdma: PeripheralRef<'d, Tx>, 78 txdma: PeripheralRef<'d, Tx>,
80 rxdma: PeripheralRef<'d, Rx>, 79 rxdma: PeripheralRef<'d, Rx>,
81 current_word_size: WordSize, 80 current_word_size: word_impl::Config,
82} 81}
83 82
84impl<'d, T: Instance, Tx, Rx> Spi<'d, T, Tx, Rx> { 83impl<'d, T: Instance, Tx, Rx> Spi<'d, T, Tx, Rx> {
@@ -234,14 +233,15 @@ impl<'d, T: Instance, Tx, Rx> Spi<'d, T, Tx, Rx> {
234 if mosi.is_none() { 233 if mosi.is_none() {
235 w.set_rxonly(vals::Rxonly::OUTPUTDISABLED); 234 w.set_rxonly(vals::Rxonly::OUTPUTDISABLED);
236 } 235 }
237 w.set_dff(WordSize::EightBit.dff()) 236 w.set_dff(<u8 as sealed::Word>::CONFIG)
238 }); 237 });
239 } 238 }
240 #[cfg(spi_v2)] 239 #[cfg(spi_v2)]
241 unsafe { 240 unsafe {
242 T::REGS.cr2().modify(|w| { 241 T::REGS.cr2().modify(|w| {
243 w.set_frxth(WordSize::EightBit.frxth()); 242 let (ds, frxth) = <u8 as sealed::Word>::CONFIG;
244 w.set_ds(WordSize::EightBit.ds()); 243 w.set_frxth(frxth);
244 w.set_ds(ds);
245 w.set_ssoe(false); 245 w.set_ssoe(false);
246 }); 246 });
247 T::REGS.cr1().modify(|w| { 247 T::REGS.cr1().modify(|w| {
@@ -279,7 +279,8 @@ impl<'d, T: Instance, Tx, Rx> Spi<'d, T, Tx, Rx> {
279 T::REGS.cfg1().modify(|w| { 279 T::REGS.cfg1().modify(|w| {
280 w.set_crcen(false); 280 w.set_crcen(false);
281 w.set_mbr(br); 281 w.set_mbr(br);
282 w.set_dsize(WordSize::EightBit.dsize()); 282 w.set_dsize(<u8 as sealed::Word>::CONFIG);
283 w.set_fthlv(vals::Fthlv::ONEFRAME);
283 }); 284 });
284 T::REGS.cr2().modify(|w| { 285 T::REGS.cr2().modify(|w| {
285 w.set_tsize(0); 286 w.set_tsize(0);
@@ -297,7 +298,7 @@ impl<'d, T: Instance, Tx, Rx> Spi<'d, T, Tx, Rx> {
297 miso, 298 miso,
298 txdma, 299 txdma,
299 rxdma, 300 rxdma,
300 current_word_size: WordSize::EightBit, 301 current_word_size: <u8 as sealed::Word>::CONFIG,
301 } 302 }
302 } 303 }
303 304
@@ -355,7 +356,7 @@ impl<'d, T: Instance, Tx, Rx> Spi<'d, T, Tx, Rx> {
355 } 356 }
356 } 357 }
357 358
358 fn set_word_size(&mut self, word_size: WordSize) { 359 fn set_word_size(&mut self, word_size: word_impl::Config) {
359 if self.current_word_size == word_size { 360 if self.current_word_size == word_size {
360 return; 361 return;
361 } 362 }
@@ -364,7 +365,7 @@ impl<'d, T: Instance, Tx, Rx> Spi<'d, T, Tx, Rx> {
364 unsafe { 365 unsafe {
365 T::REGS.cr1().modify(|reg| { 366 T::REGS.cr1().modify(|reg| {
366 reg.set_spe(false); 367 reg.set_spe(false);
367 reg.set_dff(word_size.dff()) 368 reg.set_dff(word_size)
368 }); 369 });
369 T::REGS.cr1().modify(|reg| { 370 T::REGS.cr1().modify(|reg| {
370 reg.set_spe(true); 371 reg.set_spe(true);
@@ -376,8 +377,8 @@ impl<'d, T: Instance, Tx, Rx> Spi<'d, T, Tx, Rx> {
376 w.set_spe(false); 377 w.set_spe(false);
377 }); 378 });
378 T::REGS.cr2().modify(|w| { 379 T::REGS.cr2().modify(|w| {
379 w.set_frxth(word_size.frxth()); 380 w.set_frxth(word_size.1);
380 w.set_ds(word_size.ds()); 381 w.set_ds(word_size.0);
381 }); 382 });
382 T::REGS.cr1().modify(|w| { 383 T::REGS.cr1().modify(|w| {
383 w.set_spe(true); 384 w.set_spe(true);
@@ -393,7 +394,7 @@ impl<'d, T: Instance, Tx, Rx> Spi<'d, T, Tx, Rx> {
393 w.set_spe(false); 394 w.set_spe(false);
394 }); 395 });
395 T::REGS.cfg1().modify(|w| { 396 T::REGS.cfg1().modify(|w| {
396 w.set_dsize(word_size.dsize()); 397 w.set_dsize(word_size);
397 }); 398 });
398 T::REGS.cr1().modify(|w| { 399 T::REGS.cr1().modify(|w| {
399 w.set_csusp(false); 400 w.set_csusp(false);
@@ -412,7 +413,7 @@ impl<'d, T: Instance, Tx, Rx> Spi<'d, T, Tx, Rx> {
412 return Ok(()); 413 return Ok(());
413 } 414 }
414 415
415 self.set_word_size(W::WORDSIZE); 416 self.set_word_size(W::CONFIG);
416 unsafe { 417 unsafe {
417 T::REGS.cr1().modify(|w| { 418 T::REGS.cr1().modify(|w| {
418 w.set_spe(false); 419 w.set_spe(false);
@@ -450,7 +451,7 @@ impl<'d, T: Instance, Tx, Rx> Spi<'d, T, Tx, Rx> {
450 return Ok(()); 451 return Ok(());
451 } 452 }
452 453
453 self.set_word_size(W::WORDSIZE); 454 self.set_word_size(W::CONFIG);
454 unsafe { 455 unsafe {
455 T::REGS.cr1().modify(|w| { 456 T::REGS.cr1().modify(|w| {
456 w.set_spe(false); 457 w.set_spe(false);
@@ -513,7 +514,7 @@ impl<'d, T: Instance, Tx, Rx> Spi<'d, T, Tx, Rx> {
513 return Ok(()); 514 return Ok(());
514 } 515 }
515 516
516 self.set_word_size(W::WORDSIZE); 517 self.set_word_size(W::CONFIG);
517 unsafe { 518 unsafe {
518 T::REGS.cr1().modify(|w| { 519 T::REGS.cr1().modify(|w| {
519 w.set_spe(false); 520 w.set_spe(false);
@@ -571,7 +572,7 @@ impl<'d, T: Instance, Tx, Rx> Spi<'d, T, Tx, Rx> {
571 pub fn blocking_write<W: Word>(&mut self, words: &[W]) -> Result<(), Error> { 572 pub fn blocking_write<W: Word>(&mut self, words: &[W]) -> Result<(), Error> {
572 unsafe { T::REGS.cr1().modify(|w| w.set_spe(true)) } 573 unsafe { T::REGS.cr1().modify(|w| w.set_spe(true)) }
573 flush_rx_fifo(T::REGS); 574 flush_rx_fifo(T::REGS);
574 self.set_word_size(W::WORDSIZE); 575 self.set_word_size(W::CONFIG);
575 for word in words.iter() { 576 for word in words.iter() {
576 let _ = transfer_word(T::REGS, *word)?; 577 let _ = transfer_word(T::REGS, *word)?;
577 } 578 }
@@ -581,7 +582,7 @@ impl<'d, T: Instance, Tx, Rx> Spi<'d, T, Tx, Rx> {
581 pub fn blocking_read<W: Word>(&mut self, words: &mut [W]) -> Result<(), Error> { 582 pub fn blocking_read<W: Word>(&mut self, words: &mut [W]) -> Result<(), Error> {
582 unsafe { T::REGS.cr1().modify(|w| w.set_spe(true)) } 583 unsafe { T::REGS.cr1().modify(|w| w.set_spe(true)) }
583 flush_rx_fifo(T::REGS); 584 flush_rx_fifo(T::REGS);
584 self.set_word_size(W::WORDSIZE); 585 self.set_word_size(W::CONFIG);
585 for word in words.iter_mut() { 586 for word in words.iter_mut() {
586 *word = transfer_word(T::REGS, W::default())?; 587 *word = transfer_word(T::REGS, W::default())?;
587 } 588 }
@@ -591,7 +592,7 @@ impl<'d, T: Instance, Tx, Rx> Spi<'d, T, Tx, Rx> {
591 pub fn blocking_transfer_in_place<W: Word>(&mut self, words: &mut [W]) -> Result<(), Error> { 592 pub fn blocking_transfer_in_place<W: Word>(&mut self, words: &mut [W]) -> Result<(), Error> {
592 unsafe { T::REGS.cr1().modify(|w| w.set_spe(true)) } 593 unsafe { T::REGS.cr1().modify(|w| w.set_spe(true)) }
593 flush_rx_fifo(T::REGS); 594 flush_rx_fifo(T::REGS);
594 self.set_word_size(W::WORDSIZE); 595 self.set_word_size(W::CONFIG);
595 for word in words.iter_mut() { 596 for word in words.iter_mut() {
596 *word = transfer_word(T::REGS, *word)?; 597 *word = transfer_word(T::REGS, *word)?;
597 } 598 }
@@ -601,7 +602,7 @@ impl<'d, T: Instance, Tx, Rx> Spi<'d, T, Tx, Rx> {
601 pub fn blocking_transfer<W: Word>(&mut self, read: &mut [W], write: &[W]) -> Result<(), Error> { 602 pub fn blocking_transfer<W: Word>(&mut self, read: &mut [W], write: &[W]) -> Result<(), Error> {
602 unsafe { T::REGS.cr1().modify(|w| w.set_spe(true)) } 603 unsafe { T::REGS.cr1().modify(|w| w.set_spe(true)) }
603 flush_rx_fifo(T::REGS); 604 flush_rx_fifo(T::REGS);
604 self.set_word_size(W::WORDSIZE); 605 self.set_word_size(W::CONFIG);
605 let len = read.len().max(write.len()); 606 let len = read.len().max(write.len());
606 for i in 0..len { 607 for i in 0..len {
607 let wb = write.get(i).copied().unwrap_or_default(); 608 let wb = write.get(i).copied().unwrap_or_default();
@@ -933,70 +934,89 @@ pub(crate) mod sealed {
933 const REGS: Regs; 934 const REGS: Regs;
934 } 935 }
935 936
936 pub trait Word: Copy + 'static { 937 pub trait Word {
937 const WORDSIZE: WordSize; 938 const CONFIG: word_impl::Config;
938 }
939
940 impl Word for u8 {
941 const WORDSIZE: WordSize = WordSize::EightBit;
942 }
943 impl Word for u16 {
944 const WORDSIZE: WordSize = WordSize::SixteenBit;
945 } 939 }
940}
946 941
947 #[derive(Copy, Clone, PartialOrd, PartialEq)] 942pub trait Word: word::Word + sealed::Word {}
948 pub enum WordSize {
949 EightBit,
950 SixteenBit,
951 }
952 943
953 impl WordSize { 944macro_rules! impl_word {
954 #[cfg(any(spi_v1, spi_f1))] 945 ($T:ty, $config:expr) => {
955 pub fn dff(&self) -> vals::Dff { 946 impl sealed::Word for $T {
956 match self { 947 const CONFIG: Config = $config;
957 WordSize::EightBit => vals::Dff::EIGHTBIT,
958 WordSize::SixteenBit => vals::Dff::SIXTEENBIT,
959 }
960 } 948 }
949 impl Word for $T {}
950 };
951}
961 952
962 #[cfg(spi_v2)] 953#[cfg(any(spi_v1, spi_f1))]
963 pub fn ds(&self) -> vals::Ds { 954mod word_impl {
964 match self { 955 use super::*;
965 WordSize::EightBit => vals::Ds::EIGHTBIT,
966 WordSize::SixteenBit => vals::Ds::SIXTEENBIT,
967 }
968 }
969 956
970 #[cfg(spi_v2)] 957 pub type Config = vals::Dff;
971 pub fn frxth(&self) -> vals::Frxth {
972 match self {
973 WordSize::EightBit => vals::Frxth::QUARTER,
974 WordSize::SixteenBit => vals::Frxth::HALF,
975 }
976 }
977 958
978 #[cfg(any(spi_v3, spi_v4, spi_v5))] 959 impl_word!(u8, vals::Dff::EIGHTBIT);
979 pub fn dsize(&self) -> u8 { 960 impl_word!(u16, vals::Dff::SIXTEENBIT);
980 match self { 961}
981 WordSize::EightBit => 0b0111,
982 WordSize::SixteenBit => 0b1111,
983 }
984 }
985 962
986 #[cfg(any(spi_v3, spi_v4, spi_v5))] 963#[cfg(any(spi_v2))]
987 pub fn _frxth(&self) -> vals::Fthlv { 964mod word_impl {
988 match self { 965 use super::*;
989 WordSize::EightBit => vals::Fthlv::ONEFRAME, 966
990 WordSize::SixteenBit => vals::Fthlv::ONEFRAME, 967 pub type Config = (vals::Ds, vals::Frxth);
991 } 968
992 } 969 impl_word!(word::U4, (vals::Ds::FOURBIT, vals::Frxth::QUARTER));
993 } 970 impl_word!(word::U5, (vals::Ds::FIVEBIT, vals::Frxth::QUARTER));
971 impl_word!(word::U6, (vals::Ds::SIXBIT, vals::Frxth::QUARTER));
972 impl_word!(word::U7, (vals::Ds::SEVENBIT, vals::Frxth::QUARTER));
973 impl_word!(u8, (vals::Ds::EIGHTBIT, vals::Frxth::QUARTER));
974 impl_word!(word::U9, (vals::Ds::NINEBIT, vals::Frxth::HALF));
975 impl_word!(word::U10, (vals::Ds::TENBIT, vals::Frxth::HALF));
976 impl_word!(word::U11, (vals::Ds::ELEVENBIT, vals::Frxth::HALF));
977 impl_word!(word::U12, (vals::Ds::TWELVEBIT, vals::Frxth::HALF));
978 impl_word!(word::U13, (vals::Ds::THIRTEENBIT, vals::Frxth::HALF));
979 impl_word!(word::U14, (vals::Ds::FOURTEENBIT, vals::Frxth::HALF));
980 impl_word!(word::U15, (vals::Ds::FIFTEENBIT, vals::Frxth::HALF));
981 impl_word!(u16, (vals::Ds::SIXTEENBIT, vals::Frxth::HALF));
994} 982}
995 983
996pub trait Word: Copy + 'static + sealed::Word + Default + crate::dma::Word {} 984#[cfg(any(spi_v3, spi_v4, spi_v5))]
985mod word_impl {
986 use super::*;
997 987
998impl Word for u8 {} 988 pub type Config = u8;
999impl Word for u16 {} 989
990 impl_word!(word::U4, 4 - 1);
991 impl_word!(word::U5, 5 - 1);
992 impl_word!(word::U6, 6 - 1);
993 impl_word!(word::U7, 7 - 1);
994 impl_word!(u8, 8 - 1);
995 impl_word!(word::U9, 9 - 1);
996 impl_word!(word::U10, 10 - 1);
997 impl_word!(word::U11, 11 - 1);
998 impl_word!(word::U12, 12 - 1);
999 impl_word!(word::U13, 13 - 1);
1000 impl_word!(word::U14, 14 - 1);
1001 impl_word!(word::U15, 15 - 1);
1002 impl_word!(u16, 16 - 1);
1003 impl_word!(word::U17, 17 - 1);
1004 impl_word!(word::U18, 18 - 1);
1005 impl_word!(word::U19, 19 - 1);
1006 impl_word!(word::U20, 20 - 1);
1007 impl_word!(word::U21, 21 - 1);
1008 impl_word!(word::U22, 22 - 1);
1009 impl_word!(word::U23, 23 - 1);
1010 impl_word!(word::U24, 24 - 1);
1011 impl_word!(word::U25, 25 - 1);
1012 impl_word!(word::U26, 26 - 1);
1013 impl_word!(word::U27, 27 - 1);
1014 impl_word!(word::U28, 28 - 1);
1015 impl_word!(word::U29, 29 - 1);
1016 impl_word!(word::U30, 30 - 1);
1017 impl_word!(word::U31, 31 - 1);
1018 impl_word!(u32, 32 - 1);
1019}
1000 1020
1001pub trait Instance: Peripheral<P = Self> + sealed::Instance + RccPeripheral {} 1021pub trait Instance: Peripheral<P = Self> + sealed::Instance + RccPeripheral {}
1002pin_trait!(SckPin, Instance); 1022pin_trait!(SckPin, Instance);