diff options
| author | Dario Nieuwenhuis <[email protected]> | 2024-04-18 19:08:24 +0200 |
|---|---|---|
| committer | Dario Nieuwenhuis <[email protected]> | 2024-05-20 23:43:10 +0200 |
| commit | ca2eef5387b521a0ea95f26bae530d9bdfbba4d7 (patch) | |
| tree | e593f3d75210fdb159b216496983dddd6def7154 /embassy-stm32/src | |
| parent | eeb6ffce4cfa0e0055da8d6738f6d28c3fa43f15 (diff) | |
stm32/spi: remove peripheral generic param.
Diffstat (limited to 'embassy-stm32/src')
| -rw-r--r-- | embassy-stm32/src/i2s.rs | 14 | ||||
| -rw-r--r-- | embassy-stm32/src/macros.rs | 25 | ||||
| -rw-r--r-- | embassy-stm32/src/spi/mod.rs | 237 |
3 files changed, 152 insertions, 124 deletions
diff --git a/embassy-stm32/src/i2s.rs b/embassy-stm32/src/i2s.rs index 9b80dc1d0..c102c0035 100644 --- a/embassy-stm32/src/i2s.rs +++ b/embassy-stm32/src/i2s.rs | |||
| @@ -153,17 +153,17 @@ impl Default for Config { | |||
| 153 | } | 153 | } |
| 154 | 154 | ||
| 155 | /// I2S driver. | 155 | /// I2S driver. |
| 156 | pub struct I2S<'d, T: Instance> { | 156 | pub struct I2S<'d> { |
| 157 | _peri: Spi<'d, T, Async>, | 157 | _peri: Spi<'d, Async>, |
| 158 | sd: Option<PeripheralRef<'d, AnyPin>>, | 158 | sd: Option<PeripheralRef<'d, AnyPin>>, |
| 159 | ws: Option<PeripheralRef<'d, AnyPin>>, | 159 | ws: Option<PeripheralRef<'d, AnyPin>>, |
| 160 | ck: Option<PeripheralRef<'d, AnyPin>>, | 160 | ck: Option<PeripheralRef<'d, AnyPin>>, |
| 161 | mck: Option<PeripheralRef<'d, AnyPin>>, | 161 | mck: Option<PeripheralRef<'d, AnyPin>>, |
| 162 | } | 162 | } |
| 163 | 163 | ||
| 164 | impl<'d, T: Instance> I2S<'d, T> { | 164 | impl<'d> I2S<'d> { |
| 165 | /// Note: Full-Duplex modes are not supported at this time | 165 | /// Note: Full-Duplex modes are not supported at this time |
| 166 | pub fn new( | 166 | pub fn new<T: Instance>( |
| 167 | peri: impl Peripheral<P = T> + 'd, | 167 | peri: impl Peripheral<P = T> + 'd, |
| 168 | sd: impl Peripheral<P = impl MosiPin<T>> + 'd, | 168 | sd: impl Peripheral<P = impl MosiPin<T>> + 'd, |
| 169 | ws: impl Peripheral<P = impl WsPin<T>> + 'd, | 169 | ws: impl Peripheral<P = impl WsPin<T>> + 'd, |
| @@ -208,7 +208,7 @@ impl<'d, T: Instance> I2S<'d, T> { | |||
| 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 | T::REGS.i2spr().modify(|w| { | 211 | spi.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, T: Instance> I2S<'d, T> { | |||
| 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 | T::REGS.i2scfgr().modify(|w| { | 238 | spi.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); |
| @@ -276,7 +276,7 @@ impl<'d, T: Instance> I2S<'d, T> { | |||
| 276 | } | 276 | } |
| 277 | } | 277 | } |
| 278 | 278 | ||
| 279 | impl<'d, T: Instance> Drop for I2S<'d, T> { | 279 | impl<'d> Drop for I2S<'d> { |
| 280 | fn drop(&mut self) { | 280 | fn drop(&mut self) { |
| 281 | self.sd.as_ref().map(|x| x.set_as_disconnected()); | 281 | self.sd.as_ref().map(|x| x.set_as_disconnected()); |
| 282 | self.ws.as_ref().map(|x| x.set_as_disconnected()); | 282 | self.ws.as_ref().map(|x| x.set_as_disconnected()); |
diff --git a/embassy-stm32/src/macros.rs b/embassy-stm32/src/macros.rs index 02dce1266..9c459a932 100644 --- a/embassy-stm32/src/macros.rs +++ b/embassy-stm32/src/macros.rs | |||
| @@ -1,5 +1,30 @@ | |||
| 1 | #![macro_use] | 1 | #![macro_use] |
| 2 | 2 | ||
| 3 | macro_rules! peri_trait { | ||
| 4 | () => { | ||
| 5 | #[allow(private_interfaces)] | ||
| 6 | pub(crate) trait SealedInstance { | ||
| 7 | const INFO: Info; | ||
| 8 | const STATE: &'static State; | ||
| 9 | } | ||
| 10 | |||
| 11 | /// SPI instance trait. | ||
| 12 | #[allow(private_bounds)] | ||
| 13 | pub trait Instance: Peripheral<P = Self> + SealedInstance + RccPeripheral {} | ||
| 14 | }; | ||
| 15 | } | ||
| 16 | |||
| 17 | macro_rules! peri_trait_impl { | ||
| 18 | ($instance:ident, $info:expr) => { | ||
| 19 | #[allow(private_interfaces)] | ||
| 20 | impl SealedInstance for crate::peripherals::$instance { | ||
| 21 | const INFO: Info = $info; | ||
| 22 | const STATE: &'static State = &State::new(); | ||
| 23 | } | ||
| 24 | impl Instance for crate::peripherals::$instance {} | ||
| 25 | }; | ||
| 26 | } | ||
| 27 | |||
| 3 | macro_rules! pin_trait { | 28 | macro_rules! pin_trait { |
| 4 | ($signal:ident, $instance:path $(, $mode:path)?) => { | 29 | ($signal:ident, $instance:path $(, $mode:path)?) => { |
| 5 | #[doc = concat!(stringify!($signal), " pin trait")] | 30 | #[doc = concat!(stringify!($signal), " pin trait")] |
diff --git a/embassy-stm32/src/spi/mod.rs b/embassy-stm32/src/spi/mod.rs index c39ef1913..5a2ee105d 100644 --- a/embassy-stm32/src/spi/mod.rs +++ b/embassy-stm32/src/spi/mod.rs | |||
| @@ -6,16 +6,16 @@ use core::ptr; | |||
| 6 | 6 | ||
| 7 | use embassy_embedded_hal::SetConfig; | 7 | use embassy_embedded_hal::SetConfig; |
| 8 | use embassy_futures::join::join; | 8 | use embassy_futures::join::join; |
| 9 | use embassy_hal_internal::{into_ref, PeripheralRef}; | 9 | use embassy_hal_internal::PeripheralRef; |
| 10 | pub use embedded_hal_02::spi::{Mode, Phase, Polarity, MODE_0, MODE_1, MODE_2, MODE_3}; | 10 | pub use embedded_hal_02::spi::{Mode, Phase, Polarity, MODE_0, MODE_1, MODE_2, MODE_3}; |
| 11 | 11 | ||
| 12 | use crate::dma::{slice_ptr_parts, word, ChannelAndRequest}; | 12 | 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::RccPeripheral; | 16 | use crate::rcc::{ClockEnableBit, RccPeripheral}; |
| 17 | use crate::time::Hertz; | 17 | use crate::time::Hertz; |
| 18 | use crate::{peripherals, Peripheral}; | 18 | use crate::Peripheral; |
| 19 | 19 | ||
| 20 | /// SPI error. | 20 | /// SPI error. |
| 21 | #[derive(Debug, PartialEq, Eq)] | 21 | #[derive(Debug, PartialEq, Eq)] |
| @@ -92,8 +92,10 @@ impl Config { | |||
| 92 | } | 92 | } |
| 93 | } | 93 | } |
| 94 | /// SPI driver. | 94 | /// SPI driver. |
| 95 | pub struct Spi<'d, T: Instance, M: PeriMode> { | 95 | pub struct Spi<'d, M: PeriMode> { |
| 96 | _peri: PeripheralRef<'d, T>, | 96 | pub(crate) regs: Regs, |
| 97 | enable_bit: ClockEnableBit, | ||
| 98 | kernel_clock: Hertz, | ||
| 97 | sck: Option<PeripheralRef<'d, AnyPin>>, | 99 | sck: Option<PeripheralRef<'d, AnyPin>>, |
| 98 | mosi: Option<PeripheralRef<'d, AnyPin>>, | 100 | mosi: Option<PeripheralRef<'d, AnyPin>>, |
| 99 | miso: Option<PeripheralRef<'d, AnyPin>>, | 101 | miso: Option<PeripheralRef<'d, AnyPin>>, |
| @@ -103,9 +105,9 @@ pub struct Spi<'d, T: Instance, M: PeriMode> { | |||
| 103 | current_word_size: word_impl::Config, | 105 | current_word_size: word_impl::Config, |
| 104 | } | 106 | } |
| 105 | 107 | ||
| 106 | impl<'d, T: Instance, M: PeriMode> Spi<'d, T, M> { | 108 | impl<'d, M: PeriMode> Spi<'d, M> { |
| 107 | fn new_inner( | 109 | fn new_inner<T: Instance>( |
| 108 | peri: impl Peripheral<P = T> + 'd, | 110 | _peri: impl Peripheral<P = T> + 'd, |
| 109 | sck: Option<PeripheralRef<'d, AnyPin>>, | 111 | sck: Option<PeripheralRef<'d, AnyPin>>, |
| 110 | mosi: Option<PeripheralRef<'d, AnyPin>>, | 112 | mosi: Option<PeripheralRef<'d, AnyPin>>, |
| 111 | miso: Option<PeripheralRef<'d, AnyPin>>, | 113 | miso: Option<PeripheralRef<'d, AnyPin>>, |
| @@ -113,11 +115,9 @@ impl<'d, T: Instance, M: PeriMode> Spi<'d, T, M> { | |||
| 113 | rx_dma: Option<ChannelAndRequest<'d>>, | 115 | rx_dma: Option<ChannelAndRequest<'d>>, |
| 114 | config: Config, | 116 | config: Config, |
| 115 | ) -> Self { | 117 | ) -> Self { |
| 116 | into_ref!(peri); | 118 | let regs = T::INFO.regs; |
| 117 | 119 | let kernel_clock = T::frequency(); | |
| 118 | let pclk = T::frequency(); | 120 | let br = compute_baud_rate(kernel_clock, config.frequency); |
| 119 | let freq = config.frequency; | ||
| 120 | let br = compute_baud_rate(pclk, freq); | ||
| 121 | 121 | ||
| 122 | let cpha = config.raw_phase(); | 122 | let cpha = config.raw_phase(); |
| 123 | let cpol = config.raw_polarity(); | 123 | let cpol = config.raw_polarity(); |
| @@ -128,10 +128,10 @@ impl<'d, T: Instance, M: PeriMode> Spi<'d, T, M> { | |||
| 128 | 128 | ||
| 129 | #[cfg(any(spi_v1, spi_f1))] | 129 | #[cfg(any(spi_v1, spi_f1))] |
| 130 | { | 130 | { |
| 131 | T::REGS.cr2().modify(|w| { | 131 | regs.cr2().modify(|w| { |
| 132 | w.set_ssoe(false); | 132 | w.set_ssoe(false); |
| 133 | }); | 133 | }); |
| 134 | T::REGS.cr1().modify(|w| { | 134 | regs.cr1().modify(|w| { |
| 135 | w.set_cpha(cpha); | 135 | w.set_cpha(cpha); |
| 136 | w.set_cpol(cpol); | 136 | w.set_cpol(cpol); |
| 137 | 137 | ||
| @@ -151,13 +151,13 @@ impl<'d, T: Instance, M: PeriMode> Spi<'d, T, M> { | |||
| 151 | } | 151 | } |
| 152 | #[cfg(spi_v2)] | 152 | #[cfg(spi_v2)] |
| 153 | { | 153 | { |
| 154 | T::REGS.cr2().modify(|w| { | 154 | regs.cr2().modify(|w| { |
| 155 | let (ds, frxth) = <u8 as SealedWord>::CONFIG; | 155 | let (ds, frxth) = <u8 as SealedWord>::CONFIG; |
| 156 | w.set_frxth(frxth); | 156 | w.set_frxth(frxth); |
| 157 | w.set_ds(ds); | 157 | w.set_ds(ds); |
| 158 | w.set_ssoe(false); | 158 | w.set_ssoe(false); |
| 159 | }); | 159 | }); |
| 160 | T::REGS.cr1().modify(|w| { | 160 | regs.cr1().modify(|w| { |
| 161 | w.set_cpha(cpha); | 161 | w.set_cpha(cpha); |
| 162 | w.set_cpol(cpol); | 162 | w.set_cpol(cpol); |
| 163 | 163 | ||
| @@ -173,8 +173,8 @@ impl<'d, T: Instance, M: PeriMode> Spi<'d, T, M> { | |||
| 173 | } | 173 | } |
| 174 | #[cfg(any(spi_v3, spi_v4, spi_v5))] | 174 | #[cfg(any(spi_v3, spi_v4, spi_v5))] |
| 175 | { | 175 | { |
| 176 | T::REGS.ifcr().write(|w| w.0 = 0xffff_ffff); | 176 | regs.ifcr().write(|w| w.0 = 0xffff_ffff); |
| 177 | T::REGS.cfg2().modify(|w| { | 177 | regs.cfg2().modify(|w| { |
| 178 | //w.set_ssoe(true); | 178 | //w.set_ssoe(true); |
| 179 | w.set_ssoe(false); | 179 | w.set_ssoe(false); |
| 180 | w.set_cpha(cpha); | 180 | w.set_cpha(cpha); |
| @@ -189,23 +189,25 @@ impl<'d, T: Instance, M: PeriMode> Spi<'d, T, M> { | |||
| 189 | w.set_afcntr(true); | 189 | w.set_afcntr(true); |
| 190 | w.set_ssiop(vals::Ssiop::ACTIVEHIGH); | 190 | w.set_ssiop(vals::Ssiop::ACTIVEHIGH); |
| 191 | }); | 191 | }); |
| 192 | T::REGS.cfg1().modify(|w| { | 192 | regs.cfg1().modify(|w| { |
| 193 | w.set_crcen(false); | 193 | w.set_crcen(false); |
| 194 | w.set_mbr(br); | 194 | w.set_mbr(br); |
| 195 | w.set_dsize(<u8 as SealedWord>::CONFIG); | 195 | w.set_dsize(<u8 as SealedWord>::CONFIG); |
| 196 | w.set_fthlv(vals::Fthlv::ONEFRAME); | 196 | w.set_fthlv(vals::Fthlv::ONEFRAME); |
| 197 | }); | 197 | }); |
| 198 | T::REGS.cr2().modify(|w| { | 198 | regs.cr2().modify(|w| { |
| 199 | w.set_tsize(0); | 199 | w.set_tsize(0); |
| 200 | }); | 200 | }); |
| 201 | T::REGS.cr1().modify(|w| { | 201 | regs.cr1().modify(|w| { |
| 202 | w.set_ssi(false); | 202 | w.set_ssi(false); |
| 203 | w.set_spe(true); | 203 | w.set_spe(true); |
| 204 | }); | 204 | }); |
| 205 | } | 205 | } |
| 206 | 206 | ||
| 207 | Self { | 207 | Self { |
| 208 | _peri: peri, | 208 | regs, |
| 209 | enable_bit: T::enable_bit(), | ||
| 210 | kernel_clock, | ||
| 209 | sck, | 211 | sck, |
| 210 | mosi, | 212 | mosi, |
| 211 | miso, | 213 | miso, |
| @@ -223,12 +225,10 @@ impl<'d, T: Instance, M: PeriMode> Spi<'d, T, M> { | |||
| 223 | 225 | ||
| 224 | let lsbfirst = config.raw_byte_order(); | 226 | let lsbfirst = config.raw_byte_order(); |
| 225 | 227 | ||
| 226 | let pclk = T::frequency(); | 228 | let br = compute_baud_rate(self.kernel_clock, config.frequency); |
| 227 | let freq = config.frequency; | ||
| 228 | let br = compute_baud_rate(pclk, freq); | ||
| 229 | 229 | ||
| 230 | #[cfg(any(spi_v1, spi_f1, spi_v2))] | 230 | #[cfg(any(spi_v1, spi_f1, spi_v2))] |
| 231 | T::REGS.cr1().modify(|w| { | 231 | self.regs.cr1().modify(|w| { |
| 232 | w.set_cpha(cpha); | 232 | w.set_cpha(cpha); |
| 233 | w.set_cpol(cpol); | 233 | w.set_cpol(cpol); |
| 234 | w.set_br(br); | 234 | w.set_br(br); |
| @@ -237,12 +237,12 @@ impl<'d, T: Instance, M: PeriMode> Spi<'d, T, M> { | |||
| 237 | 237 | ||
| 238 | #[cfg(any(spi_v3, spi_v4, spi_v5))] | 238 | #[cfg(any(spi_v3, spi_v4, spi_v5))] |
| 239 | { | 239 | { |
| 240 | T::REGS.cfg2().modify(|w| { | 240 | self.regs.cfg2().modify(|w| { |
| 241 | w.set_cpha(cpha); | 241 | w.set_cpha(cpha); |
| 242 | w.set_cpol(cpol); | 242 | w.set_cpol(cpol); |
| 243 | w.set_lsbfirst(lsbfirst); | 243 | w.set_lsbfirst(lsbfirst); |
| 244 | }); | 244 | }); |
| 245 | T::REGS.cfg1().modify(|w| { | 245 | self.regs.cfg1().modify(|w| { |
| 246 | w.set_mbr(br); | 246 | w.set_mbr(br); |
| 247 | }); | 247 | }); |
| 248 | } | 248 | } |
| @@ -252,11 +252,11 @@ impl<'d, T: Instance, M: PeriMode> Spi<'d, T, M> { | |||
| 252 | /// Get current SPI configuration. | 252 | /// Get current SPI configuration. |
| 253 | pub fn get_current_config(&self) -> Config { | 253 | pub fn get_current_config(&self) -> Config { |
| 254 | #[cfg(any(spi_v1, spi_f1, spi_v2))] | 254 | #[cfg(any(spi_v1, spi_f1, spi_v2))] |
| 255 | let cfg = T::REGS.cr1().read(); | 255 | let cfg = self.regs.cr1().read(); |
| 256 | #[cfg(any(spi_v3, spi_v4, spi_v5))] | 256 | #[cfg(any(spi_v3, spi_v4, spi_v5))] |
| 257 | let cfg = T::REGS.cfg2().read(); | 257 | let cfg = self.regs.cfg2().read(); |
| 258 | #[cfg(any(spi_v3, spi_v4, spi_v5))] | 258 | #[cfg(any(spi_v3, spi_v4, spi_v5))] |
| 259 | let cfg1 = T::REGS.cfg1().read(); | 259 | let cfg1 = self.regs.cfg1().read(); |
| 260 | 260 | ||
| 261 | let polarity = if cfg.cpol() == vals::Cpol::IDLELOW { | 261 | let polarity = if cfg.cpol() == vals::Cpol::IDLELOW { |
| 262 | Polarity::IdleLow | 262 | Polarity::IdleLow |
| @@ -280,8 +280,7 @@ impl<'d, T: Instance, M: PeriMode> Spi<'d, T, M> { | |||
| 280 | #[cfg(any(spi_v3, spi_v4, spi_v5))] | 280 | #[cfg(any(spi_v3, spi_v4, spi_v5))] |
| 281 | let br = cfg1.mbr(); | 281 | let br = cfg1.mbr(); |
| 282 | 282 | ||
| 283 | let pclk = T::frequency(); | 283 | let frequency = compute_frequency(self.kernel_clock, br); |
| 284 | let frequency = compute_frequency(pclk, br); | ||
| 285 | 284 | ||
| 286 | Config { | 285 | Config { |
| 287 | mode: Mode { polarity, phase }, | 286 | mode: Mode { polarity, phase }, |
| @@ -297,40 +296,40 @@ impl<'d, T: Instance, M: PeriMode> Spi<'d, T, M> { | |||
| 297 | 296 | ||
| 298 | #[cfg(any(spi_v1, spi_f1))] | 297 | #[cfg(any(spi_v1, spi_f1))] |
| 299 | { | 298 | { |
| 300 | T::REGS.cr1().modify(|reg| { | 299 | self.regs.cr1().modify(|reg| { |
| 301 | reg.set_spe(false); | 300 | reg.set_spe(false); |
| 302 | reg.set_dff(word_size) | 301 | reg.set_dff(word_size) |
| 303 | }); | 302 | }); |
| 304 | T::REGS.cr1().modify(|reg| { | 303 | self.regs.cr1().modify(|reg| { |
| 305 | reg.set_spe(true); | 304 | reg.set_spe(true); |
| 306 | }); | 305 | }); |
| 307 | } | 306 | } |
| 308 | #[cfg(spi_v2)] | 307 | #[cfg(spi_v2)] |
| 309 | { | 308 | { |
| 310 | T::REGS.cr1().modify(|w| { | 309 | self.regs.cr1().modify(|w| { |
| 311 | w.set_spe(false); | 310 | w.set_spe(false); |
| 312 | }); | 311 | }); |
| 313 | T::REGS.cr2().modify(|w| { | 312 | self.regs.cr2().modify(|w| { |
| 314 | w.set_frxth(word_size.1); | 313 | w.set_frxth(word_size.1); |
| 315 | w.set_ds(word_size.0); | 314 | w.set_ds(word_size.0); |
| 316 | }); | 315 | }); |
| 317 | T::REGS.cr1().modify(|w| { | 316 | self.regs.cr1().modify(|w| { |
| 318 | w.set_spe(true); | 317 | w.set_spe(true); |
| 319 | }); | 318 | }); |
| 320 | } | 319 | } |
| 321 | #[cfg(any(spi_v3, spi_v4, spi_v5))] | 320 | #[cfg(any(spi_v3, spi_v4, spi_v5))] |
| 322 | { | 321 | { |
| 323 | T::REGS.cr1().modify(|w| { | 322 | self.regs.cr1().modify(|w| { |
| 324 | w.set_csusp(true); | 323 | w.set_csusp(true); |
| 325 | }); | 324 | }); |
| 326 | while T::REGS.sr().read().eot() {} | 325 | while self.regs.sr().read().eot() {} |
| 327 | T::REGS.cr1().modify(|w| { | 326 | self.regs.cr1().modify(|w| { |
| 328 | w.set_spe(false); | 327 | w.set_spe(false); |
| 329 | }); | 328 | }); |
| 330 | T::REGS.cfg1().modify(|w| { | 329 | self.regs.cfg1().modify(|w| { |
| 331 | w.set_dsize(word_size); | 330 | w.set_dsize(word_size); |
| 332 | }); | 331 | }); |
| 333 | T::REGS.cr1().modify(|w| { | 332 | self.regs.cr1().modify(|w| { |
| 334 | w.set_csusp(false); | 333 | w.set_csusp(false); |
| 335 | w.set_spe(true); | 334 | w.set_spe(true); |
| 336 | }); | 335 | }); |
| @@ -341,22 +340,22 @@ impl<'d, T: Instance, M: PeriMode> Spi<'d, T, M> { | |||
| 341 | 340 | ||
| 342 | /// Blocking write. | 341 | /// Blocking write. |
| 343 | pub fn blocking_write<W: Word>(&mut self, words: &[W]) -> Result<(), Error> { | 342 | pub fn blocking_write<W: Word>(&mut self, words: &[W]) -> Result<(), Error> { |
| 344 | T::REGS.cr1().modify(|w| w.set_spe(true)); | 343 | self.regs.cr1().modify(|w| w.set_spe(true)); |
| 345 | flush_rx_fifo(T::REGS); | 344 | flush_rx_fifo(self.regs); |
| 346 | self.set_word_size(W::CONFIG); | 345 | self.set_word_size(W::CONFIG); |
| 347 | for word in words.iter() { | 346 | for word in words.iter() { |
| 348 | let _ = transfer_word(T::REGS, *word)?; | 347 | let _ = transfer_word(self.regs, *word)?; |
| 349 | } | 348 | } |
| 350 | Ok(()) | 349 | Ok(()) |
| 351 | } | 350 | } |
| 352 | 351 | ||
| 353 | /// Blocking read. | 352 | /// Blocking read. |
| 354 | pub fn blocking_read<W: Word>(&mut self, words: &mut [W]) -> Result<(), Error> { | 353 | pub fn blocking_read<W: Word>(&mut self, words: &mut [W]) -> Result<(), Error> { |
| 355 | T::REGS.cr1().modify(|w| w.set_spe(true)); | 354 | self.regs.cr1().modify(|w| w.set_spe(true)); |
| 356 | flush_rx_fifo(T::REGS); | 355 | flush_rx_fifo(self.regs); |
| 357 | self.set_word_size(W::CONFIG); | 356 | self.set_word_size(W::CONFIG); |
| 358 | for word in words.iter_mut() { | 357 | for word in words.iter_mut() { |
| 359 | *word = transfer_word(T::REGS, W::default())?; | 358 | *word = transfer_word(self.regs, W::default())?; |
| 360 | } | 359 | } |
| 361 | Ok(()) | 360 | Ok(()) |
| 362 | } | 361 | } |
| @@ -365,11 +364,11 @@ impl<'d, T: Instance, M: PeriMode> Spi<'d, T, M> { | |||
| 365 | /// | 364 | /// |
| 366 | /// This writes the contents of `data` on MOSI, and puts the received data on MISO in `data`, at the same time. | 365 | /// This writes the contents of `data` on MOSI, and puts the received data on MISO in `data`, at the same time. |
| 367 | pub fn blocking_transfer_in_place<W: Word>(&mut self, words: &mut [W]) -> Result<(), Error> { | 366 | pub fn blocking_transfer_in_place<W: Word>(&mut self, words: &mut [W]) -> Result<(), Error> { |
| 368 | T::REGS.cr1().modify(|w| w.set_spe(true)); | 367 | self.regs.cr1().modify(|w| w.set_spe(true)); |
| 369 | flush_rx_fifo(T::REGS); | 368 | flush_rx_fifo(self.regs); |
| 370 | self.set_word_size(W::CONFIG); | 369 | self.set_word_size(W::CONFIG); |
| 371 | for word in words.iter_mut() { | 370 | for word in words.iter_mut() { |
| 372 | *word = transfer_word(T::REGS, *word)?; | 371 | *word = transfer_word(self.regs, *word)?; |
| 373 | } | 372 | } |
| 374 | Ok(()) | 373 | Ok(()) |
| 375 | } | 374 | } |
| @@ -381,13 +380,13 @@ impl<'d, T: Instance, M: PeriMode> Spi<'d, T, M> { | |||
| 381 | /// The transfer runs for `max(read.len(), write.len())` bytes. If `read` is shorter extra bytes are ignored. | 380 | /// The transfer runs for `max(read.len(), write.len())` bytes. If `read` is shorter extra bytes are ignored. |
| 382 | /// If `write` is shorter it is padded with zero bytes. | 381 | /// If `write` is shorter it is padded with zero bytes. |
| 383 | pub fn blocking_transfer<W: Word>(&mut self, read: &mut [W], write: &[W]) -> Result<(), Error> { | 382 | pub fn blocking_transfer<W: Word>(&mut self, read: &mut [W], write: &[W]) -> Result<(), Error> { |
| 384 | T::REGS.cr1().modify(|w| w.set_spe(true)); | 383 | self.regs.cr1().modify(|w| w.set_spe(true)); |
| 385 | flush_rx_fifo(T::REGS); | 384 | flush_rx_fifo(self.regs); |
| 386 | self.set_word_size(W::CONFIG); | 385 | self.set_word_size(W::CONFIG); |
| 387 | let len = read.len().max(write.len()); | 386 | let len = read.len().max(write.len()); |
| 388 | for i in 0..len { | 387 | for i in 0..len { |
| 389 | let wb = write.get(i).copied().unwrap_or_default(); | 388 | let wb = write.get(i).copied().unwrap_or_default(); |
| 390 | let rb = transfer_word(T::REGS, wb)?; | 389 | let rb = transfer_word(self.regs, wb)?; |
| 391 | if let Some(r) = read.get_mut(i) { | 390 | if let Some(r) = read.get_mut(i) { |
| 392 | *r = rb; | 391 | *r = rb; |
| 393 | } | 392 | } |
| @@ -396,9 +395,9 @@ impl<'d, T: Instance, M: PeriMode> Spi<'d, T, M> { | |||
| 396 | } | 395 | } |
| 397 | } | 396 | } |
| 398 | 397 | ||
| 399 | impl<'d, T: Instance> Spi<'d, T, Blocking> { | 398 | impl<'d> Spi<'d, Blocking> { |
| 400 | /// Create a new blocking SPI driver. | 399 | /// Create a new blocking SPI driver. |
| 401 | pub fn new_blocking( | 400 | pub fn new_blocking<T: Instance>( |
| 402 | peri: impl Peripheral<P = T> + 'd, | 401 | peri: impl Peripheral<P = T> + 'd, |
| 403 | sck: impl Peripheral<P = impl SckPin<T>> + 'd, | 402 | sck: impl Peripheral<P = impl SckPin<T>> + 'd, |
| 404 | mosi: impl Peripheral<P = impl MosiPin<T>> + 'd, | 403 | mosi: impl Peripheral<P = impl MosiPin<T>> + 'd, |
| @@ -417,7 +416,7 @@ impl<'d, T: Instance> Spi<'d, T, Blocking> { | |||
| 417 | } | 416 | } |
| 418 | 417 | ||
| 419 | /// Create a new blocking SPI driver, in RX-only mode (only MISO pin, no MOSI). | 418 | /// Create a new blocking SPI driver, in RX-only mode (only MISO pin, no MOSI). |
| 420 | pub fn new_blocking_rxonly( | 419 | pub fn new_blocking_rxonly<T: Instance>( |
| 421 | peri: impl Peripheral<P = T> + 'd, | 420 | peri: impl Peripheral<P = T> + 'd, |
| 422 | sck: impl Peripheral<P = impl SckPin<T>> + 'd, | 421 | sck: impl Peripheral<P = impl SckPin<T>> + 'd, |
| 423 | miso: impl Peripheral<P = impl MisoPin<T>> + 'd, | 422 | miso: impl Peripheral<P = impl MisoPin<T>> + 'd, |
| @@ -435,7 +434,7 @@ impl<'d, T: Instance> Spi<'d, T, Blocking> { | |||
| 435 | } | 434 | } |
| 436 | 435 | ||
| 437 | /// Create a new blocking SPI driver, in TX-only mode (only MOSI pin, no MISO). | 436 | /// Create a new blocking SPI driver, in TX-only mode (only MOSI pin, no MISO). |
| 438 | pub fn new_blocking_txonly( | 437 | pub fn new_blocking_txonly<T: Instance>( |
| 439 | peri: impl Peripheral<P = T> + 'd, | 438 | peri: impl Peripheral<P = T> + 'd, |
| 440 | sck: impl Peripheral<P = impl SckPin<T>> + 'd, | 439 | sck: impl Peripheral<P = impl SckPin<T>> + 'd, |
| 441 | mosi: impl Peripheral<P = impl MosiPin<T>> + 'd, | 440 | mosi: impl Peripheral<P = impl MosiPin<T>> + 'd, |
| @@ -455,7 +454,7 @@ impl<'d, T: Instance> Spi<'d, T, Blocking> { | |||
| 455 | /// Create a new SPI driver, in TX-only mode, without SCK pin. | 454 | /// Create a new SPI driver, in TX-only mode, without SCK pin. |
| 456 | /// | 455 | /// |
| 457 | /// This can be useful for bit-banging non-SPI protocols. | 456 | /// This can be useful for bit-banging non-SPI protocols. |
| 458 | pub fn new_blocking_txonly_nosck( | 457 | pub fn new_blocking_txonly_nosck<T: Instance>( |
| 459 | peri: impl Peripheral<P = T> + 'd, | 458 | peri: impl Peripheral<P = T> + 'd, |
| 460 | mosi: impl Peripheral<P = impl MosiPin<T>> + 'd, | 459 | mosi: impl Peripheral<P = impl MosiPin<T>> + 'd, |
| 461 | config: Config, | 460 | config: Config, |
| @@ -472,9 +471,9 @@ impl<'d, T: Instance> Spi<'d, T, Blocking> { | |||
| 472 | } | 471 | } |
| 473 | } | 472 | } |
| 474 | 473 | ||
| 475 | impl<'d, T: Instance> Spi<'d, T, Async> { | 474 | impl<'d> Spi<'d, Async> { |
| 476 | /// Create a new SPI driver. | 475 | /// Create a new SPI driver. |
| 477 | pub fn new( | 476 | pub fn new<T: Instance>( |
| 478 | peri: impl Peripheral<P = T> + 'd, | 477 | peri: impl Peripheral<P = T> + 'd, |
| 479 | sck: impl Peripheral<P = impl SckPin<T>> + 'd, | 478 | sck: impl Peripheral<P = impl SckPin<T>> + 'd, |
| 480 | mosi: impl Peripheral<P = impl MosiPin<T>> + 'd, | 479 | mosi: impl Peripheral<P = impl MosiPin<T>> + 'd, |
| @@ -495,7 +494,7 @@ impl<'d, T: Instance> Spi<'d, T, Async> { | |||
| 495 | } | 494 | } |
| 496 | 495 | ||
| 497 | /// Create a new SPI driver, in RX-only mode (only MISO pin, no MOSI). | 496 | /// Create a new SPI driver, in RX-only mode (only MISO pin, no MOSI). |
| 498 | pub fn new_rxonly( | 497 | pub fn new_rxonly<T: Instance>( |
| 499 | peri: impl Peripheral<P = T> + 'd, | 498 | peri: impl Peripheral<P = T> + 'd, |
| 500 | sck: impl Peripheral<P = impl SckPin<T>> + 'd, | 499 | sck: impl Peripheral<P = impl SckPin<T>> + 'd, |
| 501 | miso: impl Peripheral<P = impl MisoPin<T>> + 'd, | 500 | miso: impl Peripheral<P = impl MisoPin<T>> + 'd, |
| @@ -514,7 +513,7 @@ impl<'d, T: Instance> Spi<'d, T, Async> { | |||
| 514 | } | 513 | } |
| 515 | 514 | ||
| 516 | /// Create a new SPI driver, in TX-only mode (only MOSI pin, no MISO). | 515 | /// Create a new SPI driver, in TX-only mode (only MOSI pin, no MISO). |
| 517 | pub fn new_txonly( | 516 | pub fn new_txonly<T: Instance>( |
| 518 | peri: impl Peripheral<P = T> + 'd, | 517 | peri: impl Peripheral<P = T> + 'd, |
| 519 | sck: impl Peripheral<P = impl SckPin<T>> + 'd, | 518 | sck: impl Peripheral<P = impl SckPin<T>> + 'd, |
| 520 | mosi: impl Peripheral<P = impl MosiPin<T>> + 'd, | 519 | mosi: impl Peripheral<P = impl MosiPin<T>> + 'd, |
| @@ -535,7 +534,7 @@ impl<'d, T: Instance> Spi<'d, T, Async> { | |||
| 535 | /// Create a new SPI driver, in TX-only mode, without SCK pin. | 534 | /// Create a new SPI driver, in TX-only mode, without SCK pin. |
| 536 | /// | 535 | /// |
| 537 | /// This can be useful for bit-banging non-SPI protocols. | 536 | /// This can be useful for bit-banging non-SPI protocols. |
| 538 | pub fn new_txonly_nosck( | 537 | pub fn new_txonly_nosck<T: Instance>( |
| 539 | peri: impl Peripheral<P = T> + 'd, | 538 | peri: impl Peripheral<P = T> + 'd, |
| 540 | mosi: impl Peripheral<P = impl MosiPin<T>> + 'd, | 539 | mosi: impl Peripheral<P = impl MosiPin<T>> + 'd, |
| 541 | tx_dma: impl Peripheral<P = impl TxDma<T>> + 'd, | 540 | tx_dma: impl Peripheral<P = impl TxDma<T>> + 'd, |
| @@ -554,7 +553,7 @@ impl<'d, T: Instance> Spi<'d, T, Async> { | |||
| 554 | 553 | ||
| 555 | #[cfg(stm32wl)] | 554 | #[cfg(stm32wl)] |
| 556 | /// Useful for on chip peripherals like SUBGHZ which are hardwired. | 555 | /// Useful for on chip peripherals like SUBGHZ which are hardwired. |
| 557 | pub fn new_subghz( | 556 | pub fn new_subghz<T: Instance>( |
| 558 | peri: impl Peripheral<P = T> + 'd, | 557 | peri: impl Peripheral<P = T> + 'd, |
| 559 | tx_dma: impl Peripheral<P = impl TxDma<T>> + 'd, | 558 | tx_dma: impl Peripheral<P = impl TxDma<T>> + 'd, |
| 560 | rx_dma: impl Peripheral<P = impl RxDma<T>> + 'd, | 559 | rx_dma: impl Peripheral<P = impl RxDma<T>> + 'd, |
| @@ -562,7 +561,7 @@ impl<'d, T: Instance> Spi<'d, T, Async> { | |||
| 562 | // see RM0453 rev 1 section 7.2.13 page 291 | 561 | // see RM0453 rev 1 section 7.2.13 page 291 |
| 563 | // The SUBGHZSPI_SCK frequency is obtained by PCLK3 divided by two. | 562 | // The SUBGHZSPI_SCK frequency is obtained by PCLK3 divided by two. |
| 564 | // The SUBGHZSPI_SCK clock maximum speed must not exceed 16 MHz. | 563 | // The SUBGHZSPI_SCK clock maximum speed must not exceed 16 MHz. |
| 565 | let pclk3_freq = <peripherals::SUBGHZSPI as crate::rcc::SealedRccPeripheral>::frequency().0; | 564 | let pclk3_freq = <crate::peripherals::SUBGHZSPI as crate::rcc::SealedRccPeripheral>::frequency().0; |
| 566 | let freq = Hertz(core::cmp::min(pclk3_freq / 2, 16_000_000)); | 565 | let freq = Hertz(core::cmp::min(pclk3_freq / 2, 16_000_000)); |
| 567 | let mut config = Config::default(); | 566 | let mut config = Config::default(); |
| 568 | config.mode = MODE_0; | 567 | config.mode = MODE_0; |
| @@ -573,7 +572,7 @@ impl<'d, T: Instance> Spi<'d, T, Async> { | |||
| 573 | } | 572 | } |
| 574 | 573 | ||
| 575 | #[allow(dead_code)] | 574 | #[allow(dead_code)] |
| 576 | pub(crate) fn new_internal( | 575 | pub(crate) fn new_internal<T: Instance>( |
| 577 | peri: impl Peripheral<P = T> + 'd, | 576 | peri: impl Peripheral<P = T> + 'd, |
| 578 | tx_dma: impl Peripheral<P = impl TxDma<T>> + 'd, | 577 | tx_dma: impl Peripheral<P = impl TxDma<T>> + 'd, |
| 579 | rx_dma: impl Peripheral<P = impl RxDma<T>> + 'd, | 578 | rx_dma: impl Peripheral<P = impl RxDma<T>> + 'd, |
| @@ -589,25 +588,25 @@ impl<'d, T: Instance> Spi<'d, T, Async> { | |||
| 589 | } | 588 | } |
| 590 | 589 | ||
| 591 | self.set_word_size(W::CONFIG); | 590 | self.set_word_size(W::CONFIG); |
| 592 | T::REGS.cr1().modify(|w| { | 591 | self.regs.cr1().modify(|w| { |
| 593 | w.set_spe(false); | 592 | w.set_spe(false); |
| 594 | }); | 593 | }); |
| 595 | 594 | ||
| 596 | let tx_dst = T::REGS.tx_ptr(); | 595 | let tx_dst = self.regs.tx_ptr(); |
| 597 | let tx_f = unsafe { self.tx_dma.as_mut().unwrap().write(data, tx_dst, Default::default()) }; | 596 | let tx_f = unsafe { self.tx_dma.as_mut().unwrap().write(data, tx_dst, Default::default()) }; |
| 598 | 597 | ||
| 599 | set_txdmaen(T::REGS, true); | 598 | set_txdmaen(self.regs, true); |
| 600 | T::REGS.cr1().modify(|w| { | 599 | self.regs.cr1().modify(|w| { |
| 601 | w.set_spe(true); | 600 | w.set_spe(true); |
| 602 | }); | 601 | }); |
| 603 | #[cfg(any(spi_v3, spi_v4, spi_v5))] | 602 | #[cfg(any(spi_v3, spi_v4, spi_v5))] |
| 604 | T::REGS.cr1().modify(|w| { | 603 | self.regs.cr1().modify(|w| { |
| 605 | w.set_cstart(true); | 604 | w.set_cstart(true); |
| 606 | }); | 605 | }); |
| 607 | 606 | ||
| 608 | tx_f.await; | 607 | tx_f.await; |
| 609 | 608 | ||
| 610 | finish_dma(T::REGS); | 609 | finish_dma(self.regs); |
| 611 | 610 | ||
| 612 | Ok(()) | 611 | Ok(()) |
| 613 | } | 612 | } |
| @@ -619,22 +618,22 @@ impl<'d, T: Instance> Spi<'d, T, Async> { | |||
| 619 | } | 618 | } |
| 620 | 619 | ||
| 621 | self.set_word_size(W::CONFIG); | 620 | self.set_word_size(W::CONFIG); |
| 622 | T::REGS.cr1().modify(|w| { | 621 | self.regs.cr1().modify(|w| { |
| 623 | w.set_spe(false); | 622 | w.set_spe(false); |
| 624 | }); | 623 | }); |
| 625 | 624 | ||
| 626 | // SPIv3 clears rxfifo on SPE=0 | 625 | // SPIv3 clears rxfifo on SPE=0 |
| 627 | #[cfg(not(any(spi_v3, spi_v4, spi_v5)))] | 626 | #[cfg(not(any(spi_v3, spi_v4, spi_v5)))] |
| 628 | flush_rx_fifo(T::REGS); | 627 | flush_rx_fifo(self.regs); |
| 629 | 628 | ||
| 630 | set_rxdmaen(T::REGS, true); | 629 | set_rxdmaen(self.regs, true); |
| 631 | 630 | ||
| 632 | let clock_byte_count = data.len(); | 631 | let clock_byte_count = data.len(); |
| 633 | 632 | ||
| 634 | let rx_src = T::REGS.rx_ptr(); | 633 | let rx_src = self.regs.rx_ptr(); |
| 635 | let rx_f = unsafe { self.rx_dma.as_mut().unwrap().read(rx_src, data, Default::default()) }; | 634 | let rx_f = unsafe { self.rx_dma.as_mut().unwrap().read(rx_src, data, Default::default()) }; |
| 636 | 635 | ||
| 637 | let tx_dst = T::REGS.tx_ptr(); | 636 | let tx_dst = self.regs.tx_ptr(); |
| 638 | let clock_byte = 0x00u8; | 637 | let clock_byte = 0x00u8; |
| 639 | let tx_f = unsafe { | 638 | let tx_f = unsafe { |
| 640 | self.tx_dma | 639 | self.tx_dma |
| @@ -643,18 +642,18 @@ impl<'d, T: Instance> Spi<'d, T, Async> { | |||
| 643 | .write_repeated(&clock_byte, clock_byte_count, tx_dst, Default::default()) | 642 | .write_repeated(&clock_byte, clock_byte_count, tx_dst, Default::default()) |
| 644 | }; | 643 | }; |
| 645 | 644 | ||
| 646 | set_txdmaen(T::REGS, true); | 645 | set_txdmaen(self.regs, true); |
| 647 | T::REGS.cr1().modify(|w| { | 646 | self.regs.cr1().modify(|w| { |
| 648 | w.set_spe(true); | 647 | w.set_spe(true); |
| 649 | }); | 648 | }); |
| 650 | #[cfg(any(spi_v3, spi_v4, spi_v5))] | 649 | #[cfg(any(spi_v3, spi_v4, spi_v5))] |
| 651 | T::REGS.cr1().modify(|w| { | 650 | self.regs.cr1().modify(|w| { |
| 652 | w.set_cstart(true); | 651 | w.set_cstart(true); |
| 653 | }); | 652 | }); |
| 654 | 653 | ||
| 655 | join(tx_f, rx_f).await; | 654 | join(tx_f, rx_f).await; |
| 656 | 655 | ||
| 657 | finish_dma(T::REGS); | 656 | finish_dma(self.regs); |
| 658 | 657 | ||
| 659 | Ok(()) | 658 | Ok(()) |
| 660 | } | 659 | } |
| @@ -668,20 +667,20 @@ impl<'d, T: Instance> Spi<'d, T, Async> { | |||
| 668 | } | 667 | } |
| 669 | 668 | ||
| 670 | self.set_word_size(W::CONFIG); | 669 | self.set_word_size(W::CONFIG); |
| 671 | T::REGS.cr1().modify(|w| { | 670 | self.regs.cr1().modify(|w| { |
| 672 | w.set_spe(false); | 671 | w.set_spe(false); |
| 673 | }); | 672 | }); |
| 674 | 673 | ||
| 675 | // SPIv3 clears rxfifo on SPE=0 | 674 | // SPIv3 clears rxfifo on SPE=0 |
| 676 | #[cfg(not(any(spi_v3, spi_v4, spi_v5)))] | 675 | #[cfg(not(any(spi_v3, spi_v4, spi_v5)))] |
| 677 | flush_rx_fifo(T::REGS); | 676 | flush_rx_fifo(self.regs); |
| 678 | 677 | ||
| 679 | set_rxdmaen(T::REGS, true); | 678 | set_rxdmaen(self.regs, true); |
| 680 | 679 | ||
| 681 | let rx_src = T::REGS.rx_ptr(); | 680 | let rx_src = self.regs.rx_ptr(); |
| 682 | let rx_f = unsafe { self.rx_dma.as_mut().unwrap().read_raw(rx_src, read, Default::default()) }; | 681 | let rx_f = unsafe { self.rx_dma.as_mut().unwrap().read_raw(rx_src, read, Default::default()) }; |
| 683 | 682 | ||
| 684 | let tx_dst = T::REGS.tx_ptr(); | 683 | let tx_dst = self.regs.tx_ptr(); |
| 685 | let tx_f = unsafe { | 684 | let tx_f = unsafe { |
| 686 | self.tx_dma | 685 | self.tx_dma |
| 687 | .as_mut() | 686 | .as_mut() |
| @@ -689,18 +688,18 @@ impl<'d, T: Instance> Spi<'d, T, Async> { | |||
| 689 | .write_raw(write, tx_dst, Default::default()) | 688 | .write_raw(write, tx_dst, Default::default()) |
| 690 | }; | 689 | }; |
| 691 | 690 | ||
| 692 | set_txdmaen(T::REGS, true); | 691 | set_txdmaen(self.regs, true); |
| 693 | T::REGS.cr1().modify(|w| { | 692 | self.regs.cr1().modify(|w| { |
| 694 | w.set_spe(true); | 693 | w.set_spe(true); |
| 695 | }); | 694 | }); |
| 696 | #[cfg(any(spi_v3, spi_v4, spi_v5))] | 695 | #[cfg(any(spi_v3, spi_v4, spi_v5))] |
| 697 | T::REGS.cr1().modify(|w| { | 696 | self.regs.cr1().modify(|w| { |
| 698 | w.set_cstart(true); | 697 | w.set_cstart(true); |
| 699 | }); | 698 | }); |
| 700 | 699 | ||
| 701 | join(tx_f, rx_f).await; | 700 | join(tx_f, rx_f).await; |
| 702 | 701 | ||
| 703 | finish_dma(T::REGS); | 702 | finish_dma(self.regs); |
| 704 | 703 | ||
| 705 | Ok(()) | 704 | Ok(()) |
| 706 | } | 705 | } |
| @@ -723,13 +722,13 @@ impl<'d, T: Instance> Spi<'d, T, Async> { | |||
| 723 | } | 722 | } |
| 724 | } | 723 | } |
| 725 | 724 | ||
| 726 | impl<'d, T: Instance, M: PeriMode> Drop for Spi<'d, T, M> { | 725 | impl<'d, M: PeriMode> Drop for Spi<'d, M> { |
| 727 | fn drop(&mut self) { | 726 | fn drop(&mut self) { |
| 728 | self.sck.as_ref().map(|x| x.set_as_disconnected()); | 727 | self.sck.as_ref().map(|x| x.set_as_disconnected()); |
| 729 | self.mosi.as_ref().map(|x| x.set_as_disconnected()); | 728 | self.mosi.as_ref().map(|x| x.set_as_disconnected()); |
| 730 | self.miso.as_ref().map(|x| x.set_as_disconnected()); | 729 | self.miso.as_ref().map(|x| x.set_as_disconnected()); |
| 731 | 730 | ||
| 732 | T::disable(); | 731 | self.enable_bit.disable(); |
| 733 | } | 732 | } |
| 734 | } | 733 | } |
| 735 | 734 | ||
| @@ -738,8 +737,8 @@ use vals::Br; | |||
| 738 | #[cfg(any(spi_v3, spi_v4, spi_v5))] | 737 | #[cfg(any(spi_v3, spi_v4, spi_v5))] |
| 739 | use vals::Mbr as Br; | 738 | use vals::Mbr as Br; |
| 740 | 739 | ||
| 741 | fn compute_baud_rate(clocks: Hertz, freq: Hertz) -> Br { | 740 | fn compute_baud_rate(kernel_clock: Hertz, freq: Hertz) -> Br { |
| 742 | let val = match clocks.0 / freq.0 { | 741 | let val = match kernel_clock.0 / freq.0 { |
| 743 | 0 => panic!("You are trying to reach a frequency higher than the clock"), | 742 | 0 => panic!("You are trying to reach a frequency higher than the clock"), |
| 744 | 1..=2 => 0b000, | 743 | 1..=2 => 0b000, |
| 745 | 3..=5 => 0b001, | 744 | 3..=5 => 0b001, |
| @@ -754,7 +753,7 @@ fn compute_baud_rate(clocks: Hertz, freq: Hertz) -> Br { | |||
| 754 | Br::from_bits(val) | 753 | Br::from_bits(val) |
| 755 | } | 754 | } |
| 756 | 755 | ||
| 757 | fn compute_frequency(clocks: Hertz, br: Br) -> Hertz { | 756 | fn compute_frequency(kernel_clock: Hertz, br: Br) -> Hertz { |
| 758 | let div: u16 = match br { | 757 | let div: u16 = match br { |
| 759 | Br::DIV2 => 2, | 758 | Br::DIV2 => 2, |
| 760 | Br::DIV4 => 4, | 759 | Br::DIV4 => 4, |
| @@ -766,7 +765,7 @@ fn compute_frequency(clocks: Hertz, br: Br) -> Hertz { | |||
| 766 | Br::DIV256 => 256, | 765 | Br::DIV256 => 256, |
| 767 | }; | 766 | }; |
| 768 | 767 | ||
| 769 | clocks / div | 768 | kernel_clock / div |
| 770 | } | 769 | } |
| 771 | 770 | ||
| 772 | trait RegsExt { | 771 | trait RegsExt { |
| @@ -941,7 +940,7 @@ fn transfer_word<W: Word>(regs: Regs, tx_word: W) -> Result<W, Error> { | |||
| 941 | // some marker traits. For details, see https://github.com/rust-embedded/embedded-hal/pull/289 | 940 | // some marker traits. For details, see https://github.com/rust-embedded/embedded-hal/pull/289 |
| 942 | macro_rules! impl_blocking { | 941 | macro_rules! impl_blocking { |
| 943 | ($w:ident) => { | 942 | ($w:ident) => { |
| 944 | impl<'d, T: Instance, M: PeriMode> embedded_hal_02::blocking::spi::Write<$w> for Spi<'d, T, M> { | 943 | impl<'d, M: PeriMode> embedded_hal_02::blocking::spi::Write<$w> for Spi<'d, M> { |
| 945 | type Error = Error; | 944 | type Error = Error; |
| 946 | 945 | ||
| 947 | fn write(&mut self, words: &[$w]) -> Result<(), Self::Error> { | 946 | fn write(&mut self, words: &[$w]) -> Result<(), Self::Error> { |
| @@ -949,7 +948,7 @@ macro_rules! impl_blocking { | |||
| 949 | } | 948 | } |
| 950 | } | 949 | } |
| 951 | 950 | ||
| 952 | impl<'d, T: Instance, M: PeriMode> embedded_hal_02::blocking::spi::Transfer<$w> for Spi<'d, T, M> { | 951 | impl<'d, M: PeriMode> embedded_hal_02::blocking::spi::Transfer<$w> for Spi<'d, M> { |
| 953 | type Error = Error; | 952 | type Error = Error; |
| 954 | 953 | ||
| 955 | fn transfer<'w>(&mut self, words: &'w mut [$w]) -> Result<&'w [$w], Self::Error> { | 954 | fn transfer<'w>(&mut self, words: &'w mut [$w]) -> Result<&'w [$w], Self::Error> { |
| @@ -963,11 +962,11 @@ macro_rules! impl_blocking { | |||
| 963 | impl_blocking!(u8); | 962 | impl_blocking!(u8); |
| 964 | impl_blocking!(u16); | 963 | impl_blocking!(u16); |
| 965 | 964 | ||
| 966 | impl<'d, T: Instance, M: PeriMode> embedded_hal_1::spi::ErrorType for Spi<'d, T, M> { | 965 | impl<'d, M: PeriMode> embedded_hal_1::spi::ErrorType for Spi<'d, M> { |
| 967 | type Error = Error; | 966 | type Error = Error; |
| 968 | } | 967 | } |
| 969 | 968 | ||
| 970 | impl<'d, T: Instance, W: Word, M: PeriMode> embedded_hal_1::spi::SpiBus<W> for Spi<'d, T, M> { | 969 | impl<'d, W: Word, M: PeriMode> embedded_hal_1::spi::SpiBus<W> for Spi<'d, M> { |
| 971 | fn flush(&mut self) -> Result<(), Self::Error> { | 970 | fn flush(&mut self) -> Result<(), Self::Error> { |
| 972 | Ok(()) | 971 | Ok(()) |
| 973 | } | 972 | } |
| @@ -1000,7 +999,7 @@ impl embedded_hal_1::spi::Error for Error { | |||
| 1000 | } | 999 | } |
| 1001 | } | 1000 | } |
| 1002 | 1001 | ||
| 1003 | impl<'d, T: Instance, W: Word> embedded_hal_async::spi::SpiBus<W> for Spi<'d, T, Async> { | 1002 | impl<'d, W: Word> embedded_hal_async::spi::SpiBus<W> for Spi<'d, Async> { |
| 1004 | async fn flush(&mut self) -> Result<(), Self::Error> { | 1003 | async fn flush(&mut self) -> Result<(), Self::Error> { |
| 1005 | Ok(()) | 1004 | Ok(()) |
| 1006 | } | 1005 | } |
| @@ -1022,10 +1021,6 @@ impl<'d, T: Instance, W: Word> embedded_hal_async::spi::SpiBus<W> for Spi<'d, T, | |||
| 1022 | } | 1021 | } |
| 1023 | } | 1022 | } |
| 1024 | 1023 | ||
| 1025 | pub(crate) trait SealedInstance { | ||
| 1026 | const REGS: Regs; | ||
| 1027 | } | ||
| 1028 | |||
| 1029 | trait SealedWord { | 1024 | trait SealedWord { |
| 1030 | const CONFIG: word_impl::Config; | 1025 | const CONFIG: word_impl::Config; |
| 1031 | } | 1026 | } |
| @@ -1111,9 +1106,19 @@ mod word_impl { | |||
| 1111 | impl_word!(u32, 32 - 1); | 1106 | impl_word!(u32, 32 - 1); |
| 1112 | } | 1107 | } |
| 1113 | 1108 | ||
| 1114 | /// SPI instance trait. | 1109 | struct Info { |
| 1115 | #[allow(private_bounds)] | 1110 | regs: Regs, |
| 1116 | pub trait Instance: Peripheral<P = Self> + SealedInstance + RccPeripheral {} | 1111 | } |
| 1112 | |||
| 1113 | struct State {} | ||
| 1114 | |||
| 1115 | impl State { | ||
| 1116 | const fn new() -> Self { | ||
| 1117 | Self {} | ||
| 1118 | } | ||
| 1119 | } | ||
| 1120 | |||
| 1121 | peri_trait!(); | ||
| 1117 | 1122 | ||
| 1118 | pin_trait!(SckPin, Instance); | 1123 | pin_trait!(SckPin, Instance); |
| 1119 | pin_trait!(MosiPin, Instance); | 1124 | pin_trait!(MosiPin, Instance); |
| @@ -1127,15 +1132,13 @@ dma_trait!(TxDma, Instance); | |||
| 1127 | 1132 | ||
| 1128 | foreach_peripheral!( | 1133 | foreach_peripheral!( |
| 1129 | (spi, $inst:ident) => { | 1134 | (spi, $inst:ident) => { |
| 1130 | impl SealedInstance for peripherals::$inst { | 1135 | peri_trait_impl!($inst, Info { |
| 1131 | const REGS: Regs = crate::pac::$inst; | 1136 | regs: crate::pac::$inst, |
| 1132 | } | 1137 | }); |
| 1133 | |||
| 1134 | impl Instance for peripherals::$inst {} | ||
| 1135 | }; | 1138 | }; |
| 1136 | ); | 1139 | ); |
| 1137 | 1140 | ||
| 1138 | impl<'d, T: Instance, M: PeriMode> SetConfig for Spi<'d, T, M> { | 1141 | impl<'d, M: PeriMode> SetConfig for Spi<'d, M> { |
| 1139 | type Config = Config; | 1142 | type Config = Config; |
| 1140 | type ConfigError = (); | 1143 | type ConfigError = (); |
| 1141 | fn set_config(&mut self, config: &Self::Config) -> Result<(), ()> { | 1144 | fn set_config(&mut self, config: &Self::Config) -> Result<(), ()> { |
