diff --git a/embassy-stm32/src/usart/buffered.rs b/embassy-stm32/src/usart/buffered.rs index 3be0677bd..0a6d6e149 100644 --- a/embassy-stm32/src/usart/buffered.rs +++ b/embassy-stm32/src/usart/buffered.rs @@ -45,6 +45,51 @@ impl<'d, T: BasicInstance> Unpin for BufferedUart<'d, T> {} impl<'d, T: BasicInstance> BufferedUart<'d, T> { pub fn new( + state: &'d mut State<'d, T>, + peri: impl Peripheral
+ 'd, + rx: impl Peripheral
> + 'd, + tx: impl Peripheral
> + 'd, + irq: impl Peripheral
+ 'd, + tx_buffer: &'d mut [u8], + rx_buffer: &'d mut [u8], + config: Config, + ) -> BufferedUart<'d, T> { + T::enable(); + T::reset(); + + Self::new_inner(state, peri, rx, tx, irq, tx_buffer, rx_buffer, config) + } + + pub fn new_with_rtscts( + state: &'d mut State<'d, T>, + peri: impl Peripheral
+ 'd, + rx: impl Peripheral
> + 'd, + tx: impl Peripheral
> + 'd, + irq: impl Peripheral
+ 'd, + rts: impl Peripheral
> + 'd, + cts: impl Peripheral
> + 'd, + tx_buffer: &'d mut [u8], + rx_buffer: &'d mut [u8], + config: Config, + ) -> BufferedUart<'d, T> { + into_ref!(cts, rts); + + T::enable(); + T::reset(); + + unsafe { + rts.set_as_af(rts.af_num(), AFType::OutputPushPull); + cts.set_as_af(cts.af_num(), AFType::Input); + T::regs().cr3().write(|w| { + w.set_rtse(true); + w.set_ctse(true); + }); + } + + Self::new_inner(state, peri, rx, tx, irq, tx_buffer, rx_buffer, config) + } + + fn new_inner( state: &'d mut State<'d, T>, _peri: impl Peripheral
+ 'd, rx: impl Peripheral
> + 'd, @@ -56,34 +101,17 @@ impl<'d, T: BasicInstance> BufferedUart<'d, T> { ) -> BufferedUart<'d, T> { into_ref!(_peri, rx, tx, irq); - T::enable(); - T::reset(); - let r = T::regs(); - configure(r, &config, T::frequency(), T::MULTIPLIER); - unsafe { rx.set_as_af(rx.af_num(), AFType::Input); tx.set_as_af(tx.af_num(), AFType::OutputPushPull); + } - r.cr2().write(|_w| {}); - r.cr3().write(|_w| {}); - r.cr1().write(|w| { - w.set_ue(true); - w.set_te(true); - w.set_re(true); - w.set_m0(if config.parity != Parity::ParityNone { - vals::M0::BIT9 - } else { - vals::M0::BIT8 - }); - w.set_pce(config.parity != Parity::ParityNone); - w.set_ps(match config.parity { - Parity::ParityOdd => vals::Ps::ODD, - Parity::ParityEven => vals::Ps::EVEN, - _ => vals::Ps::EVEN, - }); + configure(r, &config, T::frequency(), T::MULTIPLIER, true, true); + + unsafe { + r.cr1().modify(|w| { w.set_rxneie(true); w.set_idleie(true); }); diff --git a/embassy-stm32/src/usart/mod.rs b/embassy-stm32/src/usart/mod.rs index dee466b21..716247d9e 100644 --- a/embassy-stm32/src/usart/mod.rs +++ b/embassy-stm32/src/usart/mod.rs @@ -102,7 +102,59 @@ pub struct UartRx<'d, T: BasicInstance, RxDma = NoDma> { } impl<'d, T: BasicInstance, TxDma> UartTx<'d, T, TxDma> { - fn new(tx_dma: PeripheralRef<'d, TxDma>) -> Self { + /// usefull if you only want Uart Tx. It saves 1 pin and consumes a little less power + pub fn new( + peri: impl Peripheral
+ 'd, + tx: impl Peripheral
> + 'd, + tx_dma: impl Peripheral
+ 'd, + config: Config, + ) -> Self { + T::enable(); + T::reset(); + + Self::new_inner(peri, tx, tx_dma, config) + } + + pub fn new_with_cts( + peri: impl Peripheral
+ 'd, + tx: impl Peripheral
> + 'd, + cts: impl Peripheral
> + 'd, + tx_dma: impl Peripheral
+ 'd, + config: Config, + ) -> Self { + into_ref!(cts); + + T::enable(); + T::reset(); + + unsafe { + cts.set_as_af(cts.af_num(), AFType::Input); + T::regs().cr3().write(|w| { + w.set_ctse(true); + }); + } + Self::new_inner(peri, tx, tx_dma, config) + } + + fn new_inner( + _peri: impl Peripheral
+ 'd, + tx: impl Peripheral
> + 'd, + tx_dma: impl Peripheral
+ 'd, + config: Config, + ) -> Self { + into_ref!(_peri, tx, tx_dma); + + let r = T::regs(); + + unsafe { + tx.set_as_af(tx.af_num(), AFType::OutputPushPull); + } + + configure(r, &config, T::frequency(), T::MULTIPLIER, false, true); + + // create state once! + let _s = T::state(); + Self { tx_dma, phantom: PhantomData, @@ -156,44 +208,52 @@ impl<'d, T: BasicInstance, RxDma> UartRx<'d, T, RxDma> { rx_dma: impl Peripheral
+ 'd, config: Config, ) -> Self { - into_ref!(peri, irq, rx, rx_dma); + T::enable(); + T::reset(); + + Self::new_inner(peri, irq, rx, rx_dma, config) + } + + pub fn new_with_rts( + peri: impl Peripheral
+ 'd, + irq: impl Peripheral
+ 'd, + rx: impl Peripheral
> + 'd, + rts: impl Peripheral
> + 'd, + rx_dma: impl Peripheral
+ 'd, + config: Config, + ) -> Self { + into_ref!(rts); T::enable(); T::reset(); - let r = T::regs(); + unsafe { + rts.set_as_af(rts.af_num(), AFType::OutputPushPull); + T::regs().cr3().write(|w| { + w.set_rtse(true); + }); + } - configure(r, &config, T::frequency(), T::MULTIPLIER); + Self::new_inner(peri, irq, rx, rx_dma, config) + } + + fn new_inner( + peri: impl Peripheral
+ 'd, + irq: impl Peripheral
+ 'd, + rx: impl Peripheral
> + 'd, + rx_dma: impl Peripheral
+ 'd,
+ config: Config,
+ ) -> Self {
+ into_ref!(peri, irq, rx, rx_dma);
+
+ let r = T::regs();
unsafe {
rx.set_as_af(rx.af_num(), AFType::Input);
-
- r.cr2().write(|_w| {});
- r.cr3().write(|w| {
- // enable Error Interrupt: (Frame error, Noise error, Overrun error)
- w.set_eie(true);
- });
- r.cr1().write(|w| {
- // enable uart
- w.set_ue(true);
- // enable receiver
- w.set_re(true);
- // configure word size
- w.set_m0(if config.parity != Parity::ParityNone {
- vals::M0::BIT9
- } else {
- vals::M0::BIT8
- });
- // configure parity
- w.set_pce(config.parity != Parity::ParityNone);
- w.set_ps(match config.parity {
- Parity::ParityOdd => vals::Ps::ODD,
- Parity::ParityEven => vals::Ps::EVEN,
- _ => vals::Ps::EVEN,
- });
- });
}
+ configure(r, &config, T::frequency(), T::MULTIPLIER, true, false);
+
irq.set_handler(Self::on_interrupt);
irq.unpend();
irq.enable();
@@ -563,31 +623,13 @@ impl<'d, T: BasicInstance, TxDma, RxDma> Uart<'d, T, TxDma, RxDma> {
let r = T::regs();
- configure(r, &config, T::frequency(), T::MULTIPLIER);
-
unsafe {
rx.set_as_af(rx.af_num(), AFType::Input);
tx.set_as_af(tx.af_num(), AFType::OutputPushPull);
-
- r.cr2().write(|_w| {});
- r.cr1().write(|w| {
- w.set_ue(true);
- w.set_te(true);
- w.set_re(true);
- w.set_m0(if config.parity != Parity::ParityNone {
- vals::M0::BIT9
- } else {
- vals::M0::BIT8
- });
- w.set_pce(config.parity != Parity::ParityNone);
- w.set_ps(match config.parity {
- Parity::ParityOdd => vals::Ps::ODD,
- Parity::ParityEven => vals::Ps::EVEN,
- _ => vals::Ps::EVEN,
- });
- });
}
+ configure(r, &config, T::frequency(), T::MULTIPLIER, true, true);
+
irq.set_handler(UartRx::