diff options
| author | Dario Nieuwenhuis <[email protected]> | 2024-05-21 01:24:10 +0200 |
|---|---|---|
| committer | Dario Nieuwenhuis <[email protected]> | 2024-05-21 01:24:10 +0200 |
| commit | 6a508b32101b0af1a77624ef0a22c72c972b1b74 (patch) | |
| tree | c3ce31065078063c768b9f94d6faacea2fe2e80b | |
| parent | 2b09f9efd7e621708cd00bc512ce981735907103 (diff) | |
stm32: use funcs for info/state, const for ENABLE_BIT.
| -rw-r--r-- | embassy-stm32/build.rs | 6 | ||||
| -rw-r--r-- | embassy-stm32/src/i2s.rs | 4 | ||||
| -rw-r--r-- | embassy-stm32/src/macros.rs | 16 | ||||
| -rw-r--r-- | embassy-stm32/src/rcc/mod.rs | 5 | ||||
| -rw-r--r-- | embassy-stm32/src/spi/mod.rs | 122 |
5 files changed, 81 insertions, 72 deletions
diff --git a/embassy-stm32/build.rs b/embassy-stm32/build.rs index f17c6bef6..e615c6307 100644 --- a/embassy-stm32/build.rs +++ b/embassy-stm32/build.rs | |||
| @@ -653,9 +653,9 @@ fn main() { | |||
| 653 | crate::pac::RCC.#en_reg().modify(|w| w.#set_en_field(false)); | 653 | crate::pac::RCC.#en_reg().modify(|w| w.#set_en_field(false)); |
| 654 | #decr_stop_refcount | 654 | #decr_stop_refcount |
| 655 | } | 655 | } |
| 656 | fn enable_bit() -> crate::rcc::ClockEnableBit { | 656 | |
| 657 | unsafe { crate::rcc::ClockEnableBit::new(#en_reg_offs, #en_bit_offs) } | 657 | const ENABLE_BIT: crate::rcc::ClockEnableBit = |
| 658 | } | 658 | unsafe { crate::rcc::ClockEnableBit::new(#en_reg_offs, #en_bit_offs) }; |
| 659 | } | 659 | } |
| 660 | 660 | ||
| 661 | impl crate::rcc::RccPeripheral for peripherals::#pname {} | 661 | impl crate::rcc::RccPeripheral for peripherals::#pname {} |
diff --git a/embassy-stm32/src/i2s.rs b/embassy-stm32/src/i2s.rs index c102c0035..c78810a38 100644 --- a/embassy-stm32/src/i2s.rs +++ b/embassy-stm32/src/i2s.rs | |||
| @@ -208,7 +208,7 @@ impl<'d> I2S<'d> { | |||
| 208 | // rate to reach the proper audio sample frequency. The ODD bit in the SPI_I2SPR | 208 | // rate to reach the proper audio sample frequency. The ODD bit in the SPI_I2SPR |
| 209 | // register also has to be defined. | 209 | // register also has to be defined. |
| 210 | 210 | ||
| 211 | spi.regs.i2spr().modify(|w| { | 211 | spi.info.regs.i2spr().modify(|w| { |
| 212 | w.set_i2sdiv(div); | 212 | w.set_i2sdiv(div); |
| 213 | w.set_odd(match odd { | 213 | w.set_odd(match odd { |
| 214 | true => Odd::ODD, | 214 | true => Odd::ODD, |
| @@ -235,7 +235,7 @@ impl<'d> I2S<'d> { | |||
| 235 | 235 | ||
| 236 | // 5. The I2SE bit in SPI_I2SCFGR register must be set. | 236 | // 5. The I2SE bit in SPI_I2SCFGR register must be set. |
| 237 | 237 | ||
| 238 | spi.regs.i2scfgr().modify(|w| { | 238 | spi.info.regs.i2scfgr().modify(|w| { |
| 239 | w.set_ckpol(config.clock_polarity.ckpol()); | 239 | w.set_ckpol(config.clock_polarity.ckpol()); |
| 240 | 240 | ||
| 241 | w.set_i2smod(true); | 241 | w.set_i2smod(true); |
diff --git a/embassy-stm32/src/macros.rs b/embassy-stm32/src/macros.rs index 9c459a932..6a5691181 100644 --- a/embassy-stm32/src/macros.rs +++ b/embassy-stm32/src/macros.rs | |||
| @@ -4,8 +4,10 @@ macro_rules! peri_trait { | |||
| 4 | () => { | 4 | () => { |
| 5 | #[allow(private_interfaces)] | 5 | #[allow(private_interfaces)] |
| 6 | pub(crate) trait SealedInstance { | 6 | pub(crate) trait SealedInstance { |
| 7 | const INFO: Info; | 7 | #[allow(unused)] |
| 8 | const STATE: &'static State; | 8 | fn info() -> &'static Info; |
| 9 | #[allow(unused)] | ||
| 10 | fn state() -> &'static State; | ||
| 9 | } | 11 | } |
| 10 | 12 | ||
| 11 | /// SPI instance trait. | 13 | /// SPI instance trait. |
| @@ -18,8 +20,14 @@ macro_rules! peri_trait_impl { | |||
| 18 | ($instance:ident, $info:expr) => { | 20 | ($instance:ident, $info:expr) => { |
| 19 | #[allow(private_interfaces)] | 21 | #[allow(private_interfaces)] |
| 20 | impl SealedInstance for crate::peripherals::$instance { | 22 | impl SealedInstance for crate::peripherals::$instance { |
| 21 | const INFO: Info = $info; | 23 | fn info() -> &'static Info { |
| 22 | const STATE: &'static State = &State::new(); | 24 | static INFO: Info = $info; |
| 25 | &INFO | ||
| 26 | } | ||
| 27 | fn state() -> &'static State { | ||
| 28 | static STATE: State = State::new(); | ||
| 29 | &STATE | ||
| 30 | } | ||
| 23 | } | 31 | } |
| 24 | impl Instance for crate::peripherals::$instance {} | 32 | impl Instance for crate::peripherals::$instance {} |
| 25 | }; | 33 | }; |
diff --git a/embassy-stm32/src/rcc/mod.rs b/embassy-stm32/src/rcc/mod.rs index c413b62ef..28816256c 100644 --- a/embassy-stm32/src/rcc/mod.rs +++ b/embassy-stm32/src/rcc/mod.rs | |||
| @@ -67,10 +67,11 @@ pub(crate) unsafe fn get_freqs() -> &'static Clocks { | |||
| 67 | } | 67 | } |
| 68 | 68 | ||
| 69 | pub(crate) trait SealedRccPeripheral { | 69 | pub(crate) trait SealedRccPeripheral { |
| 70 | const ENABLE_BIT: ClockEnableBit; | ||
| 71 | |||
| 70 | fn frequency() -> Hertz; | 72 | fn frequency() -> Hertz; |
| 71 | fn enable_and_reset_with_cs(cs: CriticalSection); | 73 | fn enable_and_reset_with_cs(cs: CriticalSection); |
| 72 | fn disable_with_cs(cs: CriticalSection); | 74 | fn disable_with_cs(cs: CriticalSection); |
| 73 | fn enable_bit() -> ClockEnableBit; | ||
| 74 | 75 | ||
| 75 | fn enable_and_reset() { | 76 | fn enable_and_reset() { |
| 76 | critical_section::with(|cs| Self::enable_and_reset_with_cs(cs)) | 77 | critical_section::with(|cs| Self::enable_and_reset_with_cs(cs)) |
| @@ -151,7 +152,7 @@ pub(crate) struct ClockEnableBit { | |||
| 151 | 152 | ||
| 152 | impl ClockEnableBit { | 153 | impl ClockEnableBit { |
| 153 | /// Safety: offset+bit must correspond to a valid xxxEN bit. | 154 | /// Safety: offset+bit must correspond to a valid xxxEN bit. |
| 154 | pub(crate) unsafe fn new(offset: u8, bit: u8) -> Self { | 155 | pub(crate) const unsafe fn new(offset: u8, bit: u8) -> Self { |
| 155 | Self { offset, bit } | 156 | Self { offset, bit } |
| 156 | } | 157 | } |
| 157 | 158 | ||
diff --git a/embassy-stm32/src/spi/mod.rs b/embassy-stm32/src/spi/mod.rs index 5a2ee105d..0875cfe41 100644 --- a/embassy-stm32/src/spi/mod.rs +++ b/embassy-stm32/src/spi/mod.rs | |||
| @@ -13,7 +13,7 @@ use crate::dma::{slice_ptr_parts, word, ChannelAndRequest}; | |||
| 13 | use crate::gpio::{AFType, AnyPin, Pull, SealedPin as _, Speed}; | 13 | use crate::gpio::{AFType, AnyPin, Pull, SealedPin as _, Speed}; |
| 14 | use crate::mode::{Async, Blocking, Mode as PeriMode}; | 14 | use crate::mode::{Async, Blocking, Mode as PeriMode}; |
| 15 | use crate::pac::spi::{regs, vals, Spi as Regs}; | 15 | use crate::pac::spi::{regs, vals, Spi as Regs}; |
| 16 | use crate::rcc::{ClockEnableBit, RccPeripheral}; | 16 | use crate::rcc::{ClockEnableBit, SealedRccPeripheral}; |
| 17 | use crate::time::Hertz; | 17 | use crate::time::Hertz; |
| 18 | use crate::Peripheral; | 18 | use crate::Peripheral; |
| 19 | 19 | ||
| @@ -93,8 +93,7 @@ impl Config { | |||
| 93 | } | 93 | } |
| 94 | /// SPI driver. | 94 | /// SPI driver. |
| 95 | pub struct Spi<'d, M: PeriMode> { | 95 | pub struct Spi<'d, M: PeriMode> { |
| 96 | pub(crate) regs: Regs, | 96 | pub(crate) info: &'static Info, |
| 97 | enable_bit: ClockEnableBit, | ||
| 98 | kernel_clock: Hertz, | 97 | kernel_clock: Hertz, |
| 99 | sck: Option<PeripheralRef<'d, AnyPin>>, | 98 | sck: Option<PeripheralRef<'d, AnyPin>>, |
| 100 | mosi: Option<PeripheralRef<'d, AnyPin>>, | 99 | mosi: Option<PeripheralRef<'d, AnyPin>>, |
| @@ -115,7 +114,7 @@ impl<'d, M: PeriMode> Spi<'d, M> { | |||
| 115 | rx_dma: Option<ChannelAndRequest<'d>>, | 114 | rx_dma: Option<ChannelAndRequest<'d>>, |
| 116 | config: Config, | 115 | config: Config, |
| 117 | ) -> Self { | 116 | ) -> Self { |
| 118 | let regs = T::INFO.regs; | 117 | let regs = T::info().regs; |
| 119 | let kernel_clock = T::frequency(); | 118 | let kernel_clock = T::frequency(); |
| 120 | let br = compute_baud_rate(kernel_clock, config.frequency); | 119 | let br = compute_baud_rate(kernel_clock, config.frequency); |
| 121 | 120 | ||
| @@ -205,8 +204,7 @@ impl<'d, M: PeriMode> Spi<'d, M> { | |||
| 205 | } | 204 | } |
| 206 | 205 | ||
| 207 | Self { | 206 | Self { |
| 208 | regs, | 207 | info: T::info(), |
| 209 | enable_bit: T::enable_bit(), | ||
| 210 | kernel_clock, | 208 | kernel_clock, |
| 211 | sck, | 209 | sck, |
| 212 | mosi, | 210 | mosi, |
| @@ -228,7 +226,7 @@ impl<'d, M: PeriMode> Spi<'d, M> { | |||
| 228 | let br = compute_baud_rate(self.kernel_clock, config.frequency); | 226 | let br = compute_baud_rate(self.kernel_clock, config.frequency); |
| 229 | 227 | ||
| 230 | #[cfg(any(spi_v1, spi_f1, spi_v2))] | 228 | #[cfg(any(spi_v1, spi_f1, spi_v2))] |
| 231 | self.regs.cr1().modify(|w| { | 229 | self.info.regs.cr1().modify(|w| { |
| 232 | w.set_cpha(cpha); | 230 | w.set_cpha(cpha); |
| 233 | w.set_cpol(cpol); | 231 | w.set_cpol(cpol); |
| 234 | w.set_br(br); | 232 | w.set_br(br); |
| @@ -237,12 +235,12 @@ impl<'d, M: PeriMode> Spi<'d, M> { | |||
| 237 | 235 | ||
| 238 | #[cfg(any(spi_v3, spi_v4, spi_v5))] | 236 | #[cfg(any(spi_v3, spi_v4, spi_v5))] |
| 239 | { | 237 | { |
| 240 | self.regs.cfg2().modify(|w| { | 238 | self.info.regs.cfg2().modify(|w| { |
| 241 | w.set_cpha(cpha); | 239 | w.set_cpha(cpha); |
| 242 | w.set_cpol(cpol); | 240 | w.set_cpol(cpol); |
| 243 | w.set_lsbfirst(lsbfirst); | 241 | w.set_lsbfirst(lsbfirst); |
| 244 | }); | 242 | }); |
| 245 | self.regs.cfg1().modify(|w| { | 243 | self.info.regs.cfg1().modify(|w| { |
| 246 | w.set_mbr(br); | 244 | w.set_mbr(br); |
| 247 | }); | 245 | }); |
| 248 | } | 246 | } |
| @@ -252,11 +250,11 @@ impl<'d, M: PeriMode> Spi<'d, M> { | |||
| 252 | /// Get current SPI configuration. | 250 | /// Get current SPI configuration. |
| 253 | pub fn get_current_config(&self) -> Config { | 251 | pub fn get_current_config(&self) -> Config { |
| 254 | #[cfg(any(spi_v1, spi_f1, spi_v2))] | 252 | #[cfg(any(spi_v1, spi_f1, spi_v2))] |
| 255 | let cfg = self.regs.cr1().read(); | 253 | let cfg = self.info.regs.cr1().read(); |
| 256 | #[cfg(any(spi_v3, spi_v4, spi_v5))] | 254 | #[cfg(any(spi_v3, spi_v4, spi_v5))] |
| 257 | let cfg = self.regs.cfg2().read(); | 255 | let cfg = self.info.regs.cfg2().read(); |
| 258 | #[cfg(any(spi_v3, spi_v4, spi_v5))] | 256 | #[cfg(any(spi_v3, spi_v4, spi_v5))] |
| 259 | let cfg1 = self.regs.cfg1().read(); | 257 | let cfg1 = self.info.regs.cfg1().read(); |
| 260 | 258 | ||
| 261 | let polarity = if cfg.cpol() == vals::Cpol::IDLELOW { | 259 | let polarity = if cfg.cpol() == vals::Cpol::IDLELOW { |
| 262 | Polarity::IdleLow | 260 | Polarity::IdleLow |
| @@ -296,40 +294,40 @@ impl<'d, M: PeriMode> Spi<'d, M> { | |||
| 296 | 294 | ||
| 297 | #[cfg(any(spi_v1, spi_f1))] | 295 | #[cfg(any(spi_v1, spi_f1))] |
| 298 | { | 296 | { |
| 299 | self.regs.cr1().modify(|reg| { | 297 | self.info.regs.cr1().modify(|reg| { |
| 300 | reg.set_spe(false); | 298 | reg.set_spe(false); |
| 301 | reg.set_dff(word_size) | 299 | reg.set_dff(word_size) |
| 302 | }); | 300 | }); |
| 303 | self.regs.cr1().modify(|reg| { | 301 | self.info.regs.cr1().modify(|reg| { |
| 304 | reg.set_spe(true); | 302 | reg.set_spe(true); |
| 305 | }); | 303 | }); |
| 306 | } | 304 | } |
| 307 | #[cfg(spi_v2)] | 305 | #[cfg(spi_v2)] |
| 308 | { | 306 | { |
| 309 | self.regs.cr1().modify(|w| { | 307 | self.info.regs.cr1().modify(|w| { |
| 310 | w.set_spe(false); | 308 | w.set_spe(false); |
| 311 | }); | 309 | }); |
| 312 | self.regs.cr2().modify(|w| { | 310 | self.info.regs.cr2().modify(|w| { |
| 313 | w.set_frxth(word_size.1); | 311 | w.set_frxth(word_size.1); |
| 314 | w.set_ds(word_size.0); | 312 | w.set_ds(word_size.0); |
| 315 | }); | 313 | }); |
| 316 | self.regs.cr1().modify(|w| { | 314 | self.info.regs.cr1().modify(|w| { |
| 317 | w.set_spe(true); | 315 | w.set_spe(true); |
| 318 | }); | 316 | }); |
| 319 | } | 317 | } |
| 320 | #[cfg(any(spi_v3, spi_v4, spi_v5))] | 318 | #[cfg(any(spi_v3, spi_v4, spi_v5))] |
| 321 | { | 319 | { |
| 322 | self.regs.cr1().modify(|w| { | 320 | self.info.regs.cr1().modify(|w| { |
| 323 | w.set_csusp(true); | 321 | w.set_csusp(true); |
| 324 | }); | 322 | }); |
| 325 | while self.regs.sr().read().eot() {} | 323 | while self.info.regs.sr().read().eot() {} |
| 326 | self.regs.cr1().modify(|w| { | 324 | self.info.regs.cr1().modify(|w| { |
| 327 | w.set_spe(false); | 325 | w.set_spe(false); |
| 328 | }); | 326 | }); |
| 329 | self.regs.cfg1().modify(|w| { | 327 | self.info.regs.cfg1().modify(|w| { |
| 330 | w.set_dsize(word_size); | 328 | w.set_dsize(word_size); |
| 331 | }); | 329 | }); |
| 332 | self.regs.cr1().modify(|w| { | 330 | self.info.regs.cr1().modify(|w| { |
| 333 | w.set_csusp(false); | 331 | w.set_csusp(false); |
| 334 | w.set_spe(true); | 332 | w.set_spe(true); |
| 335 | }); | 333 | }); |
| @@ -340,22 +338,22 @@ impl<'d, M: PeriMode> Spi<'d, M> { | |||
| 340 | 338 | ||
| 341 | /// Blocking write. | 339 | /// Blocking write. |
| 342 | pub fn blocking_write<W: Word>(&mut self, words: &[W]) -> Result<(), Error> { | 340 | pub fn blocking_write<W: Word>(&mut self, words: &[W]) -> Result<(), Error> { |
| 343 | self.regs.cr1().modify(|w| w.set_spe(true)); | 341 | self.info.regs.cr1().modify(|w| w.set_spe(true)); |
| 344 | flush_rx_fifo(self.regs); | 342 | flush_rx_fifo(self.info.regs); |
| 345 | self.set_word_size(W::CONFIG); | 343 | self.set_word_size(W::CONFIG); |
| 346 | for word in words.iter() { | 344 | for word in words.iter() { |
| 347 | let _ = transfer_word(self.regs, *word)?; | 345 | let _ = transfer_word(self.info.regs, *word)?; |
| 348 | } | 346 | } |
| 349 | Ok(()) | 347 | Ok(()) |
| 350 | } | 348 | } |
| 351 | 349 | ||
| 352 | /// Blocking read. | 350 | /// Blocking read. |
| 353 | pub fn blocking_read<W: Word>(&mut self, words: &mut [W]) -> Result<(), Error> { | 351 | pub fn blocking_read<W: Word>(&mut self, words: &mut [W]) -> Result<(), Error> { |
| 354 | self.regs.cr1().modify(|w| w.set_spe(true)); | 352 | self.info.regs.cr1().modify(|w| w.set_spe(true)); |
| 355 | flush_rx_fifo(self.regs); | 353 | flush_rx_fifo(self.info.regs); |
| 356 | self.set_word_size(W::CONFIG); | 354 | self.set_word_size(W::CONFIG); |
| 357 | for word in words.iter_mut() { | 355 | for word in words.iter_mut() { |
| 358 | *word = transfer_word(self.regs, W::default())?; | 356 | *word = transfer_word(self.info.regs, W::default())?; |
| 359 | } | 357 | } |
| 360 | Ok(()) | 358 | Ok(()) |
| 361 | } | 359 | } |
| @@ -364,11 +362,11 @@ impl<'d, M: PeriMode> Spi<'d, M> { | |||
| 364 | /// | 362 | /// |
| 365 | /// This writes the contents of `data` on MOSI, and puts the received data on MISO in `data`, at the same time. | 363 | /// This writes the contents of `data` on MOSI, and puts the received data on MISO in `data`, at the same time. |
| 366 | pub fn blocking_transfer_in_place<W: Word>(&mut self, words: &mut [W]) -> Result<(), Error> { | 364 | pub fn blocking_transfer_in_place<W: Word>(&mut self, words: &mut [W]) -> Result<(), Error> { |
| 367 | self.regs.cr1().modify(|w| w.set_spe(true)); | 365 | self.info.regs.cr1().modify(|w| w.set_spe(true)); |
| 368 | flush_rx_fifo(self.regs); | 366 | flush_rx_fifo(self.info.regs); |
| 369 | self.set_word_size(W::CONFIG); | 367 | self.set_word_size(W::CONFIG); |
| 370 | for word in words.iter_mut() { | 368 | for word in words.iter_mut() { |
| 371 | *word = transfer_word(self.regs, *word)?; | 369 | *word = transfer_word(self.info.regs, *word)?; |
| 372 | } | 370 | } |
| 373 | Ok(()) | 371 | Ok(()) |
| 374 | } | 372 | } |
| @@ -380,13 +378,13 @@ impl<'d, M: PeriMode> Spi<'d, M> { | |||
| 380 | /// The transfer runs for `max(read.len(), write.len())` bytes. If `read` is shorter extra bytes are ignored. | 378 | /// The transfer runs for `max(read.len(), write.len())` bytes. If `read` is shorter extra bytes are ignored. |
| 381 | /// If `write` is shorter it is padded with zero bytes. | 379 | /// If `write` is shorter it is padded with zero bytes. |
| 382 | pub fn blocking_transfer<W: Word>(&mut self, read: &mut [W], write: &[W]) -> Result<(), Error> { | 380 | pub fn blocking_transfer<W: Word>(&mut self, read: &mut [W], write: &[W]) -> Result<(), Error> { |
| 383 | self.regs.cr1().modify(|w| w.set_spe(true)); | 381 | self.info.regs.cr1().modify(|w| w.set_spe(true)); |
| 384 | flush_rx_fifo(self.regs); | 382 | flush_rx_fifo(self.info.regs); |
| 385 | self.set_word_size(W::CONFIG); | 383 | self.set_word_size(W::CONFIG); |
| 386 | let len = read.len().max(write.len()); | 384 | let len = read.len().max(write.len()); |
| 387 | for i in 0..len { | 385 | for i in 0..len { |
| 388 | let wb = write.get(i).copied().unwrap_or_default(); | 386 | let wb = write.get(i).copied().unwrap_or_default(); |
| 389 | let rb = transfer_word(self.regs, wb)?; | 387 | let rb = transfer_word(self.info.regs, wb)?; |
| 390 | if let Some(r) = read.get_mut(i) { | 388 | if let Some(r) = read.get_mut(i) { |
| 391 | *r = rb; | 389 | *r = rb; |
| 392 | } | 390 | } |
| @@ -588,25 +586,25 @@ impl<'d> Spi<'d, Async> { | |||
| 588 | } | 586 | } |
| 589 | 587 | ||
| 590 | self.set_word_size(W::CONFIG); | 588 | self.set_word_size(W::CONFIG); |
| 591 | self.regs.cr1().modify(|w| { | 589 | self.info.regs.cr1().modify(|w| { |
| 592 | w.set_spe(false); | 590 | w.set_spe(false); |
| 593 | }); | 591 | }); |
| 594 | 592 | ||
| 595 | let tx_dst = self.regs.tx_ptr(); | 593 | let tx_dst = self.info.regs.tx_ptr(); |
| 596 | let tx_f = unsafe { self.tx_dma.as_mut().unwrap().write(data, tx_dst, Default::default()) }; | 594 | let tx_f = unsafe { self.tx_dma.as_mut().unwrap().write(data, tx_dst, Default::default()) }; |
| 597 | 595 | ||
| 598 | set_txdmaen(self.regs, true); | 596 | set_txdmaen(self.info.regs, true); |
| 599 | self.regs.cr1().modify(|w| { | 597 | self.info.regs.cr1().modify(|w| { |
| 600 | w.set_spe(true); | 598 | w.set_spe(true); |
| 601 | }); | 599 | }); |
| 602 | #[cfg(any(spi_v3, spi_v4, spi_v5))] | 600 | #[cfg(any(spi_v3, spi_v4, spi_v5))] |
| 603 | self.regs.cr1().modify(|w| { | 601 | self.info.regs.cr1().modify(|w| { |
| 604 | w.set_cstart(true); | 602 | w.set_cstart(true); |
| 605 | }); | 603 | }); |
| 606 | 604 | ||
| 607 | tx_f.await; | 605 | tx_f.await; |
| 608 | 606 | ||
| 609 | finish_dma(self.regs); | 607 | finish_dma(self.info.regs); |
| 610 | 608 | ||
| 611 | Ok(()) | 609 | Ok(()) |
| 612 | } | 610 | } |
| @@ -618,22 +616,22 @@ impl<'d> Spi<'d, Async> { | |||
| 618 | } | 616 | } |
| 619 | 617 | ||
| 620 | self.set_word_size(W::CONFIG); | 618 | self.set_word_size(W::CONFIG); |
| 621 | self.regs.cr1().modify(|w| { | 619 | self.info.regs.cr1().modify(|w| { |
| 622 | w.set_spe(false); | 620 | w.set_spe(false); |
| 623 | }); | 621 | }); |
| 624 | 622 | ||
| 625 | // SPIv3 clears rxfifo on SPE=0 | 623 | // SPIv3 clears rxfifo on SPE=0 |
| 626 | #[cfg(not(any(spi_v3, spi_v4, spi_v5)))] | 624 | #[cfg(not(any(spi_v3, spi_v4, spi_v5)))] |
| 627 | flush_rx_fifo(self.regs); | 625 | flush_rx_fifo(self.info.regs); |
| 628 | 626 | ||
| 629 | set_rxdmaen(self.regs, true); | 627 | set_rxdmaen(self.info.regs, true); |
| 630 | 628 | ||
| 631 | let clock_byte_count = data.len(); | 629 | let clock_byte_count = data.len(); |
| 632 | 630 | ||
| 633 | let rx_src = self.regs.rx_ptr(); | 631 | let rx_src = self.info.regs.rx_ptr(); |
| 634 | let rx_f = unsafe { self.rx_dma.as_mut().unwrap().read(rx_src, data, Default::default()) }; | 632 | let rx_f = unsafe { self.rx_dma.as_mut().unwrap().read(rx_src, data, Default::default()) }; |
| 635 | 633 | ||
| 636 | let tx_dst = self.regs.tx_ptr(); | 634 | let tx_dst = self.info.regs.tx_ptr(); |
| 637 | let clock_byte = 0x00u8; | 635 | let clock_byte = 0x00u8; |
| 638 | let tx_f = unsafe { | 636 | let tx_f = unsafe { |
| 639 | self.tx_dma | 637 | self.tx_dma |
| @@ -642,18 +640,18 @@ impl<'d> Spi<'d, Async> { | |||
| 642 | .write_repeated(&clock_byte, clock_byte_count, tx_dst, Default::default()) | 640 | .write_repeated(&clock_byte, clock_byte_count, tx_dst, Default::default()) |
| 643 | }; | 641 | }; |
| 644 | 642 | ||
| 645 | set_txdmaen(self.regs, true); | 643 | set_txdmaen(self.info.regs, true); |
| 646 | self.regs.cr1().modify(|w| { | 644 | self.info.regs.cr1().modify(|w| { |
| 647 | w.set_spe(true); | 645 | w.set_spe(true); |
| 648 | }); | 646 | }); |
| 649 | #[cfg(any(spi_v3, spi_v4, spi_v5))] | 647 | #[cfg(any(spi_v3, spi_v4, spi_v5))] |
| 650 | self.regs.cr1().modify(|w| { | 648 | self.info.regs.cr1().modify(|w| { |
| 651 | w.set_cstart(true); | 649 | w.set_cstart(true); |
| 652 | }); | 650 | }); |
| 653 | 651 | ||
| 654 | join(tx_f, rx_f).await; | 652 | join(tx_f, rx_f).await; |
| 655 | 653 | ||
| 656 | finish_dma(self.regs); | 654 | finish_dma(self.info.regs); |
| 657 | 655 | ||
| 658 | Ok(()) | 656 | Ok(()) |
| 659 | } | 657 | } |
| @@ -667,20 +665,20 @@ impl<'d> Spi<'d, Async> { | |||
| 667 | } | 665 | } |
| 668 | 666 | ||
| 669 | self.set_word_size(W::CONFIG); | 667 | self.set_word_size(W::CONFIG); |
| 670 | self.regs.cr1().modify(|w| { | 668 | self.info.regs.cr1().modify(|w| { |
| 671 | w.set_spe(false); | 669 | w.set_spe(false); |
| 672 | }); | 670 | }); |
| 673 | 671 | ||
| 674 | // SPIv3 clears rxfifo on SPE=0 | 672 | // SPIv3 clears rxfifo on SPE=0 |
| 675 | #[cfg(not(any(spi_v3, spi_v4, spi_v5)))] | 673 | #[cfg(not(any(spi_v3, spi_v4, spi_v5)))] |
| 676 | flush_rx_fifo(self.regs); | 674 | flush_rx_fifo(self.info.regs); |
| 677 | 675 | ||
| 678 | set_rxdmaen(self.regs, true); | 676 | set_rxdmaen(self.info.regs, true); |
| 679 | 677 | ||
| 680 | let rx_src = self.regs.rx_ptr(); | 678 | let rx_src = self.info.regs.rx_ptr(); |
| 681 | let rx_f = unsafe { self.rx_dma.as_mut().unwrap().read_raw(rx_src, read, Default::default()) }; | 679 | let rx_f = unsafe { self.rx_dma.as_mut().unwrap().read_raw(rx_src, read, Default::default()) }; |
| 682 | 680 | ||
| 683 | let tx_dst = self.regs.tx_ptr(); | 681 | let tx_dst = self.info.regs.tx_ptr(); |
| 684 | let tx_f = unsafe { | 682 | let tx_f = unsafe { |
| 685 | self.tx_dma | 683 | self.tx_dma |
| 686 | .as_mut() | 684 | .as_mut() |
| @@ -688,18 +686,18 @@ impl<'d> Spi<'d, Async> { | |||
| 688 | .write_raw(write, tx_dst, Default::default()) | 686 | .write_raw(write, tx_dst, Default::default()) |
| 689 | }; | 687 | }; |
| 690 | 688 | ||
| 691 | set_txdmaen(self.regs, true); | 689 | set_txdmaen(self.info.regs, true); |
| 692 | self.regs.cr1().modify(|w| { | 690 | self.info.regs.cr1().modify(|w| { |
| 693 | w.set_spe(true); | 691 | w.set_spe(true); |
| 694 | }); | 692 | }); |
| 695 | #[cfg(any(spi_v3, spi_v4, spi_v5))] | 693 | #[cfg(any(spi_v3, spi_v4, spi_v5))] |
| 696 | self.regs.cr1().modify(|w| { | 694 | self.info.regs.cr1().modify(|w| { |
| 697 | w.set_cstart(true); | 695 | w.set_cstart(true); |
| 698 | }); | 696 | }); |
| 699 | 697 | ||
| 700 | join(tx_f, rx_f).await; | 698 | join(tx_f, rx_f).await; |
| 701 | 699 | ||
| 702 | finish_dma(self.regs); | 700 | finish_dma(self.info.regs); |
| 703 | 701 | ||
| 704 | Ok(()) | 702 | Ok(()) |
| 705 | } | 703 | } |
| @@ -728,7 +726,7 @@ impl<'d, M: PeriMode> Drop for Spi<'d, M> { | |||
| 728 | self.mosi.as_ref().map(|x| x.set_as_disconnected()); | 726 | self.mosi.as_ref().map(|x| x.set_as_disconnected()); |
| 729 | self.miso.as_ref().map(|x| x.set_as_disconnected()); | 727 | self.miso.as_ref().map(|x| x.set_as_disconnected()); |
| 730 | 728 | ||
| 731 | self.enable_bit.disable(); | 729 | self.info.enable_bit.disable(); |
| 732 | } | 730 | } |
| 733 | } | 731 | } |
| 734 | 732 | ||
| @@ -1106,8 +1104,9 @@ mod word_impl { | |||
| 1106 | impl_word!(u32, 32 - 1); | 1104 | impl_word!(u32, 32 - 1); |
| 1107 | } | 1105 | } |
| 1108 | 1106 | ||
| 1109 | struct Info { | 1107 | pub(crate) struct Info { |
| 1110 | regs: Regs, | 1108 | pub(crate) regs: Regs, |
| 1109 | pub(crate) enable_bit: ClockEnableBit, | ||
| 1111 | } | 1110 | } |
| 1112 | 1111 | ||
| 1113 | struct State {} | 1112 | struct State {} |
| @@ -1134,6 +1133,7 @@ foreach_peripheral!( | |||
| 1134 | (spi, $inst:ident) => { | 1133 | (spi, $inst:ident) => { |
| 1135 | peri_trait_impl!($inst, Info { | 1134 | peri_trait_impl!($inst, Info { |
| 1136 | regs: crate::pac::$inst, | 1135 | regs: crate::pac::$inst, |
| 1136 | enable_bit: crate::peripherals::$inst::ENABLE_BIT, | ||
| 1137 | }); | 1137 | }); |
| 1138 | }; | 1138 | }; |
| 1139 | ); | 1139 | ); |
