Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

stm32/usart: Implement data bit selection #3595

Merged
merged 1 commit into from
Dec 1, 2024
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
85 changes: 63 additions & 22 deletions embassy-stm32/src/usart/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,8 @@ unsafe fn on_interrupt(r: Regs, s: &'static State) {
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
/// Number of data bits
pub enum DataBits {
/// 7 Data Bits
DataBits7,
/// 8 Data Bits
DataBits8,
/// 9 Data Bits
Expand Down Expand Up @@ -134,6 +136,8 @@ pub enum ConfigError {
BaudrateTooHigh,
/// Rx or Tx not enabled
RxOrTxNotEnabled,
/// Data bits and parity combination not supported
DataParityNotSupported,
}

#[non_exhaustive]
Expand Down Expand Up @@ -1617,39 +1621,76 @@ fn configure(
w.set_re(enable_rx);
}

// configure word size
// if using odd or even parity it must be configured to 9bits
w.set_m0(if config.parity != Parity::ParityNone {
trace!("USART: m0: vals::M0::BIT9");
vals::M0::BIT9
} else {
trace!("USART: m0: vals::M0::BIT8");
vals::M0::BIT8
});
// 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
// configure word size and parity, since the parity bit is inserted into the MSB position,
// it increases the effective word size
match (config.parity, config.data_bits) {
(Parity::ParityNone, DataBits::DataBits8) => {
trace!("USART: m0: 8 data bits, no parity");
w.set_m0(vals::M0::BIT8);
#[cfg(any(usart_v3, usart_v4))]
w.set_m1(vals::M1::M0);
w.set_pce(false);
}
(Parity::ParityNone, DataBits::DataBits9) => {
trace!("USART: m0: 9 data bits, no parity");
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::ParityEven => {
trace!("USART: set_ps: vals::Ps::EVEN");
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");
vals::Ps::EVEN
return Err(ConfigError::DataParityNotSupported);
}
});
}
#[cfg(not(usart_v1))]
w.set_over8(vals::Over8::from_bits(over8 as _));
#[cfg(usart_v4)]
{
trace!("USART: set_fifoen: true (usart_v4)");
w.set_fifoen(true);
}
});

Ok(())
})?;

Ok(())
}
Expand Down