Skip to content

Commit e5ca471

Browse files
Add a tx only and a rx only serial instance
1 parent 7da190e commit e5ca471

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
@@ -186,16 +186,53 @@ unsafe impl<USART> Send for Tx<USART> {}
186186

187187
#[cfg(feature = "device-selected")]
188188
macro_rules! usart {
189-
($($USART:ident: ($usart:ident, $usartXen:ident, $apbenr:ident),)+) => {
189+
($($USART:ident: ($usart:ident, $usarttx:ident, $usartrx:ident, $usartXen:ident, $apbenr:ident),)+) => {
190190
$(
191191
use crate::stm32::$USART;
192-
impl<TXPIN, RXPIN> Serial<$USART, TXPIN, RXPIN> {
192+
impl<TXPIN, RXPIN> Serial<$USART, TXPIN, RXPIN>
193+
where
194+
TXPIN: TxPin<$USART>,
195+
RXPIN: RxPin<$USART>,
196+
{
193197
/// Creates a new serial instance
194198
pub fn $usart(usart: $USART, pins: (TXPIN, RXPIN), baud_rate: Bps, clocks: Clocks) -> Self
195-
where
196-
TXPIN: TxPin<$USART>,
197-
RXPIN: RxPin<$USART>,
198199
{
200+
let mut serial = Serial { usart, pins };
201+
serial.enable(baud_rate, clocks);
202+
serial
203+
}
204+
}
205+
206+
impl<TXPIN> Serial<$USART, TXPIN, ()>
207+
where
208+
TXPIN: TxPin<$USART>,
209+
{
210+
/// Creates a new tx-only serial instance
211+
pub fn $usarttx(usart: $USART, txpin: TXPIN, baud_rate: Bps, clocks: Clocks) -> Self
212+
{
213+
let rxpin = ();
214+
let mut serial = Serial { usart, pins: (txpin, rxpin) };
215+
serial.enable(baud_rate, clocks);
216+
serial
217+
}
218+
}
219+
220+
impl<RXPIN> Serial<$USART, (), RXPIN>
221+
where
222+
RXPIN: RxPin<$USART>,
223+
{
224+
/// Creates a new tx-only serial instance
225+
pub fn $usartrx(usart: $USART, rxpin: RXPIN, baud_rate: Bps, clocks: Clocks) -> Self
226+
{
227+
let txpin = ();
228+
let mut serial = Serial { usart, pins: (txpin, rxpin) };
229+
serial.enable(baud_rate, clocks);
230+
serial
231+
}
232+
}
233+
234+
impl<TXPIN, RXPIN> Serial<$USART, TXPIN, RXPIN> {
235+
fn enable(&mut self, baud_rate: Bps, clocks: Clocks) {
199236
// NOTE(unsafe) This executes only during initialisation
200237
let rcc = unsafe { &(*crate::stm32::RCC::ptr()) };
201238

@@ -204,16 +241,14 @@ macro_rules! usart {
204241

205242
// Calculate correct baudrate divisor on the fly
206243
let brr = clocks.pclk().0 / baud_rate.0;
207-
usart.brr.write(|w| unsafe { w.bits(brr) });
244+
self.usart.brr.write(|w| unsafe { w.bits(brr) });
208245

209246
// Reset other registers to disable advanced USART features
210-
usart.cr2.reset();
211-
usart.cr3.reset();
247+
self.usart.cr2.reset();
248+
self.usart.cr3.reset();
212249

213250
// Enable transmission and receiving
214-
usart.cr1.modify(|_, w| w.te().set_bit().re().set_bit().ue().set_bit());
215-
216-
Serial { usart, pins }
251+
self.usart.cr1.modify(|_, w| w.te().set_bit().re().set_bit().ue().set_bit());
217252
}
218253

219254
/// Starts listening for an interrupt event
@@ -252,7 +287,7 @@ macro_rules! usart {
252287

253288
#[cfg(feature = "device-selected")]
254289
usart! {
255-
USART1: (usart1, usart1en, apb2enr),
290+
USART1: (usart1, usart1tx, usart1rx, usart1en, apb2enr),
256291
}
257292
#[cfg(any(
258293
feature = "stm32f030x8",
@@ -262,21 +297,21 @@ usart! {
262297
feature = "stm32f072",
263298
))]
264299
usart! {
265-
USART2: (usart2, usart2en, apb1enr),
300+
USART2: (usart2, usart2tx, usart2rx,usart2en, apb1enr),
266301
}
267302
#[cfg(any(
268303
feature = "stm32f030xc",
269304
feature = "stm32f070xb",
270305
feature = "stm32f072",
271306
))]
272307
usart! {
273-
USART3: (usart3, usart3en, apb1enr),
274-
USART4: (usart4, usart4en, apb1enr),
308+
USART3: (usart3, usart3tx, usart3rx,usart3en, apb1enr),
309+
USART4: (usart4, usart4tx, usart4rx,usart4en, apb1enr),
275310
}
276311
#[cfg(feature = "stm32f030xc")]
277312
usart! {
278-
USART5: (usart5, usart5en, apb1enr),
279-
USART6: (usart6, usart6en, apb2enr),
313+
USART5: (usart5, usart5tx, usart5rx,usart5en, apb1enr),
314+
USART6: (usart6, usart6tx, usart6rx,usart6en, apb2enr),
280315
}
281316

282317
// It's s needed for the impls, but rustc doesn't recognize that
@@ -313,6 +348,22 @@ where
313348
}
314349
}
315350

351+
impl<USART, TXPIN, RXPIN> embedded_hal::serial::Read<u8> for Serial<USART, TXPIN, RXPIN>
352+
where
353+
USART: Deref<Target = SerialRegisterBlock>,
354+
RXPIN: RxPin<USART>,
355+
{
356+
type Error = Error;
357+
358+
/// Tries to read a byte from the uart
359+
fn read(&mut self) -> nb::Result<u8, Error> {
360+
Rx {
361+
usart: &self.usart as *const _,
362+
}
363+
.read()
364+
}
365+
}
366+
316367
#[cfg(feature = "device-selected")]
317368
impl<USART> embedded_hal::serial::Write<u8> for Tx<USART>
318369
where
@@ -349,14 +400,43 @@ where
349400
}
350401
}
351402

