diff options
| author | Dario Nieuwenhuis <[email protected]> | 2024-05-21 20:46:03 +0000 |
|---|---|---|
| committer | GitHub <[email protected]> | 2024-05-21 20:46:03 +0000 |
| commit | a636bace984c8fddeb6d6ac0b8f8a61bffce3673 (patch) | |
| tree | 2e78cd716988fc5ec04950cb5cfe3dda80d3669f | |
| parent | 2da2e57b38e31059d752cc2e39ec3db96c8bb1d0 (diff) | |
| parent | 45a12fd41f1f6230a4aabbfe87552adc610fdc99 (diff) | |
Merge pull request #2974 from embassy-rs/spi-nogenerics
stm32/i2c: remove peripheral generic param.
| -rw-r--r-- | embassy-stm32/build.rs | 6 | ||||
| -rw-r--r-- | embassy-stm32/src/i2c/mod.rs | 68 | ||||
| -rw-r--r-- | embassy-stm32/src/i2c/v1.rs | 184 | ||||
| -rw-r--r-- | embassy-stm32/src/i2c/v2.rs | 129 | ||||
| -rw-r--r-- | embassy-stm32/src/i2s.rs | 4 | ||||
| -rw-r--r-- | embassy-stm32/src/macros.rs | 29 | ||||
| -rw-r--r-- | embassy-stm32/src/rcc/mod.rs | 5 | ||||
| -rw-r--r-- | embassy-stm32/src/spi/mod.rs | 122 | ||||
| -rw-r--r-- | examples/stm32h7/src/bin/i2c_shared.rs | 5 | ||||
| -rw-r--r-- | examples/stm32l4/src/bin/spe_adin1110_http_server.rs | 2 |
10 files changed, 291 insertions, 263 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/i2c/mod.rs b/embassy-stm32/src/i2c/mod.rs index 0b2a56305..ef5fd0972 100644 --- a/embassy-stm32/src/i2c/mod.rs +++ b/embassy-stm32/src/i2c/mod.rs | |||
| @@ -9,7 +9,7 @@ use core::future::Future; | |||
| 9 | use core::iter; | 9 | use core::iter; |
| 10 | use core::marker::PhantomData; | 10 | use core::marker::PhantomData; |
| 11 | 11 | ||
| 12 | use embassy_hal_internal::{into_ref, Peripheral, PeripheralRef}; | 12 | use embassy_hal_internal::{into_ref, Peripheral}; |
| 13 | use embassy_sync::waitqueue::AtomicWaker; | 13 | use embassy_sync::waitqueue::AtomicWaker; |
| 14 | #[cfg(feature = "time")] | 14 | #[cfg(feature = "time")] |
| 15 | use embassy_time::{Duration, Instant}; | 15 | use embassy_time::{Duration, Instant}; |
| @@ -18,6 +18,7 @@ use crate::dma::ChannelAndRequest; | |||
| 18 | use crate::gpio::{AFType, Pull}; | 18 | use crate::gpio::{AFType, Pull}; |
| 19 | use crate::interrupt::typelevel::Interrupt; | 19 | use crate::interrupt::typelevel::Interrupt; |
| 20 | use crate::mode::{Async, Blocking, Mode}; | 20 | use crate::mode::{Async, Blocking, Mode}; |
| 21 | use crate::rcc::{ClockEnableBit, SealedRccPeripheral}; | ||
| 21 | use crate::time::Hertz; | 22 | use crate::time::Hertz; |
| 22 | use crate::{interrupt, peripherals}; | 23 | use crate::{interrupt, peripherals}; |
| 23 | 24 | ||
| @@ -72,8 +73,10 @@ impl Default for Config { | |||
| 72 | } | 73 | } |
| 73 | 74 | ||
| 74 | /// I2C driver. | 75 | /// I2C driver. |
| 75 | pub struct I2c<'d, T: Instance, M: Mode> { | 76 | pub struct I2c<'d, M: Mode> { |
| 76 | _peri: PeripheralRef<'d, T>, | 77 | info: &'static Info, |
| 78 | state: &'static State, | ||
| 79 | kernel_clock: Hertz, | ||
| 77 | tx_dma: Option<ChannelAndRequest<'d>>, | 80 | tx_dma: Option<ChannelAndRequest<'d>>, |
| 78 | rx_dma: Option<ChannelAndRequest<'d>>, | 81 | rx_dma: Option<ChannelAndRequest<'d>>, |
| 79 | #[cfg(feature = "time")] | 82 | #[cfg(feature = "time")] |
| @@ -81,9 +84,9 @@ pub struct I2c<'d, T: Instance, M: Mode> { | |||
| 81 | _phantom: PhantomData<M>, | 84 | _phantom: PhantomData<M>, |
| 82 | } | 85 | } |
| 83 | 86 | ||
| 84 | impl<'d, T: Instance> I2c<'d, T, Async> { | 87 | impl<'d> I2c<'d, Async> { |
| 85 | /// Create a new I2C driver. | 88 | /// Create a new I2C driver. |
| 86 | pub fn new( | 89 | pub fn new<T: Instance>( |
| 87 | peri: impl Peripheral<P = T> + 'd, | 90 | peri: impl Peripheral<P = T> + 'd, |
| 88 | scl: impl Peripheral<P = impl SclPin<T>> + 'd, | 91 | scl: impl Peripheral<P = impl SclPin<T>> + 'd, |
| 89 | sda: impl Peripheral<P = impl SdaPin<T>> + 'd, | 92 | sda: impl Peripheral<P = impl SdaPin<T>> + 'd, |
| @@ -99,9 +102,9 @@ impl<'d, T: Instance> I2c<'d, T, Async> { | |||
| 99 | } | 102 | } |
| 100 | } | 103 | } |
| 101 | 104 | ||
| 102 | impl<'d, T: Instance> I2c<'d, T, Blocking> { | 105 | impl<'d> I2c<'d, Blocking> { |
| 103 | /// Create a new blocking I2C driver. | 106 | /// Create a new blocking I2C driver. |
| 104 | pub fn new_blocking( | 107 | pub fn new_blocking<T: Instance>( |
| 105 | peri: impl Peripheral<P = T> + 'd, | 108 | peri: impl Peripheral<P = T> + 'd, |
| 106 | scl: impl Peripheral<P = impl SclPin<T>> + 'd, | 109 | scl: impl Peripheral<P = impl SclPin<T>> + 'd, |
| 107 | sda: impl Peripheral<P = impl SdaPin<T>> + 'd, | 110 | sda: impl Peripheral<P = impl SdaPin<T>> + 'd, |
| @@ -112,10 +115,10 @@ impl<'d, T: Instance> I2c<'d, T, Blocking> { | |||
| 112 | } | 115 | } |
| 113 | } | 116 | } |
| 114 | 117 | ||
| 115 | impl<'d, T: Instance, M: Mode> I2c<'d, T, M> { | 118 | impl<'d, M: Mode> I2c<'d, M> { |
| 116 | /// Create a new I2C driver. | 119 | /// Create a new I2C driver. |
| 117 | fn new_inner( | 120 | fn new_inner<T: Instance>( |
| 118 | peri: impl Peripheral<P = T> + 'd, | 121 | _peri: impl Peripheral<P = T> + 'd, |
| 119 | scl: impl Peripheral<P = impl SclPin<T>> + 'd, | 122 | scl: impl Peripheral<P = impl SclPin<T>> + 'd, |
| 120 | sda: impl Peripheral<P = impl SdaPin<T>> + 'd, | 123 | sda: impl Peripheral<P = impl SdaPin<T>> + 'd, |
| 121 | tx_dma: Option<ChannelAndRequest<'d>>, | 124 | tx_dma: Option<ChannelAndRequest<'d>>, |
| @@ -123,7 +126,7 @@ impl<'d, T: Instance, M: Mode> I2c<'d, T, M> { | |||
| 123 | freq: Hertz, | 126 | freq: Hertz, |
| 124 | config: Config, | 127 | config: Config, |
| 125 | ) -> Self { | 128 | ) -> Self { |
| 126 | into_ref!(peri, scl, sda); | 129 | into_ref!(scl, sda); |
| 127 | 130 | ||
| 128 | T::enable_and_reset(); | 131 | T::enable_and_reset(); |
| 129 | 132 | ||
| @@ -148,7 +151,9 @@ impl<'d, T: Instance, M: Mode> I2c<'d, T, M> { | |||
| 148 | unsafe { T::ErrorInterrupt::enable() }; | 151 | unsafe { T::ErrorInterrupt::enable() }; |
| 149 | 152 | ||
| 150 | let mut this = Self { | 153 | let mut this = Self { |
| 151 | _peri: peri, | 154 | info: T::info(), |
| 155 | state: T::state(), | ||
| 156 | kernel_clock: T::frequency(), | ||
| 152 | tx_dma, | 157 | tx_dma, |
| 153 | rx_dma, | 158 | rx_dma, |
| 154 | #[cfg(feature = "time")] | 159 | #[cfg(feature = "time")] |
| @@ -217,19 +222,14 @@ impl State { | |||
| 217 | } | 222 | } |
| 218 | } | 223 | } |
| 219 | 224 | ||
| 220 | trait SealedInstance: crate::rcc::RccPeripheral { | 225 | struct Info { |
| 221 | fn regs() -> crate::pac::i2c::I2c; | 226 | regs: crate::pac::i2c::I2c, |
| 222 | fn state() -> &'static State; | 227 | pub(crate) enable_bit: ClockEnableBit, |
| 223 | } | 228 | } |
| 224 | 229 | ||
| 225 | /// I2C peripheral instance | 230 | peri_trait!( |
| 226 | #[allow(private_bounds)] | 231 | irqs: [EventInterrupt, ErrorInterrupt], |
| 227 | pub trait Instance: SealedInstance + 'static { | 232 | ); |
| 228 | /// Event interrupt for this instance | ||
| 229 | type EventInterrupt: interrupt::typelevel::Interrupt; | ||
| 230 | /// Error interrupt for this instance | ||
| 231 | type ErrorInterrupt: interrupt::typelevel::Interrupt; | ||
| 232 | } | ||
| 233 | 233 | ||
| 234 | pin_trait!(SclPin, Instance); | 234 | pin_trait!(SclPin, Instance); |
| 235 | pin_trait!(SdaPin, Instance); | 235 | pin_trait!(SdaPin, Instance); |
| @@ -260,11 +260,15 @@ impl<T: Instance> interrupt::typelevel::Handler<T::ErrorInterrupt> for ErrorInte | |||
| 260 | 260 | ||
| 261 | foreach_peripheral!( | 261 | foreach_peripheral!( |
| 262 | (i2c, $inst:ident) => { | 262 | (i2c, $inst:ident) => { |
| 263 | #[allow(private_interfaces)] | ||
| 263 | impl SealedInstance for peripherals::$inst { | 264 | impl SealedInstance for peripherals::$inst { |
| 264 | fn regs() -> crate::pac::i2c::I2c { | 265 | fn info() -> &'static Info { |
| 265 | crate::pac::$inst | 266 | static INFO: Info = Info{ |
| 267 | regs: crate::pac::$inst, | ||
| 268 | enable_bit: crate::peripherals::$inst::ENABLE_BIT, | ||
| 269 | }; | ||
| 270 | &INFO | ||
| 266 | } | 271 | } |
| 267 | |||
| 268 | fn state() -> &'static State { | 272 | fn state() -> &'static State { |
| 269 | static STATE: State = State::new(); | 273 | static STATE: State = State::new(); |
| 270 | &STATE | 274 | &STATE |
| @@ -278,7 +282,7 @@ foreach_peripheral!( | |||
| 278 | }; | 282 | }; |
| 279 | ); | 283 | ); |
| 280 | 284 | ||
| 281 | impl<'d, T: Instance, M: Mode> embedded_hal_02::blocking::i2c::Read for I2c<'d, T, M> { | 285 | impl<'d, M: Mode> embedded_hal_02::blocking::i2c::Read for I2c<'d, M> { |
| 282 | type Error = Error; | 286 | type Error = Error; |
| 283 | 287 | ||
| 284 | fn read(&mut self, address: u8, buffer: &mut [u8]) -> Result<(), Self::Error> { | 288 | fn read(&mut self, address: u8, buffer: &mut [u8]) -> Result<(), Self::Error> { |
| @@ -286,7 +290,7 @@ impl<'d, T: Instance, M: Mode> embedded_hal_02::blocking::i2c::Read for I2c<'d, | |||
| 286 | } | 290 | } |
| 287 | } | 291 | } |
| 288 | 292 | ||
| 289 | impl<'d, T: Instance, M: Mode> embedded_hal_02::blocking::i2c::Write for I2c<'d, T, M> { | 293 | impl<'d, M: Mode> embedded_hal_02::blocking::i2c::Write for I2c<'d, M> { |
| 290 | type Error = Error; | 294 | type Error = Error; |
| 291 | 295 | ||
| 292 | fn write(&mut self, address: u8, write: &[u8]) -> Result<(), Self::Error> { | 296 | fn write(&mut self, address: u8, write: &[u8]) -> Result<(), Self::Error> { |
| @@ -294,7 +298,7 @@ impl<'d, T: Instance, M: Mode> embedded_hal_02::blocking::i2c::Write for I2c<'d, | |||
| 294 | } | 298 | } |
| 295 | } | 299 | } |
| 296 | 300 | ||
| 297 | impl<'d, T: Instance, M: Mode> embedded_hal_02::blocking::i2c::WriteRead for I2c<'d, T, M> { | 301 | impl<'d, M: Mode> embedded_hal_02::blocking::i2c::WriteRead for I2c<'d, M> { |
| 298 | type Error = Error; | 302 | type Error = Error; |
| 299 | 303 | ||
| 300 | fn write_read(&mut self, address: u8, write: &[u8], read: &mut [u8]) -> Result<(), Self::Error> { | 304 | fn write_read(&mut self, address: u8, write: &[u8], read: &mut [u8]) -> Result<(), Self::Error> { |
| @@ -318,11 +322,11 @@ impl embedded_hal_1::i2c::Error for Error { | |||
| 318 | } | 322 | } |
| 319 | } | 323 | } |
| 320 | 324 | ||
| 321 | impl<'d, T: Instance, M: Mode> embedded_hal_1::i2c::ErrorType for I2c<'d, T, M> { | 325 | impl<'d, M: Mode> embedded_hal_1::i2c::ErrorType for I2c<'d, M> { |
| 322 | type Error = Error; | 326 | type Error = Error; |
| 323 | } | 327 | } |
| 324 | 328 | ||
| 325 | impl<'d, T: Instance, M: Mode> embedded_hal_1::i2c::I2c for I2c<'d, T, M> { | 329 | impl<'d, M: Mode> embedded_hal_1::i2c::I2c for I2c<'d, M> { |
| 326 | fn read(&mut self, address: u8, read: &mut [u8]) -> Result<(), Self::Error> { | 330 | fn read(&mut self, address: u8, read: &mut [u8]) -> Result<(), Self::Error> { |
| 327 | self.blocking_read(address, read) | 331 | self.blocking_read(address, read) |
| 328 | } | 332 | } |
| @@ -344,7 +348,7 @@ impl<'d, T: Instance, M: Mode> embedded_hal_1::i2c::I2c for I2c<'d, T, M> { | |||
| 344 | } | 348 | } |
| 345 | } | 349 | } |
| 346 | 350 | ||
| 347 | impl<'d, T: Instance> embedded_hal_async::i2c::I2c for I2c<'d, T, Async> { | 351 | impl<'d> embedded_hal_async::i2c::I2c for I2c<'d, Async> { |
| 348 | async fn read(&mut self, address: u8, read: &mut [u8]) -> Result<(), Self::Error> { | 352 | async fn read(&mut self, address: u8, read: &mut [u8]) -> Result<(), Self::Error> { |
| 349 | self.read(address, read).await | 353 | self.read(address, read).await |
| 350 | } | 354 | } |
diff --git a/embassy-stm32/src/i2c/v1.rs b/embassy-stm32/src/i2c/v1.rs index ac4fa1b9e..0269e53aa 100644 --- a/embassy-stm32/src/i2c/v1.rs +++ b/embassy-stm32/src/i2c/v1.rs | |||
| @@ -28,7 +28,7 @@ use crate::pac::i2c; | |||
| 28 | // There's some more details there, and we might have a fix for you. But please let us know if you | 28 | // There's some more details there, and we might have a fix for you. But please let us know if you |
| 29 | // hit a case like this! | 29 | // hit a case like this! |
| 30 | pub unsafe fn on_interrupt<T: Instance>() { | 30 | pub unsafe fn on_interrupt<T: Instance>() { |
| 31 | let regs = T::regs(); | 31 | let regs = T::info().regs; |
| 32 | // i2c v2 only woke the task on transfer complete interrupts. v1 uses interrupts for a bunch of | 32 | // i2c v2 only woke the task on transfer complete interrupts. v1 uses interrupts for a bunch of |
| 33 | // other stuff, so we wake the task on every interrupt. | 33 | // other stuff, so we wake the task on every interrupt. |
| 34 | T::state().waker.wake(); | 34 | T::state().waker.wake(); |
| @@ -41,9 +41,9 @@ pub unsafe fn on_interrupt<T: Instance>() { | |||
| 41 | }); | 41 | }); |
| 42 | } | 42 | } |
| 43 | 43 | ||
| 44 | impl<'d, T: Instance, M: PeriMode> I2c<'d, T, M> { | 44 | impl<'d, M: PeriMode> I2c<'d, M> { |
| 45 | pub(crate) fn init(&mut self, freq: Hertz, _config: Config) { | 45 | pub(crate) fn init(&mut self, freq: Hertz, _config: Config) { |
| 46 | T::regs().cr1().modify(|reg| { | 46 | self.info.regs.cr1().modify(|reg| { |
| 47 | reg.set_pe(false); | 47 | reg.set_pe(false); |
| 48 | //reg.set_anfoff(false); | 48 | //reg.set_anfoff(false); |
| 49 | }); | 49 | }); |
| @@ -67,39 +67,39 @@ impl<'d, T: Instance, M: PeriMode> I2c<'d, T, M> { | |||
| 67 | // | 67 | // |
| 68 | // This presents as an ~infinite hang on read or write, as the START condition | 68 | // This presents as an ~infinite hang on read or write, as the START condition |
| 69 | // is never generated, meaning the start event is never generated. | 69 | // is never generated, meaning the start event is never generated. |
| 70 | T::regs().cr1().modify(|reg| { | 70 | self.info.regs.cr1().modify(|reg| { |
| 71 | reg.set_swrst(true); | 71 | reg.set_swrst(true); |
| 72 | }); | 72 | }); |
| 73 | T::regs().cr1().modify(|reg| { | 73 | self.info.regs.cr1().modify(|reg| { |
| 74 | reg.set_swrst(false); | 74 | reg.set_swrst(false); |
| 75 | }); | 75 | }); |
| 76 | 76 | ||
| 77 | let timings = Timings::new(T::frequency(), freq); | 77 | let timings = Timings::new(self.kernel_clock, freq); |
| 78 | 78 | ||
| 79 | T::regs().cr2().modify(|reg| { | 79 | self.info.regs.cr2().modify(|reg| { |
| 80 | reg.set_freq(timings.freq); | 80 | reg.set_freq(timings.freq); |
| 81 | }); | 81 | }); |
| 82 | T::regs().ccr().modify(|reg| { | 82 | self.info.regs.ccr().modify(|reg| { |
| 83 | reg.set_f_s(timings.mode.f_s()); | 83 | reg.set_f_s(timings.mode.f_s()); |
| 84 | reg.set_duty(timings.duty.duty()); | 84 | reg.set_duty(timings.duty.duty()); |
| 85 | reg.set_ccr(timings.ccr); | 85 | reg.set_ccr(timings.ccr); |
| 86 | }); | 86 | }); |
| 87 | T::regs().trise().modify(|reg| { | 87 | self.info.regs.trise().modify(|reg| { |
| 88 | reg.set_trise(timings.trise); | 88 | reg.set_trise(timings.trise); |
| 89 | }); | 89 | }); |
| 90 | 90 | ||
| 91 | T::regs().cr1().modify(|reg| { | 91 | self.info.regs.cr1().modify(|reg| { |
| 92 | reg.set_pe(true); | 92 | reg.set_pe(true); |
| 93 | }); | 93 | }); |
| 94 | } | 94 | } |
| 95 | 95 | ||
| 96 | fn check_and_clear_error_flags() -> Result<i2c::regs::Sr1, Error> { | 96 | fn check_and_clear_error_flags(info: &'static Info) -> Result<i2c::regs::Sr1, Error> { |
| 97 | // Note that flags should only be cleared once they have been registered. If flags are | 97 | // Note that flags should only be cleared once they have been registered. If flags are |
| 98 | // cleared otherwise, there may be an inherent race condition and flags may be missed. | 98 | // cleared otherwise, there may be an inherent race condition and flags may be missed. |
| 99 | let sr1 = T::regs().sr1().read(); | 99 | let sr1 = info.regs.sr1().read(); |
| 100 | 100 | ||
| 101 | if sr1.timeout() { | 101 | if sr1.timeout() { |
| 102 | T::regs().sr1().write(|reg| { | 102 | info.regs.sr1().write(|reg| { |
| 103 | reg.0 = !0; | 103 | reg.0 = !0; |
| 104 | reg.set_timeout(false); | 104 | reg.set_timeout(false); |
| 105 | }); | 105 | }); |
| @@ -107,7 +107,7 @@ impl<'d, T: Instance, M: PeriMode> I2c<'d, T, M> { | |||
| 107 | } | 107 | } |
| 108 | 108 | ||
| 109 | if sr1.pecerr() { | 109 | if sr1.pecerr() { |
| 110 | T::regs().sr1().write(|reg| { | 110 | info.regs.sr1().write(|reg| { |
| 111 | reg.0 = !0; | 111 | reg.0 = !0; |
| 112 | reg.set_pecerr(false); | 112 | reg.set_pecerr(false); |
| 113 | }); | 113 | }); |
| @@ -115,7 +115,7 @@ impl<'d, T: Instance, M: PeriMode> I2c<'d, T, M> { | |||
| 115 | } | 115 | } |
| 116 | 116 | ||
| 117 | if sr1.ovr() { | 117 | if sr1.ovr() { |
| 118 | T::regs().sr1().write(|reg| { | 118 | info.regs.sr1().write(|reg| { |
| 119 | reg.0 = !0; | 119 | reg.0 = !0; |
| 120 | reg.set_ovr(false); | 120 | reg.set_ovr(false); |
| 121 | }); | 121 | }); |
| @@ -123,7 +123,7 @@ impl<'d, T: Instance, M: PeriMode> I2c<'d, T, M> { | |||
| 123 | } | 123 | } |
| 124 | 124 | ||
| 125 | if sr1.af() { | 125 | if sr1.af() { |
| 126 | T::regs().sr1().write(|reg| { | 126 | info.regs.sr1().write(|reg| { |
| 127 | reg.0 = !0; | 127 | reg.0 = !0; |
| 128 | reg.set_af(false); | 128 | reg.set_af(false); |
| 129 | }); | 129 | }); |
| @@ -131,7 +131,7 @@ impl<'d, T: Instance, M: PeriMode> I2c<'d, T, M> { | |||
| 131 | } | 131 | } |
| 132 | 132 | ||
| 133 | if sr1.arlo() { | 133 | if sr1.arlo() { |
| 134 | T::regs().sr1().write(|reg| { | 134 | info.regs.sr1().write(|reg| { |
| 135 | reg.0 = !0; | 135 | reg.0 = !0; |
| 136 | reg.set_arlo(false); | 136 | reg.set_arlo(false); |
| 137 | }); | 137 | }); |
| @@ -141,7 +141,7 @@ impl<'d, T: Instance, M: PeriMode> I2c<'d, T, M> { | |||
| 141 | // The errata indicates that BERR may be incorrectly detected. It recommends ignoring and | 141 | // The errata indicates that BERR may be incorrectly detected. It recommends ignoring and |
| 142 | // clearing the BERR bit instead. | 142 | // clearing the BERR bit instead. |
| 143 | if sr1.berr() { | 143 | if sr1.berr() { |
| 144 | T::regs().sr1().write(|reg| { | 144 | info.regs.sr1().write(|reg| { |
| 145 | reg.0 = !0; | 145 | reg.0 = !0; |
| 146 | reg.set_berr(false); | 146 | reg.set_berr(false); |
| 147 | }); | 147 | }); |
| @@ -154,32 +154,32 @@ impl<'d, T: Instance, M: PeriMode> I2c<'d, T, M> { | |||
| 154 | if frame.send_start() { | 154 | if frame.send_start() { |
| 155 | // Send a START condition | 155 | // Send a START condition |
| 156 | 156 | ||
| 157 | T::regs().cr1().modify(|reg| { | 157 | self.info.regs.cr1().modify(|reg| { |
| 158 | reg.set_start(true); | 158 | reg.set_start(true); |
| 159 | }); | 159 | }); |
| 160 | 160 | ||
| 161 | // Wait until START condition was generated | 161 | // Wait until START condition was generated |
| 162 | while !Self::check_and_clear_error_flags()?.start() { | 162 | while !Self::check_and_clear_error_flags(self.info)?.start() { |
| 163 | timeout.check()?; | 163 | timeout.check()?; |
| 164 | } | 164 | } |
| 165 | 165 | ||
| 166 | // Check if we were the ones to generate START | 166 | // Check if we were the ones to generate START |
| 167 | if T::regs().cr1().read().start() || !T::regs().sr2().read().msl() { | 167 | if self.info.regs.cr1().read().start() || !self.info.regs.sr2().read().msl() { |
| 168 | return Err(Error::Arbitration); | 168 | return Err(Error::Arbitration); |
| 169 | } | 169 | } |
| 170 | 170 | ||
| 171 | // Set up current address we're trying to talk to | 171 | // Set up current address we're trying to talk to |
| 172 | T::regs().dr().write(|reg| reg.set_dr(addr << 1)); | 172 | self.info.regs.dr().write(|reg| reg.set_dr(addr << 1)); |
| 173 | 173 | ||
| 174 | // Wait until address was sent | 174 | // Wait until address was sent |
| 175 | // Wait for the address to be acknowledged | 175 | // Wait for the address to be acknowledged |
| 176 | // Check for any I2C errors. If a NACK occurs, the ADDR bit will never be set. | 176 | // Check for any I2C errors. If a NACK occurs, the ADDR bit will never be set. |
| 177 | while !Self::check_and_clear_error_flags()?.addr() { | 177 | while !Self::check_and_clear_error_flags(self.info)?.addr() { |
| 178 | timeout.check()?; | 178 | timeout.check()?; |
| 179 | } | 179 | } |
| 180 | 180 | ||
| 181 | // Clear condition by reading SR2 | 181 | // Clear condition by reading SR2 |
| 182 | let _ = T::regs().sr2().read(); | 182 | let _ = self.info.regs.sr2().read(); |
| 183 | } | 183 | } |
| 184 | 184 | ||
| 185 | // Send bytes | 185 | // Send bytes |
| @@ -189,7 +189,7 @@ impl<'d, T: Instance, M: PeriMode> I2c<'d, T, M> { | |||
| 189 | 189 | ||
| 190 | if frame.send_stop() { | 190 | if frame.send_stop() { |
| 191 | // Send a STOP condition | 191 | // Send a STOP condition |
| 192 | T::regs().cr1().modify(|reg| reg.set_stop(true)); | 192 | self.info.regs.cr1().modify(|reg| reg.set_stop(true)); |
| 193 | } | 193 | } |
| 194 | 194 | ||
| 195 | // Fallthrough is success | 195 | // Fallthrough is success |
| @@ -200,18 +200,18 @@ impl<'d, T: Instance, M: PeriMode> I2c<'d, T, M> { | |||
| 200 | // Wait until we're ready for sending | 200 | // Wait until we're ready for sending |
| 201 | while { | 201 | while { |
| 202 | // Check for any I2C errors. If a NACK occurs, the ADDR bit will never be set. | 202 | // Check for any I2C errors. If a NACK occurs, the ADDR bit will never be set. |
| 203 | !Self::check_and_clear_error_flags()?.txe() | 203 | !Self::check_and_clear_error_flags(self.info)?.txe() |
| 204 | } { | 204 | } { |
| 205 | timeout.check()?; | 205 | timeout.check()?; |
| 206 | } | 206 | } |
| 207 | 207 | ||
| 208 | // Push out a byte of data | 208 | // Push out a byte of data |
| 209 | T::regs().dr().write(|reg| reg.set_dr(byte)); | 209 | self.info.regs.dr().write(|reg| reg.set_dr(byte)); |
| 210 | 210 | ||
| 211 | // Wait until byte is transferred | 211 | // Wait until byte is transferred |
| 212 | while { | 212 | while { |
| 213 | // Check for any potential error conditions. | 213 | // Check for any potential error conditions. |
| 214 | !Self::check_and_clear_error_flags()?.btf() | 214 | !Self::check_and_clear_error_flags(self.info)?.btf() |
| 215 | } { | 215 | } { |
| 216 | timeout.check()?; | 216 | timeout.check()?; |
| 217 | } | 217 | } |
| @@ -222,14 +222,14 @@ impl<'d, T: Instance, M: PeriMode> I2c<'d, T, M> { | |||
| 222 | fn recv_byte(&self, timeout: Timeout) -> Result<u8, Error> { | 222 | fn recv_byte(&self, timeout: Timeout) -> Result<u8, Error> { |
| 223 | while { | 223 | while { |
| 224 | // Check for any potential error conditions. | 224 | // Check for any potential error conditions. |
| 225 | Self::check_and_clear_error_flags()?; | 225 | Self::check_and_clear_error_flags(self.info)?; |
| 226 | 226 | ||
| 227 | !T::regs().sr1().read().rxne() | 227 | !self.info.regs.sr1().read().rxne() |
| 228 | } { | 228 | } { |
| 229 | timeout.check()?; | 229 | timeout.check()?; |
| 230 | } | 230 | } |
| 231 | 231 | ||
| 232 | let value = T::regs().dr().read().dr(); | 232 | let value = self.info.regs.dr().read().dr(); |
| 233 | Ok(value) | 233 | Ok(value) |
| 234 | } | 234 | } |
| 235 | 235 | ||
| @@ -246,32 +246,32 @@ impl<'d, T: Instance, M: PeriMode> I2c<'d, T, M> { | |||
| 246 | 246 | ||
| 247 | if frame.send_start() { | 247 | if frame.send_start() { |
| 248 | // Send a START condition and set ACK bit | 248 | // Send a START condition and set ACK bit |
| 249 | T::regs().cr1().modify(|reg| { | 249 | self.info.regs.cr1().modify(|reg| { |
| 250 | reg.set_start(true); | 250 | reg.set_start(true); |
| 251 | reg.set_ack(true); | 251 | reg.set_ack(true); |
| 252 | }); | 252 | }); |
| 253 | 253 | ||
| 254 | // Wait until START condition was generated | 254 | // Wait until START condition was generated |
| 255 | while !Self::check_and_clear_error_flags()?.start() { | 255 | while !Self::check_and_clear_error_flags(self.info)?.start() { |
| 256 | timeout.check()?; | 256 | timeout.check()?; |
| 257 | } | 257 | } |
| 258 | 258 | ||
| 259 | // Check if we were the ones to generate START | 259 | // Check if we were the ones to generate START |
| 260 | if T::regs().cr1().read().start() || !T::regs().sr2().read().msl() { | 260 | if self.info.regs.cr1().read().start() || !self.info.regs.sr2().read().msl() { |
| 261 | return Err(Error::Arbitration); | 261 | return Err(Error::Arbitration); |
| 262 | } | 262 | } |
| 263 | 263 | ||
| 264 | // Set up current address we're trying to talk to | 264 | // Set up current address we're trying to talk to |
| 265 | T::regs().dr().write(|reg| reg.set_dr((addr << 1) + 1)); | 265 | self.info.regs.dr().write(|reg| reg.set_dr((addr << 1) + 1)); |
| 266 | 266 | ||
| 267 | // Wait until address was sent | 267 | // Wait until address was sent |
| 268 | // Wait for the address to be acknowledged | 268 | // Wait for the address to be acknowledged |
| 269 | while !Self::check_and_clear_error_flags()?.addr() { | 269 | while !Self::check_and_clear_error_flags(self.info)?.addr() { |
| 270 | timeout.check()?; | 270 | timeout.check()?; |
| 271 | } | 271 | } |
| 272 | 272 | ||
| 273 | // Clear condition by reading SR2 | 273 | // Clear condition by reading SR2 |
| 274 | let _ = T::regs().sr2().read(); | 274 | let _ = self.info.regs.sr2().read(); |
| 275 | } | 275 | } |
| 276 | 276 | ||
| 277 | // Receive bytes into buffer | 277 | // Receive bytes into buffer |
| @@ -280,7 +280,7 @@ impl<'d, T: Instance, M: PeriMode> I2c<'d, T, M> { | |||
| 280 | } | 280 | } |
| 281 | 281 | ||
| 282 | // Prepare to send NACK then STOP after next byte | 282 | // Prepare to send NACK then STOP after next byte |
| 283 | T::regs().cr1().modify(|reg| { | 283 | self.info.regs.cr1().modify(|reg| { |
| 284 | if frame.send_nack() { | 284 | if frame.send_nack() { |
| 285 | reg.set_ack(false); | 285 | reg.set_ack(false); |
| 286 | } | 286 | } |
| @@ -346,17 +346,17 @@ impl<'d, T: Instance, M: PeriMode> I2c<'d, T, M> { | |||
| 346 | // Async | 346 | // Async |
| 347 | 347 | ||
| 348 | #[inline] // pretty sure this should always be inlined | 348 | #[inline] // pretty sure this should always be inlined |
| 349 | fn enable_interrupts() -> () { | 349 | fn enable_interrupts(info: &'static Info) -> () { |
| 350 | T::regs().cr2().modify(|w| { | 350 | info.regs.cr2().modify(|w| { |
| 351 | w.set_iterren(true); | 351 | w.set_iterren(true); |
| 352 | w.set_itevten(true); | 352 | w.set_itevten(true); |
| 353 | }); | 353 | }); |
| 354 | } | 354 | } |
| 355 | } | 355 | } |
| 356 | 356 | ||
| 357 | impl<'d, T: Instance> I2c<'d, T, Async> { | 357 | impl<'d> I2c<'d, Async> { |
| 358 | async fn write_frame(&mut self, address: u8, write: &[u8], frame: FrameOptions) -> Result<(), Error> { | 358 | async fn write_frame(&mut self, address: u8, write: &[u8], frame: FrameOptions) -> Result<(), Error> { |
| 359 | T::regs().cr2().modify(|w| { | 359 | self.info.regs.cr2().modify(|w| { |
| 360 | // Note: Do not enable the ITBUFEN bit in the I2C_CR2 register if DMA is used for | 360 | // Note: Do not enable the ITBUFEN bit in the I2C_CR2 register if DMA is used for |
| 361 | // reception. | 361 | // reception. |
| 362 | w.set_itbufen(false); | 362 | w.set_itbufen(false); |
| @@ -370,33 +370,31 @@ impl<'d, T: Instance> I2c<'d, T, Async> { | |||
| 370 | // Sentinel to disable transfer when an error occurs or future is canceled. | 370 | // Sentinel to disable transfer when an error occurs or future is canceled. |
| 371 | // TODO: Generate STOP condition on cancel? | 371 | // TODO: Generate STOP condition on cancel? |
| 372 | let on_drop = OnDrop::new(|| { | 372 | let on_drop = OnDrop::new(|| { |
| 373 | T::regs().cr2().modify(|w| { | 373 | self.info.regs.cr2().modify(|w| { |
| 374 | w.set_dmaen(false); | 374 | w.set_dmaen(false); |
| 375 | w.set_iterren(false); | 375 | w.set_iterren(false); |
| 376 | w.set_itevten(false); | 376 | w.set_itevten(false); |
| 377 | }) | 377 | }) |
| 378 | }); | 378 | }); |
| 379 | 379 | ||
| 380 | let state = T::state(); | ||
| 381 | |||
| 382 | if frame.send_start() { | 380 | if frame.send_start() { |
| 383 | // Send a START condition | 381 | // Send a START condition |
| 384 | T::regs().cr1().modify(|reg| { | 382 | self.info.regs.cr1().modify(|reg| { |
| 385 | reg.set_start(true); | 383 | reg.set_start(true); |
| 386 | }); | 384 | }); |
| 387 | 385 | ||
| 388 | // Wait until START condition was generated | 386 | // Wait until START condition was generated |
| 389 | poll_fn(|cx| { | 387 | poll_fn(|cx| { |
| 390 | state.waker.register(cx.waker()); | 388 | self.state.waker.register(cx.waker()); |
| 391 | 389 | ||
| 392 | match Self::check_and_clear_error_flags() { | 390 | match Self::check_and_clear_error_flags(self.info) { |
| 393 | Err(e) => Poll::Ready(Err(e)), | 391 | Err(e) => Poll::Ready(Err(e)), |
| 394 | Ok(sr1) => { | 392 | Ok(sr1) => { |
| 395 | if sr1.start() { | 393 | if sr1.start() { |
| 396 | Poll::Ready(Ok(())) | 394 | Poll::Ready(Ok(())) |
| 397 | } else { | 395 | } else { |
| 398 | // When pending, (re-)enable interrupts to wake us up. | 396 | // When pending, (re-)enable interrupts to wake us up. |
| 399 | Self::enable_interrupts(); | 397 | Self::enable_interrupts(self.info); |
| 400 | Poll::Pending | 398 | Poll::Pending |
| 401 | } | 399 | } |
| 402 | } | 400 | } |
| @@ -405,25 +403,25 @@ impl<'d, T: Instance> I2c<'d, T, Async> { | |||
| 405 | .await?; | 403 | .await?; |
| 406 | 404 | ||
| 407 | // Check if we were the ones to generate START | 405 | // Check if we were the ones to generate START |
| 408 | if T::regs().cr1().read().start() || !T::regs().sr2().read().msl() { | 406 | if self.info.regs.cr1().read().start() || !self.info.regs.sr2().read().msl() { |
| 409 | return Err(Error::Arbitration); | 407 | return Err(Error::Arbitration); |
| 410 | } | 408 | } |
| 411 | 409 | ||
| 412 | // Set up current address we're trying to talk to | 410 | // Set up current address we're trying to talk to |
| 413 | T::regs().dr().write(|reg| reg.set_dr(address << 1)); | 411 | self.info.regs.dr().write(|reg| reg.set_dr(address << 1)); |
| 414 | 412 | ||
| 415 | // Wait for the address to be acknowledged | 413 | // Wait for the address to be acknowledged |
| 416 | poll_fn(|cx| { | 414 | poll_fn(|cx| { |
| 417 | state.waker.register(cx.waker()); | 415 | self.state.waker.register(cx.waker()); |
| 418 | 416 | ||
| 419 | match Self::check_and_clear_error_flags() { | 417 | match Self::check_and_clear_error_flags(self.info) { |
| 420 | Err(e) => Poll::Ready(Err(e)), | 418 | Err(e) => Poll::Ready(Err(e)), |
| 421 | Ok(sr1) => { | 419 | Ok(sr1) => { |
| 422 | if sr1.addr() { | 420 | if sr1.addr() { |
| 423 | Poll::Ready(Ok(())) | 421 | Poll::Ready(Ok(())) |
| 424 | } else { | 422 | } else { |
| 425 | // When pending, (re-)enable interrupts to wake us up. | 423 | // When pending, (re-)enable interrupts to wake us up. |
| 426 | Self::enable_interrupts(); | 424 | Self::enable_interrupts(self.info); |
| 427 | Poll::Pending | 425 | Poll::Pending |
| 428 | } | 426 | } |
| 429 | } | 427 | } |
| @@ -432,26 +430,26 @@ impl<'d, T: Instance> I2c<'d, T, Async> { | |||
| 432 | .await?; | 430 | .await?; |
| 433 | 431 | ||
| 434 | // Clear condition by reading SR2 | 432 | // Clear condition by reading SR2 |
| 435 | T::regs().sr2().read(); | 433 | self.info.regs.sr2().read(); |
| 436 | } | 434 | } |
| 437 | 435 | ||
| 438 | let dma_transfer = unsafe { | 436 | let dma_transfer = unsafe { |
| 439 | // Set the I2C_DR register address in the DMA_SxPAR register. The data will be moved to | 437 | // Set the I2C_DR register address in the DMA_SxPAR register. The data will be moved to |
| 440 | // this address from the memory after each TxE event. | 438 | // this address from the memory after each TxE event. |
| 441 | let dst = T::regs().dr().as_ptr() as *mut u8; | 439 | let dst = self.info.regs.dr().as_ptr() as *mut u8; |
| 442 | 440 | ||
| 443 | self.tx_dma.as_mut().unwrap().write(write, dst, Default::default()) | 441 | self.tx_dma.as_mut().unwrap().write(write, dst, Default::default()) |
| 444 | }; | 442 | }; |
| 445 | 443 | ||
| 446 | // Wait for bytes to be sent, or an error to occur. | 444 | // Wait for bytes to be sent, or an error to occur. |
| 447 | let poll_error = poll_fn(|cx| { | 445 | let poll_error = poll_fn(|cx| { |
| 448 | state.waker.register(cx.waker()); | 446 | self.state.waker.register(cx.waker()); |
| 449 | 447 | ||
| 450 | match Self::check_and_clear_error_flags() { | 448 | match Self::check_and_clear_error_flags(self.info) { |
| 451 | Err(e) => Poll::Ready(Err::<(), Error>(e)), | 449 | Err(e) => Poll::Ready(Err::<(), Error>(e)), |
| 452 | Ok(_) => { | 450 | Ok(_) => { |
| 453 | // When pending, (re-)enable interrupts to wake us up. | 451 | // When pending, (re-)enable interrupts to wake us up. |
| 454 | Self::enable_interrupts(); | 452 | Self::enable_interrupts(self.info); |
| 455 | Poll::Pending | 453 | Poll::Pending |
| 456 | } | 454 | } |
| 457 | } | 455 | } |
| @@ -463,7 +461,7 @@ impl<'d, T: Instance> I2c<'d, T, Async> { | |||
| 463 | _ => Ok(()), | 461 | _ => Ok(()), |
| 464 | }?; | 462 | }?; |
| 465 | 463 | ||
| 466 | T::regs().cr2().modify(|w| { | 464 | self.info.regs.cr2().modify(|w| { |
| 467 | w.set_dmaen(false); | 465 | w.set_dmaen(false); |
| 468 | }); | 466 | }); |
| 469 | 467 | ||
| @@ -473,16 +471,16 @@ impl<'d, T: Instance> I2c<'d, T, Async> { | |||
| 473 | // 18.3.8 “Master transmitter: In the interrupt routine after the EOT interrupt, disable DMA | 471 | // 18.3.8 “Master transmitter: In the interrupt routine after the EOT interrupt, disable DMA |
| 474 | // requests then wait for a BTF event before programming the Stop condition.” | 472 | // requests then wait for a BTF event before programming the Stop condition.” |
| 475 | poll_fn(|cx| { | 473 | poll_fn(|cx| { |
| 476 | state.waker.register(cx.waker()); | 474 | self.state.waker.register(cx.waker()); |
| 477 | 475 | ||
| 478 | match Self::check_and_clear_error_flags() { | 476 | match Self::check_and_clear_error_flags(self.info) { |
| 479 | Err(e) => Poll::Ready(Err(e)), | 477 | Err(e) => Poll::Ready(Err(e)), |
| 480 | Ok(sr1) => { | 478 | Ok(sr1) => { |
| 481 | if sr1.btf() { | 479 | if sr1.btf() { |
| 482 | Poll::Ready(Ok(())) | 480 | Poll::Ready(Ok(())) |
| 483 | } else { | 481 | } else { |
| 484 | // When pending, (re-)enable interrupts to wake us up. | 482 | // When pending, (re-)enable interrupts to wake us up. |
| 485 | Self::enable_interrupts(); | 483 | Self::enable_interrupts(self.info); |
| 486 | Poll::Pending | 484 | Poll::Pending |
| 487 | } | 485 | } |
| 488 | } | 486 | } |
| @@ -490,7 +488,7 @@ impl<'d, T: Instance> I2c<'d, T, Async> { | |||
| 490 | }) | 488 | }) |
| 491 | .await?; | 489 | .await?; |
| 492 | 490 | ||
| 493 | T::regs().cr1().modify(|w| { | 491 | self.info.regs.cr1().modify(|w| { |
| 494 | w.set_stop(true); | 492 | w.set_stop(true); |
| 495 | }); | 493 | }); |
| 496 | } | 494 | } |
| @@ -525,7 +523,7 @@ impl<'d, T: Instance> I2c<'d, T, Async> { | |||
| 525 | // Some branches below depend on whether the buffer contains only a single byte. | 523 | // Some branches below depend on whether the buffer contains only a single byte. |
| 526 | let single_byte = buffer.len() == 1; | 524 | let single_byte = buffer.len() == 1; |
| 527 | 525 | ||
| 528 | T::regs().cr2().modify(|w| { | 526 | self.info.regs.cr2().modify(|w| { |
| 529 | // Note: Do not enable the ITBUFEN bit in the I2C_CR2 register if DMA is used for | 527 | // Note: Do not enable the ITBUFEN bit in the I2C_CR2 register if DMA is used for |
| 530 | // reception. | 528 | // reception. |
| 531 | w.set_itbufen(false); | 529 | w.set_itbufen(false); |
| @@ -541,34 +539,32 @@ impl<'d, T: Instance> I2c<'d, T, Async> { | |||
| 541 | // Sentinel to disable transfer when an error occurs or future is canceled. | 539 | // Sentinel to disable transfer when an error occurs or future is canceled. |
| 542 | // TODO: Generate STOP condition on cancel? | 540 | // TODO: Generate STOP condition on cancel? |
| 543 | let on_drop = OnDrop::new(|| { | 541 | let on_drop = OnDrop::new(|| { |
| 544 | T::regs().cr2().modify(|w| { | 542 | self.info.regs.cr2().modify(|w| { |
| 545 | w.set_dmaen(false); | 543 | w.set_dmaen(false); |
| 546 | w.set_iterren(false); | 544 | w.set_iterren(false); |
| 547 | w.set_itevten(false); | 545 | w.set_itevten(false); |
| 548 | }) | 546 | }) |
| 549 | }); | 547 | }); |
| 550 | 548 | ||
| 551 | let state = T::state(); | ||
| 552 | |||
| 553 | if frame.send_start() { | 549 | if frame.send_start() { |
| 554 | // Send a START condition and set ACK bit | 550 | // Send a START condition and set ACK bit |
| 555 | T::regs().cr1().modify(|reg| { | 551 | self.info.regs.cr1().modify(|reg| { |
| 556 | reg.set_start(true); | 552 | reg.set_start(true); |
| 557 | reg.set_ack(true); | 553 | reg.set_ack(true); |
| 558 | }); | 554 | }); |
| 559 | 555 | ||
| 560 | // Wait until START condition was generated | 556 | // Wait until START condition was generated |
| 561 | poll_fn(|cx| { | 557 | poll_fn(|cx| { |
| 562 | state.waker.register(cx.waker()); | 558 | self.state.waker.register(cx.waker()); |
| 563 | 559 | ||
| 564 | match Self::check_and_clear_error_flags() { | 560 | match Self::check_and_clear_error_flags(self.info) { |
| 565 | Err(e) => Poll::Ready(Err(e)), | 561 | Err(e) => Poll::Ready(Err(e)), |
| 566 | Ok(sr1) => { | 562 | Ok(sr1) => { |
| 567 | if sr1.start() { | 563 | if sr1.start() { |
| 568 | Poll::Ready(Ok(())) | 564 | Poll::Ready(Ok(())) |
| 569 | } else { | 565 | } else { |
| 570 | // When pending, (re-)enable interrupts to wake us up. | 566 | // When pending, (re-)enable interrupts to wake us up. |
| 571 | Self::enable_interrupts(); | 567 | Self::enable_interrupts(self.info); |
| 572 | Poll::Pending | 568 | Poll::Pending |
| 573 | } | 569 | } |
| 574 | } | 570 | } |
| @@ -577,25 +573,25 @@ impl<'d, T: Instance> I2c<'d, T, Async> { | |||
| 577 | .await?; | 573 | .await?; |
| 578 | 574 | ||
| 579 | // Check if we were the ones to generate START | 575 | // Check if we were the ones to generate START |
| 580 | if T::regs().cr1().read().start() || !T::regs().sr2().read().msl() { | 576 | if self.info.regs.cr1().read().start() || !self.info.regs.sr2().read().msl() { |
| 581 | return Err(Error::Arbitration); | 577 | return Err(Error::Arbitration); |
| 582 | } | 578 | } |
| 583 | 579 | ||
| 584 | // Set up current address we're trying to talk to | 580 | // Set up current address we're trying to talk to |
| 585 | T::regs().dr().write(|reg| reg.set_dr((address << 1) + 1)); | 581 | self.info.regs.dr().write(|reg| reg.set_dr((address << 1) + 1)); |
| 586 | 582 | ||
| 587 | // Wait for the address to be acknowledged | 583 | // Wait for the address to be acknowledged |
| 588 | poll_fn(|cx| { | 584 | poll_fn(|cx| { |
| 589 | state.waker.register(cx.waker()); | 585 | self.state.waker.register(cx.waker()); |
| 590 | 586 | ||
| 591 | match Self::check_and_clear_error_flags() { | 587 | match Self::check_and_clear_error_flags(self.info) { |
| 592 | Err(e) => Poll::Ready(Err(e)), | 588 | Err(e) => Poll::Ready(Err(e)), |
| 593 | Ok(sr1) => { | 589 | Ok(sr1) => { |
| 594 | if sr1.addr() { | 590 | if sr1.addr() { |
| 595 | Poll::Ready(Ok(())) | 591 | Poll::Ready(Ok(())) |
| 596 | } else { | 592 | } else { |
| 597 | // When pending, (re-)enable interrupts to wake us up. | 593 | // When pending, (re-)enable interrupts to wake us up. |
| 598 | Self::enable_interrupts(); | 594 | Self::enable_interrupts(self.info); |
| 599 | Poll::Pending | 595 | Poll::Pending |
| 600 | } | 596 | } |
| 601 | } | 597 | } |
| @@ -606,18 +602,18 @@ impl<'d, T: Instance> I2c<'d, T, Async> { | |||
| 606 | // 18.3.8: When a single byte must be received: the NACK must be programmed during EV6 | 602 | // 18.3.8: When a single byte must be received: the NACK must be programmed during EV6 |
| 607 | // event, i.e. program ACK=0 when ADDR=1, before clearing ADDR flag. | 603 | // event, i.e. program ACK=0 when ADDR=1, before clearing ADDR flag. |
| 608 | if frame.send_nack() && single_byte { | 604 | if frame.send_nack() && single_byte { |
| 609 | T::regs().cr1().modify(|w| { | 605 | self.info.regs.cr1().modify(|w| { |
| 610 | w.set_ack(false); | 606 | w.set_ack(false); |
| 611 | }); | 607 | }); |
| 612 | } | 608 | } |
| 613 | 609 | ||
| 614 | // Clear condition by reading SR2 | 610 | // Clear condition by reading SR2 |
| 615 | T::regs().sr2().read(); | 611 | self.info.regs.sr2().read(); |
| 616 | } else { | 612 | } else { |
| 617 | // Before starting reception of single byte (but without START condition, i.e. in case | 613 | // Before starting reception of single byte (but without START condition, i.e. in case |
| 618 | // of continued frame), program NACK to emit at end of this byte. | 614 | // of continued frame), program NACK to emit at end of this byte. |
| 619 | if frame.send_nack() && single_byte { | 615 | if frame.send_nack() && single_byte { |
| 620 | T::regs().cr1().modify(|w| { | 616 | self.info.regs.cr1().modify(|w| { |
| 621 | w.set_ack(false); | 617 | w.set_ack(false); |
| 622 | }); | 618 | }); |
| 623 | } | 619 | } |
| @@ -627,7 +623,7 @@ impl<'d, T: Instance> I2c<'d, T, Async> { | |||
| 627 | // condition either after clearing ADDR flag, or in the DMA Transfer Complete interrupt | 623 | // condition either after clearing ADDR flag, or in the DMA Transfer Complete interrupt |
| 628 | // routine. | 624 | // routine. |
| 629 | if frame.send_stop() && single_byte { | 625 | if frame.send_stop() && single_byte { |
| 630 | T::regs().cr1().modify(|w| { | 626 | self.info.regs.cr1().modify(|w| { |
| 631 | w.set_stop(true); | 627 | w.set_stop(true); |
| 632 | }); | 628 | }); |
| 633 | } | 629 | } |
| @@ -635,20 +631,20 @@ impl<'d, T: Instance> I2c<'d, T, Async> { | |||
| 635 | let dma_transfer = unsafe { | 631 | let dma_transfer = unsafe { |
| 636 | // Set the I2C_DR register address in the DMA_SxPAR register. The data will be moved | 632 | // Set the I2C_DR register address in the DMA_SxPAR register. The data will be moved |
| 637 | // from this address from the memory after each RxE event. | 633 | // from this address from the memory after each RxE event. |
| 638 | let src = T::regs().dr().as_ptr() as *mut u8; | 634 | let src = self.info.regs.dr().as_ptr() as *mut u8; |
| 639 | 635 | ||
| 640 | self.rx_dma.as_mut().unwrap().read(src, buffer, Default::default()) | 636 | self.rx_dma.as_mut().unwrap().read(src, buffer, Default::default()) |
| 641 | }; | 637 | }; |
| 642 | 638 | ||
| 643 | // Wait for bytes to be received, or an error to occur. | 639 | // Wait for bytes to be received, or an error to occur. |
| 644 | let poll_error = poll_fn(|cx| { | 640 | let poll_error = poll_fn(|cx| { |
| 645 | state.waker.register(cx.waker()); | 641 | self.state.waker.register(cx.waker()); |
| 646 | 642 | ||
| 647 | match Self::check_and_clear_error_flags() { | 643 | match Self::check_and_clear_error_flags(self.info) { |
| 648 | Err(e) => Poll::Ready(Err::<(), Error>(e)), | 644 | Err(e) => Poll::Ready(Err::<(), Error>(e)), |
| 649 | _ => { | 645 | _ => { |
| 650 | // When pending, (re-)enable interrupts to wake us up. | 646 | // When pending, (re-)enable interrupts to wake us up. |
| 651 | Self::enable_interrupts(); | 647 | Self::enable_interrupts(self.info); |
| 652 | Poll::Pending | 648 | Poll::Pending |
| 653 | } | 649 | } |
| 654 | } | 650 | } |
| @@ -659,12 +655,12 @@ impl<'d, T: Instance> I2c<'d, T, Async> { | |||
| 659 | _ => Ok(()), | 655 | _ => Ok(()), |
| 660 | }?; | 656 | }?; |
| 661 | 657 | ||
| 662 | T::regs().cr2().modify(|w| { | 658 | self.info.regs.cr2().modify(|w| { |
| 663 | w.set_dmaen(false); | 659 | w.set_dmaen(false); |
| 664 | }); | 660 | }); |
| 665 | 661 | ||
| 666 | if frame.send_stop() && !single_byte { | 662 | if frame.send_stop() && !single_byte { |
| 667 | T::regs().cr1().modify(|w| { | 663 | self.info.regs.cr1().modify(|w| { |
| 668 | w.set_stop(true); | 664 | w.set_stop(true); |
| 669 | }); | 665 | }); |
| 670 | } | 666 | } |
| @@ -704,9 +700,9 @@ impl<'d, T: Instance> I2c<'d, T, Async> { | |||
| 704 | } | 700 | } |
| 705 | } | 701 | } |
| 706 | 702 | ||
| 707 | impl<'d, T: Instance, M: PeriMode> Drop for I2c<'d, T, M> { | 703 | impl<'d, M: PeriMode> Drop for I2c<'d, M> { |
| 708 | fn drop(&mut self) { | 704 | fn drop(&mut self) { |
| 709 | T::disable(); | 705 | self.info.enable_bit.disable() |
| 710 | } | 706 | } |
| 711 | } | 707 | } |
| 712 | 708 | ||
| @@ -810,20 +806,20 @@ impl Timings { | |||
| 810 | } | 806 | } |
| 811 | } | 807 | } |
| 812 | 808 | ||
| 813 | impl<'d, T: Instance, M: PeriMode> SetConfig for I2c<'d, T, M> { | 809 | impl<'d, M: PeriMode> SetConfig for I2c<'d, M> { |
| 814 | type Config = Hertz; | 810 | type Config = Hertz; |
| 815 | type ConfigError = (); | 811 | type ConfigError = (); |
| 816 | fn set_config(&mut self, config: &Self::Config) -> Result<(), ()> { | 812 | fn set_config(&mut self, config: &Self::Config) -> Result<(), ()> { |
| 817 | let timings = Timings::new(T::frequency(), *config); | 813 | let timings = Timings::new(self.kernel_clock, *config); |
| 818 | T::regs().cr2().modify(|reg| { | 814 | self.info.regs.cr2().modify(|reg| { |
| 819 | reg.set_freq(timings.freq); | 815 | reg.set_freq(timings.freq); |
| 820 | }); | 816 | }); |
| 821 | T::regs().ccr().modify(|reg| { | 817 | self.info.regs.ccr().modify(|reg| { |
| 822 | reg.set_f_s(timings.mode.f_s()); | 818 | reg.set_f_s(timings.mode.f_s()); |
| 823 | reg.set_duty(timings.duty.duty()); | 819 | reg.set_duty(timings.duty.duty()); |
| 824 | reg.set_ccr(timings.ccr); | 820 | reg.set_ccr(timings.ccr); |
| 825 | }); | 821 | }); |
| 826 | T::regs().trise().modify(|reg| { | 822 | self.info.regs.trise().modify(|reg| { |
| 827 | reg.set_trise(timings.trise); | 823 | reg.set_trise(timings.trise); |
| 828 | }); | 824 | }); |
| 829 | 825 | ||
diff --git a/embassy-stm32/src/i2c/v2.rs b/embassy-stm32/src/i2c/v2.rs index 12df98534..aa6daf786 100644 --- a/embassy-stm32/src/i2c/v2.rs +++ b/embassy-stm32/src/i2c/v2.rs | |||
| @@ -10,7 +10,7 @@ use super::*; | |||
| 10 | use crate::pac::i2c; | 10 | use crate::pac::i2c; |
| 11 | 11 | ||
| 12 | pub(crate) unsafe fn on_interrupt<T: Instance>() { | 12 | pub(crate) unsafe fn on_interrupt<T: Instance>() { |
| 13 | let regs = T::regs(); | 13 | let regs = T::info().regs; |
| 14 | let isr = regs.isr().read(); | 14 | let isr = regs.isr().read(); |
| 15 | 15 | ||
| 16 | if isr.tcr() || isr.tc() { | 16 | if isr.tcr() || isr.tc() { |
| @@ -23,16 +23,16 @@ pub(crate) unsafe fn on_interrupt<T: Instance>() { | |||
| 23 | }); | 23 | }); |
| 24 | } | 24 | } |
| 25 | 25 | ||
| 26 | impl<'d, T: Instance, M: Mode> I2c<'d, T, M> { | 26 | impl<'d, M: Mode> I2c<'d, M> { |
| 27 | pub(crate) fn init(&mut self, freq: Hertz, _config: Config) { | 27 | pub(crate) fn init(&mut self, freq: Hertz, _config: Config) { |
| 28 | T::regs().cr1().modify(|reg| { | 28 | self.info.regs.cr1().modify(|reg| { |
| 29 | reg.set_pe(false); | 29 | reg.set_pe(false); |
| 30 | reg.set_anfoff(false); | 30 | reg.set_anfoff(false); |
| 31 | }); | 31 | }); |
| 32 | 32 | ||
| 33 | let timings = Timings::new(T::frequency(), freq.into()); | 33 | let timings = Timings::new(self.kernel_clock, freq.into()); |
| 34 | 34 | ||
| 35 | T::regs().timingr().write(|reg| { | 35 | self.info.regs.timingr().write(|reg| { |
| 36 | reg.set_presc(timings.prescale); | 36 | reg.set_presc(timings.prescale); |
| 37 | reg.set_scll(timings.scll); | 37 | reg.set_scll(timings.scll); |
| 38 | reg.set_sclh(timings.sclh); | 38 | reg.set_sclh(timings.sclh); |
| @@ -40,16 +40,17 @@ impl<'d, T: Instance, M: Mode> I2c<'d, T, M> { | |||
| 40 | reg.set_scldel(timings.scldel); | 40 | reg.set_scldel(timings.scldel); |
| 41 | }); | 41 | }); |
| 42 | 42 | ||
| 43 | T::regs().cr1().modify(|reg| { | 43 | self.info.regs.cr1().modify(|reg| { |
| 44 | reg.set_pe(true); | 44 | reg.set_pe(true); |
| 45 | }); | 45 | }); |
| 46 | } | 46 | } |
| 47 | 47 | ||
| 48 | fn master_stop(&mut self) { | 48 | fn master_stop(&mut self) { |
| 49 | T::regs().cr2().write(|w| w.set_stop(true)); | 49 | self.info.regs.cr2().write(|w| w.set_stop(true)); |
| 50 | } | 50 | } |
| 51 | 51 | ||
| 52 | fn master_read( | 52 | fn master_read( |
| 53 | info: &'static Info, | ||
| 53 | address: u8, | 54 | address: u8, |
| 54 | length: usize, | 55 | length: usize, |
| 55 | stop: Stop, | 56 | stop: Stop, |
| @@ -63,7 +64,7 @@ impl<'d, T: Instance, M: Mode> I2c<'d, T, M> { | |||
| 63 | // Wait for any previous address sequence to end | 64 | // Wait for any previous address sequence to end |
| 64 | // automatically. This could be up to 50% of a bus | 65 | // automatically. This could be up to 50% of a bus |
| 65 | // cycle (ie. up to 0.5/freq) | 66 | // cycle (ie. up to 0.5/freq) |
| 66 | while T::regs().cr2().read().start() { | 67 | while info.regs.cr2().read().start() { |
| 67 | timeout.check()?; | 68 | timeout.check()?; |
| 68 | } | 69 | } |
| 69 | } | 70 | } |
| @@ -78,7 +79,7 @@ impl<'d, T: Instance, M: Mode> I2c<'d, T, M> { | |||
| 78 | i2c::vals::Reload::COMPLETED | 79 | i2c::vals::Reload::COMPLETED |
| 79 | }; | 80 | }; |
| 80 | 81 | ||
| 81 | T::regs().cr2().modify(|w| { | 82 | info.regs.cr2().modify(|w| { |
| 82 | w.set_sadd((address << 1 | 0) as u16); | 83 | w.set_sadd((address << 1 | 0) as u16); |
| 83 | w.set_add10(i2c::vals::Addmode::BIT7); | 84 | w.set_add10(i2c::vals::Addmode::BIT7); |
| 84 | w.set_dir(i2c::vals::Dir::READ); | 85 | w.set_dir(i2c::vals::Dir::READ); |
| @@ -91,13 +92,20 @@ impl<'d, T: Instance, M: Mode> I2c<'d, T, M> { | |||
| 91 | Ok(()) | 92 | Ok(()) |
| 92 | } | 93 | } |
| 93 | 94 | ||
| 94 | fn master_write(address: u8, length: usize, stop: Stop, reload: bool, timeout: Timeout) -> Result<(), Error> { | 95 | fn master_write( |
| 96 | info: &'static Info, | ||
| 97 | address: u8, | ||
| 98 | length: usize, | ||
| 99 | stop: Stop, | ||
| 100 | reload: bool, | ||
| 101 | timeout: Timeout, | ||
| 102 | ) -> Result<(), Error> { | ||
| 95 | assert!(length < 256); | 103 | assert!(length < 256); |
| 96 | 104 | ||
| 97 | // Wait for any previous address sequence to end | 105 | // Wait for any previous address sequence to end |
| 98 | // automatically. This could be up to 50% of a bus | 106 | // automatically. This could be up to 50% of a bus |
| 99 | // cycle (ie. up to 0.5/freq) | 107 | // cycle (ie. up to 0.5/freq) |
| 100 | while T::regs().cr2().read().start() { | 108 | while info.regs.cr2().read().start() { |
| 101 | timeout.check()?; | 109 | timeout.check()?; |
| 102 | } | 110 | } |
| 103 | 111 | ||
| @@ -110,7 +118,7 @@ impl<'d, T: Instance, M: Mode> I2c<'d, T, M> { | |||
| 110 | // Set START and prepare to send `bytes`. The | 118 | // Set START and prepare to send `bytes`. The |
| 111 | // START bit can be set even if the bus is BUSY or | 119 | // START bit can be set even if the bus is BUSY or |
| 112 | // I2C is in slave mode. | 120 | // I2C is in slave mode. |
| 113 | T::regs().cr2().modify(|w| { | 121 | info.regs.cr2().modify(|w| { |
| 114 | w.set_sadd((address << 1 | 0) as u16); | 122 | w.set_sadd((address << 1 | 0) as u16); |
| 115 | w.set_add10(i2c::vals::Addmode::BIT7); | 123 | w.set_add10(i2c::vals::Addmode::BIT7); |
| 116 | w.set_dir(i2c::vals::Dir::WRITE); | 124 | w.set_dir(i2c::vals::Dir::WRITE); |
| @@ -123,10 +131,10 @@ impl<'d, T: Instance, M: Mode> I2c<'d, T, M> { | |||
| 123 | Ok(()) | 131 | Ok(()) |
| 124 | } | 132 | } |
| 125 | 133 | ||
| 126 | fn master_continue(length: usize, reload: bool, timeout: Timeout) -> Result<(), Error> { | 134 | fn master_continue(info: &'static Info, length: usize, reload: bool, timeout: Timeout) -> Result<(), Error> { |
| 127 | assert!(length < 256 && length > 0); | 135 | assert!(length < 256 && length > 0); |
| 128 | 136 | ||
| 129 | while !T::regs().isr().read().tcr() { | 137 | while !info.regs.isr().read().tcr() { |
| 130 | timeout.check()?; | 138 | timeout.check()?; |
| 131 | } | 139 | } |
| 132 | 140 | ||
| @@ -136,7 +144,7 @@ impl<'d, T: Instance, M: Mode> I2c<'d, T, M> { | |||
| 136 | i2c::vals::Reload::COMPLETED | 144 | i2c::vals::Reload::COMPLETED |
| 137 | }; | 145 | }; |
| 138 | 146 | ||
| 139 | T::regs().cr2().modify(|w| { | 147 | info.regs.cr2().modify(|w| { |
| 140 | w.set_nbytes(length as u8); | 148 | w.set_nbytes(length as u8); |
| 141 | w.set_reload(reload); | 149 | w.set_reload(reload); |
| 142 | }); | 150 | }); |
| @@ -145,27 +153,27 @@ impl<'d, T: Instance, M: Mode> I2c<'d, T, M> { | |||
| 145 | } | 153 | } |
| 146 | 154 | ||
| 147 | fn flush_txdr(&self) { | 155 | fn flush_txdr(&self) { |
| 148 | if T::regs().isr().read().txis() { | 156 | if self.info.regs.isr().read().txis() { |
| 149 | T::regs().txdr().write(|w| w.set_txdata(0)); | 157 | self.info.regs.txdr().write(|w| w.set_txdata(0)); |
| 150 | } | 158 | } |
| 151 | if !T::regs().isr().read().txe() { | 159 | if !self.info.regs.isr().read().txe() { |
| 152 | T::regs().isr().modify(|w| w.set_txe(true)) | 160 | self.info.regs.isr().modify(|w| w.set_txe(true)) |
| 153 | } | 161 | } |
| 154 | } | 162 | } |
| 155 | 163 | ||
| 156 | fn wait_txe(&self, timeout: Timeout) -> Result<(), Error> { | 164 | fn wait_txe(&self, timeout: Timeout) -> Result<(), Error> { |
| 157 | loop { | 165 | loop { |
| 158 | let isr = T::regs().isr().read(); | 166 | let isr = self.info.regs.isr().read(); |
| 159 | if isr.txe() { | 167 | if isr.txe() { |
| 160 | return Ok(()); | 168 | return Ok(()); |
| 161 | } else if isr.berr() { | 169 | } else if isr.berr() { |
| 162 | T::regs().icr().write(|reg| reg.set_berrcf(true)); | 170 | self.info.regs.icr().write(|reg| reg.set_berrcf(true)); |
| 163 | return Err(Error::Bus); | 171 | return Err(Error::Bus); |
| 164 | } else if isr.arlo() { | 172 | } else if isr.arlo() { |
| 165 | T::regs().icr().write(|reg| reg.set_arlocf(true)); | 173 | self.info.regs.icr().write(|reg| reg.set_arlocf(true)); |
| 166 | return Err(Error::Arbitration); | 174 | return Err(Error::Arbitration); |
| 167 | } else if isr.nackf() { | 175 | } else if isr.nackf() { |
| 168 | T::regs().icr().write(|reg| reg.set_nackcf(true)); | 176 | self.info.regs.icr().write(|reg| reg.set_nackcf(true)); |
| 169 | self.flush_txdr(); | 177 | self.flush_txdr(); |
| 170 | return Err(Error::Nack); | 178 | return Err(Error::Nack); |
| 171 | } | 179 | } |
| @@ -176,17 +184,17 @@ impl<'d, T: Instance, M: Mode> I2c<'d, T, M> { | |||
| 176 | 184 | ||
| 177 | fn wait_rxne(&self, timeout: Timeout) -> Result<(), Error> { | 185 | fn wait_rxne(&self, timeout: Timeout) -> Result<(), Error> { |
| 178 | loop { | 186 | loop { |
| 179 | let isr = T::regs().isr().read(); | 187 | let isr = self.info.regs.isr().read(); |
| 180 | if isr.rxne() { | 188 | if isr.rxne() { |
| 181 | return Ok(()); | 189 | return Ok(()); |
| 182 | } else if isr.berr() { | 190 | } else if isr.berr() { |
| 183 | T::regs().icr().write(|reg| reg.set_berrcf(true)); | 191 | self.info.regs.icr().write(|reg| reg.set_berrcf(true)); |
| 184 | return Err(Error::Bus); | 192 | return Err(Error::Bus); |
| 185 | } else if isr.arlo() { | 193 | } else if isr.arlo() { |
| 186 | T::regs().icr().write(|reg| reg.set_arlocf(true)); | 194 | self.info.regs.icr().write(|reg| reg.set_arlocf(true)); |
| 187 | return Err(Error::Arbitration); | 195 | return Err(Error::Arbitration); |
| 188 | } else if isr.nackf() { | 196 | } else if isr.nackf() { |
| 189 | T::regs().icr().write(|reg| reg.set_nackcf(true)); | 197 | self.info.regs.icr().write(|reg| reg.set_nackcf(true)); |
| 190 | self.flush_txdr(); | 198 | self.flush_txdr(); |
| 191 | return Err(Error::Nack); | 199 | return Err(Error::Nack); |
| 192 | } | 200 | } |
| @@ -197,17 +205,17 @@ impl<'d, T: Instance, M: Mode> I2c<'d, T, M> { | |||
| 197 | 205 | ||
| 198 | fn wait_tc(&self, timeout: Timeout) -> Result<(), Error> { | 206 | fn wait_tc(&self, timeout: Timeout) -> Result<(), Error> { |
| 199 | loop { | 207 | loop { |
| 200 | let isr = T::regs().isr().read(); | 208 | let isr = self.info.regs.isr().read(); |
| 201 | if isr.tc() { | 209 | if isr.tc() { |
| 202 | return Ok(()); | 210 | return Ok(()); |
| 203 | } else if isr.berr() { | 211 | } else if isr.berr() { |
| 204 | T::regs().icr().write(|reg| reg.set_berrcf(true)); | 212 | self.info.regs.icr().write(|reg| reg.set_berrcf(true)); |
| 205 | return Err(Error::Bus); | 213 | return Err(Error::Bus); |
| 206 | } else if isr.arlo() { | 214 | } else if isr.arlo() { |
| 207 | T::regs().icr().write(|reg| reg.set_arlocf(true)); | 215 | self.info.regs.icr().write(|reg| reg.set_arlocf(true)); |
| 208 | return Err(Error::Arbitration); | 216 | return Err(Error::Arbitration); |
| 209 | } else if isr.nackf() { | 217 | } else if isr.nackf() { |
| 210 | T::regs().icr().write(|reg| reg.set_nackcf(true)); | 218 | self.info.regs.icr().write(|reg| reg.set_nackcf(true)); |
| 211 | self.flush_txdr(); | 219 | self.flush_txdr(); |
| 212 | return Err(Error::Nack); | 220 | return Err(Error::Nack); |
| 213 | } | 221 | } |
| @@ -226,6 +234,7 @@ impl<'d, T: Instance, M: Mode> I2c<'d, T, M> { | |||
| 226 | let last_chunk_idx = total_chunks.saturating_sub(1); | 234 | let last_chunk_idx = total_chunks.saturating_sub(1); |
| 227 | 235 | ||
| 228 | Self::master_read( | 236 | Self::master_read( |
| 237 | self.info, | ||
| 229 | address, | 238 | address, |
| 230 | read.len().min(255), | 239 | read.len().min(255), |
| 231 | Stop::Automatic, | 240 | Stop::Automatic, |
| @@ -236,14 +245,14 @@ impl<'d, T: Instance, M: Mode> I2c<'d, T, M> { | |||
| 236 | 245 | ||
| 237 | for (number, chunk) in read.chunks_mut(255).enumerate() { | 246 | for (number, chunk) in read.chunks_mut(255).enumerate() { |
| 238 | if number != 0 { | 247 | if number != 0 { |
| 239 | Self::master_continue(chunk.len(), number != last_chunk_idx, timeout)?; | 248 | Self::master_continue(self.info, chunk.len(), number != last_chunk_idx, timeout)?; |
| 240 | } | 249 | } |
| 241 | 250 | ||
| 242 | for byte in chunk { | 251 | for byte in chunk { |
| 243 | // Wait until we have received something | 252 | // Wait until we have received something |
| 244 | self.wait_rxne(timeout)?; | 253 | self.wait_rxne(timeout)?; |
| 245 | 254 | ||
| 246 | *byte = T::regs().rxdr().read().rxdata(); | 255 | *byte = self.info.regs.rxdr().read().rxdata(); |
| 247 | } | 256 | } |
| 248 | } | 257 | } |
| 249 | Ok(()) | 258 | Ok(()) |
| @@ -262,6 +271,7 @@ impl<'d, T: Instance, M: Mode> I2c<'d, T, M> { | |||
| 262 | // | 271 | // |
| 263 | // ST SAD+W | 272 | // ST SAD+W |
| 264 | if let Err(err) = Self::master_write( | 273 | if let Err(err) = Self::master_write( |
| 274 | self.info, | ||
| 265 | address, | 275 | address, |
| 266 | write.len().min(255), | 276 | write.len().min(255), |
| 267 | Stop::Software, | 277 | Stop::Software, |
| @@ -276,7 +286,7 @@ impl<'d, T: Instance, M: Mode> I2c<'d, T, M> { | |||
| 276 | 286 | ||
| 277 | for (number, chunk) in write.chunks(255).enumerate() { | 287 | for (number, chunk) in write.chunks(255).enumerate() { |
| 278 | if number != 0 { | 288 | if number != 0 { |
| 279 | Self::master_continue(chunk.len(), number != last_chunk_idx, timeout)?; | 289 | Self::master_continue(self.info, chunk.len(), number != last_chunk_idx, timeout)?; |
| 280 | } | 290 | } |
| 281 | 291 | ||
| 282 | for byte in chunk { | 292 | for byte in chunk { |
| @@ -290,7 +300,7 @@ impl<'d, T: Instance, M: Mode> I2c<'d, T, M> { | |||
| 290 | return Err(err); | 300 | return Err(err); |
| 291 | } | 301 | } |
| 292 | 302 | ||
| 293 | T::regs().txdr().write(|w| w.set_txdata(*byte)); | 303 | self.info.regs.txdr().write(|w| w.set_txdata(*byte)); |
| 294 | } | 304 | } |
| 295 | } | 305 | } |
| 296 | // Wait until the write finishes | 306 | // Wait until the write finishes |
| @@ -348,6 +358,7 @@ impl<'d, T: Instance, M: Mode> I2c<'d, T, M> { | |||
| 348 | let last_slice_index = write.len() - 1; | 358 | let last_slice_index = write.len() - 1; |
| 349 | 359 | ||
| 350 | if let Err(err) = Self::master_write( | 360 | if let Err(err) = Self::master_write( |
| 361 | self.info, | ||
| 351 | address, | 362 | address, |
| 352 | first_length.min(255), | 363 | first_length.min(255), |
| 353 | Stop::Software, | 364 | Stop::Software, |
| @@ -370,6 +381,7 @@ impl<'d, T: Instance, M: Mode> I2c<'d, T, M> { | |||
| 370 | 381 | ||
| 371 | if idx != 0 { | 382 | if idx != 0 { |
| 372 | if let Err(err) = Self::master_continue( | 383 | if let Err(err) = Self::master_continue( |
| 384 | self.info, | ||
| 373 | slice_len.min(255), | 385 | slice_len.min(255), |
| 374 | (idx != last_slice_index) || (slice_len > 255), | 386 | (idx != last_slice_index) || (slice_len > 255), |
| 375 | timeout, | 387 | timeout, |
| @@ -382,6 +394,7 @@ impl<'d, T: Instance, M: Mode> I2c<'d, T, M> { | |||
| 382 | for (number, chunk) in slice.chunks(255).enumerate() { | 394 | for (number, chunk) in slice.chunks(255).enumerate() { |
| 383 | if number != 0 { | 395 | if number != 0 { |
| 384 | if let Err(err) = Self::master_continue( | 396 | if let Err(err) = Self::master_continue( |
| 397 | self.info, | ||
| 385 | chunk.len(), | 398 | chunk.len(), |
| 386 | (number != last_chunk_idx) || (idx != last_slice_index), | 399 | (number != last_chunk_idx) || (idx != last_slice_index), |
| 387 | timeout, | 400 | timeout, |
| @@ -402,7 +415,7 @@ impl<'d, T: Instance, M: Mode> I2c<'d, T, M> { | |||
| 402 | 415 | ||
| 403 | // Put byte on the wire | 416 | // Put byte on the wire |
| 404 | //self.i2c.txdr.write(|w| w.txdata().bits(*byte)); | 417 | //self.i2c.txdr.write(|w| w.txdata().bits(*byte)); |
| 405 | T::regs().txdr().write(|w| w.set_txdata(*byte)); | 418 | self.info.regs.txdr().write(|w| w.set_txdata(*byte)); |
| 406 | } | 419 | } |
| 407 | } | 420 | } |
| 408 | } | 421 | } |
| @@ -413,7 +426,7 @@ impl<'d, T: Instance, M: Mode> I2c<'d, T, M> { | |||
| 413 | } | 426 | } |
| 414 | } | 427 | } |
| 415 | 428 | ||
| 416 | impl<'d, T: Instance> I2c<'d, T, Async> { | 429 | impl<'d> I2c<'d, Async> { |
| 417 | async fn write_dma_internal( | 430 | async fn write_dma_internal( |
| 418 | &mut self, | 431 | &mut self, |
| 419 | address: u8, | 432 | address: u8, |
| @@ -425,7 +438,7 @@ impl<'d, T: Instance> I2c<'d, T, Async> { | |||
| 425 | let total_len = write.len(); | 438 | let total_len = write.len(); |
| 426 | 439 | ||
| 427 | let dma_transfer = unsafe { | 440 | let dma_transfer = unsafe { |
| 428 | let regs = T::regs(); | 441 | let regs = self.info.regs; |
| 429 | regs.cr1().modify(|w| { | 442 | regs.cr1().modify(|w| { |
| 430 | w.set_txdmaen(true); | 443 | w.set_txdmaen(true); |
| 431 | if first_slice { | 444 | if first_slice { |
| @@ -437,11 +450,10 @@ impl<'d, T: Instance> I2c<'d, T, Async> { | |||
| 437 | self.tx_dma.as_mut().unwrap().write(write, dst, Default::default()) | 450 | self.tx_dma.as_mut().unwrap().write(write, dst, Default::default()) |
| 438 | }; | 451 | }; |
| 439 | 452 | ||
| 440 | let state = T::state(); | ||
| 441 | let mut remaining_len = total_len; | 453 | let mut remaining_len = total_len; |
| 442 | 454 | ||
| 443 | let on_drop = OnDrop::new(|| { | 455 | let on_drop = OnDrop::new(|| { |
| 444 | let regs = T::regs(); | 456 | let regs = self.info.regs; |
| 445 | regs.cr1().modify(|w| { | 457 | regs.cr1().modify(|w| { |
| 446 | if last_slice { | 458 | if last_slice { |
| 447 | w.set_txdmaen(false); | 459 | w.set_txdmaen(false); |
| @@ -451,12 +463,13 @@ impl<'d, T: Instance> I2c<'d, T, Async> { | |||
| 451 | }); | 463 | }); |
| 452 | 464 | ||
| 453 | poll_fn(|cx| { | 465 | poll_fn(|cx| { |
| 454 | state.waker.register(cx.waker()); | 466 | self.state.waker.register(cx.waker()); |
| 455 | 467 | ||
| 456 | let isr = T::regs().isr().read(); | 468 | let isr = self.info.regs.isr().read(); |
| 457 | if remaining_len == total_len { | 469 | if remaining_len == total_len { |
| 458 | if first_slice { | 470 | if first_slice { |
| 459 | Self::master_write( | 471 | Self::master_write( |
| 472 | self.info, | ||
| 460 | address, | 473 | address, |
| 461 | total_len.min(255), | 474 | total_len.min(255), |
| 462 | Stop::Software, | 475 | Stop::Software, |
| @@ -464,8 +477,8 @@ impl<'d, T: Instance> I2c<'d, T, Async> { | |||
| 464 | timeout, | 477 | timeout, |
| 465 | )?; | 478 | )?; |
| 466 | } else { | 479 | } else { |
| 467 | Self::master_continue(total_len.min(255), (total_len > 255) || !last_slice, timeout)?; | 480 | Self::master_continue(self.info, total_len.min(255), (total_len > 255) || !last_slice, timeout)?; |
| 468 | T::regs().cr1().modify(|w| w.set_tcie(true)); | 481 | self.info.regs.cr1().modify(|w| w.set_tcie(true)); |
| 469 | } | 482 | } |
| 470 | } else if !(isr.tcr() || isr.tc()) { | 483 | } else if !(isr.tcr() || isr.tc()) { |
| 471 | // poll_fn was woken without an interrupt present | 484 | // poll_fn was woken without an interrupt present |
| @@ -475,10 +488,10 @@ impl<'d, T: Instance> I2c<'d, T, Async> { | |||
| 475 | } else { | 488 | } else { |
| 476 | let last_piece = (remaining_len <= 255) && last_slice; | 489 | let last_piece = (remaining_len <= 255) && last_slice; |
| 477 | 490 | ||
| 478 | if let Err(e) = Self::master_continue(remaining_len.min(255), !last_piece, timeout) { | 491 | if let Err(e) = Self::master_continue(self.info, remaining_len.min(255), !last_piece, timeout) { |
| 479 | return Poll::Ready(Err(e)); | 492 | return Poll::Ready(Err(e)); |
| 480 | } | 493 | } |
| 481 | T::regs().cr1().modify(|w| w.set_tcie(true)); | 494 | self.info.regs.cr1().modify(|w| w.set_tcie(true)); |
| 482 | } | 495 | } |
| 483 | 496 | ||
| 484 | remaining_len = remaining_len.saturating_sub(255); | 497 | remaining_len = remaining_len.saturating_sub(255); |
| @@ -509,7 +522,7 @@ impl<'d, T: Instance> I2c<'d, T, Async> { | |||
| 509 | let total_len = buffer.len(); | 522 | let total_len = buffer.len(); |
| 510 | 523 | ||
| 511 | let dma_transfer = unsafe { | 524 | let dma_transfer = unsafe { |
| 512 | let regs = T::regs(); | 525 | let regs = self.info.regs; |
| 513 | regs.cr1().modify(|w| { | 526 | regs.cr1().modify(|w| { |
| 514 | w.set_rxdmaen(true); | 527 | w.set_rxdmaen(true); |
| 515 | w.set_tcie(true); | 528 | w.set_tcie(true); |
| @@ -519,11 +532,10 @@ impl<'d, T: Instance> I2c<'d, T, Async> { | |||
| 519 | self.rx_dma.as_mut().unwrap().read(src, buffer, Default::default()) | 532 | self.rx_dma.as_mut().unwrap().read(src, buffer, Default::default()) |
| 520 | }; | 533 | }; |
| 521 | 534 | ||
| 522 | let state = T::state(); | ||
| 523 | let mut remaining_len = total_len; | 535 | let mut remaining_len = total_len; |
| 524 | 536 | ||
| 525 | let on_drop = OnDrop::new(|| { | 537 | let on_drop = OnDrop::new(|| { |
| 526 | let regs = T::regs(); | 538 | let regs = self.info.regs; |
| 527 | regs.cr1().modify(|w| { | 539 | regs.cr1().modify(|w| { |
| 528 | w.set_rxdmaen(false); | 540 | w.set_rxdmaen(false); |
| 529 | w.set_tcie(false); | 541 | w.set_tcie(false); |
| @@ -531,11 +543,12 @@ impl<'d, T: Instance> I2c<'d, T, Async> { | |||
| 531 | }); | 543 | }); |
| 532 | 544 | ||
| 533 | poll_fn(|cx| { | 545 | poll_fn(|cx| { |
| 534 | state.waker.register(cx.waker()); | 546 | self.state.waker.register(cx.waker()); |
| 535 | 547 | ||
| 536 | let isr = T::regs().isr().read(); | 548 | let isr = self.info.regs.isr().read(); |
| 537 | if remaining_len == total_len { | 549 | if remaining_len == total_len { |
| 538 | Self::master_read( | 550 | Self::master_read( |
| 551 | self.info, | ||
| 539 | address, | 552 | address, |
| 540 | total_len.min(255), | 553 | total_len.min(255), |
| 541 | Stop::Software, | 554 | Stop::Software, |
| @@ -551,10 +564,10 @@ impl<'d, T: Instance> I2c<'d, T, Async> { | |||
| 551 | } else { | 564 | } else { |
| 552 | let last_piece = remaining_len <= 255; | 565 | let last_piece = remaining_len <= 255; |
| 553 | 566 | ||
| 554 | if let Err(e) = Self::master_continue(remaining_len.min(255), !last_piece, timeout) { | 567 | if let Err(e) = Self::master_continue(self.info, remaining_len.min(255), !last_piece, timeout) { |
| 555 | return Poll::Ready(Err(e)); | 568 | return Poll::Ready(Err(e)); |
| 556 | } | 569 | } |
| 557 | T::regs().cr1().modify(|w| w.set_tcie(true)); | 570 | self.info.regs.cr1().modify(|w| w.set_tcie(true)); |
| 558 | } | 571 | } |
| 559 | 572 | ||
| 560 | remaining_len = remaining_len.saturating_sub(255); | 573 | remaining_len = remaining_len.saturating_sub(255); |
| @@ -658,9 +671,9 @@ impl<'d, T: Instance> I2c<'d, T, Async> { | |||
| 658 | } | 671 | } |
| 659 | } | 672 | } |
| 660 | 673 | ||
| 661 | impl<'d, T: Instance, M: Mode> Drop for I2c<'d, T, M> { | 674 | impl<'d, M: Mode> Drop for I2c<'d, M> { |
| 662 | fn drop(&mut self) { | 675 | fn drop(&mut self) { |
| 663 | T::disable(); | 676 | self.info.enable_bit.disable(); |
| 664 | } | 677 | } |
| 665 | } | 678 | } |
| 666 | 679 | ||
| @@ -788,12 +801,12 @@ impl Timings { | |||
| 788 | } | 801 | } |
| 789 | } | 802 | } |
| 790 | 803 | ||
| 791 | impl<'d, T: Instance, M: Mode> SetConfig for I2c<'d, T, M> { | 804 | impl<'d, M: Mode> SetConfig for I2c<'d, M> { |
| 792 | type Config = Hertz; | 805 | type Config = Hertz; |
| 793 | type ConfigError = (); | 806 | type ConfigError = (); |
| 794 | fn set_config(&mut self, config: &Self::Config) -> Result<(), ()> { | 807 | fn set_config(&mut self, config: &Self::Config) -> Result<(), ()> { |
| 795 | let timings = Timings::new(T::frequency(), *config); | 808 | let timings = Timings::new(self.kernel_clock, *config); |
| 796 | T::regs().timingr().write(|reg| { | 809 | self.info.regs.timingr().write(|reg| { |
| 797 | reg.set_presc(timings.prescale); | 810 | reg.set_presc(timings.prescale); |
| 798 | reg.set_scll(timings.scll); | 811 | reg.set_scll(timings.scll); |
| 799 | reg.set_sclh(timings.sclh); | 812 | reg.set_sclh(timings.sclh); |
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..7f8076043 100644 --- a/embassy-stm32/src/macros.rs +++ b/embassy-stm32/src/macros.rs | |||
| @@ -1,16 +1,25 @@ | |||
| 1 | #![macro_use] | 1 | #![macro_use] |
| 2 | 2 | ||
| 3 | macro_rules! peri_trait { | 3 | macro_rules! peri_trait { |
| 4 | () => { | 4 | ( |
| 5 | $(irqs: [$($irq:ident),*],)? | ||
| 6 | ) => { | ||
| 5 | #[allow(private_interfaces)] | 7 | #[allow(private_interfaces)] |
| 6 | pub(crate) trait SealedInstance { | 8 | pub(crate) trait SealedInstance { |
| 7 | const INFO: Info; | 9 | #[allow(unused)] |
| 8 | const STATE: &'static State; | 10 | fn info() -> &'static Info; |
| 11 | #[allow(unused)] | ||
| 12 | fn state() -> &'static State; | ||
| 9 | } | 13 | } |
| 10 | 14 | ||
| 11 | /// SPI instance trait. | 15 | /// Peripheral instance trait. |
| 12 | #[allow(private_bounds)] | 16 | #[allow(private_bounds)] |
| 13 | pub trait Instance: Peripheral<P = Self> + SealedInstance + RccPeripheral {} | 17 | pub trait Instance: crate::Peripheral<P = Self> + SealedInstance + crate::rcc::RccPeripheral { |
| 18 | $($( | ||
| 19 | /// Interrupt for this peripheral. | ||
| 20 | type $irq: crate::interrupt::typelevel::Interrupt; | ||
| 21 | )*)? | ||
| 22 | } | ||
| 14 | }; | 23 | }; |
| 15 | } | 24 | } |
| 16 | 25 | ||
| @@ -18,8 +27,14 @@ macro_rules! peri_trait_impl { | |||
| 18 | ($instance:ident, $info:expr) => { | 27 | ($instance:ident, $info:expr) => { |
| 19 | #[allow(private_interfaces)] | 28 | #[allow(private_interfaces)] |
| 20 | impl SealedInstance for crate::peripherals::$instance { | 29 | impl SealedInstance for crate::peripherals::$instance { |
| 21 | const INFO: Info = $info; | 30 | fn info() -> &'static Info { |
| 22 | const STATE: &'static State = &State::new(); | 31 | static INFO: Info = $info; |
| 32 | &INFO | ||
| 33 | } | ||
| 34 | fn state() -> &'static State { | ||
| 35 | static STATE: State = State::new(); | ||
| 36 | &STATE | ||
| 37 | } | ||
| 23 | } | 38 | } |
| 24 | impl Instance for crate::peripherals::$instance {} | 39 | impl Instance for crate::peripherals::$instance {} |
| 25 | }; | 40 | }; |
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 | ); |
diff --git a/examples/stm32h7/src/bin/i2c_shared.rs b/examples/stm32h7/src/bin/i2c_shared.rs index 79d213ae4..6f4815582 100644 --- a/examples/stm32h7/src/bin/i2c_shared.rs +++ b/examples/stm32h7/src/bin/i2c_shared.rs | |||
| @@ -6,11 +6,10 @@ use core::cell::RefCell; | |||
| 6 | use defmt::*; | 6 | use defmt::*; |
| 7 | use embassy_embedded_hal::shared_bus::blocking::i2c::I2cDevice; | 7 | use embassy_embedded_hal::shared_bus::blocking::i2c::I2cDevice; |
| 8 | use embassy_executor::Spawner; | 8 | use embassy_executor::Spawner; |
| 9 | use embassy_stm32::bind_interrupts; | ||
| 10 | use embassy_stm32::i2c::{self, I2c}; | 9 | use embassy_stm32::i2c::{self, I2c}; |
| 11 | use embassy_stm32::mode::Async; | 10 | use embassy_stm32::mode::Async; |
| 12 | use embassy_stm32::peripherals::{self, I2C1}; | ||
| 13 | use embassy_stm32::time::Hertz; | 11 | use embassy_stm32::time::Hertz; |
| 12 | use embassy_stm32::{bind_interrupts, peripherals}; | ||
| 14 | use embassy_sync::blocking_mutex::NoopMutex; | 13 | use embassy_sync::blocking_mutex::NoopMutex; |
| 15 | use embassy_time::{Duration, Timer}; | 14 | use embassy_time::{Duration, Timer}; |
| 16 | use static_cell::StaticCell; | 15 | use static_cell::StaticCell; |
| @@ -24,7 +23,7 @@ const SHTC3_WAKEUP: [u8; 2] = [0x35, 0x17]; | |||
| 24 | const SHTC3_MEASURE_RH_FIRST: [u8; 2] = [0x5c, 0x24]; | 23 | const SHTC3_MEASURE_RH_FIRST: [u8; 2] = [0x5c, 0x24]; |
| 25 | const SHTC3_SLEEP: [u8; 2] = [0xb0, 0x98]; | 24 | const SHTC3_SLEEP: [u8; 2] = [0xb0, 0x98]; |
| 26 | 25 | ||
| 27 | static I2C_BUS: StaticCell<NoopMutex<RefCell<I2c<'static, I2C1, Async>>>> = StaticCell::new(); | 26 | static I2C_BUS: StaticCell<NoopMutex<RefCell<I2c<'static, Async>>>> = StaticCell::new(); |
| 28 | 27 | ||
| 29 | bind_interrupts!(struct Irqs { | 28 | bind_interrupts!(struct Irqs { |
| 30 | I2C1_EV => i2c::EventInterruptHandler<peripherals::I2C1>; | 29 | I2C1_EV => i2c::EventInterruptHandler<peripherals::I2C1>; |
diff --git a/examples/stm32l4/src/bin/spe_adin1110_http_server.rs b/examples/stm32l4/src/bin/spe_adin1110_http_server.rs index 985ac8171..33149144c 100644 --- a/examples/stm32l4/src/bin/spe_adin1110_http_server.rs +++ b/examples/stm32l4/src/bin/spe_adin1110_http_server.rs | |||
| @@ -60,7 +60,7 @@ pub type SpeSpiCs = ExclusiveDevice<SpeSpi, Output<'static>, Delay>; | |||
| 60 | pub type SpeInt = exti::ExtiInput<'static>; | 60 | pub type SpeInt = exti::ExtiInput<'static>; |
| 61 | pub type SpeRst = Output<'static>; | 61 | pub type SpeRst = Output<'static>; |
| 62 | pub type Adin1110T = ADIN1110<SpeSpiCs>; | 62 | pub type Adin1110T = ADIN1110<SpeSpiCs>; |
| 63 | pub type TempSensI2c = I2c<'static, peripherals::I2C3, Async>; | 63 | pub type TempSensI2c = I2c<'static, Async>; |
| 64 | 64 | ||
| 65 | static TEMP: AtomicI32 = AtomicI32::new(0); | 65 | static TEMP: AtomicI32 = AtomicI32::new(0); |
| 66 | 66 | ||
