stm32f4xx_hal_rcc_ex.c 67 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682
  1. /**
  2. ******************************************************************************
  3. * @file stm32f4xx_hal_rcc_ex.c
  4. * @author MCD Application Team
  5. * @version V1.3.0
  6. * @date 09-March-2015
  7. * @brief Extension RCC HAL module driver.
  8. * This file provides firmware functions to manage the following
  9. * functionalities RCC extension peripheral:
  10. * + Extended Peripheral Control functions
  11. *
  12. ******************************************************************************
  13. * @attention
  14. *
  15. * <h2><center>&copy; COPYRIGHT(c) 2015 STMicroelectronics</center></h2>
  16. *
  17. * Redistribution and use in source and binary forms, with or without modification,
  18. * are permitted provided that the following conditions are met:
  19. * 1. Redistributions of source code must retain the above copyright notice,
  20. * this list of conditions and the following disclaimer.
  21. * 2. Redistributions in binary form must reproduce the above copyright notice,
  22. * this list of conditions and the following disclaimer in the documentation
  23. * and/or other materials provided with the distribution.
  24. * 3. Neither the name of STMicroelectronics nor the names of its contributors
  25. * may be used to endorse or promote products derived from this software
  26. * without specific prior written permission.
  27. *
  28. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
  29. * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  30. * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  31. * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
  32. * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  33. * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
  34. * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
  35. * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
  36. * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  37. * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  38. *
  39. ******************************************************************************
  40. */
  41. /* Includes ------------------------------------------------------------------*/
  42. #include "stm32f4xx_hal.h"
  43. /** @addtogroup STM32F4xx_HAL_Driver
  44. * @{
  45. */
  46. /** @defgroup RCCEx RCCEx
  47. * @brief RCCEx HAL module driver
  48. * @{
  49. */
  50. #ifdef HAL_RCC_MODULE_ENABLED
  51. /* Private typedef -----------------------------------------------------------*/
  52. /* Private define ------------------------------------------------------------*/
  53. /** @addtogroup RCCEx_Private_Constants
  54. * @{
  55. */
  56. /**
  57. * @}
  58. */
  59. /* Private macro -------------------------------------------------------------*/
  60. /* Private variables ---------------------------------------------------------*/
  61. /* Private function prototypes -----------------------------------------------*/
  62. /* Private functions ---------------------------------------------------------*/
  63. /** @defgroup RCCEx_Exported_Functions RCCEx Exported Functions
  64. * @{
  65. */
  66. /** @defgroup RCCEx_Exported_Functions_Group1 Extended Peripheral Control functions
  67. * @brief Extended Peripheral Control functions
  68. *
  69. @verbatim
  70. ===============================================================================
  71. ##### Extended Peripheral Control functions #####
  72. ===============================================================================
  73. [..]
  74. This subsection provides a set of functions allowing to control the RCC Clocks
  75. frequencies.
  76. [..]
  77. (@) Important note: Care must be taken when HAL_RCCEx_PeriphCLKConfig() is used to
  78. select the RTC clock source; in this case the Backup domain will be reset in
  79. order to modify the RTC Clock source, as consequence RTC registers (including
  80. the backup registers) and RCC_BDCR register are set to their reset values.
  81. @endverbatim
  82. * @{
  83. */
  84. #if defined(STM32F446xx)
  85. /**
  86. * @brief Initializes the RCC extended peripherals clocks according to the specified
  87. * parameters in the RCC_PeriphCLKInitTypeDef.
  88. * @param PeriphClkInit: pointer to an RCC_PeriphCLKInitTypeDef structure that
  89. * contains the configuration information for the Extended Peripherals
  90. * clocks(I2S, SAI, LTDC RTC and TIM).
  91. *
  92. * @note Care must be taken when HAL_RCCEx_PeriphCLKConfig() is used to select
  93. * the RTC clock source; in this case the Backup domain will be reset in
  94. * order to modify the RTC Clock source, as consequence RTC registers (including
  95. * the backup registers) and RCC_BDCR register are set to their reset values.
  96. *
  97. * @retval HAL status
  98. */
  99. HAL_StatusTypeDef HAL_RCCEx_PeriphCLKConfig(RCC_PeriphCLKInitTypeDef *PeriphClkInit)
  100. {
  101. uint32_t tickstart = 0;
  102. uint32_t tmpreg1 = 0;
  103. uint32_t plli2sp = 0;
  104. uint32_t plli2sq = 0;
  105. uint32_t plli2sr = 0;
  106. uint32_t pllsaip = 0;
  107. uint32_t pllsaiq = 0;
  108. uint32_t plli2sused = 0;
  109. uint32_t pllsaiused = 0;
  110. /* Check the peripheral clock selection parameters */
  111. assert_param(IS_RCC_PERIPHCLOCK(PeriphClkInit->PeriphClockSelection));
  112. /*----------------------------------- I2S APB1 configuration ----------------------------------*/
  113. if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_I2S_APB1) == (RCC_PERIPHCLK_I2S_APB1))
  114. {
  115. /* Check the parameters */
  116. assert_param(IS_RCC_I2SAPB1CLKSOURCE(PeriphClkInit->I2sApb1ClockSelection));
  117. /* Configure I2S Clock source */
  118. __HAL_RCC_I2S_APB1_CONFIG(PeriphClkInit->I2sApb1ClockSelection);
  119. /* Enable the PLLI2S when it's used as clock source for I2S */
  120. if(PeriphClkInit->I2sApb1ClockSelection == RCC_I2SAPB1CLKSOURCE_PLLI2S)
  121. {
  122. plli2sused = 1;
  123. }
  124. }
  125. /*----------------------------------- I2S APB2 configuration -----------------------------------*/
  126. if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_I2S_APB2) == (RCC_PERIPHCLK_I2S_APB2))
  127. {
  128. /* Check the parameters */
  129. assert_param(IS_RCC_I2SAPB2CLKSOURCE(PeriphClkInit->I2sApb2ClockSelection));
  130. /* Configure I2S Clock source */
  131. __HAL_RCC_I2S_APB2_CONFIG(PeriphClkInit->I2sApb2ClockSelection);
  132. /* Enable the PLLI2S when it's used as clock source for I2S */
  133. if(PeriphClkInit->I2sApb2ClockSelection == RCC_I2SAPB2CLKSOURCE_PLLI2S)
  134. {
  135. plli2sused = 1;
  136. }
  137. }
  138. /*------------------------------------ SAI1 configuration --------------------------------------*/
  139. if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_SAI1) == (RCC_PERIPHCLK_SAI1))
  140. {
  141. /* Check the parameters */
  142. assert_param(IS_RCC_SAI1CLKSOURCE(PeriphClkInit->Sai1ClockSelection));
  143. /* Configure SAI1 Clock source */
  144. __HAL_RCC_SAI1_CONFIG(PeriphClkInit->Sai1ClockSelection);
  145. /* Enable the PLLI2S when it's used as clock source for SAI */
  146. if(PeriphClkInit->Sai1ClockSelection == RCC_SAI1CLKSOURCE_PLLI2S)
  147. {
  148. plli2sused = 1;
  149. }
  150. /* Enable the PLLSAI when it's used as clock source for SAI */
  151. if(PeriphClkInit->Sai1ClockSelection == RCC_SAI1CLKSOURCE_PLLSAI)
  152. {
  153. pllsaiused = 1;
  154. }
  155. }
  156. /*------------------------------------ SAI2 configuration --------------------------------------*/
  157. if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_SAI2) == (RCC_PERIPHCLK_SAI2))
  158. {
  159. /* Check the parameters */
  160. assert_param(IS_RCC_SAI2CLKSOURCE(PeriphClkInit->Sai2ClockSelection));
  161. /* Configure SAI2 Clock source */
  162. __HAL_RCC_SAI2_CONFIG(PeriphClkInit->Sai2ClockSelection);
  163. /* Enable the PLLI2S when it's used as clock source for SAI */
  164. if(PeriphClkInit->Sai2ClockSelection == RCC_SAI2CLKSOURCE_PLLI2S)
  165. {
  166. plli2sused = 1;
  167. }
  168. /* Enable the PLLSAI when it's used as clock source for SAI */
  169. if(PeriphClkInit->Sai2ClockSelection == RCC_SAI2CLKSOURCE_PLLSAI)
  170. {
  171. pllsaiused = 1;
  172. }
  173. }
  174. /*------------------------------------ RTC configuration --------------------------------------*/
  175. if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_RTC) == (RCC_PERIPHCLK_RTC))
  176. {
  177. /* Enable Power Clock*/
  178. __HAL_RCC_PWR_CLK_ENABLE();
  179. /* Enable write access to Backup domain */
  180. PWR->CR |= PWR_CR_DBP;
  181. /* Get tick */
  182. tickstart = HAL_GetTick();
  183. while((PWR->CR & PWR_CR_DBP) == RESET)
  184. {
  185. if((HAL_GetTick() - tickstart ) > RCC_DBP_TIMEOUT_VALUE)
  186. {
  187. return HAL_TIMEOUT;
  188. }
  189. }
  190. /* Reset the Backup domain only if the RTC Clock source selction is modified */
  191. if((RCC->BDCR & RCC_BDCR_RTCSEL) != (PeriphClkInit->RTCClockSelection & RCC_BDCR_RTCSEL))
  192. {
  193. /* Store the content of BDCR register before the reset of Backup Domain */
  194. tmpreg1 = (RCC->BDCR & ~(RCC_BDCR_RTCSEL));
  195. /* RTC Clock selection can be changed only if the Backup Domain is reset */
  196. __HAL_RCC_BACKUPRESET_FORCE();
  197. __HAL_RCC_BACKUPRESET_RELEASE();
  198. /* Restore the Content of BDCR register */
  199. RCC->BDCR = tmpreg1;
  200. }
  201. /* If LSE is selected as RTC clock source, wait for LSE reactivation */
  202. if(PeriphClkInit->RTCClockSelection == RCC_RTCCLKSOURCE_LSE)
  203. {
  204. /* Get tick */
  205. tickstart = HAL_GetTick();
  206. /* Wait till LSE is ready */
  207. while(__HAL_RCC_GET_FLAG(RCC_FLAG_LSERDY) == RESET)
  208. {
  209. if((HAL_GetTick() - tickstart ) > RCC_LSE_TIMEOUT_VALUE)
  210. {
  211. return HAL_TIMEOUT;
  212. }
  213. }
  214. }
  215. __HAL_RCC_RTC_CONFIG(PeriphClkInit->RTCClockSelection);
  216. }
  217. /*------------------------------------ TIM configuration --------------------------------------*/
  218. if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_TIM) == (RCC_PERIPHCLK_TIM))
  219. {
  220. /* Configure Timer Prescaler */
  221. __HAL_RCC_TIMCLKPRESCALER(PeriphClkInit->TIMPresSelection);
  222. }
  223. /*------------------------------------- FMPI2C1 Configuration ----------------------------------*/
  224. if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_FMPI2C1) == RCC_PERIPHCLK_FMPI2C1)
  225. {
  226. /* Check the parameters */
  227. assert_param(IS_RCC_FMPI2C1CLKSOURCE(PeriphClkInit->Fmpi2c1ClockSelection));
  228. /* Configure the FMPI2C1 clock source */
  229. __HAL_RCC_FMPI2C1_CONFIG(PeriphClkInit->Fmpi2c1ClockSelection);
  230. }
  231. /*--------------------------------------- CEC Configuration -----------------------------------*/
  232. if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_CEC) == RCC_PERIPHCLK_CEC)
  233. {
  234. /* Check the parameters */
  235. assert_param(IS_RCC_CECCLKSOURCE(PeriphClkInit->CecClockSelection));
  236. /* Configure the CEC clock source */
  237. __HAL_RCC_CEC_CONFIG(PeriphClkInit->CecClockSelection);
  238. }
  239. /*-------------------------------------- CK48 Configuration -----------------------------------*/
  240. if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_CK48) == RCC_PERIPHCLK_CK48)
  241. {
  242. /* Check the parameters */
  243. assert_param(IS_RCC_CK48CLKSOURCE(PeriphClkInit->Clk48ClockSelection));
  244. /* Configure the SDIO clock source */
  245. __HAL_RCC_CLK48_CONFIG(PeriphClkInit->Clk48ClockSelection);
  246. /* Enable the PLLSAI when it's used as clock source for CK48 */
  247. if(PeriphClkInit->Clk48ClockSelection == RCC_CK48CLKSOURCE_PLLSAIP)
  248. {
  249. pllsaiused = 1;
  250. }
  251. }
  252. /*------------------------------------- SDIO Configuration ------------------------------------*/
  253. if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_SDIO) == RCC_PERIPHCLK_SDIO)
  254. {
  255. /* Check the parameters */
  256. assert_param(IS_RCC_SDIOCLKSOURCE(PeriphClkInit->SdioClockSelection));
  257. /* Configure the SDIO clock source */
  258. __HAL_RCC_SDIO_CONFIG(PeriphClkInit->SdioClockSelection);
  259. }
  260. /*------------------------------------- SPDIFRX Configuration --------------*/
  261. if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_SPDIFRX) == RCC_PERIPHCLK_SPDIFRX)
  262. {
  263. /* Check the parameters */
  264. assert_param(IS_RCC_SPDIFRXCLKSOURCE(PeriphClkInit->SpdifClockSelection));
  265. /* Configure the SPDIFRX clock source */
  266. __HAL_RCC_SPDIFRX_CONFIG(PeriphClkInit->SpdifClockSelection);
  267. /* Enable the PLLI2S when it's used as clock source for SPDIFRX */
  268. if(PeriphClkInit->SpdifClockSelection == RCC_SPDIFRXCLKSOURCE_PLLI2SP)
  269. {
  270. plli2sused = 1;
  271. }
  272. }
  273. /*-------------------------------------- PLLI2S Configuration --------------*/
  274. /* PLLI2S is configured when a peripheral will use it as source clock : SAI1, SAI2, I2S on APB1,
  275. I2S on APB2 or SPDIFRX */
  276. if((plli2sused == 1) || (PeriphClkInit->PeriphClockSelection == RCC_PERIPHCLK_PLLI2S))
  277. {
  278. /* Disable the PLLI2S */
  279. __HAL_RCC_PLLI2S_DISABLE();
  280. /* Get tick */
  281. tickstart = HAL_GetTick();
  282. /* Wait till PLLI2S is disabled */
  283. while(__HAL_RCC_GET_FLAG(RCC_FLAG_PLLI2SRDY) != RESET)
  284. {
  285. if((HAL_GetTick() - tickstart ) > PLLI2S_TIMEOUT_VALUE)
  286. {
  287. /* return in case of Timeout detected */
  288. return HAL_TIMEOUT;
  289. }
  290. }
  291. /* check for common PLLI2S Parameters */
  292. assert_param(IS_RCC_PLLI2SM_VALUE(PeriphClkInit->PLLI2S.PLLI2SM));
  293. assert_param(IS_RCC_PLLI2SN_VALUE(PeriphClkInit->PLLI2S.PLLI2SN));
  294. /*----------------- In Case of PLLI2S is selected as source clock for I2S -------------------*/
  295. if(((((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_I2S_APB1) == RCC_PERIPHCLK_I2S_APB1) && (PeriphClkInit->I2sApb1ClockSelection == RCC_I2SAPB1CLKSOURCE_PLLI2S)) ||
  296. ((((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_I2S_APB2) == RCC_PERIPHCLK_I2S_APB2) && (PeriphClkInit->I2sApb2ClockSelection == RCC_I2SAPB2CLKSOURCE_PLLI2S)))
  297. {
  298. /* check for Parameters */
  299. assert_param(IS_RCC_PLLI2SR_VALUE(PeriphClkInit->PLLI2S.PLLI2SR));
  300. /* Read PLLI2SP/PLLI2SQ value from PLLI2SCFGR register (this value is not needed for I2S configuration) */
  301. plli2sp = ((((RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SP) >> POSITION_VAL(RCC_PLLI2SCFGR_PLLI2SP)) + 1) << 1);
  302. plli2sq = ((RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SQ) >> POSITION_VAL(RCC_PLLI2SCFGR_PLLI2SQ));
  303. /* Configure the PLLI2S division factors */
  304. /* PLLI2S_VCO = f(VCO clock) = f(PLLI2S clock input) × (PLLI2SN/PLLI2SM) */
  305. /* I2SCLK = f(PLLI2S clock output) = f(VCO clock) / PLLI2SR */
  306. __HAL_RCC_PLLI2S_CONFIG(PeriphClkInit->PLLI2S.PLLI2SM, PeriphClkInit->PLLI2S.PLLI2SN , plli2sp, plli2sq, PeriphClkInit->PLLI2S.PLLI2SR);
  307. }
  308. /*----------------- In Case of PLLI2S is selected as source clock for SAI -------------------*/
  309. if(((((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_SAI1) == RCC_PERIPHCLK_SAI1) && (PeriphClkInit->Sai1ClockSelection == RCC_SAI1CLKSOURCE_PLLI2S)) ||
  310. ((((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_SAI2) == RCC_PERIPHCLK_SAI2) && (PeriphClkInit->Sai2ClockSelection == RCC_SAI2CLKSOURCE_PLLI2S)))
  311. {
  312. /* Check for PLLI2S Parameters */
  313. assert_param(IS_RCC_PLLI2SQ_VALUE(PeriphClkInit->PLLI2S.PLLI2SQ));
  314. /* Check for PLLI2S/DIVQ parameters */
  315. assert_param(IS_RCC_PLLI2S_DIVQ_VALUE(PeriphClkInit->PLLI2SDivQ));
  316. /* Read PLLI2SP/PLLI2SR value from PLLI2SCFGR register (this value is not needed for SAI configuration) */
  317. plli2sp = ((((RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SP) >> POSITION_VAL(RCC_PLLI2SCFGR_PLLI2SP)) + 1) << 1);
  318. plli2sr = ((RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SR) >> POSITION_VAL(RCC_PLLI2SCFGR_PLLI2SR));
  319. /* Configure the PLLI2S division factors */
  320. /* PLLI2S_VCO Input = PLL_SOURCE/PLLI2SM */
  321. /* PLLI2S_VCO Output = PLLI2S_VCO Input * PLLI2SN */
  322. /* SAI_CLK(first level) = PLLI2S_VCO Output/PLLI2SQ */
  323. __HAL_RCC_PLLI2S_CONFIG(PeriphClkInit->PLLI2S.PLLI2SM, PeriphClkInit->PLLI2S.PLLI2SN , plli2sp, PeriphClkInit->PLLI2S.PLLI2SQ, plli2sr);
  324. /* SAI_CLK_x = SAI_CLK(first level)/PLLI2SDIVQ */
  325. __HAL_RCC_PLLI2S_PLLSAICLKDIVQ_CONFIG(PeriphClkInit->PLLI2SDivQ);
  326. }
  327. /*----------------- In Case of PLLI2S is selected as source clock for SPDIFRX -------------------*/
  328. if((((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_SPDIFRX) == RCC_PERIPHCLK_SPDIFRX) && (PeriphClkInit->SpdifClockSelection == RCC_SPDIFRXCLKSOURCE_PLLI2SP))
  329. {
  330. /* check for Parameters */
  331. assert_param(IS_RCC_PLLI2SP_VALUE(PeriphClkInit->PLLI2S.PLLI2SP));
  332. /* Read PLLI2SR value from PLLI2SCFGR register (this value is not need for SAI configuration) */
  333. plli2sq = ((((RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SP) >> POSITION_VAL(RCC_PLLI2SCFGR_PLLI2SP)) + 1) << 1);
  334. plli2sr = ((RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SR) >> POSITION_VAL(RCC_PLLI2SCFGR_PLLI2SR));
  335. /* Configure the PLLI2S division factors */
  336. /* PLLI2S_VCO = f(VCO clock) = f(PLLI2S clock input) × (PLLI2SN/PLLI2SM) */
  337. /* SPDIFRXCLK = f(PLLI2S clock output) = f(VCO clock) / PLLI2SP */
  338. __HAL_RCC_PLLI2S_CONFIG(PeriphClkInit->PLLI2S.PLLI2SM, PeriphClkInit->PLLI2S.PLLI2SN , PeriphClkInit->PLLI2S.PLLI2SP, plli2sq, plli2sr);
  339. }
  340. /*----------------- In Case of PLLI2S is just selected -----------------*/
  341. if((PeriphClkInit->PeriphClockSelection & RCC_PERIPHCLK_PLLI2S) == RCC_PERIPHCLK_PLLI2S)
  342. {
  343. /* Check for Parameters */
  344. assert_param(IS_RCC_PLLI2SP_VALUE(PeriphClkInit->PLLI2S.PLLI2SP));
  345. assert_param(IS_RCC_PLLI2SR_VALUE(PeriphClkInit->PLLI2S.PLLI2SR));
  346. assert_param(IS_RCC_PLLI2SR_VALUE(PeriphClkInit->PLLI2S.PLLI2SQ));
  347. /* Configure the PLLI2S division factors */
  348. /* PLLI2S_VCO = f(VCO clock) = f(PLLI2S clock input) × (PLLI2SN/PLLI2SM) */
  349. /* SPDIFRXCLK = f(PLLI2S clock output) = f(VCO clock) / PLLI2SP */
  350. __HAL_RCC_PLLI2S_CONFIG(PeriphClkInit->PLLI2S.PLLI2SM, PeriphClkInit->PLLI2S.PLLI2SN , PeriphClkInit->PLLI2S.PLLI2SP, PeriphClkInit->PLLI2S.PLLI2SQ, PeriphClkInit->PLLI2S.PLLI2SR);
  351. }
  352. /* Enable the PLLI2S */
  353. __HAL_RCC_PLLI2S_ENABLE();
  354. /* Get tick */
  355. tickstart = HAL_GetTick();
  356. /* Wait till PLLI2S is ready */
  357. while(__HAL_RCC_GET_FLAG(RCC_FLAG_PLLI2SRDY) == RESET)
  358. {
  359. if((HAL_GetTick() - tickstart ) > PLLI2S_TIMEOUT_VALUE)
  360. {
  361. /* return in case of Timeout detected */
  362. return HAL_TIMEOUT;
  363. }
  364. }
  365. }
  366. /*-------------------------------------- PLLSAI Configuration ---------------------------------*/
  367. /* PLLSAI is configured when a peripheral will use it as source clock : SAI1, SAI2, CK48 or SDIO */
  368. if(pllsaiused == 1)
  369. {
  370. /* Disable PLLSAI Clock */
  371. __HAL_RCC_PLLSAI_DISABLE();
  372. /* Get tick */
  373. tickstart = HAL_GetTick();
  374. /* Wait till PLLSAI is disabled */
  375. while(__HAL_RCC_PLLSAI_GET_FLAG() != RESET)
  376. {
  377. if((HAL_GetTick() - tickstart ) > PLLSAI_TIMEOUT_VALUE)
  378. {
  379. /* return in case of Timeout detected */
  380. return HAL_TIMEOUT;
  381. }
  382. }
  383. /* Check the PLLSAI division factors */
  384. assert_param(IS_RCC_PLLSAIM_VALUE(PeriphClkInit->PLLSAI.PLLSAIM));
  385. assert_param(IS_RCC_PLLSAIN_VALUE(PeriphClkInit->PLLSAI.PLLSAIN));
  386. /*----------------- In Case of PLLSAI is selected as source clock for SAI -------------------*/
  387. if(((((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_SAI1) == RCC_PERIPHCLK_SAI1) && (PeriphClkInit->Sai1ClockSelection == RCC_SAI1CLKSOURCE_PLLSAI)) ||
  388. ((((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_SAI2) == RCC_PERIPHCLK_SAI2) && (PeriphClkInit->Sai2ClockSelection == RCC_SAI2CLKSOURCE_PLLSAI)))
  389. {
  390. /* check for PLLSAIQ Parameter */
  391. assert_param(IS_RCC_PLLSAIQ_VALUE(PeriphClkInit->PLLSAI.PLLSAIQ));
  392. /* check for PLLSAI/DIVQ Parameter */
  393. assert_param(IS_RCC_PLLSAI_DIVQ_VALUE(PeriphClkInit->PLLSAIDivQ));
  394. /* Read PLLSAIP value from PLLSAICFGR register (this value is not needed for SAI configuration) */
  395. pllsaip = ((((RCC->PLLSAICFGR & RCC_PLLSAICFGR_PLLSAIP) >> POSITION_VAL(RCC_PLLSAICFGR_PLLSAIP)) + 1) << 1);
  396. /* PLLSAI_VCO Input = PLL_SOURCE/PLLM */
  397. /* PLLSAI_VCO Output = PLLSAI_VCO Input * PLLSAIN */
  398. /* SAI_CLK(first level) = PLLSAI_VCO Output/PLLSAIQ */
  399. __HAL_RCC_PLLSAI_CONFIG(PeriphClkInit->PLLSAI.PLLSAIM, PeriphClkInit->PLLSAI.PLLSAIN , pllsaip, PeriphClkInit->PLLSAI.PLLSAIQ, 0);
  400. /* SAI_CLK_x = SAI_CLK(first level)/PLLSAIDIVQ */
  401. __HAL_RCC_PLLSAI_PLLSAICLKDIVQ_CONFIG(PeriphClkInit->PLLSAIDivQ);
  402. }
  403. /*----------------- In Case of PLLSAI is selected as source clock for CK48 -------------------*/
  404. /* In Case of PLLI2S is selected as source clock for CK48 */
  405. if((((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_CK48) == RCC_PERIPHCLK_CK48) && (PeriphClkInit->Clk48ClockSelection == RCC_CK48CLKSOURCE_PLLSAIP))
  406. {
  407. /* check for Parameters */
  408. assert_param(IS_RCC_PLLSAIP_VALUE(PeriphClkInit->PLLSAI.PLLSAIP));
  409. /* Read PLLSAIQ value from PLLI2SCFGR register (this value is not need for SAI configuration) */
  410. pllsaiq = ((RCC->PLLSAICFGR & RCC_PLLSAICFGR_PLLSAIQ) >> POSITION_VAL(RCC_PLLSAICFGR_PLLSAIQ));
  411. /* Configure the PLLSAI division factors */
  412. /* PLLSAI_VCO = f(VCO clock) = f(PLLSAI clock input) × (PLLI2SN/PLLSAIM) */
  413. /* 48CLK = f(PLLSAI clock output) = f(VCO clock) / PLLSAIP */
  414. __HAL_RCC_PLLSAI_CONFIG(PeriphClkInit->PLLSAI.PLLSAIM, PeriphClkInit->PLLSAI.PLLSAIN , PeriphClkInit->PLLSAI.PLLSAIP, pllsaiq, 0);
  415. }
  416. /* Enable PLLSAI Clock */
  417. __HAL_RCC_PLLSAI_ENABLE();
  418. /* Get tick */
  419. tickstart = HAL_GetTick();
  420. /* Wait till PLLSAI is ready */
  421. while(__HAL_RCC_PLLSAI_GET_FLAG() == RESET)
  422. {
  423. if((HAL_GetTick() - tickstart ) > PLLSAI_TIMEOUT_VALUE)
  424. {
  425. /* return in case of Timeout detected */
  426. return HAL_TIMEOUT;
  427. }
  428. }
  429. }
  430. return HAL_OK;
  431. }
  432. /**
  433. * @brief Get the RCC_PeriphCLKInitTypeDef according to the internal
  434. * RCC configuration registers.
  435. * @param PeriphClkInit: pointer to an RCC_PeriphCLKInitTypeDef structure that
  436. * will be configured.
  437. * @retval None
  438. */
  439. void HAL_RCCEx_GetPeriphCLKConfig(RCC_PeriphCLKInitTypeDef *PeriphClkInit)
  440. {
  441. uint32_t tempreg;
  442. /* Set all possible values for the extended clock type parameter------------*/
  443. PeriphClkInit->PeriphClockSelection = RCC_PERIPHCLK_I2S_APB1 | RCC_PERIPHCLK_I2S_APB2 |\
  444. RCC_PERIPHCLK_SAI1 | RCC_PERIPHCLK_SAI2 |\
  445. RCC_PERIPHCLK_TIM | RCC_PERIPHCLK_RTC |\
  446. RCC_PERIPHCLK_CEC | RCC_PERIPHCLK_FMPI2C1 |\
  447. RCC_PERIPHCLK_CK48 | RCC_PERIPHCLK_SDIO |\
  448. RCC_PERIPHCLK_SPDIFRX;
  449. /* Get the PLLI2S Clock configuration -----------------------------------------------*/
  450. PeriphClkInit->PLLI2S.PLLI2SM = (uint32_t)((RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SM) >> POSITION_VAL(RCC_PLLI2SCFGR_PLLI2SM));
  451. PeriphClkInit->PLLI2S.PLLI2SN = (uint32_t)((RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SN) >> POSITION_VAL(RCC_PLLI2SCFGR_PLLI2SN));
  452. PeriphClkInit->PLLI2S.PLLI2SP = (uint32_t)((((RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SP) >> POSITION_VAL(RCC_PLLI2SCFGR_PLLI2SP)) + 1) << 1);
  453. PeriphClkInit->PLLI2S.PLLI2SQ = (uint32_t)((RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SQ) >> POSITION_VAL(RCC_PLLI2SCFGR_PLLI2SQ));
  454. PeriphClkInit->PLLI2S.PLLI2SR = (uint32_t)((RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SR) >> POSITION_VAL(RCC_PLLI2SCFGR_PLLI2SR));
  455. /* Get the PLLSAI Clock configuration -----------------------------------------------*/
  456. PeriphClkInit->PLLSAI.PLLSAIM = (uint32_t)((RCC->PLLSAICFGR & RCC_PLLSAICFGR_PLLSAIM) >> POSITION_VAL(RCC_PLLSAICFGR_PLLSAIM));
  457. PeriphClkInit->PLLSAI.PLLSAIN = (uint32_t)((RCC->PLLSAICFGR & RCC_PLLSAICFGR_PLLSAIN) >> POSITION_VAL(RCC_PLLSAICFGR_PLLSAIN));
  458. PeriphClkInit->PLLSAI.PLLSAIP = (uint32_t)((((RCC->PLLSAICFGR & RCC_PLLSAICFGR_PLLSAIP) >> POSITION_VAL(RCC_PLLSAICFGR_PLLSAIP)) + 1) << 1);
  459. PeriphClkInit->PLLSAI.PLLSAIQ = (uint32_t)((RCC->PLLSAICFGR & RCC_PLLSAICFGR_PLLSAIQ) >> POSITION_VAL(RCC_PLLSAICFGR_PLLSAIQ));
  460. /* Get the PLLSAI/PLLI2S division factors -------------------------------------------*/
  461. PeriphClkInit->PLLI2SDivQ = (uint32_t)((RCC->DCKCFGR & RCC_DCKCFGR_PLLI2SDIVQ) >> POSITION_VAL(RCC_DCKCFGR_PLLI2SDIVQ));
  462. PeriphClkInit->PLLSAIDivQ = (uint32_t)((RCC->DCKCFGR & RCC_DCKCFGR_PLLSAIDIVQ) >> POSITION_VAL(RCC_DCKCFGR_PLLSAIDIVQ));
  463. /* Get the SAI1 clock configuration ----------------------------------------------*/
  464. PeriphClkInit->Sai1ClockSelection = __HAL_RCC_GET_SAI1_SOURCE();
  465. /* Get the SAI2 clock configuration ----------------------------------------------*/
  466. PeriphClkInit->Sai2ClockSelection = __HAL_RCC_GET_SAI2_SOURCE();
  467. /* Get the I2S APB1 clock configuration ------------------------------------------*/
  468. PeriphClkInit->I2sApb1ClockSelection = __HAL_RCC_GET_I2S_APB1_SOURCE();
  469. /* Get the I2S APB2 clock configuration ------------------------------------------*/
  470. PeriphClkInit->I2sApb2ClockSelection = __HAL_RCC_GET_I2S_APB2_SOURCE();
  471. /* Get the RTC Clock configuration -----------------------------------------------*/
  472. tempreg = (RCC->CFGR & RCC_CFGR_RTCPRE);
  473. PeriphClkInit->RTCClockSelection = (uint32_t)((tempreg) | (RCC->BDCR & RCC_BDCR_RTCSEL));
  474. /* Get the CEC clock configuration -----------------------------------------------*/
  475. PeriphClkInit->CecClockSelection = __HAL_RCC_GET_CEC_SOURCE();
  476. /* Get the FMPI2C1 clock configuration -----------------------------------------------*/
  477. PeriphClkInit->Fmpi2c1ClockSelection = __HAL_RCC_GET_FMPI2C1_SOURCE();
  478. /* Get the CK48 clock configuration -----------------------------------------------*/
  479. PeriphClkInit->Clk48ClockSelection = __HAL_RCC_GET_CLK48_SOURCE();
  480. /* Get the SDIO clock configuration -----------------------------------------------*/
  481. PeriphClkInit->SdioClockSelection = __HAL_RCC_GET_SDIO_SOURCE();
  482. /* Get the SPDIFRX clock configuration ----------------------------------------------*/
  483. PeriphClkInit->SpdifClockSelection = __HAL_RCC_GET_SPDIFRX_SOURCE();
  484. /* Get the TIM Prescaler configuration --------------------------------------------*/
  485. if ((RCC->DCKCFGR & RCC_DCKCFGR_TIMPRE) == RESET)
  486. {
  487. PeriphClkInit->TIMPresSelection = RCC_TIMPRES_DESACTIVATED;
  488. }
  489. else
  490. {
  491. PeriphClkInit->TIMPresSelection = RCC_TIMPRES_ACTIVATED;
  492. }
  493. }
  494. /**
  495. * @brief Return the peripheral clock frequency for a given peripheral(SAI..)
  496. * @note Return 0 if peripheral clock identifier not managed by this API
  497. * @param PeriphClk: Peripheral clock identifier
  498. * This parameter can be one of the following values:
  499. * @arg RCC_PERIPHCLK_SAI1: SAI1 peripheral clock
  500. * @arg RCC_PERIPHCLK_SAI2: SAI2 peripheral clock
  501. * @retval Frequency in KHz
  502. */
  503. uint32_t HAL_RCCEx_GetPeriphCLKFreq(uint32_t PeriphClk)
  504. {
  505. uint32_t tmpreg1 = 0;
  506. /* This variable used to store the SAI clock frequency (value in Hz) */
  507. uint32_t frequency = 0;
  508. /* This variable used to store the VCO Input (value in Hz) */
  509. uint32_t vcoinput = 0;
  510. /* This variable used to store the SAI clock source */
  511. uint32_t saiclocksource = 0;
  512. if ((PeriphClk == RCC_PERIPHCLK_SAI1) || (PeriphClk == RCC_PERIPHCLK_SAI2))
  513. {
  514. saiclocksource = RCC->DCKCFGR;
  515. saiclocksource &= (RCC_DCKCFGR_SAI1SRC | RCC_DCKCFGR_SAI2SRC);
  516. switch (saiclocksource)
  517. {
  518. case 0: /* PLLSAI is the clock source for SAI*/
  519. {
  520. /* Configure the PLLSAI division factor */
  521. /* PLLSAI_VCO Input = PLL_SOURCE/PLLSAIM */
  522. if((RCC->PLLCFGR & RCC_PLLCFGR_PLLSRC) == RCC_PLLSOURCE_HSI)
  523. {
  524. /* In Case the PLL Source is HSI (Internal Clock) */
  525. vcoinput = (HSI_VALUE / (uint32_t)(RCC->PLLSAICFGR & RCC_PLLSAICFGR_PLLSAIM));
  526. }
  527. else
  528. {
  529. /* In Case the PLL Source is HSE (External Clock) */
  530. vcoinput = ((HSE_VALUE / (uint32_t)(RCC->PLLSAICFGR & RCC_PLLSAICFGR_PLLSAIM)));
  531. }
  532. /* PLLSAI_VCO Output = PLLSAI_VCO Input * PLLSAIN */
  533. /* SAI_CLK(first level) = PLLSAI_VCO Output/PLLSAIQ */
  534. tmpreg1 = (RCC->PLLSAICFGR & RCC_PLLSAICFGR_PLLSAIQ) >> 24;
  535. frequency = (vcoinput * ((RCC->PLLSAICFGR & RCC_PLLSAICFGR_PLLSAIN) >> 6))/(tmpreg1);
  536. /* SAI_CLK_x = SAI_CLK(first level)/PLLSAIDIVQ */
  537. tmpreg1 = (((RCC->DCKCFGR & RCC_DCKCFGR_PLLSAIDIVQ) >> 8) + 1);
  538. frequency = frequency/(tmpreg1);
  539. break;
  540. }
  541. case RCC_DCKCFGR_SAI1SRC_0: /* PLLI2S is the clock source for SAI*/
  542. case RCC_DCKCFGR_SAI2SRC_0: /* PLLI2S is the clock source for SAI*/
  543. {
  544. /* Configure the PLLI2S division factor */
  545. /* PLLI2S_VCO Input = PLL_SOURCE/PLLI2SM */
  546. if((RCC->PLLCFGR & RCC_PLLCFGR_PLLSRC) == RCC_PLLSOURCE_HSI)
  547. {
  548. /* In Case the PLL Source is HSI (Internal Clock) */
  549. vcoinput = (HSI_VALUE / (uint32_t)(RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SM));
  550. }
  551. else
  552. {
  553. /* In Case the PLL Source is HSE (External Clock) */
  554. vcoinput = ((HSE_VALUE / (uint32_t)(RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SM)));
  555. }
  556. /* PLLI2S_VCO Output = PLLI2S_VCO Input * PLLI2SN */
  557. /* SAI_CLK(first level) = PLLI2S_VCO Output/PLLI2SQ */
  558. tmpreg1 = (RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SQ) >> 24;
  559. frequency = (vcoinput * ((RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SN) >> 6))/(tmpreg1);
  560. /* SAI_CLK_x = SAI_CLK(first level)/PLLI2SDIVQ */
  561. tmpreg1 = ((RCC->DCKCFGR & RCC_DCKCFGR_PLLI2SDIVQ) + 1);
  562. frequency = frequency/(tmpreg1);
  563. break;
  564. }
  565. case RCC_DCKCFGR_SAI1SRC_1: /* PLLR is the clock source for SAI*/
  566. case RCC_DCKCFGR_SAI2SRC_1: /* PLLR is the clock source for SAI*/
  567. {
  568. /* Configure the PLLI2S division factor */
  569. /* PLL_VCO Input = PLL_SOURCE/PLLM */
  570. if((RCC->PLLCFGR & RCC_PLLCFGR_PLLSRC) == RCC_PLLSOURCE_HSI)
  571. {
  572. /* In Case the PLL Source is HSI (Internal Clock) */
  573. vcoinput = (HSI_VALUE / (uint32_t)(RCC->PLLCFGR & RCC_PLLCFGR_PLLM));
  574. }
  575. else
  576. {
  577. /* In Case the PLL Source is HSE (External Clock) */
  578. vcoinput = ((HSE_VALUE / (uint32_t)(RCC->PLLCFGR & RCC_PLLCFGR_PLLM)));
  579. }
  580. /* PLL_VCO Output = PLL_VCO Input * PLLN */
  581. /* SAI_CLK_x = PLL_VCO Output/PLLR */
  582. tmpreg1 = (RCC->PLLCFGR & RCC_PLLCFGR_PLLR) >> 28;
  583. frequency = (vcoinput * ((RCC->PLLCFGR & RCC_PLLCFGR_PLLN) >> 6))/(tmpreg1);
  584. break;
  585. }
  586. case RCC_DCKCFGR_SAI1SRC: /* External clock is the clock source for SAI*/
  587. {
  588. frequency = EXTERNAL_CLOCK_VALUE;
  589. break;
  590. }
  591. case RCC_DCKCFGR_SAI2SRC: /* PLLSRC(HSE or HSI) is the clock source for SAI*/
  592. {
  593. if((RCC->PLLCFGR & RCC_PLLCFGR_PLLSRC) == RCC_PLLSOURCE_HSI)
  594. {
  595. /* In Case the PLL Source is HSI (Internal Clock) */
  596. frequency = (uint32_t)(HSI_VALUE);
  597. }
  598. else
  599. {
  600. /* In Case the PLL Source is HSE (External Clock) */
  601. frequency = (uint32_t)(HSE_VALUE);
  602. }
  603. break;
  604. }
  605. default :
  606. {
  607. break;
  608. }
  609. }
  610. }
  611. return frequency;
  612. }
  613. #endif /* STM32F446xx */
  614. #if defined(STM32F427xx) || defined(STM32F437xx) || defined(STM32F429xx) || defined(STM32F439xx)
  615. /**
  616. * @brief Initializes the RCC extended peripherals clocks according to the specified
  617. * parameters in the RCC_PeriphCLKInitTypeDef.
  618. * @param PeriphClkInit: pointer to an RCC_PeriphCLKInitTypeDef structure that
  619. * contains the configuration information for the Extended Peripherals
  620. * clocks(I2S, SAI, LTDC RTC and TIM).
  621. *
  622. * @note Care must be taken when HAL_RCCEx_PeriphCLKConfig() is used to select
  623. * the RTC clock source; in this case the Backup domain will be reset in
  624. * order to modify the RTC Clock source, as consequence RTC registers (including
  625. * the backup registers) and RCC_BDCR register are set to their reset values.
  626. *
  627. * @retval HAL status
  628. */
  629. HAL_StatusTypeDef HAL_RCCEx_PeriphCLKConfig(RCC_PeriphCLKInitTypeDef *PeriphClkInit)
  630. {
  631. uint32_t tickstart = 0;
  632. uint32_t tmpreg1 = 0;
  633. /* Check the parameters */
  634. assert_param(IS_RCC_PERIPHCLOCK(PeriphClkInit->PeriphClockSelection));
  635. /*----------------------- SAI/I2S Configuration (PLLI2S) -------------------------*/
  636. /*----------------------- Common configuration SAI/I2S ---------------------------*/
  637. /* In Case of SAI or I2S Clock Configuration through PLLI2S, PLLI2SN division
  638. factor is common parameters for both peripherals */
  639. if((((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_I2S) == RCC_PERIPHCLK_I2S) ||
  640. (((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_SAI_PLLI2S) == RCC_PERIPHCLK_SAI_PLLI2S))
  641. {
  642. /* check for Parameters */
  643. assert_param(IS_RCC_PLLI2SN_VALUE(PeriphClkInit->PLLI2S.PLLI2SN));
  644. /* Disable the PLLI2S */
  645. __HAL_RCC_PLLI2S_DISABLE();
  646. /* Get tick */
  647. tickstart = HAL_GetTick();
  648. /* Wait till PLLI2S is disabled */
  649. while(__HAL_RCC_GET_FLAG(RCC_FLAG_PLLI2SRDY) != RESET)
  650. {
  651. if((HAL_GetTick() - tickstart ) > PLLI2S_TIMEOUT_VALUE)
  652. {
  653. /* return in case of Timeout detected */
  654. return HAL_TIMEOUT;
  655. }
  656. }
  657. /*---------------------------- I2S configuration -------------------------------*/
  658. /* In Case of I2S Clock Configuration through PLLI2S, PLLI2SR must be added
  659. only for I2S configuration */
  660. if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_I2S) == (RCC_PERIPHCLK_I2S))
  661. {
  662. /* check for Parameters */
  663. assert_param(IS_RCC_PLLI2SR_VALUE(PeriphClkInit->PLLI2S.PLLI2SR));
  664. /* Configure the PLLI2S division factors */
  665. /* PLLI2S_VCO = f(VCO clock) = f(PLLI2S clock input) × (PLLI2SN/PLLM) */
  666. /* I2SCLK = f(PLLI2S clock output) = f(VCO clock) / PLLI2SR */
  667. __HAL_RCC_PLLI2S_CONFIG(PeriphClkInit->PLLI2S.PLLI2SN , PeriphClkInit->PLLI2S.PLLI2SR);
  668. }
  669. /*---------------------------- SAI configuration -------------------------------*/
  670. /* In Case of SAI Clock Configuration through PLLI2S, PLLI2SQ and PLLI2S_DIVQ must
  671. be added only for SAI configuration */
  672. if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_SAI_PLLI2S) == (RCC_PERIPHCLK_SAI_PLLI2S))
  673. {
  674. /* Check the PLLI2S division factors */
  675. assert_param(IS_RCC_PLLI2SQ_VALUE(PeriphClkInit->PLLI2S.PLLI2SQ));
  676. assert_param(IS_RCC_PLLI2S_DIVQ_VALUE(PeriphClkInit->PLLI2SDivQ));
  677. /* Read PLLI2SR value from PLLI2SCFGR register (this value is not need for SAI configuration) */
  678. tmpreg1 = ((RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SR) >> POSITION_VAL(RCC_PLLI2SCFGR_PLLI2SR));
  679. /* Configure the PLLI2S division factors */
  680. /* PLLI2S_VCO Input = PLL_SOURCE/PLLM */
  681. /* PLLI2S_VCO Output = PLLI2S_VCO Input * PLLI2SN */
  682. /* SAI_CLK(first level) = PLLI2S_VCO Output/PLLI2SQ */
  683. __HAL_RCC_PLLI2S_SAICLK_CONFIG(PeriphClkInit->PLLI2S.PLLI2SN , PeriphClkInit->PLLI2S.PLLI2SQ , tmpreg1);
  684. /* SAI_CLK_x = SAI_CLK(first level)/PLLI2SDIVQ */
  685. __HAL_RCC_PLLI2S_PLLSAICLKDIVQ_CONFIG(PeriphClkInit->PLLI2SDivQ);
  686. }
  687. /* Enable the PLLI2S */
  688. __HAL_RCC_PLLI2S_ENABLE();
  689. /* Get tick */
  690. tickstart = HAL_GetTick();
  691. /* Wait till PLLI2S is ready */
  692. while(__HAL_RCC_GET_FLAG(RCC_FLAG_PLLI2SRDY) == RESET)
  693. {
  694. if((HAL_GetTick() - tickstart ) > PLLI2S_TIMEOUT_VALUE)
  695. {
  696. /* return in case of Timeout detected */
  697. return HAL_TIMEOUT;
  698. }
  699. }
  700. }
  701. /*----------------------- SAI/LTDC Configuration (PLLSAI) ------------------*/
  702. /*----------------------- Common configuration SAI/LTDC --------------------*/
  703. /* In Case of SAI or LTDC Clock Configuration through PLLSAI, PLLSAIN division
  704. factor is common parameters for both peripherals */
  705. if((((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_SAI_PLLSAI) == RCC_PERIPHCLK_SAI_PLLSAI) ||
  706. (((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_LTDC) == RCC_PERIPHCLK_LTDC))
  707. {
  708. /* Check the PLLSAI division factors */
  709. assert_param(IS_RCC_PLLSAIN_VALUE(PeriphClkInit->PLLSAI.PLLSAIN));
  710. /* Disable PLLSAI Clock */
  711. __HAL_RCC_PLLSAI_DISABLE();
  712. /* Get tick */
  713. tickstart = HAL_GetTick();
  714. /* Wait till PLLSAI is disabled */
  715. while(__HAL_RCC_PLLSAI_GET_FLAG() != RESET)
  716. {
  717. if((HAL_GetTick() - tickstart ) > PLLSAI_TIMEOUT_VALUE)
  718. {
  719. /* return in case of Timeout detected */
  720. return HAL_TIMEOUT;
  721. }
  722. }
  723. /*---------------------------- SAI configuration -------------------------*/
  724. /* In Case of SAI Clock Configuration through PLLSAI, PLLSAIQ and PLLSAI_DIVQ must
  725. be added only for SAI configuration */
  726. if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_SAI_PLLSAI) == (RCC_PERIPHCLK_SAI_PLLSAI))
  727. {
  728. assert_param(IS_RCC_PLLSAIQ_VALUE(PeriphClkInit->PLLSAI.PLLSAIQ));
  729. assert_param(IS_RCC_PLLSAI_DIVQ_VALUE(PeriphClkInit->PLLSAIDivQ));
  730. /* Read PLLSAIR value from PLLSAICFGR register (this value is not need for SAI configuration) */
  731. tmpreg1 = ((RCC->PLLSAICFGR & RCC_PLLSAICFGR_PLLSAIR) >> POSITION_VAL(RCC_PLLSAICFGR_PLLSAIR));
  732. /* PLLSAI_VCO Input = PLL_SOURCE/PLLM */
  733. /* PLLSAI_VCO Output = PLLSAI_VCO Input * PLLSAIN */
  734. /* SAI_CLK(first level) = PLLSAI_VCO Output/PLLSAIQ */
  735. __HAL_RCC_PLLSAI_CONFIG(PeriphClkInit->PLLSAI.PLLSAIN , PeriphClkInit->PLLSAI.PLLSAIQ, tmpreg1);
  736. /* SAI_CLK_x = SAI_CLK(first level)/PLLSAIDIVQ */
  737. __HAL_RCC_PLLSAI_PLLSAICLKDIVQ_CONFIG(PeriphClkInit->PLLSAIDivQ);
  738. }
  739. /*---------------------------- LTDC configuration ------------------------*/
  740. if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_LTDC) == (RCC_PERIPHCLK_LTDC))
  741. {
  742. assert_param(IS_RCC_PLLSAIR_VALUE(PeriphClkInit->PLLSAI.PLLSAIR));
  743. assert_param(IS_RCC_PLLSAI_DIVR_VALUE(PeriphClkInit->PLLSAIDivR));
  744. /* Read PLLSAIR value from PLLSAICFGR register (this value is not need for SAI configuration) */
  745. tmpreg1 = ((RCC->PLLSAICFGR & RCC_PLLSAICFGR_PLLSAIQ) >> POSITION_VAL(RCC_PLLSAICFGR_PLLSAIQ));
  746. /* PLLSAI_VCO Input = PLL_SOURCE/PLLM */
  747. /* PLLSAI_VCO Output = PLLSAI_VCO Input * PLLSAIN */
  748. /* LTDC_CLK(first level) = PLLSAI_VCO Output/PLLSAIR */
  749. __HAL_RCC_PLLSAI_CONFIG(PeriphClkInit->PLLSAI.PLLSAIN , tmpreg1, PeriphClkInit->PLLSAI.PLLSAIR);
  750. /* LTDC_CLK = LTDC_CLK(first level)/PLLSAIDIVR */
  751. __HAL_RCC_PLLSAI_PLLSAICLKDIVR_CONFIG(PeriphClkInit->PLLSAIDivR);
  752. }
  753. /* Enable PLLSAI Clock */
  754. __HAL_RCC_PLLSAI_ENABLE();
  755. /* Get tick */
  756. tickstart = HAL_GetTick();
  757. /* Wait till PLLSAI is ready */
  758. while(__HAL_RCC_PLLSAI_GET_FLAG() == RESET)
  759. {
  760. if((HAL_GetTick() - tickstart ) > PLLSAI_TIMEOUT_VALUE)
  761. {
  762. /* return in case of Timeout detected */
  763. return HAL_TIMEOUT;
  764. }
  765. }
  766. }
  767. /*---------------------------- RTC configuration ---------------------------*/
  768. if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_RTC) == (RCC_PERIPHCLK_RTC))
  769. {
  770. /* Enable Power Clock*/
  771. __HAL_RCC_PWR_CLK_ENABLE();
  772. /* Enable write access to Backup domain */
  773. PWR->CR |= PWR_CR_DBP;
  774. /* Get tick */
  775. tickstart = HAL_GetTick();
  776. while((PWR->CR & PWR_CR_DBP) == RESET)
  777. {
  778. if((HAL_GetTick() - tickstart ) > RCC_DBP_TIMEOUT_VALUE)
  779. {
  780. return HAL_TIMEOUT;
  781. }
  782. }
  783. /* Reset the Backup domain only if the RTC Clock source selection is modified */
  784. if((RCC->BDCR & RCC_BDCR_RTCSEL) != (PeriphClkInit->RTCClockSelection & RCC_BDCR_RTCSEL))
  785. {
  786. /* Store the content of BDCR register before the reset of Backup Domain */
  787. tmpreg1 = (RCC->BDCR & ~(RCC_BDCR_RTCSEL));
  788. /* RTC Clock selection can be changed only if the Backup Domain is reset */
  789. __HAL_RCC_BACKUPRESET_FORCE();
  790. __HAL_RCC_BACKUPRESET_RELEASE();
  791. /* Restore the Content of BDCR register */
  792. RCC->BDCR = tmpreg1;
  793. }
  794. /* If LSE is selected as RTC clock source, wait for LSE reactivation */
  795. if(PeriphClkInit->RTCClockSelection == RCC_RTCCLKSOURCE_LSE)
  796. {
  797. /* Get tick */
  798. tickstart = HAL_GetTick();
  799. /* Wait till LSE is ready */
  800. while(__HAL_RCC_GET_FLAG(RCC_FLAG_LSERDY) == RESET)
  801. {
  802. if((HAL_GetTick() - tickstart ) > RCC_LSE_TIMEOUT_VALUE)
  803. {
  804. return HAL_TIMEOUT;
  805. }
  806. }
  807. }
  808. __HAL_RCC_RTC_CONFIG(PeriphClkInit->RTCClockSelection);
  809. }
  810. /*---------------------------- TIM configuration ---------------------------*/
  811. if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_TIM) == (RCC_PERIPHCLK_TIM))
  812. {
  813. __HAL_RCC_TIMCLKPRESCALER(PeriphClkInit->TIMPresSelection);
  814. }
  815. return HAL_OK;
  816. }
  817. /**
  818. * @brief Configures the RCC_OscInitStruct according to the internal
  819. * RCC configuration registers.
  820. * @param PeriphClkInit: pointer to an RCC_PeriphCLKInitTypeDef structure that
  821. * will be configured.
  822. * @retval None
  823. */
  824. void HAL_RCCEx_GetPeriphCLKConfig(RCC_PeriphCLKInitTypeDef *PeriphClkInit)
  825. {
  826. uint32_t tempreg;
  827. /* Set all possible values for the extended clock type parameter------------*/
  828. PeriphClkInit->PeriphClockSelection = RCC_PERIPHCLK_I2S | RCC_PERIPHCLK_SAI_PLLSAI | RCC_PERIPHCLK_SAI_PLLI2S | RCC_PERIPHCLK_LTDC | RCC_PERIPHCLK_TIM | RCC_PERIPHCLK_RTC;
  829. /* Get the PLLI2S Clock configuration -----------------------------------------------*/
  830. PeriphClkInit->PLLI2S.PLLI2SN = (uint32_t)((RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SN) >> POSITION_VAL(RCC_PLLI2SCFGR_PLLI2SN));
  831. PeriphClkInit->PLLI2S.PLLI2SR = (uint32_t)((RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SR) >> POSITION_VAL(RCC_PLLI2SCFGR_PLLI2SR));
  832. PeriphClkInit->PLLI2S.PLLI2SQ = (uint32_t)((RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SQ) >> POSITION_VAL(RCC_PLLI2SCFGR_PLLI2SQ));
  833. /* Get the PLLSAI Clock configuration -----------------------------------------------*/
  834. PeriphClkInit->PLLSAI.PLLSAIN = (uint32_t)((RCC->PLLSAICFGR & RCC_PLLSAICFGR_PLLSAIN) >> POSITION_VAL(RCC_PLLSAICFGR_PLLSAIN));
  835. PeriphClkInit->PLLSAI.PLLSAIR = (uint32_t)((RCC->PLLSAICFGR & RCC_PLLSAICFGR_PLLSAIR) >> POSITION_VAL(RCC_PLLSAICFGR_PLLSAIR));
  836. PeriphClkInit->PLLSAI.PLLSAIQ = (uint32_t)((RCC->PLLSAICFGR & RCC_PLLSAICFGR_PLLSAIQ) >> POSITION_VAL(RCC_PLLSAICFGR_PLLSAIQ));
  837. /* Get the PLLSAI/PLLI2S division factors -----------------------------------------------*/
  838. PeriphClkInit->PLLI2SDivQ = (uint32_t)((RCC->DCKCFGR & RCC_DCKCFGR_PLLI2SDIVQ) >> POSITION_VAL(RCC_DCKCFGR_PLLI2SDIVQ));
  839. PeriphClkInit->PLLSAIDivQ = (uint32_t)((RCC->DCKCFGR & RCC_DCKCFGR_PLLSAIDIVQ) >> POSITION_VAL(RCC_DCKCFGR_PLLSAIDIVQ));
  840. PeriphClkInit->PLLSAIDivR = (uint32_t)(RCC->DCKCFGR & RCC_DCKCFGR_PLLSAIDIVR);
  841. /* Get the RTC Clock configuration -----------------------------------------------*/
  842. tempreg = (RCC->CFGR & RCC_CFGR_RTCPRE);
  843. PeriphClkInit->RTCClockSelection = (uint32_t)((tempreg) | (RCC->BDCR & RCC_BDCR_RTCSEL));
  844. if ((RCC->DCKCFGR & RCC_DCKCFGR_TIMPRE) == RESET)
  845. {
  846. PeriphClkInit->TIMPresSelection = RCC_TIMPRES_DESACTIVATED;
  847. }
  848. else
  849. {
  850. PeriphClkInit->TIMPresSelection = RCC_TIMPRES_ACTIVATED;
  851. }
  852. }
  853. #endif /* STM32F427xx || STM32F437xx || STM32F429xx || STM32F439xx */
  854. #if defined(STM32F405xx) || defined(STM32F415xx) || defined(STM32F407xx)|| defined(STM32F417xx) ||\
  855. defined(STM32F401xC) || defined(STM32F401xE) || defined(STM32F411xE)
  856. /**
  857. * @brief Initializes the RCC extended peripherals clocks according to the specified parameters in the
  858. * RCC_PeriphCLKInitTypeDef.
  859. * @param PeriphClkInit: pointer to an RCC_PeriphCLKInitTypeDef structure that
  860. * contains the configuration information for the Extended Peripherals clocks(I2S and RTC clocks).
  861. *
  862. * @note A caution to be taken when HAL_RCCEx_PeriphCLKConfig() is used to select RTC clock selection, in this case
  863. * the Reset of Backup domain will be applied in order to modify the RTC Clock source as consequence all backup
  864. * domain (RTC and RCC_BDCR register expect BKPSRAM) will be reset
  865. *
  866. * @retval HAL status
  867. */
  868. HAL_StatusTypeDef HAL_RCCEx_PeriphCLKConfig(RCC_PeriphCLKInitTypeDef *PeriphClkInit)
  869. {
  870. uint32_t tickstart = 0;
  871. uint32_t tmpreg1 = 0;
  872. /* Check the parameters */
  873. assert_param(IS_RCC_PERIPHCLOCK(PeriphClkInit->PeriphClockSelection));
  874. /*---------------------------- I2S configuration ---------------------------*/
  875. if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_I2S) == (RCC_PERIPHCLK_I2S))
  876. {
  877. /* check for Parameters */
  878. assert_param(IS_RCC_PLLI2SR_VALUE(PeriphClkInit->PLLI2S.PLLI2SR));
  879. assert_param(IS_RCC_PLLI2SN_VALUE(PeriphClkInit->PLLI2S.PLLI2SN));
  880. #if defined(STM32F411xE)
  881. assert_param(IS_RCC_PLLI2SM_VALUE(PeriphClkInit->PLLI2S.PLLI2SM));
  882. #endif /* STM32F411xE */
  883. /* Disable the PLLI2S */
  884. __HAL_RCC_PLLI2S_DISABLE();
  885. /* Get tick */
  886. tickstart = HAL_GetTick();
  887. /* Wait till PLLI2S is disabled */
  888. while(__HAL_RCC_GET_FLAG(RCC_FLAG_PLLI2SRDY) != RESET)
  889. {
  890. if((HAL_GetTick() - tickstart ) > PLLI2S_TIMEOUT_VALUE)
  891. {
  892. /* return in case of Timeout detected */
  893. return HAL_TIMEOUT;
  894. }
  895. }
  896. #if defined(STM32F411xE)
  897. /* Configure the PLLI2S division factors */
  898. /* PLLI2S_VCO = f(VCO clock) = f(PLLI2S clock input) × (PLLI2SN/PLLI2SM) */
  899. /* I2SCLK = f(PLLI2S clock output) = f(VCO clock) / PLLI2SR */
  900. __HAL_RCC_PLLI2S_I2SCLK_CONFIG(PeriphClkInit->PLLI2S.PLLI2SM, PeriphClkInit->PLLI2S.PLLI2SN, PeriphClkInit->PLLI2S.PLLI2SR);
  901. #else
  902. /* Configure the PLLI2S division factors */
  903. /* PLLI2S_VCO = f(VCO clock) = f(PLLI2S clock input) × (PLLI2SN/PLLM) */
  904. /* I2SCLK = f(PLLI2S clock output) = f(VCO clock) / PLLI2SR */
  905. __HAL_RCC_PLLI2S_CONFIG(PeriphClkInit->PLLI2S.PLLI2SN , PeriphClkInit->PLLI2S.PLLI2SR);
  906. #endif /* STM32F411xE */
  907. /* Enable the PLLI2S */
  908. __HAL_RCC_PLLI2S_ENABLE();
  909. /* Get tick */
  910. tickstart = HAL_GetTick();
  911. /* Wait till PLLI2S is ready */
  912. while(__HAL_RCC_GET_FLAG(RCC_FLAG_PLLI2SRDY) == RESET)
  913. {
  914. if((HAL_GetTick() - tickstart ) > PLLI2S_TIMEOUT_VALUE)
  915. {
  916. /* return in case of Timeout detected */
  917. return HAL_TIMEOUT;
  918. }
  919. }
  920. }
  921. /*---------------------------- RTC configuration ---------------------------*/
  922. if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_RTC) == (RCC_PERIPHCLK_RTC))
  923. {
  924. /* Enable Power Clock*/
  925. __HAL_RCC_PWR_CLK_ENABLE();
  926. /* Enable write access to Backup domain */
  927. PWR->CR |= PWR_CR_DBP;
  928. /* Get tick */
  929. tickstart = HAL_GetTick();
  930. while((PWR->CR & PWR_CR_DBP) == RESET)
  931. {
  932. if((HAL_GetTick() - tickstart ) > RCC_DBP_TIMEOUT_VALUE)
  933. {
  934. return HAL_TIMEOUT;
  935. }
  936. }
  937. /* Reset the Backup domain only if the RTC Clock source selection is modified */
  938. if((RCC->BDCR & RCC_BDCR_RTCSEL) != (PeriphClkInit->RTCClockSelection & RCC_BDCR_RTCSEL))
  939. {
  940. /* Store the content of BDCR register before the reset of Backup Domain */
  941. tmpreg1 = (RCC->BDCR & ~(RCC_BDCR_RTCSEL));
  942. /* RTC Clock selection can be changed only if the Backup Domain is reset */
  943. __HAL_RCC_BACKUPRESET_FORCE();
  944. __HAL_RCC_BACKUPRESET_RELEASE();
  945. /* Restore the Content of BDCR register */
  946. RCC->BDCR = tmpreg1;
  947. }
  948. /* If LSE is selected as RTC clock source, wait for LSE reactivation */
  949. if(PeriphClkInit->RTCClockSelection == RCC_RTCCLKSOURCE_LSE)
  950. {
  951. /* Get tick */
  952. tickstart = HAL_GetTick();
  953. /* Wait till LSE is ready */
  954. while(__HAL_RCC_GET_FLAG(RCC_FLAG_LSERDY) == RESET)
  955. {
  956. if((HAL_GetTick() - tickstart ) > RCC_LSE_TIMEOUT_VALUE)
  957. {
  958. return HAL_TIMEOUT;
  959. }
  960. }
  961. }
  962. __HAL_RCC_RTC_CONFIG(PeriphClkInit->RTCClockSelection);
  963. }
  964. return HAL_OK;
  965. }
  966. /**
  967. * @brief Configures the RCC_OscInitStruct according to the internal
  968. * RCC configuration registers.
  969. * @param PeriphClkInit: pointer to an RCC_PeriphCLKInitTypeDef structure that
  970. * will be configured.
  971. * @retval None
  972. */
  973. void HAL_RCCEx_GetPeriphCLKConfig(RCC_PeriphCLKInitTypeDef *PeriphClkInit)
  974. {
  975. uint32_t tempreg;
  976. /* Set all possible values for the extended clock type parameter------------*/
  977. PeriphClkInit->PeriphClockSelection = RCC_PERIPHCLK_I2S | RCC_PERIPHCLK_RTC;
  978. /* Get the PLLI2S Clock configuration -----------------------------------------------*/
  979. PeriphClkInit->PLLI2S.PLLI2SN = (uint32_t)((RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SN) >> POSITION_VAL(RCC_PLLI2SCFGR_PLLI2SN));
  980. PeriphClkInit->PLLI2S.PLLI2SR = (uint32_t)((RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SR) >> POSITION_VAL(RCC_PLLI2SCFGR_PLLI2SR));
  981. #if defined(STM32F411xE)
  982. PeriphClkInit->PLLI2S.PLLI2SM = (uint32_t)(RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SM);
  983. #endif /* STM32F411xE */
  984. /* Get the RTC Clock configuration -----------------------------------------------*/
  985. tempreg = (RCC->CFGR & RCC_CFGR_RTCPRE);
  986. PeriphClkInit->RTCClockSelection = (uint32_t)((tempreg) | (RCC->BDCR & RCC_BDCR_RTCSEL));
  987. }
  988. #endif /* STM32F405xx || STM32F415xx || STM32F407xx || STM32F417xx || STM32F401xC || STM32F401xE || STM32F411xE */
  989. #if defined(STM32F411xE) || defined(STM32F446xx)
  990. /**
  991. * @brief Select LSE mode
  992. *
  993. * @note This mode is only available for STM32F411xx devices.
  994. *
  995. * @param Mode: specifies the LSE mode.
  996. * This parameter can be one of the following values:
  997. * @arg RCC_LSE_LOWPOWER_MODE: LSE oscillator in low power mode selection
  998. * @arg RCC_LSE_HIGHDRIVE_MODE: LSE oscillator in High Drive mode selection
  999. * @retval None
  1000. */
  1001. void HAL_RCCEx_SelectLSEMode(uint8_t Mode)
  1002. {
  1003. /* Check the parameters */
  1004. assert_param(IS_RCC_LSE_MODE(Mode));
  1005. if(Mode == RCC_LSE_HIGHDRIVE_MODE)
  1006. {
  1007. SET_BIT(RCC->BDCR, RCC_BDCR_LSEMOD);
  1008. }
  1009. else
  1010. {
  1011. CLEAR_BIT(RCC->BDCR, RCC_BDCR_LSEMOD);
  1012. }
  1013. }
  1014. #endif /* STM32F411xE || STM32F446xx */
  1015. #if defined(STM32F446xx)
  1016. /**
  1017. * @brief Initializes the RCC Oscillators according to the specified parameters in the
  1018. * RCC_OscInitTypeDef.
  1019. * @param RCC_OscInitStruct: pointer to an RCC_OscInitTypeDef structure that
  1020. * contains the configuration information for the RCC Oscillators.
  1021. * @note The PLL is not disabled when used as system clock.
  1022. * @note This function add the PLL/PLLR factor management during PLL configuration this feature is only available in STM32F446xx devices
  1023. * @retval HAL status
  1024. */
  1025. HAL_StatusTypeDef HAL_RCC_OscConfig(RCC_OscInitTypeDef *RCC_OscInitStruct)
  1026. {
  1027. uint32_t tickstart = 0;
  1028. /* Check the parameters */
  1029. assert_param(IS_RCC_OSCILLATORTYPE(RCC_OscInitStruct->OscillatorType));
  1030. /*------------------------------- HSE Configuration ------------------------*/
  1031. if(((RCC_OscInitStruct->OscillatorType) & RCC_OSCILLATORTYPE_HSE) == RCC_OSCILLATORTYPE_HSE)
  1032. {
  1033. /* Check the parameters */
  1034. assert_param(IS_RCC_HSE(RCC_OscInitStruct->HSEState));
  1035. /* When the HSE is used as system clock or clock source for PLL in these cases HSE will not disabled */
  1036. if((__HAL_RCC_GET_SYSCLK_SOURCE() == RCC_CFGR_SWS_HSE) ||\
  1037. ((__HAL_RCC_GET_SYSCLK_SOURCE() == RCC_CFGR_SWS_PLL) && ((RCC->PLLCFGR & RCC_PLLCFGR_PLLSRC) == RCC_PLLCFGR_PLLSRC_HSE)) ||\
  1038. ((__HAL_RCC_GET_SYSCLK_SOURCE() == RCC_CFGR_SWS_PLLR) && ((RCC->PLLCFGR & RCC_PLLCFGR_PLLSRC) == RCC_PLLCFGR_PLLSRC_HSE)))
  1039. {
  1040. if((__HAL_RCC_GET_FLAG(RCC_FLAG_HSERDY) != RESET) && (RCC_OscInitStruct->HSEState == RCC_HSE_OFF))
  1041. {
  1042. return HAL_ERROR;
  1043. }
  1044. }
  1045. else
  1046. {
  1047. /* Reset HSEON and HSEBYP bits before configuring the HSE --------------*/
  1048. __HAL_RCC_HSE_CONFIG(RCC_HSE_OFF);
  1049. /* Get Start Tick*/
  1050. tickstart = HAL_GetTick();
  1051. /* Wait till HSE is disabled */
  1052. while(__HAL_RCC_GET_FLAG(RCC_FLAG_HSERDY) != RESET)
  1053. {
  1054. if((HAL_GetTick() - tickstart ) > HSE_TIMEOUT_VALUE)
  1055. {
  1056. return HAL_TIMEOUT;
  1057. }
  1058. }
  1059. /* Set the new HSE configuration ---------------------------------------*/
  1060. __HAL_RCC_HSE_CONFIG(RCC_OscInitStruct->HSEState);
  1061. /* Check the HSE State */
  1062. if((RCC_OscInitStruct->HSEState) != RCC_HSE_OFF)
  1063. {
  1064. /* Get Start Tick*/
  1065. tickstart = HAL_GetTick();
  1066. /* Wait till HSE is ready */
  1067. while(__HAL_RCC_GET_FLAG(RCC_FLAG_HSERDY) == RESET)
  1068. {
  1069. if((HAL_GetTick() - tickstart ) > HSE_TIMEOUT_VALUE)
  1070. {
  1071. return HAL_TIMEOUT;
  1072. }
  1073. }
  1074. }
  1075. else
  1076. {
  1077. /* Get Start Tick*/
  1078. tickstart = HAL_GetTick();
  1079. /* Wait till HSE is bypassed or disabled */
  1080. while(__HAL_RCC_GET_FLAG(RCC_FLAG_HSERDY) != RESET)
  1081. {
  1082. if((HAL_GetTick() - tickstart ) > HSE_TIMEOUT_VALUE)
  1083. {
  1084. return HAL_TIMEOUT;
  1085. }
  1086. }
  1087. }
  1088. }
  1089. }
  1090. /*----------------------------- HSI Configuration --------------------------*/
  1091. if(((RCC_OscInitStruct->OscillatorType) & RCC_OSCILLATORTYPE_HSI) == RCC_OSCILLATORTYPE_HSI)
  1092. {
  1093. /* Check the parameters */
  1094. assert_param(IS_RCC_HSI(RCC_OscInitStruct->HSIState));
  1095. assert_param(IS_RCC_CALIBRATION_VALUE(RCC_OscInitStruct->HSICalibrationValue));
  1096. /* Check if HSI is used as system clock or as PLL source when PLL is selected as system clock */
  1097. if((__HAL_RCC_GET_SYSCLK_SOURCE() == RCC_CFGR_SWS_HSI) ||\
  1098. ((__HAL_RCC_GET_SYSCLK_SOURCE() == RCC_CFGR_SWS_PLL) && ((RCC->PLLCFGR & RCC_PLLCFGR_PLLSRC) == RCC_PLLCFGR_PLLSRC_HSI)) ||\
  1099. ((__HAL_RCC_GET_SYSCLK_SOURCE() == RCC_CFGR_SWS_PLLR) && ((RCC->PLLCFGR & RCC_PLLCFGR_PLLSRC) == RCC_PLLCFGR_PLLSRC_HSI)))
  1100. {
  1101. /* When HSI is used as system clock it will not disabled */
  1102. if((__HAL_RCC_GET_FLAG(RCC_FLAG_HSIRDY) != RESET) && (RCC_OscInitStruct->HSIState != RCC_HSI_ON))
  1103. {
  1104. return HAL_ERROR;
  1105. }
  1106. /* Otherwise, just the calibration is allowed */
  1107. else
  1108. {
  1109. /* Adjusts the Internal High Speed oscillator (HSI) calibration value.*/
  1110. __HAL_RCC_HSI_CALIBRATIONVALUE_ADJUST(RCC_OscInitStruct->HSICalibrationValue);
  1111. }
  1112. }
  1113. else
  1114. {
  1115. /* Check the HSI State */
  1116. if((RCC_OscInitStruct->HSIState)!= RCC_HSI_OFF)
  1117. {
  1118. /* Enable the Internal High Speed oscillator (HSI). */
  1119. __HAL_RCC_HSI_ENABLE();
  1120. /* Get Start Tick*/
  1121. tickstart = HAL_GetTick();
  1122. /* Wait till HSI is ready */
  1123. while(__HAL_RCC_GET_FLAG(RCC_FLAG_HSIRDY) == RESET)
  1124. {
  1125. if((HAL_GetTick() - tickstart ) > HSI_TIMEOUT_VALUE)
  1126. {
  1127. return HAL_TIMEOUT;
  1128. }
  1129. }
  1130. /* Adjusts the Internal High Speed oscillator (HSI) calibration value.*/
  1131. __HAL_RCC_HSI_CALIBRATIONVALUE_ADJUST(RCC_OscInitStruct->HSICalibrationValue);
  1132. }
  1133. else
  1134. {
  1135. /* Disable the Internal High Speed oscillator (HSI). */
  1136. __HAL_RCC_HSI_DISABLE();
  1137. /* Get Start Tick*/
  1138. tickstart = HAL_GetTick();
  1139. /* Wait till HSI is ready */
  1140. while(__HAL_RCC_GET_FLAG(RCC_FLAG_HSIRDY) != RESET)
  1141. {
  1142. if((HAL_GetTick() - tickstart ) > HSI_TIMEOUT_VALUE)
  1143. {
  1144. return HAL_TIMEOUT;
  1145. }
  1146. }
  1147. }
  1148. }
  1149. }
  1150. /*------------------------------ LSI Configuration -------------------------*/
  1151. if(((RCC_OscInitStruct->OscillatorType) & RCC_OSCILLATORTYPE_LSI) == RCC_OSCILLATORTYPE_LSI)
  1152. {
  1153. /* Check the parameters */
  1154. assert_param(IS_RCC_LSI(RCC_OscInitStruct->LSIState));
  1155. /* Check the LSI State */
  1156. if((RCC_OscInitStruct->LSIState)!= RCC_LSI_OFF)
  1157. {
  1158. /* Enable the Internal Low Speed oscillator (LSI). */
  1159. __HAL_RCC_LSI_ENABLE();
  1160. /* Get Start Tick*/
  1161. tickstart = HAL_GetTick();
  1162. /* Wait till LSI is ready */
  1163. while(__HAL_RCC_GET_FLAG(RCC_FLAG_LSIRDY) == RESET)
  1164. {
  1165. if((HAL_GetTick() - tickstart ) > LSI_TIMEOUT_VALUE)
  1166. {
  1167. return HAL_TIMEOUT;
  1168. }
  1169. }
  1170. }
  1171. else
  1172. {
  1173. /* Disable the Internal Low Speed oscillator (LSI). */
  1174. __HAL_RCC_LSI_DISABLE();
  1175. /* Get Start Tick*/
  1176. tickstart = HAL_GetTick();
  1177. /* Wait till LSI is ready */
  1178. while(__HAL_RCC_GET_FLAG(RCC_FLAG_LSIRDY) != RESET)
  1179. {
  1180. if((HAL_GetTick() - tickstart ) > LSI_TIMEOUT_VALUE)
  1181. {
  1182. return HAL_TIMEOUT;
  1183. }
  1184. }
  1185. }
  1186. }
  1187. /*------------------------------ LSE Configuration -------------------------*/
  1188. if(((RCC_OscInitStruct->OscillatorType) & RCC_OSCILLATORTYPE_LSE) == RCC_OSCILLATORTYPE_LSE)
  1189. {
  1190. /* Check the parameters */
  1191. assert_param(IS_RCC_LSE(RCC_OscInitStruct->LSEState));
  1192. /* Enable Power Clock*/
  1193. __HAL_RCC_PWR_CLK_ENABLE();
  1194. /* Enable write access to Backup domain */
  1195. PWR->CR |= PWR_CR_DBP;
  1196. /* Wait for Backup domain Write protection disable */
  1197. tickstart = HAL_GetTick();
  1198. while((PWR->CR & PWR_CR_DBP) == RESET)
  1199. {
  1200. if((HAL_GetTick() - tickstart ) > RCC_DBP_TIMEOUT_VALUE)
  1201. {
  1202. return HAL_TIMEOUT;
  1203. }
  1204. }
  1205. /* Reset LSEON and LSEBYP bits before configuring the LSE ----------------*/
  1206. __HAL_RCC_LSE_CONFIG(RCC_LSE_OFF);
  1207. /* Get Start Tick*/
  1208. tickstart = HAL_GetTick();
  1209. /* Wait till LSE is ready */
  1210. while(__HAL_RCC_GET_FLAG(RCC_FLAG_LSERDY) != RESET)
  1211. {
  1212. if((HAL_GetTick() - tickstart ) > RCC_LSE_TIMEOUT_VALUE)
  1213. {
  1214. return HAL_TIMEOUT;
  1215. }
  1216. }
  1217. /* Set the new LSE configuration -----------------------------------------*/
  1218. __HAL_RCC_LSE_CONFIG(RCC_OscInitStruct->LSEState);
  1219. /* Check the LSE State */
  1220. if((RCC_OscInitStruct->LSEState) != RCC_LSE_OFF)
  1221. {
  1222. /* Get Start Tick*/
  1223. tickstart = HAL_GetTick();
  1224. /* Wait till LSE is ready */
  1225. while(__HAL_RCC_GET_FLAG(RCC_FLAG_LSERDY) == RESET)
  1226. {
  1227. if((HAL_GetTick() - tickstart ) > RCC_LSE_TIMEOUT_VALUE)
  1228. {
  1229. return HAL_TIMEOUT;
  1230. }
  1231. }
  1232. }
  1233. else
  1234. {
  1235. /* Get Start Tick*/
  1236. tickstart = HAL_GetTick();
  1237. /* Wait till LSE is ready */
  1238. while(__HAL_RCC_GET_FLAG(RCC_FLAG_LSERDY) != RESET)
  1239. {
  1240. if((HAL_GetTick() - tickstart ) > RCC_LSE_TIMEOUT_VALUE)
  1241. {
  1242. return HAL_TIMEOUT;
  1243. }
  1244. }
  1245. }
  1246. }
  1247. /*-------------------------------- PLL Configuration -----------------------*/
  1248. /* Check the parameters */
  1249. assert_param(IS_RCC_PLL(RCC_OscInitStruct->PLL.PLLState));
  1250. if ((RCC_OscInitStruct->PLL.PLLState) != RCC_PLL_NONE)
  1251. {
  1252. /* Check if the PLL is used as system clock or not */
  1253. if(__HAL_RCC_GET_SYSCLK_SOURCE() != RCC_CFGR_SWS_PLL)
  1254. {
  1255. if((RCC_OscInitStruct->PLL.PLLState) == RCC_PLL_ON)
  1256. {
  1257. /* Check the parameters */
  1258. assert_param(IS_RCC_PLLSOURCE(RCC_OscInitStruct->PLL.PLLSource));
  1259. assert_param(IS_RCC_PLLM_VALUE(RCC_OscInitStruct->PLL.PLLM));
  1260. assert_param(IS_RCC_PLLN_VALUE(RCC_OscInitStruct->PLL.PLLN));
  1261. assert_param(IS_RCC_PLLP_VALUE(RCC_OscInitStruct->PLL.PLLP));
  1262. assert_param(IS_RCC_PLLQ_VALUE(RCC_OscInitStruct->PLL.PLLQ));
  1263. assert_param(IS_RCC_PLLR_VALUE(RCC_OscInitStruct->PLL.PLLR));
  1264. /* Disable the main PLL. */
  1265. __HAL_RCC_PLL_DISABLE();
  1266. /* Get Start Tick*/
  1267. tickstart = HAL_GetTick();
  1268. /* Wait till PLL is ready */
  1269. while(__HAL_RCC_GET_FLAG(RCC_FLAG_PLLRDY) != RESET)
  1270. {
  1271. if((HAL_GetTick() - tickstart ) > PLL_TIMEOUT_VALUE)
  1272. {
  1273. return HAL_TIMEOUT;
  1274. }
  1275. }
  1276. /* Configure the main PLL clock source, multiplication and division factors. */
  1277. __HAL_RCC_PLL_CONFIG(RCC_OscInitStruct->PLL.PLLSource,
  1278. RCC_OscInitStruct->PLL.PLLM,
  1279. RCC_OscInitStruct->PLL.PLLN,
  1280. RCC_OscInitStruct->PLL.PLLP,
  1281. RCC_OscInitStruct->PLL.PLLQ,
  1282. RCC_OscInitStruct->PLL.PLLR);
  1283. /* Enable the main PLL. */
  1284. __HAL_RCC_PLL_ENABLE();
  1285. /* Get Start Tick*/
  1286. tickstart = HAL_GetTick();
  1287. /* Wait till PLL is ready */
  1288. while(__HAL_RCC_GET_FLAG(RCC_FLAG_PLLRDY) == RESET)
  1289. {
  1290. if((HAL_GetTick() - tickstart ) > PLL_TIMEOUT_VALUE)
  1291. {
  1292. return HAL_TIMEOUT;
  1293. }
  1294. }
  1295. }
  1296. else
  1297. {
  1298. /* Disable the main PLL. */
  1299. __HAL_RCC_PLL_DISABLE();
  1300. /* Get Start Tick*/
  1301. tickstart = HAL_GetTick();
  1302. /* Wait till PLL is ready */
  1303. while(__HAL_RCC_GET_FLAG(RCC_FLAG_PLLRDY) != RESET)
  1304. {
  1305. if((HAL_GetTick() - tickstart ) > PLL_TIMEOUT_VALUE)
  1306. {
  1307. return HAL_TIMEOUT;
  1308. }
  1309. }
  1310. }
  1311. }
  1312. else
  1313. {
  1314. return HAL_ERROR;
  1315. }
  1316. }
  1317. return HAL_OK;
  1318. }
  1319. /**
  1320. * @brief Configures the RCC_OscInitStruct according to the internal
  1321. * RCC configuration registers.
  1322. * @param RCC_OscInitStruct: pointer to an RCC_OscInitTypeDef structure that will be configured.
  1323. *
  1324. * @note This function is only available in case of STM32F446xx devices.
  1325. * @note This function add the PLL/PLLR factor management
  1326. * @retval None
  1327. */
  1328. void HAL_RCC_GetOscConfig(RCC_OscInitTypeDef *RCC_OscInitStruct)
  1329. {
  1330. /* Set all possible values for the Oscillator type parameter ---------------*/
  1331. RCC_OscInitStruct->OscillatorType = RCC_OSCILLATORTYPE_HSE | RCC_OSCILLATORTYPE_HSI | RCC_OSCILLATORTYPE_LSE | RCC_OSCILLATORTYPE_LSI;
  1332. /* Get the HSE configuration -----------------------------------------------*/
  1333. if((RCC->CR &RCC_CR_HSEBYP) == RCC_CR_HSEBYP)
  1334. {
  1335. RCC_OscInitStruct->HSEState = RCC_HSE_BYPASS;
  1336. }
  1337. else if((RCC->CR &RCC_CR_HSEON) == RCC_CR_HSEON)
  1338. {
  1339. RCC_OscInitStruct->HSEState = RCC_HSE_ON;
  1340. }
  1341. else
  1342. {
  1343. RCC_OscInitStruct->HSEState = RCC_HSE_OFF;
  1344. }
  1345. /* Get the HSI configuration -----------------------------------------------*/
  1346. if((RCC->CR &RCC_CR_HSION) == RCC_CR_HSION)
  1347. {
  1348. RCC_OscInitStruct->HSIState = RCC_HSI_ON;
  1349. }
  1350. else
  1351. {
  1352. RCC_OscInitStruct->HSIState = RCC_HSI_OFF;
  1353. }
  1354. RCC_OscInitStruct->HSICalibrationValue = (uint32_t)((RCC->CR &RCC_CR_HSITRIM) >> POSITION_VAL(RCC_CR_HSITRIM));
  1355. /* Get the LSE configuration -----------------------------------------------*/
  1356. if((RCC->BDCR &RCC_BDCR_LSEBYP) == RCC_BDCR_LSEBYP)
  1357. {
  1358. RCC_OscInitStruct->LSEState = RCC_LSE_BYPASS;
  1359. }
  1360. else if((RCC->BDCR &RCC_BDCR_LSEON) == RCC_BDCR_LSEON)
  1361. {
  1362. RCC_OscInitStruct->LSEState = RCC_LSE_ON;
  1363. }
  1364. else
  1365. {
  1366. RCC_OscInitStruct->LSEState = RCC_LSE_OFF;
  1367. }
  1368. /* Get the LSI configuration -----------------------------------------------*/
  1369. if((RCC->CSR &RCC_CSR_LSION) == RCC_CSR_LSION)
  1370. {
  1371. RCC_OscInitStruct->LSIState = RCC_LSI_ON;
  1372. }
  1373. else
  1374. {
  1375. RCC_OscInitStruct->LSIState = RCC_LSI_OFF;
  1376. }
  1377. /* Get the PLL configuration -----------------------------------------------*/
  1378. if((RCC->CR &RCC_CR_PLLON) == RCC_CR_PLLON)
  1379. {
  1380. RCC_OscInitStruct->PLL.PLLState = RCC_PLL_ON;
  1381. }
  1382. else
  1383. {
  1384. RCC_OscInitStruct->PLL.PLLState = RCC_PLL_OFF;
  1385. }
  1386. RCC_OscInitStruct->PLL.PLLSource = (uint32_t)(RCC->PLLCFGR & RCC_PLLCFGR_PLLSRC);
  1387. RCC_OscInitStruct->PLL.PLLM = (uint32_t)(RCC->PLLCFGR & RCC_PLLCFGR_PLLM);
  1388. RCC_OscInitStruct->PLL.PLLN = (uint32_t)((RCC->PLLCFGR & RCC_PLLCFGR_PLLN) >> POSITION_VAL(RCC_PLLCFGR_PLLN));
  1389. RCC_OscInitStruct->PLL.PLLP = (uint32_t)((((RCC->PLLCFGR & RCC_PLLCFGR_PLLP) + RCC_PLLCFGR_PLLP_0) << 1) >> POSITION_VAL(RCC_PLLCFGR_PLLP));
  1390. RCC_OscInitStruct->PLL.PLLQ = (uint32_t)((RCC->PLLCFGR & RCC_PLLCFGR_PLLQ) >> POSITION_VAL(RCC_PLLCFGR_PLLQ));
  1391. RCC_OscInitStruct->PLL.PLLR = (uint32_t)((RCC->PLLCFGR & RCC_PLLCFGR_PLLR) >> POSITION_VAL(RCC_PLLCFGR_PLLR));
  1392. }
  1393. /**
  1394. * @brief Returns the SYSCLK frequency
  1395. *
  1396. * @note This function is only available in case of STM32F446xx devices.
  1397. * @note This function add the PLL/PLLR System clock source
  1398. *
  1399. * @note The system frequency computed by this function is not the real
  1400. * frequency in the chip. It is calculated based on the predefined
  1401. * constant and the selected clock source:
  1402. * @note If SYSCLK source is HSI, function returns values based on HSI_VALUE(*)
  1403. * @note If SYSCLK source is HSE, function returns values based on HSE_VALUE(**)
  1404. * @note If SYSCLK source is PLL, function returns values based on HSE_VALUE(**)
  1405. * or HSI_VALUE(*) multiplied/divided by the PLL factors.
  1406. * @note (*) HSI_VALUE is a constant defined in stm32f4xx_hal_conf.h file (default value
  1407. * 16 MHz) but the real value may vary depending on the variations
  1408. * in voltage and temperature.
  1409. * @note (**) HSE_VALUE is a constant defined in stm32f4xx_hal_conf.h file (default value
  1410. * 25 MHz), user has to ensure that HSE_VALUE is same as the real
  1411. * frequency of the crystal used. Otherwise, this function may
  1412. * have wrong result.
  1413. *
  1414. * @note The result of this function could be not correct when using fractional
  1415. * value for HSE crystal.
  1416. *
  1417. * @note This function can be used by the user application to compute the
  1418. * baudrate for the communication peripherals or configure other parameters.
  1419. *
  1420. * @note Each time SYSCLK changes, this function must be called to update the
  1421. * right SYSCLK value. Otherwise, any configuration based on this function will be incorrect.
  1422. *
  1423. *
  1424. * @retval SYSCLK frequency
  1425. */
  1426. uint32_t HAL_RCC_GetSysClockFreq(void)
  1427. {
  1428. uint32_t pllm = 0;
  1429. uint32_t pllvco = 0;
  1430. uint32_t pllp = 0;
  1431. uint32_t pllr = 0;
  1432. uint32_t sysclockfreq = 0;
  1433. /* Get SYSCLK source -------------------------------------------------------*/
  1434. switch (RCC->CFGR & RCC_CFGR_SWS)
  1435. {
  1436. case RCC_CFGR_SWS_HSI: /* HSI used as system clock source */
  1437. {
  1438. sysclockfreq = HSI_VALUE;
  1439. break;
  1440. }
  1441. case RCC_CFGR_SWS_HSE: /* HSE used as system clock source */
  1442. {
  1443. sysclockfreq = HSE_VALUE;
  1444. break;
  1445. }
  1446. case RCC_CFGR_SWS_PLL: /* PLL/PLLP used as system clock source */
  1447. {
  1448. /* PLL_VCO = (HSE_VALUE or HSI_VALUE / PLLM) * PLLN
  1449. SYSCLK = PLL_VCO / PLLP */
  1450. pllm = RCC->PLLCFGR & RCC_PLLCFGR_PLLM;
  1451. if(__HAL_RCC_GET_PLL_OSCSOURCE() != RCC_PLLSOURCE_HSI)
  1452. {
  1453. /* HSE used as PLL clock source */
  1454. pllvco = ((HSE_VALUE / pllm) * ((RCC->PLLCFGR & RCC_PLLCFGR_PLLN) >> POSITION_VAL(RCC_PLLCFGR_PLLN)));
  1455. }
  1456. else
  1457. {
  1458. /* HSI used as PLL clock source */
  1459. pllvco = ((HSI_VALUE / pllm) * ((RCC->PLLCFGR & RCC_PLLCFGR_PLLN) >> POSITION_VAL(RCC_PLLCFGR_PLLN)));
  1460. }
  1461. pllp = ((((RCC->PLLCFGR & RCC_PLLCFGR_PLLP) >> POSITION_VAL(RCC_PLLCFGR_PLLP)) + 1 ) *2);
  1462. sysclockfreq = pllvco/pllp;
  1463. break;
  1464. }
  1465. case RCC_CFGR_SWS_PLLR: /* PLL/PLLR used as system clock source */
  1466. {
  1467. /* PLL_VCO = (HSE_VALUE or HSI_VALUE / PLLM) * PLLN
  1468. SYSCLK = PLL_VCO / PLLR */
  1469. pllm = RCC->PLLCFGR & RCC_PLLCFGR_PLLM;
  1470. if(__HAL_RCC_GET_PLL_OSCSOURCE() != RCC_PLLSOURCE_HSI)
  1471. {
  1472. /* HSE used as PLL clock source */
  1473. pllvco = ((HSE_VALUE / pllm) * ((RCC->PLLCFGR & RCC_PLLCFGR_PLLN) >> POSITION_VAL(RCC_PLLCFGR_PLLN)));
  1474. }
  1475. else
  1476. {
  1477. /* HSI used as PLL clock source */
  1478. pllvco = ((HSI_VALUE / pllm) * ((RCC->PLLCFGR & RCC_PLLCFGR_PLLN) >> POSITION_VAL(RCC_PLLCFGR_PLLN)));
  1479. }
  1480. pllr = ((RCC->PLLCFGR & RCC_PLLCFGR_PLLR) >> POSITION_VAL(RCC_PLLCFGR_PLLR));
  1481. sysclockfreq = pllvco/pllr;
  1482. break;
  1483. }
  1484. default:
  1485. {
  1486. sysclockfreq = HSI_VALUE;
  1487. break;
  1488. }
  1489. }
  1490. return sysclockfreq;
  1491. }
  1492. #endif /* STM32F446xx */
  1493. /**
  1494. * @}
  1495. */
  1496. /**
  1497. * @}
  1498. */
  1499. #endif /* HAL_RCC_MODULE_ENABLED */
  1500. /**
  1501. * @}
  1502. */
  1503. /**
  1504. * @}
  1505. */
  1506. /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/