diff options
| author | Dario Nieuwenhuis <[email protected]> | 2024-12-01 21:39:27 +0000 |
|---|---|---|
| committer | GitHub <[email protected]> | 2024-12-01 21:39:27 +0000 |
| commit | c73a4d397d69541e5f0a3dde005afe60ba16fe05 (patch) | |
| tree | e37c2636978ec3eb9a2b2f6cdaa4ea1f0ff3508f | |
| parent | 67579dd0f4b664880d44fe9d49a450e1a41e1286 (diff) | |
| parent | 7d15ec921a279682c4e0b8a9eb5176e541f99b17 (diff) | |
Merge pull request #3595 from Sizurka/stm32-usart-databits
stm32/usart: Implement data bit selection
| -rw-r--r-- | embassy-stm32/src/usart/mod.rs | 85 |
1 files changed, 63 insertions, 22 deletions
diff --git a/embassy-stm32/src/usart/mod.rs b/embassy-stm32/src/usart/mod.rs index 8152fc560..d2fb85ee3 100644 --- a/embassy-stm32/src/usart/mod.rs +++ b/embassy-stm32/src/usart/mod.rs | |||
| @@ -91,6 +91,8 @@ unsafe fn on_interrupt(r: Regs, s: &'static State) { | |||
| 91 | #[cfg_attr(feature = "defmt", derive(defmt::Format))] | 91 | #[cfg_attr(feature = "defmt", derive(defmt::Format))] |
| 92 | /// Number of data bits | 92 | /// Number of data bits |
| 93 | pub enum DataBits { | 93 | pub enum DataBits { |
| 94 | /// 7 Data Bits | ||
| 95 | DataBits7, | ||
| 94 | /// 8 Data Bits | 96 | /// 8 Data Bits |
| 95 | DataBits8, | 97 | DataBits8, |
| 96 | /// 9 Data Bits | 98 | /// 9 Data Bits |
| @@ -134,6 +136,8 @@ pub enum ConfigError { | |||
| 134 | BaudrateTooHigh, | 136 | BaudrateTooHigh, |
| 135 | /// Rx or Tx not enabled | 137 | /// Rx or Tx not enabled |
| 136 | RxOrTxNotEnabled, | 138 | RxOrTxNotEnabled, |
| 139 | /// Data bits and parity combination not supported | ||
| 140 | DataParityNotSupported, | ||
| 137 | } | 141 | } |
| 138 | 142 | ||
| 139 | #[non_exhaustive] | 143 | #[non_exhaustive] |
| @@ -1617,31 +1621,66 @@ fn configure( | |||
| 1617 | w.set_re(enable_rx); | 1621 | w.set_re(enable_rx); |
| 1618 | } | 1622 | } |
| 1619 | 1623 | ||
| 1620 | // configure word size | 1624 | // configure word size and parity, since the parity bit is inserted into the MSB position, |
| 1621 | // if using odd or even parity it must be configured to 9bits | 1625 | // it increases the effective word size |
| 1622 | w.set_m0(if config.parity != Parity::ParityNone { | 1626 | match (config.parity, config.data_bits) { |
| 1623 | trace!("USART: m0: vals::M0::BIT9"); | 1627 | (Parity::ParityNone, DataBits::DataBits8) => { |
| 1624 | vals::M0::BIT9 | 1628 | trace!("USART: m0: 8 data bits, no parity"); |
| 1625 | } else { | 1629 | w.set_m0(vals::M0::BIT8); |
| 1626 | trace!("USART: m0: vals::M0::BIT8"); | 1630 | #[cfg(any(usart_v3, usart_v4))] |
| 1627 | vals::M0::BIT8 | 1631 | w.set_m1(vals::M1::M0); |
| 1628 | }); | 1632 | w.set_pce(false); |
| 1629 | // configure parity | 1633 | } |
| 1630 | w.set_pce(config.parity != Parity::ParityNone); | 1634 | (Parity::ParityNone, DataBits::DataBits9) => { |
| 1631 | w.set_ps(match config.parity { | 1635 | trace!("USART: m0: 9 data bits, no parity"); |
| 1632 | Parity::ParityOdd => { | 1636 | w.set_m0(vals::M0::BIT9); |
| 1633 | trace!("USART: set_ps: vals::Ps::ODD"); | 1637 | #[cfg(any(usart_v3, usart_v4))] |
| 1634 | vals::Ps::ODD | 1638 | w.set_m1(vals::M1::M0); |
| 1639 | w.set_pce(false); | ||
| 1640 | } | ||
| 1641 | #[cfg(any(usart_v3, usart_v4))] | ||
| 1642 | (Parity::ParityNone, DataBits::DataBits7) => { | ||
| 1643 | trace!("USART: m0: 7 data bits, no parity"); | ||
| 1644 | w.set_m0(vals::M0::BIT8); | ||
| 1645 | w.set_m1(vals::M1::BIT7); | ||
| 1646 | w.set_pce(false); | ||
| 1647 | } | ||
| 1648 | (Parity::ParityEven, DataBits::DataBits8) => { | ||
| 1649 | trace!("USART: m0: 8 data bits, even parity"); | ||
| 1650 | w.set_m0(vals::M0::BIT9); | ||
| 1651 | #[cfg(any(usart_v3, usart_v4))] | ||
| 1652 | w.set_m1(vals::M1::M0); | ||
| 1653 | w.set_pce(true); | ||
| 1654 | w.set_ps(vals::Ps::EVEN); | ||
| 1655 | } | ||
| 1656 | (Parity::ParityEven, DataBits::DataBits7) => { | ||
| 1657 | trace!("USART: m0: 7 data bits, even parity"); | ||
| 1658 | w.set_m0(vals::M0::BIT8); | ||
| 1659 | #[cfg(any(usart_v3, usart_v4))] | ||
| 1660 | w.set_m1(vals::M1::M0); | ||
| 1661 | w.set_pce(true); | ||
| 1662 | w.set_ps(vals::Ps::EVEN); | ||
| 1635 | } | 1663 | } |
| 1636 | Parity::ParityEven => { | 1664 | (Parity::ParityOdd, DataBits::DataBits8) => { |
| 1637 | trace!("USART: set_ps: vals::Ps::EVEN"); | 1665 | trace!("USART: m0: 8 data bits, odd parity"); |
| 1638 | vals::Ps::EVEN | 1666 | w.set_m0(vals::M0::BIT9); |
| 1667 | #[cfg(any(usart_v3, usart_v4))] | ||
| 1668 | w.set_m1(vals::M1::M0); | ||
| 1669 | w.set_pce(true); | ||
| 1670 | w.set_ps(vals::Ps::ODD); | ||
| 1671 | } | ||
| 1672 | (Parity::ParityOdd, DataBits::DataBits7) => { | ||
| 1673 | trace!("USART: m0: 7 data bits, odd parity"); | ||
| 1674 | w.set_m0(vals::M0::BIT8); | ||
| 1675 | #[cfg(any(usart_v3, usart_v4))] | ||
| 1676 | w.set_m1(vals::M1::M0); | ||
| 1677 | w.set_pce(true); | ||
| 1678 | w.set_ps(vals::Ps::ODD); | ||
| 1639 | } | 1679 | } |
| 1640 | _ => { | 1680 | _ => { |
| 1641 | trace!("USART: set_ps: vals::Ps::EVEN"); | 1681 | return Err(ConfigError::DataParityNotSupported); |
| 1642 | vals::Ps::EVEN | ||
| 1643 | } | 1682 | } |
| 1644 | }); | 1683 | } |
| 1645 | #[cfg(not(usart_v1))] | 1684 | #[cfg(not(usart_v1))] |
| 1646 | w.set_over8(vals::Over8::from_bits(over8 as _)); | 1685 | w.set_over8(vals::Over8::from_bits(over8 as _)); |
| 1647 | #[cfg(usart_v4)] | 1686 | #[cfg(usart_v4)] |
| @@ -1649,7 +1688,9 @@ fn configure( | |||
| 1649 | trace!("USART: set_fifoen: true (usart_v4)"); | 1688 | trace!("USART: set_fifoen: true (usart_v4)"); |
| 1650 | w.set_fifoen(true); | 1689 | w.set_fifoen(true); |
| 1651 | } | 1690 | } |
| 1652 | }); | 1691 | |
| 1692 | Ok(()) | ||
| 1693 | })?; | ||
| 1653 | 1694 | ||
| 1654 | Ok(()) | 1695 | Ok(()) |
| 1655 | } | 1696 | } |
