@@ -81,7 +81,7 @@ impl RccExt for RCC {
81
81
hse : None ,
82
82
lse : None ,
83
83
msi : None ,
84
- hsi48 : false ,
84
+ clk48_source : None ,
85
85
lsi : false ,
86
86
hclk : None ,
87
87
pclk1 : None ,
@@ -148,11 +148,13 @@ impl CRRCR {
148
148
}
149
149
150
150
/// Checks if the 48 MHz HSI is enabled
151
+ #[ inline]
151
152
pub fn is_hsi48_on ( & mut self ) -> bool {
152
153
self . crrcr ( ) . read ( ) . hsi48on ( ) . bit ( )
153
154
}
154
155
155
156
/// Checks if the 48 MHz HSI is ready
157
+ #[ inline]
156
158
pub fn is_hsi48_ready ( & mut self ) -> bool {
157
159
self . crrcr ( ) . read ( ) . hsi48rdy ( ) . bit ( )
158
160
}
@@ -347,14 +349,14 @@ pub struct CFGR {
347
349
hse : Option < HseConfig > ,
348
350
lse : Option < LseConfig > ,
349
351
msi : Option < MsiFreq > ,
350
- hsi48 : bool ,
351
352
lsi : bool ,
352
353
hclk : Option < u32 > ,
353
354
pclk1 : Option < u32 > ,
354
355
pclk2 : Option < u32 > ,
355
356
sysclk : Option < u32 > ,
356
357
pll_source : Option < PllSource > ,
357
358
pll_config : Option < PllConfig > ,
359
+ clk48_source : Option < Clk48Source > ,
358
360
}
359
361
360
362
impl CFGR {
@@ -382,12 +384,6 @@ impl CFGR {
382
384
self
383
385
}
384
386
385
- /// Enable the 48 MHz USB, RNG, SDMMC HSI clock source. Not available on all stm32l4x6 series
386
- pub fn hsi48 ( mut self , on : bool ) -> Self {
387
- self . hsi48 = on;
388
- self
389
- }
390
-
391
387
/// Enables the MSI with the specified speed
392
388
pub fn msi ( mut self , range : MsiFreq ) -> Self {
393
389
self . msi = Some ( range) ;
@@ -431,6 +427,11 @@ impl CFGR {
431
427
self
432
428
}
433
429
430
+ pub fn clk48_source ( mut self , source : Clk48Source ) -> Self {
431
+ self . clk48_source = Some ( source) ;
432
+ self
433
+ }
434
+
434
435
/// Freezes the clock configuration, making it effective
435
436
pub fn freeze ( & self , acr : & mut ACR , pwr : & mut Pwr ) -> Clocks {
436
437
let rcc = unsafe { & * RCC :: ptr ( ) } ;
@@ -553,18 +554,35 @@ impl CFGR {
553
554
while rcc. cr . read ( ) . msirdy ( ) . bit_is_clear ( ) { }
554
555
}
555
556
556
- // Turn on USB, RNG Clock using the HSI48 CLK source
557
- if self . hsi48 {
558
- // p. 180 in ref-manual
559
- rcc. crrcr . modify ( |_, w| w. hsi48on ( ) . set_bit ( ) ) ;
557
+ // Select 48 MHz clock source for SDMMC, USB, RNG, etc.
558
+ match self . clk48_source {
559
+ None => {
560
+ unsafe { rcc. ccipr . modify ( |_, w| w. clk48sel ( ) . bits ( 0b00 ) ) } ;
561
+ }
562
+ #[ cfg( any( feature = "stm32l496" , feature = "stm32l4a6" ) ) ]
563
+ Some ( Clk48Source :: Hsi48 ) => {
564
+ // Turn on USB, RNG Clock using the HSI48 CLK source.
560
565
561
- // Wait until HSI48 is running
562
- while rcc. crrcr . read ( ) . hsi48rdy ( ) . bit_is_clear ( ) { }
563
- }
566
+ // p. 180 in ref-manual
567
+ rcc. crrcr . modify ( |_, w| w. hsi48on ( ) . set_bit ( ) ) ;
568
+
569
+ // Wait until HSI48 is running.
570
+ while rcc. crrcr . read ( ) . hsi48rdy ( ) . bit_is_clear ( ) { }
564
571
565
- // Select MSI as clock source for usb48, rng ...
566
- if let Some ( MsiFreq :: RANGE48M ) = self . msi {
567
- unsafe { rcc. ccipr . modify ( |_, w| w. clk48sel ( ) . bits ( 0b11 ) ) } ;
572
+ unsafe { rcc. ccipr . modify ( |_, w| w. clk48sel ( ) . bits ( 0b00 ) ) } ;
573
+ }
574
+ Some ( Clk48Source :: PllSai1 ) => {
575
+ unsafe { rcc. ccipr . modify ( |_, w| w. clk48sel ( ) . bits ( 0b01 ) ) } ;
576
+
577
+ unimplemented ! ( )
578
+ }
579
+ Some ( Clk48Source :: Pll ) => {
580
+ unsafe { rcc. ccipr . modify ( |_, w| w. clk48sel ( ) . bits ( 0b10 ) ) } ;
581
+ }
582
+ Some ( Clk48Source :: Msi ) => {
583
+ assert_eq ! ( Some ( MsiFreq :: RANGE48M ) , self . msi) ;
584
+ unsafe { rcc. ccipr . modify ( |_, w| w. clk48sel ( ) . bits ( 0b11 ) ) } ;
585
+ }
568
586
}
569
587
570
588
//
@@ -716,14 +734,23 @@ impl CFGR {
716
734
} )
717
735
}
718
736
737
+ let mut pll48m1clk = None ;
738
+
719
739
let sysclk_src_bits;
720
740
let mut msi = self . msi ;
721
741
if let Some ( pllconf) = pllconf {
722
742
// Sanity-checks per RM0394, 6.4.4 PLL configuration register (RCC_PLLCFGR)
723
743
let r = pllconf. r . to_division_factor ( ) ;
724
744
let clock_speed = clock_speed / ( pllconf. m as u32 + 1 ) ;
725
745
let vco = clock_speed * pllconf. n as u32 ;
726
- let output_clock = vco / r;
746
+ let pllclk = vco / r;
747
+
748
+ let q = ( vco + 48_000_000 - 1 ) / 48_000_000 ;
749
+ pll48m1clk = Some ( ( vco / q) . Hz ( ) ) ;
750
+
751
+ if self . clk48_source == Some ( Clk48Source :: Pll ) {
752
+ assert_eq ! ( q, 48_000_000 ) ;
753
+ }
727
754
728
755
assert ! ( r <= 8 ) ; // Allowed max output divider
729
756
assert ! ( pllconf. n >= 8 ) ; // Allowed min multiplier
@@ -732,7 +759,7 @@ impl CFGR {
732
759
assert ! ( clock_speed <= 16_000_000 ) ; // VCO input clock max
733
760
assert ! ( vco >= 64_000_000 ) ; // VCO output min
734
761
assert ! ( vco <= 334_000_000 ) ; // VCO output max
735
- assert ! ( output_clock <= 80_000_000 ) ; // Max output clock
762
+ assert ! ( pllclk <= 80_000_000 ) ; // Max output clock
736
763
737
764
// use PLL as source
738
765
sysclk_src_bits = 0b11 ;
@@ -750,6 +777,8 @@ impl CFGR {
750
777
. bits ( pllconf. r . to_bits ( ) )
751
778
. plln ( )
752
779
. bits ( pllconf. n )
780
+ . pllq ( )
781
+ . bits ( q as u8 )
753
782
} ) ;
754
783
755
784
rcc. cr . modify ( |_, w| w. pllon ( ) . set_bit ( ) ) ;
@@ -810,15 +839,16 @@ impl CFGR {
810
839
lsi : lsi_used,
811
840
lse : self . lse . is_some ( ) ,
812
841
msi,
813
- hsi48 : self . hsi48 ,
814
842
pclk1 : pclk1. Hz ( ) ,
815
843
pclk2 : pclk2. Hz ( ) ,
816
844
ppre1,
817
845
ppre2,
846
+ pll48m1clk,
818
847
sysclk : sysclk. Hz ( ) ,
819
848
timclk1 : timclk1. Hz ( ) ,
820
849
timclk2 : timclk2. Hz ( ) ,
821
850
pll_source : pllconf. map ( |_| pll_source) ,
851
+ clk48_source : self . clk48_source ,
822
852
}
823
853
}
824
854
}
@@ -900,24 +930,39 @@ impl PllSource {
900
930
}
901
931
}
902
932
933
+ #[ derive( Clone , Copy , Debug , PartialEq ) ]
934
+ /// 48 MHz clock source used by USB OTG FS, RNG and SDMMC.
935
+ pub enum Clk48Source {
936
+ /// HSI48 clock
937
+ #[ cfg( any( feature = "stm32l496" , feature = "stm32l4a6" ) ) ]
938
+ Hsi48 ,
939
+ /// PLLSAI1 “Q” clock (PLL48M2CLK)
940
+ PllSai1 ,
941
+ /// PLL “Q” clock (PLL48M1CLK)
942
+ Pll ,
943
+ /// MSI clock
944
+ Msi ,
945
+ }
946
+
903
947
/// Frozen clock frequencies
904
948
///
905
949
/// The existence of this value indicates that the clock configuration can no longer be changed
906
950
#[ derive( Clone , Copy , Debug ) ]
907
951
pub struct Clocks {
908
952
hclk : Hertz ,
909
- hsi48 : bool ,
910
953
msi : Option < MsiFreq > ,
911
954
lsi : bool ,
912
955
lse : bool ,
913
956
pclk1 : Hertz ,
914
957
pclk2 : Hertz ,
915
958
ppre1 : u8 ,
916
959
ppre2 : u8 ,
960
+ pll48m1clk : Option < Hertz > ,
917
961
sysclk : Hertz ,
918
962
timclk1 : Hertz ,
919
963
timclk2 : Hertz ,
920
964
pll_source : Option < PllSource > ,
965
+ clk48_source : Option < Clk48Source > ,
921
966
}
922
967
923
968
impl Clocks {
@@ -928,7 +973,15 @@ impl Clocks {
928
973
929
974
/// Returns status of HSI48
930
975
pub fn hsi48 ( & self ) -> bool {
931
- self . hsi48
976
+ #[ cfg( any( feature = "stm32l496" , feature = "stm32l4a6" ) ) ]
977
+ {
978
+ self . clk48_source == Some ( Clk48Source :: Hsi48 )
979
+ }
980
+
981
+ #[ cfg( not( any( feature = "stm32l496" , feature = "stm32l4a6" ) ) ) ]
982
+ {
983
+ false
984
+ }
932
985
}
933
986
934
987
// Returns the status of the MSI
0 commit comments