403+
impl<USART, TXPIN, RXPIN> embedded_hal::serial::Write<u8> for Serial<USART, TXPIN, RXPIN>
404+
where
405+
USART: Deref<Target = SerialRegisterBlock>,
406+
TXPIN: TxPin<USART>,
407+
{
408+
type Error = void::Void;
409+
410+
/// Ensures that none of the previously written words are still buffered
411+
fn flush(&mut self) -> nb::Result<(), Self::Error> {
412+
Tx {
413+
usart: &self.usart as *const _,
414+
}
415+
.flush()
416+
}
417+
418+
/// Tries to write a byte to the uart
419+
/// Fails if the transmit buffer is full
420+
fn write(&mut self, byte: u8) -> nb::Result<(), Self::Error> {
421+
Tx {
422+
usart: &self.usart as *const _,
423+
}
424+
.write(byte)
425+
}
426+
}
427+
352428
#[cfg(feature = "device-selected")]
353429
impl<USART, TXPIN, RXPIN> Serial<USART, TXPIN, RXPIN>
354430
where
355431
USART: Deref<Target = SerialRegisterBlock>,
356432
{
357433
/// Splits the UART Peripheral in a Tx and an Rx part
358434
/// This is required for sending/receiving
359-
pub fn split(self) -> (Tx<USART>, Rx<USART>) {
435+
pub fn split(self) -> (Tx<USART>, Rx<USART>)
436+
where
437+
TXPIN: TxPin<USART>,
438+
RXPIN: RxPin<USART>,
439+
{
360440
(
361441
Tx {
362442
usart: &self.usart as *const _,
@@ -366,6 +446,7 @@ where
366446
},
367447
)
368448
}
449+
369450
pub fn release(self) -> (USART, (TXPIN, RXPIN)) {
370451
(self.usart, self.pins)
371452
}

0 commit comments

Comments
 (0)