Skip to content

Commit 8e0179d

Browse files
Add a tx only and a rx only serial instance
1 parent ac4c91b commit 8e0179d

File tree

1 file changed

+99
-18
lines changed

1 file changed

+99
-18
lines changed

src/serial.rs

Lines changed: 99 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -227,31 +227,66 @@ pub struct Tx<USART> {
227227
unsafe impl<USART> Send for Tx<USART> {}
228228

229229
macro_rules! usart {
230-
($($USART:ident: ($usart:ident, $usartXen:ident, $apbenr:ident),)+) => {
230+
($($USART:ident: ($usart:ident, $usarttx:ident, $usartrx:ident, $usartXen:ident, $apbenr:ident),)+) => {
231231
$(
232232
use crate::stm32::$USART;
233-
impl<TXPIN, RXPIN> Serial<$USART, TXPIN, RXPIN> {
233+
impl<TXPIN, RXPIN> Serial<$USART, TXPIN, RXPIN>
234+
where
235+
TXPIN: TxPin<$USART>,
236+
RXPIN: RxPin<$USART>,
237+
{
234238
/// Creates a new serial instance
235239
pub fn $usart(usart: $USART, pins: (TXPIN, RXPIN), baud_rate: Bps, rcc: &mut Rcc) -> Self
236-
where
237-
TXPIN: TxPin<$USART>,
238-
RXPIN: RxPin<$USART>,
239240
{
241+
let mut serial = Serial { usart, pins };
242+
serial.enable(baud_rate, rcc);
243+
serial
244+
}
245+
}
246+
247+
impl<TXPIN> Serial<$USART, TXPIN, ()>
248+
where
249+
TXPIN: TxPin<$USART>,
250+
{
251+
/// Creates a new tx-only serial instance
252+
pub fn $usarttx(usart: $USART, txpin: TXPIN, baud_rate: Bps, rcc: &mut Rcc) -> Self
253+
{
254+
let rxpin = ();
255+
let mut serial = Serial { usart, pins: (txpin, rxpin) };
256+
serial.enable(baud_rate, rcc);
257+
serial
258+
}
259+
}
260+
261+
impl<RXPIN> Serial<$USART, (), RXPIN>
262+
where
263+
RXPIN: RxPin<$USART>,
264+
{
265+
/// Creates a new tx-only serial instance
266+
pub fn $usartrx(usart: $USART, rxpin: RXPIN, baud_rate: Bps, rcc: &mut Rcc) -> Self
267+
{
268+
let txpin = ();
269+
let mut serial = Serial { usart, pins: (txpin, rxpin) };
270+
serial.enable(baud_rate, rcc);
271+
serial
272+
}
273+
}
274+
275+
impl<TXPIN, RXPIN> Serial<$USART, TXPIN, RXPIN> {
276+
fn enable(&mut self, baud_rate: Bps, rcc: &mut Rcc) {
240277
// Enable clock for USART
241278
rcc.regs.$apbenr.modify(|_, w| w.$usartXen().set_bit());
242279

243280
// Calculate correct baudrate divisor on the fly
244281
let brr = rcc.clocks.pclk().0 / baud_rate.0;
245-
usart.brr.write(|w| unsafe { w.bits(brr) });
282+
self.usart.brr.write(|w| unsafe { w.bits(brr) });
246283

247284
// Reset other registers to disable advanced USART features
248-
usart.cr2.reset();
249-
usart.cr3.reset();
285+
self.usart.cr2.reset();
286+
self.usart.cr3.reset();
250287

251288
// Enable transmission and receiving
252-
usart.cr1.modify(|_, w| w.te().set_bit().re().set_bit().ue().set_bit());
253-
254-
Serial { usart, pins }
289+
self.usart.cr1.modify(|_, w| w.te().set_bit().re().set_bit().ue().set_bit());
255290
}
256291

257292
/// Starts listening for an interrupt event
@@ -289,7 +324,7 @@ macro_rules! usart {
289324
}
290325

291326
usart! {
292-
USART1: (usart1, usart1en, apb2enr),
327+
USART1: (usart1, usart1tx, usart1rx, usart1en, apb2enr),
293328
}
294329
#[cfg(any(
295330
feature = "stm32f030x8",
@@ -302,7 +337,7 @@ usart! {
302337
feature = "stm32f091",
303338
))]
304339
usart! {
305-
USART2: (usart2, usart2en, apb1enr),
340+
USART2: (usart2, usart2tx, usart2rx,usart2en, apb1enr),
306341
}
307342
#[cfg(any(
308343
feature = "stm32f030xc",
@@ -312,13 +347,13 @@ usart! {
312347
feature = "stm32f091",
313348
))]
314349
usart! {
315-
USART3: (usart3, usart3en, apb1enr),
316-
USART4: (usart4, usart4en, apb1enr),
350+
USART3: (usart3, usart3tx, usart3rx,usart3en, apb1enr),
351+
USART4: (usart4, usart4tx, usart4rx,usart4en, apb1enr),
317352
}
318353
#[cfg(any(feature = "stm32f030xc", feature = "stm32f091"))]
319354
usart! {
320-
USART5: (usart5, usart5en, apb1enr),
321-
USART6: (usart6, usart6en, apb2enr),
355+
USART5: (usart5, usart5tx, usart5rx,usart5en, apb1enr),
356+
USART6: (usart6, usart6tx, usart6rx,usart6en, apb2enr),
322357
}
323358

324359
// It's s needed for the impls, but rustc doesn't recognize that
@@ -353,6 +388,22 @@ where
353388
}
354389
}
355390

391+
impl<USART, TXPIN, RXPIN> embedded_hal::serial::Read<u8> for Serial<USART, TXPIN, RXPIN>
392+
where
393+
USART: Deref<Target = SerialRegisterBlock>,
394+
RXPIN: RxPin<USART>,
395+
{
396+
type Error = Error;
397+
398+
/// Tries to read a byte from the uart
399+
fn read(&mut self) -> nb::Result<u8, Error> {
400+
Rx {
401+
usart: &self.usart as *const _,
402+
}
403+
.read()
404+
}
405+
}
406+
356407
impl<USART> embedded_hal::serial::Write<u8> for Tx<USART>
357408
where
358409
USART: Deref<Target = SerialRegisterBlock>,
@@ -388,13 +439,42 @@ where
388439
}
389440
}
390441

