@@ -12,11 +12,14 @@ use core::{convert::Infallible, ops::Deref};
12
12
use crate :: {
13
13
gpio:: { gpioa, gpiob, gpioc, AF7 } ,
14
14
hal:: { blocking, serial} ,
15
- pac:: { self , rcc:: cfgr3:: USART1SW_A , usart1:: RegisterBlock , RCC , USART1 , USART2 , USART3 } ,
15
+ pac:: { self , rcc:: cfgr3:: USART1SW_A , usart1:: RegisterBlock , USART1 , USART2 , USART3 } ,
16
16
rcc:: { Clocks , APB1 , APB2 } ,
17
17
time:: rate:: * ,
18
18
} ;
19
19
20
+ #[ allow( unused_imports) ]
21
+ use crate :: pac:: RCC ;
22
+
20
23
use cfg_if:: cfg_if;
21
24
22
25
cfg_if ! {
@@ -492,35 +495,32 @@ pub trait Instance: Deref<Target = RegisterBlock> + private::Sealed {
492
495
}
493
496
494
497
macro_rules! usart {
495
- ( $( $USARTX: ident: ( $usartXen: ident, $APB: ident, $pclkX: ident, $usartXrst: ident, $usartXsw: ident) , ) +) => {
498
+ (
499
+ $(
500
+ $USARTX: ident: (
501
+ $usartXen: ident,
502
+ $APB: ident,
503
+ $pclkX: ident,
504
+ $usartXrst: ident,
505
+ $usartXsw: ident,
506
+ $usartXclock: ident
507
+ ) ,
508
+ ) +
509
+ ) => {
496
510
$(
497
511
impl private:: Sealed for $USARTX { }
498
512
impl Instance for $USARTX {
499
513
type APB = $APB;
500
514
fn enable_clock( apb: & mut Self :: APB ) {
501
515
apb. enr( ) . modify( |_, w| w. $usartXen( ) . enabled( ) ) ;
502
516
apb. rstr( ) . modify( |_, w| w. $usartXrst( ) . reset( ) ) ;
503
- apb. rstr( ) . modify( |_, w| w. $usartXrst( ) . clear_bit( ) ) ;
504
517
}
505
518
506
519
fn clock( clocks: & Clocks ) -> Hertz {
507
- // NOTE(unsafe) atomic read with no side effects
508
-
509
- // This is only partly sovable by this. The macro has to be adjusted, to give
510
- // information about, if sw is avalible for the uart implementation or not
511
- cfg_if:: cfg_if! {
512
- if #[ cfg( any( feature = "svd-f301" , feature = "svd-f3x4" ) ) ] {
513
- clocks. $pclkX( )
514
- } else {
515
- // FIXME usart2sw() is not avalible for stm32f318x8 for example
516
- match unsafe { ( * RCC :: ptr( ) ) . cfgr3. read( ) . $usartXsw( ) . variant( ) } {
517
- USART1SW_A :: PCLK => clocks. $pclkX( ) ,
518
- USART1SW_A :: HSI => crate :: rcc:: HSI ,
519
- USART1SW_A :: SYSCLK => clocks. sysclk( ) ,
520
- USART1SW_A :: LSE => crate :: rcc:: LSE ,
521
- }
522
- }
523
- }
520
+ // Use the function created via another macro outside of this one,
521
+ // because the implementation is dependend on the type $USARTX.
522
+ // But macros can not differentiate between types.
523
+ $usartXclock( clocks)
524
524
}
525
525
}
526
526
@@ -552,12 +552,79 @@ macro_rules! usart {
552
552
( [ $( ( $X: literal, $APB: literal) ) ,+ ] ) => {
553
553
paste:: paste! {
554
554
usart!(
555
- $( [ <USART $X>] : ( [ <usart $X en>] , [ <APB $APB>] , [ <pclk $APB>] , [ <usart $X rst>] , [ <usart $X sw>] ) , ) +
555
+ $(
556
+ [ <USART $X>] : (
557
+ [ <usart $X en>] ,
558
+ [ <APB $APB>] ,
559
+ [ <pclk $APB>] ,
560
+ [ <usart $X rst>] ,
561
+ [ <usart $X sw>] ,
562
+ [ <usart $X clock>]
563
+ ) ,
564
+ ) +
565
+ ) ;
566
+ }
567
+ } ;
568
+ }
569
+
570
+ /// Generates a clock function for UART Peripherals, where
571
+ /// the only clock source can be the peripheral clock
572
+ #[ allow( unused_macros) ]
573
+ macro_rules! usart_static_clock {
574
+ ( $( $usartXclock: ident, $pclkX: ident) ,+) => {
575
+ $(
576
+ /// Return the currently set source frequency the UART peripheral
577
+ /// depending on the clock source.
578
+ fn $usartXclock( clocks: & Clocks ) -> Hertz {
579
+ clocks. $pclkX( )
580
+ }
581
+ ) +
582
+ } ;
583
+ ( [ $( ( $X: literal, $APB: literal) ) ,+ ] ) => {
584
+ paste:: paste! {
585
+ usart_static_clock!(
586
+ $( [ <usart $X clock>] , [ <pclk $APB>] ) ,+
556
587
) ;
557
588
}
558
589
} ;
559
590
}
560
591
561
- usart ! ( [ ( 1 , 2 ) ] ) ;
562
- usart ! ( [ ( 2 , 1 ) ] ) ;
563
- usart ! ( [ ( 3 , 1 ) ] ) ;
592
+ /// Generates a clock function for UART Peripherals, where
593
+ /// the clock source can vary.
594
+ macro_rules! usart_var_clock {
595
+ ( $( $usartXclock: ident, $usartXsw: ident, $pclkX: ident) ,+) => {
596
+ $(
597
+ /// Return the currently set source frequency the UART peripheral
598
+ /// depending on the clock source.
599
+ fn $usartXclock( clocks: & Clocks ) -> Hertz {
600
+ // NOTE(unsafe): atomic read with no side effects
601
+ match unsafe { ( * RCC :: ptr( ) ) . cfgr3. read( ) . $usartXsw( ) . variant( ) } {
602
+ USART1SW_A :: PCLK => clocks. $pclkX( ) ,
603
+ USART1SW_A :: HSI => crate :: rcc:: HSI ,
604
+ USART1SW_A :: SYSCLK => clocks. sysclk( ) ,
605
+ USART1SW_A :: LSE => crate :: rcc:: LSE ,
606
+ }
607
+ }
608
+ ) +
609
+ } ;
610
+ ( [ $( ( $X: literal, $APB: literal) ) ,+ ] ) => {
611
+ paste:: paste! {
612
+ usart_var_clock!(
613
+ $( [ <usart $X clock>] , [ <usart $X sw>] , [ <pclk $APB>] ) ,+
614
+ ) ;
615
+ }
616
+ } ;
617
+ }
618
+
619
+ cfg_if:: cfg_if! {
620
+ if #[ cfg( any( feature = "svd-f301" , feature = "svd-f3x4" ) ) ] {
621
+ usart_var_clock!( [ ( 1 , 2 ) ] ) ;
622
+ // These are uart peripherals, where the only clock source
623
+ // is the PCLK (peripheral clock).
624
+ usart_static_clock!( [ ( 2 , 1 ) , ( 3 , 1 ) ] ) ;
625
+ } else {
626
+ usart_var_clock!( [ ( 1 , 2 ) , ( 2 , 1 ) , ( 3 , 1 ) ] ) ;
627
+ }
628
+ }
629
+ // TODO: what about uart 4 and uart 5?
630
+ usart ! ( [ ( 1 , 2 ) , ( 2 , 1 ) , ( 3 , 1 ) ] ) ;
0 commit comments