1 /*
2  * Copyright (c) 2006-2023, RT-Thread Development Team
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  *
6  * Change Logs:
7  * Date           Author       Notes
8  * 2021-08-20     breo.com     first version
9  */
10 
11 #include "drv_clk.h"
12 #include "board.h"
13 
DumpClock(const char * msg)14 void DumpClock(const char *msg)
15 {
16     RCC_ClocksType RCC_ClockFreq;
17     rt_kprintf("--------------------------------\n");
18     rt_kprintf("%s:\n", msg);
19     RCC_GetClocksFreqValue(&RCC_ClockFreq);
20     rt_kprintf("SYSCLK: %d\n", RCC_ClockFreq.SysclkFreq);
21     rt_kprintf("HCLK: %d\n", RCC_ClockFreq.HclkFreq);
22     rt_kprintf("PCLK1: %d\n", RCC_ClockFreq.Pclk1Freq);
23     rt_kprintf("PCLK2: %d\n", RCC_ClockFreq.Pclk2Freq);
24 }
25 
SetSysClockToHSI(void)26 void SetSysClockToHSI(void)
27 {
28     RCC_DeInit();
29 
30     RCC_EnableHsi(ENABLE);
31 
32     /* Enable Prefetch Buffer */
33     FLASH_PrefetchBufSet(FLASH_PrefetchBuf_EN);
34 
35     /* Flash 0 wait state */
36     FLASH_SetLatency(FLASH_LATENCY_0);
37 
38     /* HCLK = SYSCLK */
39     RCC_ConfigHclk(RCC_SYSCLK_DIV1);
40 
41     /* PCLK2 = HCLK */
42     RCC_ConfigPclk2(RCC_HCLK_DIV1);
43 
44     /* PCLK1 = HCLK */
45     RCC_ConfigPclk1(RCC_HCLK_DIV1);
46 
47     /* Select HSE as system clock source */
48     RCC_ConfigSysclk(RCC_SYSCLK_SRC_HSI);
49 
50     /* Wait till PLL is used as system clock source */
51     while (RCC_GetSysclkSrc() != 0x00)
52     {
53     }
54 }
55 
56 /**
57  * @brief  Selects HSE as System clock source and configure HCLK, PCLK2
58  *         and PCLK1 prescalers.
59  */
SetSysClockToHSE(void)60 void SetSysClockToHSE(void)
61 {
62     ErrorStatus HSEStartUpStatus;
63 
64     /* SYSCLK, HCLK, PCLK2 and PCLK1 configuration
65      * -----------------------------*/
66     /* RCC system reset(for debug purpose) */
67     RCC_DeInit();
68 
69     /* Enable HSE */
70     RCC_ConfigHse(RCC_HSE_ENABLE);
71 
72     /* Wait till HSE is ready */
73     HSEStartUpStatus = RCC_WaitHseStable();
74 
75     if (HSEStartUpStatus == SUCCESS)
76     {
77         /* Enable Prefetch Buffer */
78         FLASH_PrefetchBufSet(FLASH_PrefetchBuf_EN);
79 
80         if (HSE_Value <= 32000000)
81         {
82             /* Flash 0 wait state */
83             FLASH_SetLatency(FLASH_LATENCY_0);
84         }
85         else
86         {
87             /* Flash 1 wait state */
88             FLASH_SetLatency(FLASH_LATENCY_1);
89         }
90 
91         /* HCLK = SYSCLK */
92         RCC_ConfigHclk(RCC_SYSCLK_DIV1);
93 
94         /* PCLK2 = HCLK */
95         RCC_ConfigPclk2(RCC_HCLK_DIV1);
96 
97         /* PCLK1 = HCLK */
98         RCC_ConfigPclk1(RCC_HCLK_DIV1);
99 
100         /* Select HSE as system clock source */
101         RCC_ConfigSysclk(RCC_SYSCLK_SRC_HSE);
102 
103         /* Wait till HSE is used as system clock source */
104         while (RCC_GetSysclkSrc() != 0x04)
105         {
106         }
107     }
108     else
109     {
110         /* If HSE fails to start-up, the application will have wrong clock
111            configuration. User can add here some code to deal with this error */
112 
113         /* Go to infinite loop */
114         while (1)
115         {
116         }
117     }
118 }
119 
SetSysClockToPLL(uint32_t freq,uint8_t src)120 void SetSysClockToPLL(uint32_t freq, uint8_t src)
121 {
122     uint32_t pllsrc = (src == SYSCLK_PLLSRC_HSI ? RCC_PLL_SRC_HSI_DIV2 : RCC_PLL_SRC_HSE_DIV2);
123     uint32_t pllmul;
124     uint32_t latency;
125     uint32_t pclk1div, pclk2div;
126     ErrorStatus HSEStartUpStatus;
127 
128     if (HSE_VALUE != 8000000)
129     {
130         /* HSE_VALUE == 8000000 is needed in this project! */
131         while (1)
132             ;
133     }
134 
135     /* SYSCLK, HCLK, PCLK2 and PCLK1 configuration
136      * -----------------------------*/
137     /* RCC system reset(for debug purpose) */
138     RCC_DeInit();
139 
140     if (src == SYSCLK_PLLSRC_HSE)
141     {
142         /* Enable HSE */
143         RCC_ConfigHse(RCC_HSE_ENABLE);
144 
145         /* Wait till HSE is ready */
146         HSEStartUpStatus = RCC_WaitHseStable();
147 
148         if (HSEStartUpStatus != SUCCESS)
149         {
150             /* If HSE fails to start-up, the application will have wrong clock
151                configuration. User can add here some code to deal with this
152                error */
153 
154             /* Go to infinite loop */
155             while (1)
156                 ;
157         }
158     }
159 
160     switch (freq)
161     {
162     case 24000000:
163         latency  = FLASH_LATENCY_0;
164         pllmul   = RCC_PLL_MUL_6;
165         pclk1div = RCC_HCLK_DIV1;
166         pclk2div = RCC_HCLK_DIV1;
167         break;
168     case 36000000:
169         latency  = FLASH_LATENCY_1;
170         pllmul   = RCC_PLL_MUL_9;
171         pclk1div = RCC_HCLK_DIV1;
172         pclk2div = RCC_HCLK_DIV1;
173         break;
174     case 48000000:
175         latency  = FLASH_LATENCY_1;
176         pllmul   = RCC_PLL_MUL_12;
177         pclk1div = RCC_HCLK_DIV2;
178         pclk2div = RCC_HCLK_DIV1;
179         break;
180     case 56000000:
181         latency  = FLASH_LATENCY_1;
182         pllmul   = RCC_PLL_MUL_14;
183         pclk1div = RCC_HCLK_DIV2;
184         pclk2div = RCC_HCLK_DIV1;
185         break;
186     case 72000000:
187         latency  = FLASH_LATENCY_2;
188         pllmul   = RCC_PLL_MUL_18;
189         pclk1div = RCC_HCLK_DIV2;
190         pclk2div = RCC_HCLK_DIV1;
191         break;
192     case 96000000:
193         latency  = FLASH_LATENCY_2;
194         pllmul   = RCC_PLL_MUL_24;
195         pclk1div = RCC_HCLK_DIV4;
196         pclk2div = RCC_HCLK_DIV2;
197         break;
198     case 128000000:
199         latency  = FLASH_LATENCY_3;
200         pllmul   = RCC_PLL_MUL_32;
201         pclk1div = RCC_HCLK_DIV4;
202         pclk2div = RCC_HCLK_DIV2;
203         break;
204     case 144000000:
205         /* must use HSE as PLL source */
206         latency  = FLASH_LATENCY_4;
207         pllsrc   = RCC_PLL_SRC_HSE_DIV1;
208         pllmul   = RCC_PLL_MUL_18;
209         pclk1div = RCC_HCLK_DIV4;
210         pclk2div = RCC_HCLK_DIV2;
211         break;
212     default:
213         while (1)
214             ;
215     }
216 
217     FLASH_SetLatency(latency);
218 
219     /* HCLK = SYSCLK */
220     RCC_ConfigHclk(RCC_SYSCLK_DIV1);
221 
222     /* PCLK2 = HCLK */
223     RCC_ConfigPclk2(pclk2div);
224 
225     /* PCLK1 = HCLK */
226     RCC_ConfigPclk1(pclk1div);
227 
228     RCC_ConfigPll(pllsrc, pllmul);
229 
230     /* Enable PLL */
231     RCC_EnablePll(ENABLE);
232 
233     /* Wait till PLL is ready */
234     while (RCC_GetFlagStatus(RCC_FLAG_PLLRD) == RESET)
235         ;
236 
237     /* Select PLL as system clock source */
238     RCC_ConfigSysclk(RCC_SYSCLK_SRC_PLLCLK);
239 
240     /* Wait till PLL is used as system clock source */
241     while (RCC_GetSysclkSrc() != 0x08)
242         ;
243 }
244 
245