diff options
| author | xoviat <[email protected]> | 2023-09-04 15:47:33 -0500 |
|---|---|---|
| committer | xoviat <[email protected]> | 2023-09-04 15:47:33 -0500 |
| commit | 274f63a879353923feac87f399aae9c5cadd4aa3 (patch) | |
| tree | 8d058a64199fbbf0bd9749386ef1d8b7aa0d14d2 | |
| parent | 3466c9cfa93cbcd796cd9125e4035e35546c3e9c (diff) | |
stm32: fix refcounts for usart, spi, and i2c
| -rw-r--r-- | embassy-stm32/build.rs | 18 | ||||
| -rw-r--r-- | embassy-stm32/src/i2c/v1.rs | 6 | ||||
| -rw-r--r-- | embassy-stm32/src/i2c/v2.rs | 6 | ||||
| -rw-r--r-- | embassy-stm32/src/spi/mod.rs | 2 | ||||
| -rw-r--r-- | embassy-stm32/src/usart/buffered.rs | 10 | ||||
| -rw-r--r-- | embassy-stm32/src/usart/mod.rs | 18 | ||||
| -rw-r--r-- | embassy-stm32/src/usart/ringbuffered.rs | 17 |
7 files changed, 60 insertions, 17 deletions
diff --git a/embassy-stm32/build.rs b/embassy-stm32/build.rs index 2b66e7dad..d3f6452b4 100644 --- a/embassy-stm32/build.rs +++ b/embassy-stm32/build.rs | |||
| @@ -347,9 +347,7 @@ fn main() { | |||
| 347 | TokenStream::new() | 347 | TokenStream::new() |
| 348 | }; | 348 | }; |
| 349 | 349 | ||
| 350 | let ptype = p | 350 | let ptype = p.name.replace(|c| char::is_numeric(c), ""); |
| 351 | .name | ||
| 352 | .replace(&['0', '1', '2', '3', '4', '5', '6', '7', '8', '9'][..], ""); | ||
| 353 | let pname = format_ident!("{}", p.name); | 351 | let pname = format_ident!("{}", p.name); |
| 354 | let clk = format_ident!("{}", rcc.clock.to_ascii_lowercase()); | 352 | let clk = format_ident!("{}", rcc.clock.to_ascii_lowercase()); |
| 355 | let en_reg = format_ident!("{}", en.register.to_ascii_lowercase()); | 353 | let en_reg = format_ident!("{}", en.register.to_ascii_lowercase()); |
| @@ -363,16 +361,14 @@ fn main() { | |||
| 363 | 361 | ||
| 364 | ( | 362 | ( |
| 365 | quote! { | 363 | quote! { |
| 366 | use atomic_polyfill::Ordering; | 364 | unsafe { refcount_statics::#refcount_static += 1 }; |
| 367 | 365 | if unsafe { refcount_statics::#refcount_static } > 1 { | |
| 368 | if refcount_statics::#refcount_static.fetch_add(1, Ordering::SeqCst) > 0 { | ||
| 369 | return; | 366 | return; |
| 370 | } | 367 | } |
| 371 | }, | 368 | }, |
| 372 | quote! { | 369 | quote! { |
| 373 | use atomic_polyfill::Ordering; | 370 | unsafe { refcount_statics::#refcount_static -= 1 }; |
| 374 | 371 | if unsafe { refcount_statics::#refcount_static } > 0 { | |
| 375 | if refcount_statics::#refcount_static.fetch_sub(1, Ordering::SeqCst) > 1 { | ||
| 376 | return; | 372 | return; |
| 377 | } | 373 | } |
| 378 | }, | 374 | }, |
| @@ -416,14 +412,12 @@ fn main() { | |||
| 416 | let mut refcount_mod = TokenStream::new(); | 412 | let mut refcount_mod = TokenStream::new(); |
| 417 | for refcount_static in refcount_statics { | 413 | for refcount_static in refcount_statics { |
| 418 | refcount_mod.extend(quote! { | 414 | refcount_mod.extend(quote! { |
| 419 | pub(crate) static #refcount_static: AtomicU8 = AtomicU8::new(0); | 415 | pub(crate) static mut #refcount_static: u8 = 0; |
| 420 | }); | 416 | }); |
| 421 | } | 417 | } |
| 422 | 418 | ||
| 423 | g.extend(quote! { | 419 | g.extend(quote! { |
| 424 | mod refcount_statics { | 420 | mod refcount_statics { |
| 425 | use atomic_polyfill::AtomicU8; | ||
| 426 | |||
| 427 | #refcount_mod | 421 | #refcount_mod |
| 428 | } | 422 | } |
| 429 | }); | 423 | }); |
diff --git a/embassy-stm32/src/i2c/v1.rs b/embassy-stm32/src/i2c/v1.rs index 618d85af2..f32dd0f0c 100644 --- a/embassy-stm32/src/i2c/v1.rs +++ b/embassy-stm32/src/i2c/v1.rs | |||
| @@ -339,6 +339,12 @@ impl<'d, T: Instance, TXDMA, RXDMA> I2c<'d, T, TXDMA, RXDMA> { | |||
| 339 | } | 339 | } |
| 340 | } | 340 | } |
| 341 | 341 | ||
| 342 | impl<'d, T: Instance, TXDMA, RXDMA> Drop for I2c<'d, T, TXDMA, RXDMA> { | ||
| 343 | fn drop(&mut self) { | ||
| 344 | T::disable(); | ||
| 345 | } | ||
| 346 | } | ||
| 347 | |||
| 342 | impl<'d, T: Instance> embedded_hal_02::blocking::i2c::Read for I2c<'d, T> { | 348 | impl<'d, T: Instance> embedded_hal_02::blocking::i2c::Read for I2c<'d, T> { |
| 343 | type Error = Error; | 349 | type Error = Error; |
| 344 | 350 | ||
diff --git a/embassy-stm32/src/i2c/v2.rs b/embassy-stm32/src/i2c/v2.rs index 4327899bb..36f70e32e 100644 --- a/embassy-stm32/src/i2c/v2.rs +++ b/embassy-stm32/src/i2c/v2.rs | |||
| @@ -838,6 +838,12 @@ impl<'d, T: Instance, TXDMA, RXDMA> I2c<'d, T, TXDMA, RXDMA> { | |||
| 838 | } | 838 | } |
| 839 | } | 839 | } |
| 840 | 840 | ||
| 841 | impl<'d, T: Instance, TXDMA, RXDMA> Drop for I2c<'d, T, TXDMA, RXDMA> { | ||
| 842 | fn drop(&mut self) { | ||
| 843 | T::disable(); | ||
| 844 | } | ||
| 845 | } | ||
| 846 | |||
| 841 | mod eh02 { | 847 | mod eh02 { |
| 842 | use super::*; | 848 | use super::*; |
| 843 | 849 | ||
diff --git a/embassy-stm32/src/spi/mod.rs b/embassy-stm32/src/spi/mod.rs index e2bc8d7f2..853de98f9 100644 --- a/embassy-stm32/src/spi/mod.rs +++ b/embassy-stm32/src/spi/mod.rs | |||
| @@ -646,6 +646,8 @@ impl<'d, T: Instance, Tx, Rx> Drop for Spi<'d, T, Tx, Rx> { | |||
| 646 | self.sck.as_ref().map(|x| x.set_as_disconnected()); | 646 | self.sck.as_ref().map(|x| x.set_as_disconnected()); |
| 647 | self.mosi.as_ref().map(|x| x.set_as_disconnected()); | 647 | self.mosi.as_ref().map(|x| x.set_as_disconnected()); |
| 648 | self.miso.as_ref().map(|x| x.set_as_disconnected()); | 648 | self.miso.as_ref().map(|x| x.set_as_disconnected()); |
| 649 | |||
| 650 | T::disable(); | ||
| 649 | } | 651 | } |
| 650 | } | 652 | } |
| 651 | 653 | ||
diff --git a/embassy-stm32/src/usart/buffered.rs b/embassy-stm32/src/usart/buffered.rs index 596d40bf9..989c88205 100644 --- a/embassy-stm32/src/usart/buffered.rs +++ b/embassy-stm32/src/usart/buffered.rs | |||
| @@ -124,6 +124,8 @@ impl<'d, T: BasicInstance> BufferedUart<'d, T> { | |||
| 124 | rx_buffer: &'d mut [u8], | 124 | rx_buffer: &'d mut [u8], |
| 125 | config: Config, | 125 | config: Config, |
| 126 | ) -> BufferedUart<'d, T> { | 126 | ) -> BufferedUart<'d, T> { |
| 127 | // UartRx and UartTx have one refcount ea. | ||
| 128 | T::enable(); | ||
| 127 | T::enable(); | 129 | T::enable(); |
| 128 | T::reset(); | 130 | T::reset(); |
| 129 | 131 | ||
| @@ -143,6 +145,8 @@ impl<'d, T: BasicInstance> BufferedUart<'d, T> { | |||
| 143 | ) -> BufferedUart<'d, T> { | 145 | ) -> BufferedUart<'d, T> { |
| 144 | into_ref!(cts, rts); | 146 | into_ref!(cts, rts); |
| 145 | 147 | ||
| 148 | // UartRx and UartTx have one refcount ea. | ||
| 149 | T::enable(); | ||
| 146 | T::enable(); | 150 | T::enable(); |
| 147 | T::reset(); | 151 | T::reset(); |
| 148 | 152 | ||
| @@ -169,6 +173,8 @@ impl<'d, T: BasicInstance> BufferedUart<'d, T> { | |||
| 169 | ) -> BufferedUart<'d, T> { | 173 | ) -> BufferedUart<'d, T> { |
| 170 | into_ref!(de); | 174 | into_ref!(de); |
| 171 | 175 | ||
| 176 | // UartRx and UartTx have one refcount ea. | ||
| 177 | T::enable(); | ||
| 172 | T::enable(); | 178 | T::enable(); |
| 173 | T::reset(); | 179 | T::reset(); |
| 174 | 180 | ||
| @@ -382,6 +388,8 @@ impl<'d, T: BasicInstance> Drop for BufferedUartRx<'d, T> { | |||
| 382 | T::Interrupt::disable(); | 388 | T::Interrupt::disable(); |
| 383 | } | 389 | } |
| 384 | } | 390 | } |
| 391 | |||
| 392 | T::disable(); | ||
| 385 | } | 393 | } |
| 386 | } | 394 | } |
| 387 | 395 | ||
| @@ -397,6 +405,8 @@ impl<'d, T: BasicInstance> Drop for BufferedUartTx<'d, T> { | |||
| 397 | T::Interrupt::disable(); | 405 | T::Interrupt::disable(); |
| 398 | } | 406 | } |
| 399 | } | 407 | } |
| 408 | |||
| 409 | T::disable(); | ||
| 400 | } | 410 | } |
| 401 | } | 411 | } |
| 402 | 412 | ||
diff --git a/embassy-stm32/src/usart/mod.rs b/embassy-stm32/src/usart/mod.rs index 255ddfd4b..bfb056718 100644 --- a/embassy-stm32/src/usart/mod.rs +++ b/embassy-stm32/src/usart/mod.rs | |||
| @@ -618,6 +618,18 @@ impl<'d, T: BasicInstance, RxDma> UartRx<'d, T, RxDma> { | |||
| 618 | } | 618 | } |
| 619 | } | 619 | } |
| 620 | 620 | ||
| 621 | impl<'d, T: BasicInstance, TxDma> Drop for UartTx<'d, T, TxDma> { | ||
| 622 | fn drop(&mut self) { | ||
| 623 | T::disable(); | ||
| 624 | } | ||
| 625 | } | ||
| 626 | |||
| 627 | impl<'d, T: BasicInstance, TxDma> Drop for UartRx<'d, T, TxDma> { | ||
| 628 | fn drop(&mut self) { | ||
| 629 | T::disable(); | ||
| 630 | } | ||
| 631 | } | ||
| 632 | |||
| 621 | impl<'d, T: BasicInstance, TxDma, RxDma> Uart<'d, T, TxDma, RxDma> { | 633 | impl<'d, T: BasicInstance, TxDma, RxDma> Uart<'d, T, TxDma, RxDma> { |
| 622 | pub fn new( | 634 | pub fn new( |
| 623 | peri: impl Peripheral<P = T> + 'd, | 635 | peri: impl Peripheral<P = T> + 'd, |
| @@ -628,6 +640,8 @@ impl<'d, T: BasicInstance, TxDma, RxDma> Uart<'d, T, TxDma, RxDma> { | |||
| 628 | rx_dma: impl Peripheral<P = RxDma> + 'd, | 640 | rx_dma: impl Peripheral<P = RxDma> + 'd, |
| 629 | config: Config, | 641 | config: Config, |
| 630 | ) -> Self { | 642 | ) -> Self { |
| 643 | // UartRx and UartTx have one refcount ea. | ||
| 644 | T::enable(); | ||
| 631 | T::enable(); | 645 | T::enable(); |
| 632 | T::reset(); | 646 | T::reset(); |
| 633 | 647 | ||
| @@ -647,6 +661,8 @@ impl<'d, T: BasicInstance, TxDma, RxDma> Uart<'d, T, TxDma, RxDma> { | |||
| 647 | ) -> Self { | 661 | ) -> Self { |
| 648 | into_ref!(cts, rts); | 662 | into_ref!(cts, rts); |
| 649 | 663 | ||
| 664 | // UartRx and UartTx have one refcount ea. | ||
| 665 | T::enable(); | ||
| 650 | T::enable(); | 666 | T::enable(); |
| 651 | T::reset(); | 667 | T::reset(); |
| 652 | 668 | ||
| @@ -672,6 +688,8 @@ impl<'d, T: BasicInstance, TxDma, RxDma> Uart<'d, T, TxDma, RxDma> { | |||
| 672 | ) -> Self { | 688 | ) -> Self { |
| 673 | into_ref!(de); | 689 | into_ref!(de); |
| 674 | 690 | ||
| 691 | // UartRx and UartTx have one refcount ea. | ||
| 692 | T::enable(); | ||
| 675 | T::enable(); | 693 | T::enable(); |
| 676 | T::reset(); | 694 | T::reset(); |
| 677 | 695 | ||
diff --git a/embassy-stm32/src/usart/ringbuffered.rs b/embassy-stm32/src/usart/ringbuffered.rs index b3f570624..e990eaca8 100644 --- a/embassy-stm32/src/usart/ringbuffered.rs +++ b/embassy-stm32/src/usart/ringbuffered.rs | |||
| @@ -1,4 +1,5 @@ | |||
| 1 | use core::future::poll_fn; | 1 | use core::future::poll_fn; |
| 2 | use core::mem; | ||
| 2 | use core::sync::atomic::{compiler_fence, Ordering}; | 3 | use core::sync::atomic::{compiler_fence, Ordering}; |
| 3 | use core::task::Poll; | 4 | use core::task::Poll; |
| 4 | 5 | ||
| @@ -24,12 +25,16 @@ impl<'d, T: BasicInstance, RxDma: super::RxDma<T>> UartRx<'d, T, RxDma> { | |||
| 24 | let request = self.rx_dma.request(); | 25 | let request = self.rx_dma.request(); |
| 25 | let opts = Default::default(); | 26 | let opts = Default::default(); |
| 26 | 27 | ||
| 27 | let ring_buf = unsafe { ReadableRingBuffer::new_read(self.rx_dma, request, rdr(T::regs()), dma_buf, opts) }; | 28 | // Safety: we forget the struct before this function returns. |
| 29 | let rx_dma = unsafe { self.rx_dma.clone_unchecked() }; | ||
| 30 | let _peri = unsafe { self._peri.clone_unchecked() }; | ||
| 28 | 31 | ||
| 29 | RingBufferedUartRx { | 32 | let ring_buf = unsafe { ReadableRingBuffer::new_read(rx_dma, request, rdr(T::regs()), dma_buf, opts) }; |
| 30 | _peri: self._peri, | 33 | |
| 31 | ring_buf, | 34 | // Don't disable the clock |
| 32 | } | 35 | mem::forget(self); |
| 36 | |||
| 37 | RingBufferedUartRx { _peri, ring_buf } | ||
| 33 | } | 38 | } |
| 34 | } | 39 | } |
| 35 | 40 | ||
| @@ -186,6 +191,8 @@ impl<'d, T: BasicInstance, RxDma: super::RxDma<T>> RingBufferedUartRx<'d, T, RxD | |||
| 186 | impl<T: BasicInstance, RxDma: super::RxDma<T>> Drop for RingBufferedUartRx<'_, T, RxDma> { | 191 | impl<T: BasicInstance, RxDma: super::RxDma<T>> Drop for RingBufferedUartRx<'_, T, RxDma> { |
| 187 | fn drop(&mut self) { | 192 | fn drop(&mut self) { |
| 188 | self.teardown_uart(); | 193 | self.teardown_uart(); |
| 194 | |||
| 195 | T::disable(); | ||
| 189 | } | 196 | } |
| 190 | } | 197 | } |
| 191 | /// Return an error result if the Sr register has errors | 198 | /// Return an error result if the Sr register has errors |
