Add a tx only and a rx only serial instance
This commit is contained in:
parent
ac4c91b95f
commit
8e0179d60c
117
src/serial.rs
117
src/serial.rs
|
@ -227,31 +227,66 @@ pub struct Tx<USART> {
|
|||
unsafe impl<USART> Send for Tx<USART> {}
|
||||
|
||||
macro_rules! usart {
|
||||
($($USART:ident: ($usart:ident, $usartXen:ident, $apbenr:ident),)+) => {
|
||||
($($USART:ident: ($usart:ident, $usarttx:ident, $usartrx:ident, $usartXen:ident, $apbenr:ident),)+) => {
|
||||
$(
|
||||
use crate::stm32::$USART;
|
||||
impl<TXPIN, RXPIN> Serial<$USART, TXPIN, RXPIN> {
|
||||
impl<TXPIN, RXPIN> Serial<$USART, TXPIN, RXPIN>
|
||||
where
|
||||
TXPIN: TxPin<$USART>,
|
||||
RXPIN: RxPin<$USART>,
|
||||
{
|
||||
/// Creates a new serial instance
|
||||
pub fn $usart(usart: $USART, pins: (TXPIN, RXPIN), baud_rate: Bps, rcc: &mut Rcc) -> Self
|
||||
where
|
||||
TXPIN: TxPin<$USART>,
|
||||
RXPIN: RxPin<$USART>,
|
||||
{
|
||||
let mut serial = Serial { usart, pins };
|
||||
serial.enable(baud_rate, rcc);
|
||||
serial
|
||||
}
|
||||
}
|
||||
|
||||
impl<TXPIN> Serial<$USART, TXPIN, ()>
|
||||
where
|
||||
TXPIN: TxPin<$USART>,
|
||||
{
|
||||
/// Creates a new tx-only serial instance
|
||||
pub fn $usarttx(usart: $USART, txpin: TXPIN, baud_rate: Bps, rcc: &mut Rcc) -> Self
|
||||
{
|
||||
let rxpin = ();
|
||||
let mut serial = Serial { usart, pins: (txpin, rxpin) };
|
||||
serial.enable(baud_rate, rcc);
|
||||
serial
|
||||
}
|
||||
}
|
||||
|
||||
impl<RXPIN> Serial<$USART, (), RXPIN>
|
||||
where
|
||||
RXPIN: RxPin<$USART>,
|
||||
{
|
||||
/// Creates a new tx-only serial instance
|
||||
pub fn $usartrx(usart: $USART, rxpin: RXPIN, baud_rate: Bps, rcc: &mut Rcc) -> Self
|
||||
{
|
||||
let txpin = ();
|
||||
let mut serial = Serial { usart, pins: (txpin, rxpin) };
|
||||
serial.enable(baud_rate, rcc);
|
||||
serial
|
||||
}
|
||||
}
|
||||
|
||||
impl<TXPIN, RXPIN> Serial<$USART, TXPIN, RXPIN> {
|
||||
fn enable(&mut self, baud_rate: Bps, rcc: &mut Rcc) {
|
||||
// Enable clock for USART
|
||||
rcc.regs.$apbenr.modify(|_, w| w.$usartXen().set_bit());
|
||||
|
||||
// Calculate correct baudrate divisor on the fly
|
||||
let brr = rcc.clocks.pclk().0 / baud_rate.0;
|
||||
usart.brr.write(|w| unsafe { w.bits(brr) });
|
||||
self.usart.brr.write(|w| unsafe { w.bits(brr) });
|
||||
|
||||
// Reset other registers to disable advanced USART features
|
||||
usart.cr2.reset();
|
||||
usart.cr3.reset();
|
||||
self.usart.cr2.reset();
|
||||
self.usart.cr3.reset();
|
||||
|
||||
// Enable transmission and receiving
|
||||
usart.cr1.modify(|_, w| w.te().set_bit().re().set_bit().ue().set_bit());
|
||||
|
||||
Serial { usart, pins }
|
||||
self.usart.cr1.modify(|_, w| w.te().set_bit().re().set_bit().ue().set_bit());
|
||||
}
|
||||
|
||||
/// Starts listening for an interrupt event
|
||||
|
@ -289,7 +324,7 @@ macro_rules! usart {
|
|||
}
|
||||
|
||||
usart! {
|
||||
USART1: (usart1, usart1en, apb2enr),
|
||||
USART1: (usart1, usart1tx, usart1rx, usart1en, apb2enr),
|
||||
}
|
||||
#[cfg(any(
|
||||
feature = "stm32f030x8",
|
||||
|
@ -302,7 +337,7 @@ usart! {
|
|||
feature = "stm32f091",
|
||||
))]
|
||||
usart! {
|
||||
USART2: (usart2, usart2en, apb1enr),
|
||||
USART2: (usart2, usart2tx, usart2rx,usart2en, apb1enr),
|
||||
}
|
||||
#[cfg(any(
|
||||
feature = "stm32f030xc",
|
||||
|
@ -312,13 +347,13 @@ usart! {
|
|||
feature = "stm32f091",
|
||||
))]
|
||||
usart! {
|
||||
USART3: (usart3, usart3en, apb1enr),
|
||||
USART4: (usart4, usart4en, apb1enr),
|
||||
USART3: (usart3, usart3tx, usart3rx,usart3en, apb1enr),
|
||||
USART4: (usart4, usart4tx, usart4rx,usart4en, apb1enr),
|
||||
}
|
||||
#[cfg(any(feature = "stm32f030xc", feature = "stm32f091"))]
|
||||
usart! {
|
||||
USART5: (usart5, usart5en, apb1enr),
|
||||
USART6: (usart6, usart6en, apb2enr),
|
||||
USART5: (usart5, usart5tx, usart5rx,usart5en, apb1enr),
|
||||
USART6: (usart6, usart6tx, usart6rx,usart6en, apb2enr),
|
||||
}
|
||||
|
||||
// It's s needed for the impls, but rustc doesn't recognize that
|
||||
|
@ -353,6 +388,22 @@ where
|
|||
}
|
||||
}
|
||||
|
||||
impl<USART, TXPIN, RXPIN> embedded_hal::serial::Read<u8> for Serial<USART, TXPIN, RXPIN>
|
||||
where
|
||||
USART: Deref<Target = SerialRegisterBlock>,
|
||||
RXPIN: RxPin<USART>,
|
||||
{
|
||||
type Error = Error;
|
||||
|
||||
/// Tries to read a byte from the uart
|
||||
fn read(&mut self) -> nb::Result<u8, Error> {
|
||||
Rx {
|
||||
usart: &self.usart as *const _,
|
||||
}
|
||||
.read()
|
||||
}
|
||||
}
|
||||
|
||||
impl<USART> embedded_hal::serial::Write<u8> for Tx<USART>
|
||||
where
|
||||
USART: Deref<Target = SerialRegisterBlock>,
|
||||
|
@ -388,13 +439,42 @@ where
|
|||
}
|
||||
}
|
||||
|
||||
impl<USART, TXPIN, RXPIN> embedded_hal::serial::Write<u8> for Serial<USART, TXPIN, RXPIN>
|
||||
where
|
||||
USART: Deref<Target = SerialRegisterBlock>,
|
||||
TXPIN: TxPin<USART>,
|
||||
{
|
||||
type Error = void::Void;
|
||||
|
||||
/// Ensures that none of the previously written words are still buffered
|
||||
fn flush(&mut self) -> nb::Result<(), Self::Error> {
|
||||
Tx {
|
||||
usart: &self.usart as *const _,
|
||||
}
|
||||
.flush()
|
||||
}
|
||||
|
||||
/// Tries to write a byte to the uart
|
||||
/// Fails if the transmit buffer is full
|
||||
fn write(&mut self, byte: u8) -> nb::Result<(), Self::Error> {
|
||||
Tx {
|
||||
usart: &self.usart as *const _,
|
||||
}
|
||||
.write(byte)
|
||||
}
|
||||
}
|
||||
|
||||
impl<USART, TXPIN, RXPIN> Serial<USART, TXPIN, RXPIN>
|
||||
where
|
||||
USART: Deref<Target = SerialRegisterBlock>,
|
||||
{
|
||||
/// Splits the UART Peripheral in a Tx and an Rx part
|
||||
/// This is required for sending/receiving
|
||||
pub fn split(self) -> (Tx<USART>, Rx<USART>) {
|
||||
pub fn split(self) -> (Tx<USART>, Rx<USART>)
|
||||
where
|
||||
TXPIN: TxPin<USART>,
|
||||
RXPIN: RxPin<USART>,
|
||||
{
|
||||
(
|
||||
Tx {
|
||||
usart: &self.usart as *const _,
|
||||
|
@ -404,6 +484,7 @@ where
|
|||
},
|
||||
)
|
||||
}
|
||||
|
||||
pub fn release(self) -> (USART, (TXPIN, RXPIN)) {
|
||||
(self.usart, self.pins)
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue