stm32/usart: move init code to function that's not generic in T
This commit is contained in:
		
							parent
							
								
									44e4a2c9e9
								
							
						
					
					
						commit
						664e4a5c03
					
				| @ -16,9 +16,7 @@ use super::{ | ||||
|     Regs, RtsPin, RxPin, TxPin, | ||||
| }; | ||||
| use crate::gpio::{AFType, AnyPin, SealedPin as _}; | ||||
| use crate::interrupt::typelevel::Interrupt as _; | ||||
| use crate::interrupt::{self, InterruptExt}; | ||||
| use crate::rcc; | ||||
| use crate::time::Hertz; | ||||
| 
 | ||||
| /// Interrupt handler.
 | ||||
| @ -284,35 +282,11 @@ impl<'d> BufferedUart<'d> { | ||||
|         rx_buffer: &'d mut [u8], | ||||
|         config: Config, | ||||
|     ) -> Result<Self, ConfigError> { | ||||
|         rcc::enable_and_reset::<T>(); | ||||
| 
 | ||||
|         let info = T::info(); | ||||
|         let state = T::buffered_state(); | ||||
|         let kernel_clock = T::frequency(); | ||||
|         let len = tx_buffer.len(); | ||||
|         unsafe { state.tx_buf.init(tx_buffer.as_mut_ptr(), len) }; | ||||
|         let len = rx_buffer.len(); | ||||
|         unsafe { state.rx_buf.init(rx_buffer.as_mut_ptr(), len) }; | ||||
| 
 | ||||
|         info.regs.cr3().write(|w| { | ||||
|             w.set_rtse(rts.is_some()); | ||||
|             w.set_ctse(cts.is_some()); | ||||
|             #[cfg(not(any(usart_v1, usart_v2)))] | ||||
|             w.set_dem(de.is_some()); | ||||
|         }); | ||||
|         configure(info, kernel_clock, &config, true, true)?; | ||||
| 
 | ||||
|         info.regs.cr1().modify(|w| { | ||||
|             w.set_rxneie(true); | ||||
|             w.set_idleie(true); | ||||
|         }); | ||||
| 
 | ||||
|         T::Interrupt::unpend(); | ||||
|         unsafe { T::Interrupt::enable() }; | ||||
| 
 | ||||
|         state.tx_rx_refcount.store(2, Ordering::Relaxed); | ||||
| 
 | ||||
|         Ok(Self { | ||||
|         let mut this = Self { | ||||
|             rx: BufferedUartRx { | ||||
|                 info, | ||||
|                 state, | ||||
| @ -328,7 +302,45 @@ impl<'d> BufferedUart<'d> { | ||||
|                 cts, | ||||
|                 de, | ||||
|             }, | ||||
|         }) | ||||
|         }; | ||||
|         this.enable_and_configure(tx_buffer, rx_buffer, &config)?; | ||||
|         Ok(this) | ||||
|     } | ||||
| 
 | ||||
|     fn enable_and_configure( | ||||
|         &mut self, | ||||
|         tx_buffer: &'d mut [u8], | ||||
|         rx_buffer: &'d mut [u8], | ||||
|         config: &Config, | ||||
|     ) -> Result<(), ConfigError> { | ||||
|         let info = self.rx.info; | ||||
|         let state = self.rx.state; | ||||
| 
 | ||||
|         info.rcc.enable_and_reset(); | ||||
| 
 | ||||
|         let len = tx_buffer.len(); | ||||
|         unsafe { state.tx_buf.init(tx_buffer.as_mut_ptr(), len) }; | ||||
|         let len = rx_buffer.len(); | ||||
|         unsafe { state.rx_buf.init(rx_buffer.as_mut_ptr(), len) }; | ||||
| 
 | ||||
|         info.regs.cr3().write(|w| { | ||||
|             w.set_rtse(self.rx.rts.is_some()); | ||||
|             w.set_ctse(self.tx.cts.is_some()); | ||||
|             #[cfg(not(any(usart_v1, usart_v2)))] | ||||
|             w.set_dem(self.tx.de.is_some()); | ||||
|         }); | ||||
|         configure(info, self.rx.kernel_clock, &config, true, true)?; | ||||
| 
 | ||||
|         info.regs.cr1().modify(|w| { | ||||
|             w.set_rxneie(true); | ||||
|             w.set_idleie(true); | ||||
|         }); | ||||
| 
 | ||||
|         info.interrupt.unpend(); | ||||
|         unsafe { info.interrupt.enable() }; | ||||
| 
 | ||||
|         state.tx_rx_refcount.store(2, Ordering::Relaxed); | ||||
|         Ok(()) | ||||
|     } | ||||
| 
 | ||||
|     /// Split the driver into a Tx and Rx part (useful for sending to separate tasks)
 | ||||
|  | ||||
| @ -28,7 +28,7 @@ use crate::pac::usart::Lpuart as Regs; | ||||
| #[cfg(any(usart_v1, usart_v2))] | ||||
| use crate::pac::usart::Usart as Regs; | ||||
| use crate::pac::usart::{regs, vals}; | ||||
| use crate::rcc::{self, RccInfo, SealedRccPeripheral}; | ||||
| use crate::rcc::{RccInfo, SealedRccPeripheral}; | ||||
| use crate::time::Hertz; | ||||
| use crate::Peripheral; | ||||
| 
 | ||||
| @ -429,29 +429,33 @@ impl<'d, M: Mode> UartTx<'d, M> { | ||||
|         tx_dma: Option<ChannelAndRequest<'d>>, | ||||
|         config: Config, | ||||
|     ) -> Result<Self, ConfigError> { | ||||
|         rcc::enable_and_reset::<T>(); | ||||
| 
 | ||||
|         let info = T::info(); | ||||
|         let state = T::state(); | ||||
|         let kernel_clock = T::frequency(); | ||||
|         let r = info.regs; | ||||
|         r.cr3().modify(|w| { | ||||
|             w.set_ctse(cts.is_some()); | ||||
|         }); | ||||
|         configure(info, kernel_clock, &config, false, true)?; | ||||
| 
 | ||||
|         state.tx_rx_refcount.store(1, Ordering::Relaxed); | ||||
| 
 | ||||
|         Ok(Self { | ||||
|             info, | ||||
|             state, | ||||
|             kernel_clock, | ||||
|         let mut this = Self { | ||||
|             info: T::info(), | ||||
|             state: T::state(), | ||||
|             kernel_clock: T::frequency(), | ||||
|             tx, | ||||
|             cts, | ||||
|             de: None, | ||||
|             tx_dma, | ||||
|             _phantom: PhantomData, | ||||
|         }) | ||||
|         }; | ||||
|         this.enable_and_configure(&config)?; | ||||
|         Ok(this) | ||||
|     } | ||||
| 
 | ||||
|     fn enable_and_configure(&mut self, config: &Config) -> Result<(), ConfigError> { | ||||
|         let info = self.info; | ||||
|         let state = self.state; | ||||
| 
 | ||||
|         info.rcc.enable_and_reset(); | ||||
| 
 | ||||
|         info.regs.cr3().modify(|w| { | ||||
|             w.set_ctse(self.cts.is_some()); | ||||
|         }); | ||||
|         configure(info, self.kernel_clock, config, false, true)?; | ||||
| 
 | ||||
|         state.tx_rx_refcount.store(1, Ordering::Relaxed); | ||||
|         Ok(()) | ||||
|     } | ||||
| 
 | ||||
|     /// Reconfigure the driver
 | ||||
| @ -775,34 +779,38 @@ impl<'d, M: Mode> UartRx<'d, M> { | ||||
|         rx_dma: Option<ChannelAndRequest<'d>>, | ||||
|         config: Config, | ||||
|     ) -> Result<Self, ConfigError> { | ||||
|         rcc::enable_and_reset::<T>(); | ||||
| 
 | ||||
|         let info = T::info(); | ||||
|         let state = T::state(); | ||||
|         let kernel_clock = T::frequency(); | ||||
|         let r = info.regs; | ||||
|         r.cr3().write(|w| { | ||||
|             w.set_rtse(rts.is_some()); | ||||
|         }); | ||||
|         configure(info, kernel_clock, &config, true, false)?; | ||||
| 
 | ||||
|         T::Interrupt::unpend(); | ||||
|         unsafe { T::Interrupt::enable() }; | ||||
| 
 | ||||
|         state.tx_rx_refcount.store(1, Ordering::Relaxed); | ||||
| 
 | ||||
|         Ok(Self { | ||||
|         let mut this = Self { | ||||
|             _phantom: PhantomData, | ||||
|             info, | ||||
|             state, | ||||
|             kernel_clock, | ||||
|             info: T::info(), | ||||
|             state: T::state(), | ||||
|             kernel_clock: T::frequency(), | ||||
|             rx, | ||||
|             rts, | ||||
|             rx_dma, | ||||
|             detect_previous_overrun: config.detect_previous_overrun, | ||||
|             #[cfg(any(usart_v1, usart_v2))] | ||||
|             buffered_sr: stm32_metapac::usart::regs::Sr(0), | ||||
|         }) | ||||
|         }; | ||||
|         this.enable_and_configure(&config)?; | ||||
|         Ok(this) | ||||
|     } | ||||
| 
 | ||||
|     fn enable_and_configure(&mut self, config: &Config) -> Result<(), ConfigError> { | ||||
|         let info = self.info; | ||||
|         let state = self.state; | ||||
| 
 | ||||
|         info.rcc.enable_and_reset(); | ||||
| 
 | ||||
|         info.regs.cr3().write(|w| { | ||||
|             w.set_rtse(self.rts.is_some()); | ||||
|         }); | ||||
|         configure(info, self.kernel_clock, &config, true, false)?; | ||||
| 
 | ||||
|         info.interrupt.unpend(); | ||||
|         unsafe { info.interrupt.enable() }; | ||||
| 
 | ||||
|         state.tx_rx_refcount.store(1, Ordering::Relaxed); | ||||
|         Ok(()) | ||||
|     } | ||||
| 
 | ||||
|     /// Reconfigure the driver
 | ||||
| @ -1228,26 +1236,11 @@ impl<'d, M: Mode> Uart<'d, M> { | ||||
|         rx_dma: Option<ChannelAndRequest<'d>>, | ||||
|         config: Config, | ||||
|     ) -> Result<Self, ConfigError> { | ||||
|         rcc::enable_and_reset::<T>(); | ||||
| 
 | ||||
|         let info = T::info(); | ||||
|         let state = T::state(); | ||||
|         let kernel_clock = T::frequency(); | ||||
| 
 | ||||
|         info.regs.cr3().write(|w| { | ||||
|             w.set_rtse(rts.is_some()); | ||||
|             w.set_ctse(cts.is_some()); | ||||
|             #[cfg(not(any(usart_v1, usart_v2)))] | ||||
|             w.set_dem(de.is_some()); | ||||
|         }); | ||||
|         configure(info, kernel_clock, &config, true, true)?; | ||||
| 
 | ||||
|         T::Interrupt::unpend(); | ||||
|         unsafe { T::Interrupt::enable() }; | ||||
| 
 | ||||
|         state.tx_rx_refcount.store(2, Ordering::Relaxed); | ||||
| 
 | ||||
|         Ok(Self { | ||||
|         let mut this = Self { | ||||
|             tx: UartTx { | ||||
|                 _phantom: PhantomData, | ||||
|                 info, | ||||
| @ -1270,7 +1263,30 @@ impl<'d, M: Mode> Uart<'d, M> { | ||||
|                 #[cfg(any(usart_v1, usart_v2))] | ||||
|                 buffered_sr: stm32_metapac::usart::regs::Sr(0), | ||||
|             }, | ||||
|         }) | ||||
|         }; | ||||
|         this.enable_and_configure(&config)?; | ||||
|         Ok(this) | ||||
|     } | ||||
| 
 | ||||
|     fn enable_and_configure(&mut self, config: &Config) -> Result<(), ConfigError> { | ||||
|         let info = self.rx.info; | ||||
|         let state = self.rx.state; | ||||
| 
 | ||||
|         info.rcc.enable_and_reset(); | ||||
| 
 | ||||
|         info.regs.cr3().write(|w| { | ||||
|             w.set_rtse(self.rx.rts.is_some()); | ||||
|             w.set_ctse(self.tx.cts.is_some()); | ||||
|             #[cfg(not(any(usart_v1, usart_v2)))] | ||||
|             w.set_dem(self.tx.de.is_some()); | ||||
|         }); | ||||
|         configure(info, self.rx.kernel_clock, config, true, true)?; | ||||
| 
 | ||||
|         info.interrupt.unpend(); | ||||
|         unsafe { info.interrupt.enable() }; | ||||
| 
 | ||||
|         state.tx_rx_refcount.store(2, Ordering::Relaxed); | ||||
|         Ok(()) | ||||
|     } | ||||
| 
 | ||||
|     /// Perform a blocking write
 | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user