stm32: fix refcounts for usart, spi, and i2c
This commit is contained in:
		| @@ -347,9 +347,7 @@ fn main() { | ||||
|                 TokenStream::new() | ||||
|             }; | ||||
|  | ||||
|             let ptype = p | ||||
|                 .name | ||||
|                 .replace(&['0', '1', '2', '3', '4', '5', '6', '7', '8', '9'][..], ""); | ||||
|             let ptype = p.name.replace(|c| char::is_numeric(c), ""); | ||||
|             let pname = format_ident!("{}", p.name); | ||||
|             let clk = format_ident!("{}", rcc.clock.to_ascii_lowercase()); | ||||
|             let en_reg = format_ident!("{}", en.register.to_ascii_lowercase()); | ||||
| @@ -363,16 +361,14 @@ fn main() { | ||||
|  | ||||
|                 ( | ||||
|                     quote! { | ||||
|                         use atomic_polyfill::Ordering; | ||||
|  | ||||
|                         if refcount_statics::#refcount_static.fetch_add(1, Ordering::SeqCst) > 0 { | ||||
|                         unsafe { refcount_statics::#refcount_static += 1 }; | ||||
|                         if unsafe { refcount_statics::#refcount_static } > 1 { | ||||
|                             return; | ||||
|                         } | ||||
|                     }, | ||||
|                     quote! { | ||||
|                         use atomic_polyfill::Ordering; | ||||
|  | ||||
|                         if refcount_statics::#refcount_static.fetch_sub(1, Ordering::SeqCst) > 1 { | ||||
|                         unsafe { refcount_statics::#refcount_static -= 1 }; | ||||
|                         if unsafe { refcount_statics::#refcount_static } > 0  { | ||||
|                             return; | ||||
|                         } | ||||
|                     }, | ||||
| @@ -416,14 +412,12 @@ fn main() { | ||||
|     let mut refcount_mod = TokenStream::new(); | ||||
|     for refcount_static in refcount_statics { | ||||
|         refcount_mod.extend(quote! { | ||||
|             pub(crate) static #refcount_static: AtomicU8 = AtomicU8::new(0); | ||||
|             pub(crate) static mut #refcount_static: u8 = 0; | ||||
|         }); | ||||
|     } | ||||
|  | ||||
|     g.extend(quote! { | ||||
|         mod refcount_statics { | ||||
|             use atomic_polyfill::AtomicU8; | ||||
|  | ||||
|             #refcount_mod | ||||
|         } | ||||
|     }); | ||||
|   | ||||
| @@ -339,6 +339,12 @@ impl<'d, T: Instance, TXDMA, RXDMA> I2c<'d, T, TXDMA, RXDMA> { | ||||
|     } | ||||
| } | ||||
|  | ||||
| impl<'d, T: Instance, TXDMA, RXDMA> Drop for I2c<'d, T, TXDMA, RXDMA> { | ||||
|     fn drop(&mut self) { | ||||
|         T::disable(); | ||||
|     } | ||||
| } | ||||
|  | ||||
| impl<'d, T: Instance> embedded_hal_02::blocking::i2c::Read for I2c<'d, T> { | ||||
|     type Error = Error; | ||||
|  | ||||
|   | ||||
| @@ -838,6 +838,12 @@ impl<'d, T: Instance, TXDMA, RXDMA> I2c<'d, T, TXDMA, RXDMA> { | ||||
|     } | ||||
| } | ||||
|  | ||||
| impl<'d, T: Instance, TXDMA, RXDMA> Drop for I2c<'d, T, TXDMA, RXDMA> { | ||||
|     fn drop(&mut self) { | ||||
|         T::disable(); | ||||
|     } | ||||
| } | ||||
|  | ||||
| mod eh02 { | ||||
|     use super::*; | ||||
|  | ||||
|   | ||||
| @@ -646,6 +646,8 @@ impl<'d, T: Instance, Tx, Rx> Drop for Spi<'d, T, Tx, Rx> { | ||||
|         self.sck.as_ref().map(|x| x.set_as_disconnected()); | ||||
|         self.mosi.as_ref().map(|x| x.set_as_disconnected()); | ||||
|         self.miso.as_ref().map(|x| x.set_as_disconnected()); | ||||
|  | ||||
|         T::disable(); | ||||
|     } | ||||
| } | ||||
|  | ||||
|   | ||||
| @@ -124,6 +124,8 @@ impl<'d, T: BasicInstance> BufferedUart<'d, T> { | ||||
|         rx_buffer: &'d mut [u8], | ||||
|         config: Config, | ||||
|     ) -> BufferedUart<'d, T> { | ||||
|         // UartRx and UartTx have one refcount ea. | ||||
|         T::enable(); | ||||
|         T::enable(); | ||||
|         T::reset(); | ||||
|  | ||||
| @@ -143,6 +145,8 @@ impl<'d, T: BasicInstance> BufferedUart<'d, T> { | ||||
|     ) -> BufferedUart<'d, T> { | ||||
|         into_ref!(cts, rts); | ||||
|  | ||||
|         // UartRx and UartTx have one refcount ea. | ||||
|         T::enable(); | ||||
|         T::enable(); | ||||
|         T::reset(); | ||||
|  | ||||
| @@ -169,6 +173,8 @@ impl<'d, T: BasicInstance> BufferedUart<'d, T> { | ||||
|     ) -> BufferedUart<'d, T> { | ||||
|         into_ref!(de); | ||||
|  | ||||
|         // UartRx and UartTx have one refcount ea. | ||||
|         T::enable(); | ||||
|         T::enable(); | ||||
|         T::reset(); | ||||
|  | ||||
| @@ -382,6 +388,8 @@ impl<'d, T: BasicInstance> Drop for BufferedUartRx<'d, T> { | ||||
|                 T::Interrupt::disable(); | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         T::disable(); | ||||
|     } | ||||
| } | ||||
|  | ||||
| @@ -397,6 +405,8 @@ impl<'d, T: BasicInstance> Drop for BufferedUartTx<'d, T> { | ||||
|                 T::Interrupt::disable(); | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         T::disable(); | ||||
|     } | ||||
| } | ||||
|  | ||||
|   | ||||
| @@ -618,6 +618,18 @@ impl<'d, T: BasicInstance, RxDma> UartRx<'d, T, RxDma> { | ||||
|     } | ||||
| } | ||||
|  | ||||
| impl<'d, T: BasicInstance, TxDma> Drop for UartTx<'d, T, TxDma> { | ||||
|     fn drop(&mut self) { | ||||
|         T::disable(); | ||||
|     } | ||||
| } | ||||
|  | ||||
| impl<'d, T: BasicInstance, TxDma> Drop for UartRx<'d, T, TxDma> { | ||||
|     fn drop(&mut self) { | ||||
|         T::disable(); | ||||
|     } | ||||
| } | ||||
|  | ||||
| impl<'d, T: BasicInstance, TxDma, RxDma> Uart<'d, T, TxDma, RxDma> { | ||||
|     pub fn new( | ||||
|         peri: impl Peripheral<P = T> + 'd, | ||||
| @@ -628,6 +640,8 @@ impl<'d, T: BasicInstance, TxDma, RxDma> Uart<'d, T, TxDma, RxDma> { | ||||
|         rx_dma: impl Peripheral<P = RxDma> + 'd, | ||||
|         config: Config, | ||||
|     ) -> Self { | ||||
|         // UartRx and UartTx have one refcount ea. | ||||
|         T::enable(); | ||||
|         T::enable(); | ||||
|         T::reset(); | ||||
|  | ||||
| @@ -647,6 +661,8 @@ impl<'d, T: BasicInstance, TxDma, RxDma> Uart<'d, T, TxDma, RxDma> { | ||||
|     ) -> Self { | ||||
|         into_ref!(cts, rts); | ||||
|  | ||||
|         // UartRx and UartTx have one refcount ea. | ||||
|         T::enable(); | ||||
|         T::enable(); | ||||
|         T::reset(); | ||||
|  | ||||
| @@ -672,6 +688,8 @@ impl<'d, T: BasicInstance, TxDma, RxDma> Uart<'d, T, TxDma, RxDma> { | ||||
|     ) -> Self { | ||||
|         into_ref!(de); | ||||
|  | ||||
|         // UartRx and UartTx have one refcount ea. | ||||
|         T::enable(); | ||||
|         T::enable(); | ||||
|         T::reset(); | ||||
|  | ||||
|   | ||||
| @@ -1,4 +1,5 @@ | ||||
| use core::future::poll_fn; | ||||
| use core::mem; | ||||
| use core::sync::atomic::{compiler_fence, Ordering}; | ||||
| use core::task::Poll; | ||||
|  | ||||
| @@ -24,12 +25,16 @@ impl<'d, T: BasicInstance, RxDma: super::RxDma<T>> UartRx<'d, T, RxDma> { | ||||
|         let request = self.rx_dma.request(); | ||||
|         let opts = Default::default(); | ||||
|  | ||||
|         let ring_buf = unsafe { ReadableRingBuffer::new_read(self.rx_dma, request, rdr(T::regs()), dma_buf, opts) }; | ||||
|         // Safety: we forget the struct before this function returns. | ||||
|         let rx_dma = unsafe { self.rx_dma.clone_unchecked() }; | ||||
|         let _peri = unsafe { self._peri.clone_unchecked() }; | ||||
|  | ||||
|         RingBufferedUartRx { | ||||
|             _peri: self._peri, | ||||
|             ring_buf, | ||||
|         } | ||||
|         let ring_buf = unsafe { ReadableRingBuffer::new_read(rx_dma, request, rdr(T::regs()), dma_buf, opts) }; | ||||
|  | ||||
|         // Don't disable the clock | ||||
|         mem::forget(self); | ||||
|  | ||||
|         RingBufferedUartRx { _peri, ring_buf } | ||||
|     } | ||||
| } | ||||
|  | ||||
| @@ -186,6 +191,8 @@ impl<'d, T: BasicInstance, RxDma: super::RxDma<T>> RingBufferedUartRx<'d, T, RxD | ||||
| impl<T: BasicInstance, RxDma: super::RxDma<T>> Drop for RingBufferedUartRx<'_, T, RxDma> { | ||||
|     fn drop(&mut self) { | ||||
|         self.teardown_uart(); | ||||
|  | ||||
|         T::disable(); | ||||
|     } | ||||
| } | ||||
| /// Return an error result if the Sr register has errors | ||||
|   | ||||
		Reference in New Issue
	
	Block a user