stm32/usart: Implement data bit selection

Implement data bit size selection and add 7-bit mode.
This commit is contained in:
Derek Hageman 2024-12-01 09:30:23 -07:00
parent 1a1d5c4689
commit 7d15ec921a

View File

@ -91,6 +91,8 @@ unsafe fn on_interrupt(r: Regs, s: &'static State) {
#[cfg_attr(feature = "defmt", derive(defmt::Format))] #[cfg_attr(feature = "defmt", derive(defmt::Format))]
/// Number of data bits /// Number of data bits
pub enum DataBits { pub enum DataBits {
/// 7 Data Bits
DataBits7,
/// 8 Data Bits /// 8 Data Bits
DataBits8, DataBits8,
/// 9 Data Bits /// 9 Data Bits
@ -134,6 +136,8 @@ pub enum ConfigError {
BaudrateTooHigh, BaudrateTooHigh,
/// Rx or Tx not enabled /// Rx or Tx not enabled
RxOrTxNotEnabled, RxOrTxNotEnabled,
/// Data bits and parity combination not supported
DataParityNotSupported,
} }
#[non_exhaustive] #[non_exhaustive]
@ -1617,31 +1621,66 @@ fn configure(
w.set_re(enable_rx); w.set_re(enable_rx);
} }
// configure word size // configure word size and parity, since the parity bit is inserted into the MSB position,
// if using odd or even parity it must be configured to 9bits // it increases the effective word size
w.set_m0(if config.parity != Parity::ParityNone { match (config.parity, config.data_bits) {
trace!("USART: m0: vals::M0::BIT9"); (Parity::ParityNone, DataBits::DataBits8) => {
vals::M0::BIT9 trace!("USART: m0: 8 data bits, no parity");
} else { w.set_m0(vals::M0::BIT8);
trace!("USART: m0: vals::M0::BIT8"); #[cfg(any(usart_v3, usart_v4))]
vals::M0::BIT8 w.set_m1(vals::M1::M0);
}); w.set_pce(false);
// configure parity
w.set_pce(config.parity != Parity::ParityNone);
w.set_ps(match config.parity {
Parity::ParityOdd => {
trace!("USART: set_ps: vals::Ps::ODD");
vals::Ps::ODD
} }
Parity::ParityEven => { (Parity::ParityNone, DataBits::DataBits9) => {
trace!("USART: set_ps: vals::Ps::EVEN"); trace!("USART: m0: 9 data bits, no parity");
vals::Ps::EVEN w.set_m0(vals::M0::BIT9);
#[cfg(any(usart_v3, usart_v4))]
w.set_m1(vals::M1::M0);
w.set_pce(false);
}
#[cfg(any(usart_v3, usart_v4))]
(Parity::ParityNone, DataBits::DataBits7) => {
trace!("USART: m0: 7 data bits, no parity");
w.set_m0(vals::M0::BIT8);
w.set_m1(vals::M1::BIT7);
w.set_pce(false);
}
(Parity::ParityEven, DataBits::DataBits8) => {
trace!("USART: m0: 8 data bits, even parity");
w.set_m0(vals::M0::BIT9);
#[cfg(any(usart_v3, usart_v4))]
w.set_m1(vals::M1::M0);
w.set_pce(true);
w.set_ps(vals::Ps::EVEN);
}
(Parity::ParityEven, DataBits::DataBits7) => {
trace!("USART: m0: 7 data bits, even parity");
w.set_m0(vals::M0::BIT8);
#[cfg(any(usart_v3, usart_v4))]
w.set_m1(vals::M1::M0);
w.set_pce(true);
w.set_ps(vals::Ps::EVEN);
}
(Parity::ParityOdd, DataBits::DataBits8) => {
trace!("USART: m0: 8 data bits, odd parity");
w.set_m0(vals::M0::BIT9);
#[cfg(any(usart_v3, usart_v4))]
w.set_m1(vals::M1::M0);
w.set_pce(true);
w.set_ps(vals::Ps::ODD);
}
(Parity::ParityOdd, DataBits::DataBits7) => {
trace!("USART: m0: 7 data bits, odd parity");
w.set_m0(vals::M0::BIT8);
#[cfg(any(usart_v3, usart_v4))]
w.set_m1(vals::M1::M0);
w.set_pce(true);
w.set_ps(vals::Ps::ODD);
} }
_ => { _ => {
trace!("USART: set_ps: vals::Ps::EVEN"); return Err(ConfigError::DataParityNotSupported);
vals::Ps::EVEN }
} }
});
#[cfg(not(usart_v1))] #[cfg(not(usart_v1))]
w.set_over8(vals::Over8::from_bits(over8 as _)); w.set_over8(vals::Over8::from_bits(over8 as _));
#[cfg(usart_v4)] #[cfg(usart_v4)]
@ -1649,7 +1688,9 @@ fn configure(
trace!("USART: set_fifoen: true (usart_v4)"); trace!("USART: set_fifoen: true (usart_v4)");
w.set_fifoen(true); w.set_fifoen(true);
} }
});
Ok(())
})?;
Ok(()) Ok(())
} }