@@ -195,6 +195,8 @@ static const uint32_t CLOCK_MSI_RANGE[] =
195195 4194000 ,
196196};
197197
198+ static const uint32_t CLOCK_PLL_MULTIPLIER [] = {3 , 4 , 6 , 8 , 12 , 16 , 24 , 32 , 48 };
199+ static const uint32_t CLOCK_PLL_DIVIDER [] = {1 , 2 , 3 , 4 };
198200
199201typedef struct _Clock_Device
200202{
@@ -261,7 +263,7 @@ static System_Errors Clock_deInit (void);
261263 *
262264 * @return value of PLL source clock.
263265 */
264- // static uint32_t Clock_getActualPllInputValue (void);
266+ static uint32_t Clock_getActualPllInputValue (void );
265267
266268/**
267269 * Return the source clock of PLL set in configuration struct.
@@ -270,7 +272,7 @@ static System_Errors Clock_deInit (void);
270272 *
271273 * @return value of source clock of PLL.
272274 */
273- // static uint32_t Clock_getConfigPllValue (Clock_Config *config, Clock_PLLConfig *pllConfig );
275+ static uint32_t Clock_getConfigPllValue (Clock_Config * config );
274276
275277/**
276278 * Return the clock set for MSI in configuration struct.
@@ -320,14 +322,16 @@ static uint32_t Clock_getActualSystemValue (void)
320322// case CLOCK_SYSTEMSOURCESWS_HSE:
321323// systemClock = clk0.externalClock;
322324// break;
323- // case CLOCK_SYSTEMSOURCESWS_PLL:
324- // {
325- // uint32_t pllmClock = Clock_getActualPllInputValue();
326- // uint32_t pllnReg = UTILITY_READ_REGISTER_BIT(clk0.regmap->PLLCFGR, RCC_PLLCFGR_PLLN_Msk) >> RCC_PLLCFGR_PLLN_Pos;
327- // uint32_t pllrReg = UTILITY_READ_REGISTER_BIT(clk0.regmap->PLLCFGR, RCC_PLLCFGR_PLLR_Msk) >> RCC_PLLCFGR_PLLR_Pos;
328- // systemClock = (((pllmClock) * pllnReg) / ((pllrReg + 1) * 2));
329- // }
330- // break;
325+ case CLOCK_SYSTEMSOURCESWS_PLL :
326+ {
327+ uint32_t pllClock = Clock_getActualPllInputValue ();
328+
329+ uint32_t mult = UTILITY_READ_REGISTER_BIT (clk .regmap -> CFGR , RCC_CFGR_PLLMUL_Msk ) >> RCC_CFGR_PLLMUL_Pos ;
330+ uint32_t div = UTILITY_READ_REGISTER_BIT (clk .regmap -> CFGR , RCC_CFGR_PLLDIV_Msk ) >> RCC_CFGR_PLLDIV_Pos ;
331+
332+ systemClock = (((pllClock ) * CLOCK_PLL_MULTIPLIER [mult ]) / (CLOCK_PLL_DIVIDER [div ]));
333+ }
334+ break ;
331335 }
332336
333337 return systemClock ;
@@ -593,6 +597,54 @@ static System_Errors Clock_oscillatorConfig (Clock_Config* config)
593597 }
594598 }
595599
600+ if (config -> sysSource == CLOCK_SYSTEMSOURCE_PLL )
601+ {
602+ if (config -> pllState == CLOCK_OSCILLATORSTATE_ON )
603+ {
604+ // Disable the PLL by setting PLLON to 0 in Clock control register (RCC_CR).
605+ UTILITY_CLEAR_REGISTER_BIT (clk .regmap -> CR ,RCC_CR_PLLON );
606+ // Wait until PLLRDY is cleared. The PLL is now fully stopped.
607+ tickstart = System_currentTick ();
608+ while (UTILITY_READ_REGISTER_BIT (clk .regmap -> CR , RCC_CR_PLLRDY ) == 1 )
609+ {
610+ // 2ms minimum
611+ if ((System_currentTick () - tickstart ) > 20u )
612+ return ERRORS_CLOCK_TIMEOUT ;
613+ }
614+
615+ // FIXME: Some check on parameters validity!
616+
617+ // Change the desired parameter.
618+ UTILITY_MODIFY_REGISTER (clk .regmap -> CFGR , RCC_CFGR_PLLSRC_Msk , (config -> pllSource << RCC_CFGR_PLLSRC_Pos ));
619+ UTILITY_MODIFY_REGISTER (clk .regmap -> CFGR , RCC_CFGR_PLLMUL_Msk , (config -> pllMultiplier << RCC_CFGR_PLLMUL_Pos ));
620+ UTILITY_MODIFY_REGISTER (clk .regmap -> CFGR , RCC_CFGR_PLLDIV_Msk , (config -> pllDivider << RCC_CFGR_PLLDIV_Pos ));
621+
622+ // Enable the PLL again by setting PLLON to 1.
623+ UTILITY_SET_REGISTER_BIT (clk .regmap -> CR ,RCC_CR_PLLON );
624+
625+ // Wait until PLLRDY is cleared. The PLL is now fully started.
626+ tickstart = System_currentTick ();
627+ while (UTILITY_READ_REGISTER_BIT (clk .regmap -> CR , RCC_CR_PLLRDY ) == 1 )
628+ {
629+ // 2ms minimum
630+ if ((System_currentTick () - tickstart ) > 20u )
631+ return ERRORS_CLOCK_TIMEOUT ;
632+ }
633+ }
634+ else
635+ {
636+ // Disable the PLL by setting PLLON to 0 in Clock control register (RCC_CR).
637+ UTILITY_CLEAR_REGISTER_BIT (clk .regmap -> CR ,RCC_CR_PLLON );
638+ // Wait until PLLRDY is cleared. The PLL is now fully stopped.
639+ tickstart = System_currentTick ();
640+ while (UTILITY_READ_REGISTER_BIT (clk .regmap -> CR , RCC_CR_PLLRDY ) == 1 )
641+ {
642+ // 2ms minimum
643+ if ((System_currentTick () - tickstart ) > 20u )
644+ return ERRORS_CLOCK_TIMEOUT ;
645+ }
646+ }
647+ }
596648// UTILITY_MODIFY_REGISTER(clk.regmap->CFGR, RCC_CFGR_MCOSEL_Msk, (config->mcoSource << RCC_CFGR_MCOSEL_Pos));
597649// UTILITY_MODIFY_REGISTER(clk.regmap->CFGR, RCC_CFGR_MCOPRE_Msk, (config->mcoPrescaler << RCC_CFGR_MCOPRE_Pos));
598650
@@ -610,13 +662,13 @@ static System_Errors Clock_outputConfig (Clock_Config* config)
610662 // PLL is selected as sys clock
611663 if (config -> sysSource == CLOCK_SYSTEMSOURCE_PLL )
612664 {
613- // // Check if the source is ready
614- // if (UTILITY_READ_REGISTER_BIT(clk0 .regmap->CR,RCC_CR_PLLRDY) == 0)
615- // {
616- // return ERRORS_CLOCK_PLL_NOT_READY;
617- // }
618- //
619- // cfgrSW = RCC_CFGR_SW_PLL;
665+ // Check if the source is ready
666+ if (UTILITY_READ_REGISTER_BIT (clk .regmap -> CR ,RCC_CR_PLLRDY ) == 0 )
667+ {
668+ return ERRORS_CLOCK_PLL_NOT_READY ;
669+ }
670+
671+ cfgrSW = RCC_CFGR_SW_PLL ;
620672 }
621673 else if (config -> sysSource == CLOCK_SYSTEMSOURCE_HSI )
622674 {
@@ -1321,42 +1373,14 @@ uint32_t Clock_getConfigOscillatorValue (Clock_Config *config)
13211373#endif
13221374 break ;
13231375 case CLOCK_SYSTEMSOURCE_PLL :
1324- // systemClock = Clock_getConfigPllValue(config, &config->pll );
1376+ systemClock = Clock_getConfigPllValue (config );
13251377 break ;
13261378 }
13271379
13281380 return systemClock ;
13291381}
13301382
1331- #if 0
1332- static uint32_t Clock_getActualPllInputValue (void )
1333- {
1334- uint32_t baseClock = 0 , pllmClock = 0 ;
1335- Clock_PllSource pllSource = (Clock_PllSource )(UTILITY_READ_REGISTER_BIT (clk0 .regmap -> PLLCFGR , RCC_PLLCFGR_PLLSRC_Msk ));
1336- uint32_t pllmReg = UTILITY_READ_REGISTER_BIT (clk0 .regmap -> PLLCFGR , RCC_PLLCFGR_PLLM_Msk ) >> RCC_PLLCFGR_PLLM_Pos ;
1337-
1338- switch (pllSource )
1339- {
1340- default :
1341- case CLOCK_PLLSOURCE_NONE :
1342- baseClock = 0 ;
1343- break ;
1344- case CLOCK_PLLSOURCE_MSI :
1345- baseClock = Clock_getActualMsiValue ();
1346- break ;
1347- case CLOCK_PLLSOURCE_HSI :
1348- baseClock = CLOCK_FREQ_HSI ;
1349- break ;
1350- case CLOCK_PLLSOURCE_HSE :
1351- baseClock = clk0 .externalClock ;
1352- break ;
1353- }
1354-
1355- pllmClock = ((baseClock ) / (pllmReg + 1 ));
1356- return pllmClock ;
1357- }
1358-
1359- static uint32_t Clock_getConfigPllValue (Clock_Config * config , Clock_PLLConfig * pllConfig )
1383+ static uint32_t Clock_getConfigPllValue (Clock_Config * config )
13601384{
13611385 uint32_t base = 0 , frequency = 0 ;
13621386
@@ -1366,47 +1390,44 @@ static uint32_t Clock_getConfigPllValue (Clock_Config* config, Clock_PLLConfig *
13661390 case CLOCK_PLLSOURCE_NONE :
13671391 return 0 ;
13681392
1369- case CLOCK_PLLSOURCE_MSI :
1370- base = Clock_msiRange [config -> msiRange ];
1371- break ;
1372-
13731393 case CLOCK_PLLSOURCE_HSI :
13741394 base = CLOCK_FREQ_HSI ;
13751395 break ;
1376-
1377- case CLOCK_PLLSOURCE_HSE :
1378- base = clk0 .externalClock ;
1379- break ;
13801396 }
13811397
13821398 frequency = base / (config -> pllPrescaler + 1 );
1383- frequency *= pllConfig -> multiplier ;
13841399
1385- switch (pllConfig -> dividerR )
1386- {
1387- case CLOCK_PLLDIVIDER_R_2 :
1388- frequency /= 2 ;
1389- break ;
1400+ frequency *= CLOCK_PLL_MULTIPLIER [config -> pllMultiplier ];
1401+ frequency /= CLOCK_PLL_DIVIDER [config -> pllDivider ];
13901402
1391- case CLOCK_PLLDIVIDER_R_4 :
1392- frequency /= 4 ;
1393- break ;
1403+ return frequency ;
1404+ }
13941405
1395- case CLOCK_PLLDIVIDER_R_6 :
1396- frequency /= 6 ;
1397- break ;
1406+ static uint32_t Clock_getActualPllInputValue (void )
1407+ {
1408+ uint32_t baseClock = 0 , pllmClock = 0 ;
1409+ Clock_PllSource pllSource = (Clock_PllSource )(UTILITY_READ_REGISTER_BIT (clk .regmap -> CFGR , RCC_CFGR_PLLSRC_Msk ));
13981410
1411+ //uint32_t pre = UTILITY_READ_REGISTER_BIT(clk.regmap->CFGR, RCC_CFGR_PLLMUL_Msk) >> RCC_CFGR_PLLMUL_Pos;
1412+ //uint32_t mult = UTILITY_READ_REGISTER_BIT(clk.regmap->CFGR, RCC_CFGR_PLLMUL_Msk) >> RCC_CFGR_PLLMUL_Pos;
1413+ //uint32_t div = UTILITY_READ_REGISTER_BIT(clk.regmap->CFGR, RCC_CFGR_PLLDIV_Msk) >> RCC_CFGR_PLLDIV_Pos;
1414+
1415+ switch (pllSource )
1416+ {
13991417 default :
1400- case CLOCK_PLLDIVIDER_R_8 :
1401- frequency /= 8 ;
1418+ case CLOCK_PLLSOURCE_NONE :
1419+ baseClock = 0 ;
1420+ break ;
1421+ case CLOCK_PLLSOURCE_HSI :
1422+ baseClock = CLOCK_FREQ_HSI ;
14021423 break ;
14031424 }
14041425
1405- return frequency ;
1426+ //pllmClock = ((baseClock) / (pllmReg + 1));
1427+ //return pllmClock;
1428+ return baseClock ;
14061429}
14071430
1408- #endif
1409-
14101431#endif // LIBOHIBOARD_STM32L0
14111432
14121433#ifdef __cplusplus
0 commit comments