442+
impl<USART, TXPIN, RXPIN> embedded_hal::serial::Write<u8> for Serial<USART, TXPIN, RXPIN>
443+
where
444+
USART: Deref<Target = SerialRegisterBlock>,
445+
TXPIN: TxPin<USART>,
446+
{
447+
type Error = void::Void;
448+
449+
/// Ensures that none of the previously written words are still buffered
450+
fn flush(&mut self) -> nb::Result<(), Self::Error> {
451+
Tx {
452+
usart: &self.usart as *const _,
453+
}
454+
.flush()
455+
}
456+
457+
/// Tries to write a byte to the uart
458+
/// Fails if the transmit buffer is full
459+
fn write(&mut self, byte: u8) -> nb::Result<(), Self::Error> {
460+
Tx {
461+
usart: &self.usart as *const _,
462+
}
463+
.write(byte)
464+
}
465+
}
466+
391467
impl<USART, TXPIN, RXPIN> Serial<USART, TXPIN, RXPIN>
392468
where
393469
USART: Deref<Target = SerialRegisterBlock>,
394470
{
395471
/// Splits the UART Peripheral in a Tx and an Rx part
396472
/// This is required for sending/receiving
397-
pub fn split(self) -> (Tx<USART>, Rx<USART>) {
473+
pub fn split(self) -> (Tx<USART>, Rx<USART>)
474+
where
475+
TXPIN: TxPin<USART>,
476+
RXPIN: RxPin<USART>,
477+
{
398478
(
399479
Tx {
400480
usart: &self.usart as *const _,
@@ -404,6 +484,7 @@ where
404484
},
405485
)
406486
}
487+
407488
pub fn release(self) -> (USART, (TXPIN, RXPIN)) {
408489
(self.usart, self.pins)
409490
}

0 commit comments

Comments
 (0)