@@ -227,31 +227,66 @@ pub struct Tx<USART> {
227227unsafe impl < USART > Send for Tx < USART > { }
228228
229229macro_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
291326usart ! {
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) ) ]
304339usart ! {
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) ) ]
314349usart ! {
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" ) ) ]
319354usart ! {
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+
356407impl < USART > embedded_hal:: serial:: Write < u8 > for Tx < USART >
357408where
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+
391467impl < USART , TXPIN , RXPIN > Serial < USART , TXPIN , RXPIN >
392468where
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