Add a tx only and a rx only serial instance

This commit is contained in:
David Sawatzke 2019-01-05 22:05:22 +01:00
parent ac4c91b95f
commit 8e0179d60c
1 changed files with 99 additions and 18 deletions

View File

@ -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)
}