@@ -14,6 +14,7 @@ use core::convert::Infallible;
14
14
use core:: marker:: PhantomData ;
15
15
use core:: ops:: Deref ;
16
16
17
+ use crate :: gpio:: { InputSignal , OutputSignal } ;
17
18
use crate :: target;
18
19
use crate :: target:: { uart, UART0 , UART1 , UART2 } ;
19
20
@@ -163,24 +164,26 @@ pub struct Serial<
163
164
uart : UART ,
164
165
pins : Pins < TX , RX , CTS , RTS > ,
165
166
clock_control : crate :: clock_control:: ClockControlConfig ,
166
- apb_lock : Option < crate :: clock_control:: dfs:: LockAPB > ,
167
+ rx : Rx < UART > ,
168
+ tx : Tx < UART > ,
167
169
}
168
170
169
171
/// Serial receiver
170
172
pub struct Rx < UART : Instance > {
171
173
_uart : PhantomData < UART > ,
172
- _apb_lock : Option < crate :: clock_control:: dfs:: LockAPB > ,
174
+ apb_lock : Option < crate :: clock_control:: dfs:: LockAPB > ,
173
175
}
174
176
175
177
/// Serial transmitter
176
178
pub struct Tx < UART : Instance > {
177
179
_uart : PhantomData < UART > ,
178
- _apb_lock : Option < crate :: clock_control:: dfs:: LockAPB > ,
180
+ apb_lock : Option < crate :: clock_control:: dfs:: LockAPB > ,
179
181
}
180
182
181
183
impl < UART : Instance , TX : OutputPin , RX : InputPin , CTS : InputPin , RTS : OutputPin >
182
184
Serial < UART , TX , RX , CTS , RTS >
183
185
{
186
+ /// Create a new serial driver
184
187
pub fn new (
185
188
uart : UART ,
186
189
pins : Pins < TX , RX , CTS , RTS > ,
@@ -192,8 +195,17 @@ impl<UART: Instance, TX: OutputPin, RX: InputPin, CTS: InputPin, RTS: OutputPin>
192
195
uart,
193
196
pins,
194
197
clock_control,
195
- apb_lock : None ,
198
+ rx : Rx {
199
+ _uart : PhantomData ,
200
+ apb_lock : None ,
201
+ } ,
202
+ tx : Tx {
203
+ _uart : PhantomData ,
204
+ apb_lock : None ,
205
+ } ,
196
206
} ;
207
+
208
+ serial. uart . init_pins ( & mut serial. pins ) ;
197
209
serial. uart . reset ( dport) . enable ( dport) ;
198
210
serial
199
211
. change_stop_bits ( config. stop_bits )
@@ -203,6 +215,7 @@ impl<UART: Instance, TX: OutputPin, RX: InputPin, CTS: InputPin, RTS: OutputPin>
203
215
Ok ( serial)
204
216
}
205
217
218
+ /// Change the number of stop bits
206
219
pub fn change_stop_bits ( & mut self , stop_bits : config:: StopBits ) -> & mut Self {
207
220
//workaround for hardware issue, when UART stop bit set as 2-bit mode.
208
221
self . uart
@@ -219,6 +232,7 @@ impl<UART: Instance, TX: OutputPin, RX: InputPin, CTS: InputPin, RTS: OutputPin>
219
232
self
220
233
}
221
234
235
+ /// Change the number of data bits
222
236
pub fn change_data_bits ( & mut self , data_bits : config:: DataBits ) -> & mut Self {
223
237
self . uart . conf0 . modify ( |_, w| match data_bits {
224
238
config:: DataBits :: DataBits5 => w. bit_num ( ) . data_bits_5 ( ) ,
@@ -230,6 +244,7 @@ impl<UART: Instance, TX: OutputPin, RX: InputPin, CTS: InputPin, RTS: OutputPin>
230
244
self
231
245
}
232
246
247
+ /// Change the type of parity checking
233
248
pub fn change_parity ( & mut self , parity : config:: Parity ) -> & mut Self {
234
249
self . uart . conf0 . modify ( |_, w| match parity {
235
250
config:: Parity :: ParityNone => w. parity_en ( ) . clear_bit ( ) ,
@@ -242,10 +257,10 @@ impl<UART: Instance, TX: OutputPin, RX: InputPin, CTS: InputPin, RTS: OutputPin>
242
257
243
258
/// Change the baudrate.
244
259
///
245
- /// Will automatically select the clock source. WHen possible the reference clock (1MHz) will be used,
246
- /// because this is constant when the clock source/frequency changes.
247
- /// However if one of the clock frequencies is below 10MHz
248
- /// or if the baudrate is above the reference clock or if the baudrate cannot be set within 1.5%
260
+ /// Will automatically select the clock source. When possible the reference clock (1MHz) will
261
+ /// be used, because this is constant when the clock source/frequency changes.
262
+ /// However if one of the clock frequencies is below 10MHz or if the baudrate is above
263
+ /// the reference clock or if the baudrate cannot be set within 1.5%
249
264
/// then use the APB clock.
250
265
pub fn change_baudrate < T : Into < Hertz > + Copy > (
251
266
& mut self ,
@@ -287,13 +302,15 @@ impl<UART: Instance, TX: OutputPin, RX: InputPin, CTS: InputPin, RTS: OutputPin>
287
302
baudrate : T ,
288
303
use_apb_frequency : bool ,
289
304
) -> Result < & mut Self , Error > {
290
- if let None = self . apb_lock {
305
+ if let None = self . rx . apb_lock {
291
306
if use_apb_frequency {
292
- self . apb_lock = Some ( self . clock_control . lock_apb_frequency ( ) ) ;
307
+ self . rx . apb_lock = Some ( self . clock_control . lock_apb_frequency ( ) ) ;
308
+ self . tx . apb_lock = Some ( self . clock_control . lock_apb_frequency ( ) ) ;
293
309
}
294
310
} else {
295
311
if !use_apb_frequency {
296
- self . apb_lock = None ;
312
+ self . rx . apb_lock = None ;
313
+ self . tx . apb_lock = None ;
297
314
}
298
315
}
299
316
@@ -330,10 +347,12 @@ impl<UART: Instance, TX: OutputPin, RX: InputPin, CTS: InputPin, RTS: OutputPin>
330
347
Ok ( self )
331
348
}
332
349
350
+ /// Returns if the reference or APB clock is used
333
351
pub fn is_clock_apb ( & self ) -> bool {
334
352
self . uart . conf0 . read ( ) . tick_ref_always_on ( ) . bit_is_set ( )
335
353
}
336
354
355
+ /// Returns the current baudrate
337
356
pub fn baudrate ( & self ) -> Hertz {
338
357
let use_apb_frequency = self . uart . conf0 . read ( ) . tick_ref_always_on ( ) . bit_is_set ( ) ;
339
358
let sclk_freq = if use_apb_frequency {
@@ -368,71 +387,15 @@ impl<UART: Instance, TX: OutputPin, RX: InputPin, CTS: InputPin, RTS: OutputPin>
368
387
self . uart . status . read ( ) . st_utx_out ( ) . is_tx_idle ( )
369
388
}
370
389
390
+ /// Split the serial driver in separate TX and RX drivers
371
391
pub fn split ( self ) -> ( Tx < UART > , Rx < UART > ) {
372
- (
373
- Tx {
374
- _uart : PhantomData ,
375
- _apb_lock : if let None = self . apb_lock {
376
- None
377
- } else {
378
- Some ( self . clock_control . lock_apb_frequency ( ) )
379
- } ,
380
- } ,
381
- Rx {
382
- _uart : PhantomData ,
383
- _apb_lock : if let None = self . apb_lock {
384
- None
385
- } else {
386
- Some ( self . clock_control . lock_apb_frequency ( ) )
387
- } ,
388
- } ,
389
- )
392
+ ( self . tx , self . rx )
390
393
}
391
394
395
+ /// Release the UART and GPIO resources
392
396
pub fn release ( self ) -> ( UART , Pins < TX , RX , CTS , RTS > ) {
393
397
( self . uart , self . pins )
394
398
}
395
-
396
- fn rx_count ( & self ) -> u8 {
397
- unsafe { self . uart . status . read ( ) . rxfifo_cnt ( ) . bits ( ) }
398
- }
399
-
400
- fn rx_is_idle ( & self ) -> bool {
401
- unsafe { self . uart . status . read ( ) . st_urx_out ( ) . is_rx_idle ( ) }
402
- }
403
-
404
- fn read ( & mut self ) -> nb:: Result < u8 , Infallible > {
405
- if self . rx_count ( ) == 0 {
406
- Err ( nb:: Error :: WouldBlock )
407
- } else {
408
- Ok ( unsafe { self . uart . rx_fifo . read ( ) . bits ( ) } )
409
- }
410
- }
411
-
412
- fn tx_count ( & self ) -> u8 {
413
- unsafe { self . uart . status . read ( ) . txfifo_cnt ( ) . bits ( ) }
414
- }
415
-
416
- fn tx_is_idle ( & self ) -> bool {
417
- unsafe { self . uart . status . read ( ) . st_utx_out ( ) . is_tx_idle ( ) }
418
- }
419
-
420
- fn flush ( & mut self ) -> nb:: Result < ( ) , Infallible > {
421
- if self . tx_is_idle ( ) {
422
- Ok ( ( ) )
423
- } else {
424
- Err ( nb:: Error :: WouldBlock )
425
- }
426
- }
427
-
428
- fn write ( & mut self , byte : u8 ) -> nb:: Result < ( ) , Infallible > {
429
- if self . tx_count ( ) < UART_FIFO_SIZE {
430
- unsafe { self . uart . tx_fifo . write_with_zero ( |w| w. bits ( byte) ) }
431
- Ok ( ( ) )
432
- } else {
433
- Err ( nb:: Error :: WouldBlock )
434
- }
435
- }
436
399
}
437
400
438
401
impl < UART : Instance , TX : OutputPin , RX : InputPin , CTS : InputPin , RTS : OutputPin > serial:: Read < u8 >
@@ -441,7 +404,7 @@ impl<UART: Instance, TX: OutputPin, RX: InputPin, CTS: InputPin, RTS: OutputPin>
441
404
type Error = Infallible ;
442
405
443
406
fn read ( & mut self ) -> nb:: Result < u8 , Self :: Error > {
444
- self . read ( )
407
+ self . rx . read ( )
445
408
}
446
409
}
447
410
@@ -451,11 +414,11 @@ impl<UART: Instance, TX: OutputPin, RX: InputPin, CTS: InputPin, RTS: OutputPin>
451
414
type Error = Infallible ;
452
415
453
416
fn flush ( & mut self ) -> nb:: Result < ( ) , Self :: Error > {
454
- self . flush ( )
417
+ self . tx . flush ( )
455
418
}
456
419
457
420
fn write ( & mut self , byte : u8 ) -> nb:: Result < ( ) , Self :: Error > {
458
- self . write ( byte)
421
+ self . tx . write ( byte)
459
422
}
460
423
}
461
424
@@ -472,10 +435,12 @@ impl<UART: Instance, TX: OutputPin, RX: InputPin, CTS: InputPin, RTS: OutputPin>
472
435
}
473
436
474
437
impl < UART : Instance > Rx < UART > {
438
+ /// Get count of bytes in the receive FIFO
475
439
pub fn count ( & self ) -> u8 {
476
440
unsafe { ( * UART :: ptr ( ) ) . status . read ( ) . rxfifo_cnt ( ) . bits ( ) }
477
441
}
478
442
443
+ /// Check if the receivers is idle
479
444
pub fn is_idle ( & self ) -> bool {
480
445
unsafe { ( * UART :: ptr ( ) ) . status . read ( ) . st_urx_out ( ) . is_rx_idle ( ) }
481
446
}
@@ -494,10 +459,12 @@ impl<UART: Instance> serial::Read<u8> for Rx<UART> {
494
459
}
495
460
496
461
impl < UART : Instance > Tx < UART > {
462
+ /// Get count of bytes in the transmitter FIFO
497
463
pub fn count ( & self ) -> u8 {
498
464
unsafe { ( * UART :: ptr ( ) ) . status . read ( ) . txfifo_cnt ( ) . bits ( ) }
499
465
}
500
466
467
+ /// Check if the transmitter is idle
501
468
pub fn is_idle ( & self ) -> bool {
502
469
unsafe { ( * UART :: ptr ( ) ) . status . read ( ) . st_utx_out ( ) . is_tx_idle ( ) }
503
470
}
@@ -539,16 +506,25 @@ where
539
506
540
507
pub trait Instance : Deref < Target = uart:: RegisterBlock > {
541
508
fn ptr ( ) -> * const uart:: RegisterBlock ;
509
+ /// Enable peripheral
542
510
fn enable ( & mut self , dport : & mut target:: DPORT ) -> & mut Self ;
511
+ /// Disable peripheral
543
512
fn disable ( & mut self , dport : & mut target:: DPORT ) -> & mut Self ;
513
+ /// Reset peripheral
544
514
fn reset ( & mut self , dport : & mut target:: DPORT ) -> & mut Self ;
515
+
516
+ /// Initialize pins
517
+ fn init_pins < TX : OutputPin , RX : InputPin , CTS : InputPin , RTS : OutputPin > (
518
+ & mut self ,
519
+ pins : & mut Pins < TX , RX , CTS , RTS > ,
520
+ ) -> & mut Self ;
545
521
}
546
522
547
523
static UART_MEM_LOCK : CriticalSectionSpinLockMutex < ( ) > = CriticalSectionSpinLockMutex :: new ( ( ) ) ;
548
524
549
525
macro_rules! halUart {
550
526
( $(
551
- $UARTX: ident: ( $uartX: ident) ,
527
+ $UARTX: ident: ( $uartX: ident, $txd : ident , $rxd : ident , $cts : ident , $rts : ident ) ,
552
528
) +) => {
553
529
$(
554
530
impl Instance for $UARTX {
@@ -584,13 +560,40 @@ macro_rules! halUart {
584
560
self
585
561
586
562
}
563
+
564
+ fn init_pins<TX : OutputPin , RX : InputPin , CTS : InputPin , RTS : OutputPin >(
565
+ & mut self , pins: & mut Pins <TX , RX , CTS , RTS >
566
+ ) -> & mut Self {
567
+ pins
568
+ . tx
569
+ . set_to_push_pull_output( )
570
+ . connect_peripheral_to_output( OutputSignal :: $txd) ;
571
+
572
+ pins
573
+ . rx
574
+ . set_to_input( )
575
+ . connect_input_to_peripheral( InputSignal :: $rxd) ;
576
+
577
+ if let Some ( cts) = pins. cts. as_mut( ) {
578
+ cts
579
+ . set_to_input( )
580
+ . connect_input_to_peripheral( InputSignal :: $cts) ;
581
+ }
582
+
583
+ if let Some ( rts) = pins. rts. as_mut( ) {
584
+ rts
585
+ . set_to_push_pull_output( )
586
+ . connect_peripheral_to_output( OutputSignal :: $rts) ;
587
+ }
588
+ self
589
+ }
587
590
}
588
591
) +
589
592
}
590
593
}
591
594
592
595
halUart ! {
593
- UART0 : ( uart0) ,
594
- UART1 : ( uart1) ,
595
- UART2 : ( uart2) ,
596
+ UART0 : ( uart0, U0TXD , U0RXD , U0CTS , U0RTS ) ,
597
+ UART1 : ( uart1, U1TXD , U1RXD , U1CTS , U1RTS ) ,
598
+ UART2 : ( uart2, U2TXD , U2RXD , U2CTS , U2RTS ) ,
596
599
}
0 commit comments