1 /**
2 ******************************************************************************
3 * @file bl602_clock.c
4 * @version V1.0
5 * @date
6 * @brief This file is the standard driver c file
7 ******************************************************************************
8 * @attention
9 *
10 * <h2><center>© COPYRIGHT(c) 2020 Bouffalo Lab</center></h2>
11 *
12 * Redistribution and use in source and binary forms, with or without modification,
13 * are permitted provided that the following conditions are met:
14 * 1. Redistributions of source code must retain the above copyright notice,
15 * this list of conditions and the following disclaimer.
16 * 2. Redistributions in binary form must reproduce the above copyright notice,
17 * this list of conditions and the following disclaimer in the documentation
18 * and/or other materials provided with the distribution.
19 * 3. Neither the name of Bouffalo Lab nor the names of its contributors
20 * may be used to endorse or promote products derived from this software
21 * without specific prior written permission.
22 *
23 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
24 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
25 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
26 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
27 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
28 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
29 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
30 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
31 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
32 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33 *
34 ******************************************************************************
35 */
36
37 #include "bl602_clock.h"
38 // #include "bl602_pwm.h"
39
40 /** @addtogroup BL602_Peripheral_Driver
41 * @{
42 */
43
44 /** @addtogroup CLOCK
45 * @{
46 */
47
48 /** @defgroup CLOCK_Private_Macros
49 * @{
50 */
51
52 /*@} end of group CLOCK_Private_Macros */
53
54 /** @defgroup CLOCK_Private_Types
55 * @{
56 */
57
58 /*@} end of group CLOCK_Private_Types */
59
60 /** @defgroup CLOCK_Private_Variables
61 * @{
62 */
63 //static inline Clock_Cfg_Type clkCfg;
64
65 /*@} end of group CLOCK_Private_Variables */
66
67 /** @defgroup CLOCK_Global_Variables
68 * @{
69 */
70
71 /*@} end of group CLOCK_Global_Variables */
72
73 /** @defgroup CLOCK_Private_Fun_Declaration
74 * @{
75 */
76
77 /*@} end of group CLOCK_Private_Fun_Declaration */
78
79 /** @defgroup CLOCK_Private_Functions
80 * @{
81 */
82
83 /*@} end of group CLOCK_Private_Functions */
84
85 /** @defgroup CLOCK_Public_Functions
86 * @{
87 */
88
Clock_Xtal_Output(void)89 static inline uint32_t Clock_Xtal_Output(void)
90 {
91 uint32_t tmpVal;
92
93 /* get clkpll_sdmin */
94 tmpVal = BL_RD_REG(PDS_BASE, PDS_CLKPLL_SDM);
95 tmpVal = BL_GET_REG_BITS_VAL(tmpVal, PDS_CLKPLL_SDMIN);
96
97 switch (tmpVal) {
98 case 0x500000:
99 /* 24m */
100 return (24 * 1000 * 1000);
101
102 case 0x3C0000:
103 /* 32m */
104 return (32 * 1000 * 1000);
105
106 case 0x320000:
107 /* 38.4m */
108 return (384 * 100 * 1000);
109
110 case 0x300000:
111 /* 40m */
112 return (40 * 1000 * 1000);
113
114 case 0x49D39D:
115 /* 26m */
116 return (26 * 1000 * 1000);
117
118 default:
119 /* 32m */
120 return (32 * 1000 * 1000);
121 }
122 }
123
Clock_XClk_Mux_Output(uint8_t sel)124 static inline uint32_t Clock_XClk_Mux_Output(uint8_t sel)
125 {
126 if (sel == 0) {
127 /* rc32m */
128 return (32 * 1000 * 1000);
129 } else {
130 /* xtal */
131 return Clock_Xtal_Output();
132 }
133 }
134
Clock_Get_MCU_XClk_Sel_Val(void)135 static inline uint8_t Clock_Get_MCU_XClk_Sel_Val(void)
136 {
137 uint32_t tmpVal = 0;
138
139 tmpVal = BL_RD_REG(GLB_BASE, GLB_CLK_CFG0);
140 tmpVal = BL_GET_REG_BITS_VAL(tmpVal, GLB_HBN_ROOT_CLK_SEL);
141
142 return (tmpVal & 0x1);
143 }
144
Clock_Get_MCU_Root_Clk_Sel_Val(void)145 static inline uint8_t Clock_Get_MCU_Root_Clk_Sel_Val(void)
146 {
147 uint32_t tmpVal;
148
149 tmpVal = BL_RD_REG(GLB_BASE, GLB_CLK_CFG0);
150 tmpVal = BL_GET_REG_BITS_VAL(tmpVal, GLB_HBN_ROOT_CLK_SEL);
151
152 return ((tmpVal >> 1) & 0x1);
153 }
154
Clock_MCU_Clk_Mux_Output(uint8_t sel)155 static inline uint32_t Clock_MCU_Clk_Mux_Output(uint8_t sel)
156 {
157 if (sel == 0) {
158 /* pll 48m */
159 return (48 * 1000 * 1000);
160 } else if (sel == 1) {
161 /* pll 120m */
162 return (120 * 1000 * 1000);
163 } else if (sel == 2) {
164 /* pll 160m */
165 return (160 * 1000 * 1000);
166 } else if (sel == 3) {
167 /* pll 192m */
168 return (192 * 1000 * 1000);
169 } else {
170 return 0;
171 }
172 }
173
Clock_MCU_Root_Clk_Mux_Output(uint8_t sel)174 static inline uint32_t Clock_MCU_Root_Clk_Mux_Output(uint8_t sel)
175 {
176 uint32_t tmpVal;
177
178 if (sel == 0) {
179 /* xclk */
180 return Clock_XClk_Mux_Output(Clock_Get_MCU_XClk_Sel_Val());
181 } else if (sel == 1) {
182 /* pll */
183 tmpVal = BL_RD_REG(GLB_BASE, GLB_CLK_CFG0);
184 tmpVal = BL_GET_REG_BITS_VAL(tmpVal, GLB_REG_PLL_SEL);
185 return Clock_MCU_Clk_Mux_Output(tmpVal);
186 } else {
187 return 0;
188 }
189 }
190
Clock_Get_MCU_HClk_Div_Val(void)191 static inline uint8_t Clock_Get_MCU_HClk_Div_Val(void)
192 {
193 uint32_t tmpVal;
194
195 tmpVal = BL_RD_REG(GLB_BASE, GLB_CLK_CFG0);
196
197 return BL_GET_REG_BITS_VAL(tmpVal, GLB_REG_HCLK_DIV);
198 }
199
Clock_Get_Peri_BClk_Div_Val(void)200 static inline uint8_t Clock_Get_Peri_BClk_Div_Val(void)
201 {
202 uint32_t tmpVal;
203
204 tmpVal = BL_RD_REG(GLB_BASE, GLB_CLK_CFG0);
205
206 return BL_GET_REG_BITS_VAL(tmpVal, GLB_REG_BCLK_DIV);
207 }
208
Clock_F32k_Mux_Output(uint8_t sel)209 static inline uint32_t Clock_F32k_Mux_Output(uint8_t sel)
210 {
211 uint32_t tmpVal;
212 uint32_t div = 0;
213
214 tmpVal = BL_RD_REG(GLB_BASE, GLB_DIG32K_WAKEUP_CTRL);
215 div = BL_GET_REG_BITS_VAL(tmpVal, GLB_DIG_32K_DIV);
216
217 if (sel == 0) {
218 /* src32K */
219 return (32 * 1000);
220 } else if (sel == 1) {
221 /* xtal 32K */
222 return (32 * 1000);
223 } else {
224 return Clock_Xtal_Output() / (div + 1);
225 }
226 }
227
Clock_Get_F32k_Sel_Val(void)228 static inline uint8_t Clock_Get_F32k_Sel_Val(void)
229 {
230 uint32_t tmpVal;
231
232 tmpVal = BL_RD_REG(HBN_BASE, HBN_GLB);
233
234 return BL_GET_REG_BITS_VAL(tmpVal, HBN_F32K_SEL);
235 }
236
237 /****************************************************************************/ /**
238 * @brief Get System Clock
239 *
240 * @param type: System clock type
241 *
242 * @return System clock value
243 *
244 *******************************************************************************/
Clock_System_Clock_Get(BL_System_Clock_Type type)245 uint32_t Clock_System_Clock_Get(BL_System_Clock_Type type)
246 {
247 uint32_t clock = 0;
248 uint32_t div = 0;
249
250 switch (type) {
251 case BL_SYSTEM_CLOCK_XCLK:
252 /*!< mcu xclk clock */
253 return Clock_XClk_Mux_Output(Clock_Get_MCU_XClk_Sel_Val());
254
255 case BL_SYSTEM_CLOCK_ROOT:
256 /*!< mcu root clock */
257 return Clock_MCU_Root_Clk_Mux_Output(Clock_Get_MCU_Root_Clk_Sel_Val());
258
259 case BL_SYSTEM_CLOCK_FCLK:
260 /*!< mcu fast clock/cpu clock */
261 clock = Clock_MCU_Root_Clk_Mux_Output(Clock_Get_MCU_Root_Clk_Sel_Val());
262 div = Clock_Get_MCU_HClk_Div_Val();
263 return clock / (div + 1);
264
265 case BL_SYSTEM_CLOCK_BCLK:
266 /*!< mcu peri bus clock */
267 clock = Clock_System_Clock_Get(BL_SYSTEM_CLOCK_FCLK);
268 div = Clock_Get_Peri_BClk_Div_Val();
269 return clock / (div + 1);
270
271 case BL_SYSTEM_CLOCK_XTAL:
272 /*!< xtal clock */
273 return Clock_Xtal_Output();
274
275 case BL_SYSTEM_CLOCK_F32K:
276 /*!< f32k clock */
277 return Clock_F32k_Mux_Output(Clock_Get_F32k_Sel_Val());
278
279 default:
280 return 0;
281 }
282 }
283
Clock_UART_Clk_Mux_Output(uint8_t sel)284 static inline uint32_t Clock_UART_Clk_Mux_Output(uint8_t sel)
285 {
286 if (sel == 0) {
287 /* fclk */
288 return Clock_System_Clock_Get(BL_SYSTEM_CLOCK_FCLK);
289 } else {
290 /* 160m */
291 return (160 * 1000 * 1000);
292 }
293 }
294
Clock_Get_UART_Clk_Sel_Val(void)295 static inline uint8_t Clock_Get_UART_Clk_Sel_Val(void)
296 {
297 uint32_t tmpVal;
298
299 tmpVal = BL_RD_REG(HBN_BASE, HBN_GLB);
300
301 return BL_GET_REG_BITS_VAL(tmpVal, HBN_UART_CLK_SEL);
302 }
303
Clock_Get_UART_Div_Val(void)304 static inline uint8_t Clock_Get_UART_Div_Val(void)
305 {
306 uint32_t tmpVal;
307
308 tmpVal = BL_RD_REG(GLB_BASE, GLB_CLK_CFG2);
309
310 return BL_GET_REG_BITS_VAL(tmpVal, GLB_UART_CLK_DIV);
311 }
312
Clock_SPI_Clk_Mux_Output(void)313 static inline uint32_t Clock_SPI_Clk_Mux_Output(void)
314 {
315 /* pbclk */
316 return Clock_System_Clock_Get(BL_SYSTEM_CLOCK_BCLK);
317 }
318
Clock_Get_SPI_Div_Val(void)319 static inline uint8_t Clock_Get_SPI_Div_Val(void)
320 {
321 uint32_t tmpVal;
322
323 tmpVal = BL_RD_REG(GLB_BASE, GLB_CLK_CFG3);
324
325 return BL_GET_REG_BITS_VAL(tmpVal, GLB_SPI_CLK_DIV);
326 }
327
Clock_I2C_Clk_Mux_Output()328 static inline uint32_t Clock_I2C_Clk_Mux_Output()
329 {
330 /* pbclk */
331 return Clock_System_Clock_Get(BL_SYSTEM_CLOCK_BCLK);
332 }
333
Clock_Get_I2C_Div_Val(void)334 static inline uint8_t Clock_Get_I2C_Div_Val(void)
335 {
336 uint32_t tmpVal;
337
338 tmpVal = BL_RD_REG(GLB_BASE, GLB_CLK_CFG3);
339
340 return BL_GET_REG_BITS_VAL(tmpVal, GLB_I2C_CLK_DIV);
341 }
342
Clock_Get_GPADC_Div_Val(void)343 static inline uint8_t Clock_Get_GPADC_Div_Val(void)
344 {
345 uint32_t tmpVal;
346
347 tmpVal = BL_RD_REG(GLB_BASE, GLB_GPADC_32M_SRC_CTRL);
348
349 return BL_GET_REG_BITS_VAL(tmpVal, GLB_GPADC_32M_CLK_DIV);
350 }
351
Clock_GPADC_Clk_Output(uint8_t sel)352 static inline uint32_t Clock_GPADC_Clk_Output(uint8_t sel)
353 {
354 if (sel == 0) {
355 /* 96m */
356 return (96 * 1000 * 1000);
357 } else {
358 /* xclk */
359 return Clock_System_Clock_Get(BL_SYSTEM_CLOCK_XCLK);
360 }
361 }
362
Clock_Get_GPADC_32M_Clk_Sel_Val(void)363 static inline uint8_t Clock_Get_GPADC_32M_Clk_Sel_Val(void)
364 {
365 uint32_t tmpVal;
366
367 tmpVal = BL_RD_REG(GLB_BASE, GLB_GPADC_32M_SRC_CTRL);
368
369 return BL_GET_REG_BITS_VAL(tmpVal, GLB_GPADC_32M_CLK_SEL);
370 }
371
Clock_GPADC_Clk_Mux_Output(uint8_t sel)372 static inline uint32_t Clock_GPADC_Clk_Mux_Output(uint8_t sel)
373 {
374 uint32_t div = 0;
375
376 if (sel == 1) {
377 /* f32k clk */
378 return Clock_F32k_Mux_Output(Clock_Get_F32k_Sel_Val());
379 } else {
380 div = Clock_Get_GPADC_Div_Val();
381 return Clock_GPADC_Clk_Output(Clock_Get_GPADC_32M_Clk_Sel_Val()) / (div + 1);
382 }
383 }
384
Clock_Get_GPADC_Clk_Sel_Val(void)385 static inline uint8_t Clock_Get_GPADC_Clk_Sel_Val(void)
386 {
387 uint32_t tmpVal;
388
389 tmpVal = BL_RD_REG(HBN_BASE, HBN_PIR_CFG);
390
391 return BL_GET_REG_BITS_VAL(tmpVal, HBN_PIR_EN);
392 }
393
Clock_GPDAC_Clk_Mux_Output(uint8_t sel)394 static inline uint32_t Clock_GPDAC_Clk_Mux_Output(uint8_t sel)
395 {
396 if (sel == 0) {
397 /* pll 32m */
398 return (32 * 1000 * 1000);
399 } else {
400 /* xclk */
401 return Clock_System_Clock_Get(BL_SYSTEM_CLOCK_XCLK);
402 }
403 }
404
Clock_Get_GPDAC_Div_Val(void)405 static inline uint8_t Clock_Get_GPDAC_Div_Val(void)
406 {
407 uint32_t tmpVal;
408
409 tmpVal = BL_RD_REG(GLB_BASE, GLB_DIG32K_WAKEUP_CTRL);
410
411 return BL_GET_REG_BITS_VAL(tmpVal, GLB_DIG_512K_DIV);
412 }
413
Clock_Get_GPDAC_Clk_Sel_Val(void)414 static inline uint8_t Clock_Get_GPDAC_Clk_Sel_Val(void)
415 {
416 uint32_t tmpVal;
417
418 tmpVal = BL_RD_REG(GLB_BASE, GLB_DIG32K_WAKEUP_CTRL);
419
420 return BL_GET_REG_BITS_VAL(tmpVal, GLB_DIG_CLK_SRC_SEL);
421 }
422
423 // static inline uint32_t Clock_PWM_Clk_Mux_Output(uint8_t sel)
424 // {
425 // if (sel == 0) {
426 // /* xclk */
427 // return Clock_System_Clock_Get(BL_SYSTEM_CLOCK_XCLK);
428 // } else if (sel == 1) {
429 // /* pbclk */
430 // return Clock_System_Clock_Get(BL_SYSTEM_CLOCK_BCLK);
431 // } else {
432 // /* f32k clk */
433 // return Clock_F32k_Mux_Output(Clock_Get_F32k_Sel_Val());
434 // }
435 // }
436
437 // static inline uint8_t Clock_Get_PWM_Div_Val(void)
438 // {
439 // uint32_t tmpVal;
440
441 // tmpVal = BL_RD_REG(PWM_BASE + PWM_CHANNEL_OFFSET, PWM_CLKDIV);
442
443 // return tmpVal;
444 // }
445
446 // static inline uint8_t Clock_Get_PWM_Clk_Sel_Val(void)
447 // {
448 // uint32_t tmpVal;
449
450 // tmpVal = BL_RD_REG(PWM_BASE + PWM_CHANNEL_OFFSET, PWM_CONFIG);
451
452 // return BL_GET_REG_BITS_VAL(tmpVal, PWM_REG_CLK_SEL);
453 // }
454
Clock_IR_Clk_Mux_Output(void)455 static inline uint32_t Clock_IR_Clk_Mux_Output(void)
456 {
457 /* xclk */
458 return Clock_System_Clock_Get(BL_SYSTEM_CLOCK_XCLK);
459 }
460
Clock_Get_IR_Div_Val(void)461 static inline uint8_t Clock_Get_IR_Div_Val(void)
462 {
463 uint32_t tmpVal;
464
465 tmpVal = BL_RD_REG(GLB_BASE, GLB_CLK_CFG2);
466
467 return BL_GET_REG_BITS_VAL(tmpVal, GLB_IR_CLK_DIV);
468 }
469
Clock_Get_SF_Clk_Sel2_Val(void)470 static inline uint8_t Clock_Get_SF_Clk_Sel2_Val(void)
471 {
472 uint32_t tmpVal;
473
474 tmpVal = BL_RD_REG(GLB_BASE, GLB_CLK_CFG2);
475
476 return BL_GET_REG_BITS_VAL(tmpVal, GLB_SF_CLK_SEL2);
477 }
478
Clock_SF_SEL2_Clk_Mux_Output(uint8_t sel)479 static inline uint32_t Clock_SF_SEL2_Clk_Mux_Output(uint8_t sel)
480 {
481 if (sel == 0) {
482 /* 120m */
483 return (120 * 1000 * 1000);
484 } else if (sel == 1) {
485 /* xclk */
486 return Clock_System_Clock_Get(BL_SYSTEM_CLOCK_XCLK);
487 } else {
488 /* 48m */
489 return (48 * 1000 * 1000);
490 }
491 }
492
Clock_SF_SEL_Clk_Mux_Output(uint8_t sel)493 static inline uint32_t Clock_SF_SEL_Clk_Mux_Output(uint8_t sel)
494 {
495 if (sel == 0) {
496 /* sf sel2 */
497 return Clock_SF_SEL2_Clk_Mux_Output(Clock_Get_SF_Clk_Sel2_Val());
498 } else if (sel == 1) {
499 /* 80m */
500 return (80 * 1000 * 1000);
501 } else if (sel == 2) {
502 /* pbclk */
503 return Clock_System_Clock_Get(BL_SYSTEM_CLOCK_BCLK);
504 } else {
505 /* 96m */
506 return (96 * 1000 * 1000);
507 }
508 }
509
Clock_Get_SF_Clk_Sel_Val(void)510 static inline uint8_t Clock_Get_SF_Clk_Sel_Val(void)
511 {
512 uint32_t tmpVal;
513
514 tmpVal = BL_RD_REG(GLB_BASE, GLB_CLK_CFG2);
515
516 return BL_GET_REG_BITS_VAL(tmpVal, GLB_SF_CLK_SEL);
517 }
518
Clock_Get_SF_Div_Val(void)519 static inline uint8_t Clock_Get_SF_Div_Val(void)
520 {
521 uint32_t tmpVal;
522
523 tmpVal = BL_RD_REG(GLB_BASE, GLB_CLK_CFG2);
524
525 return BL_GET_REG_BITS_VAL(tmpVal, GLB_SF_CLK_DIV);
526 }
527
528 /****************************************************************************/ /**
529 * @brief Get Peripheral Clock
530 *
531 * @param type: Peripheral clock type
532 *
533 * @return Peripheral clock value
534 *
535 *******************************************************************************/
Clock_Peripheral_Clock_Get(BL_Peripheral_Type type)536 uint32_t Clock_Peripheral_Clock_Get(BL_Peripheral_Type type)
537 {
538 uint32_t clock = 0;
539 uint32_t div = 0;
540
541 switch (type) {
542 /*!< uart0 clock */
543 case BL_PERIPHERAL_CLOCK_UART0:
544 ATTR_FALLTHROUGH();
545
546 /*!< uart1 clock */
547 case BL_PERIPHERAL_CLOCK_UART1:
548 clock = Clock_UART_Clk_Mux_Output(Clock_Get_UART_Clk_Sel_Val());
549 div = Clock_Get_UART_Div_Val();
550 return clock / (div + 1);
551
552 /*!< FLASH clock */
553 case BL_PERIPHERAL_CLOCK_FLASH:
554 clock = Clock_SF_SEL_Clk_Mux_Output(Clock_Get_SF_Clk_Sel_Val());
555 div = Clock_Get_SF_Div_Val();
556 return clock / (div + 1);
557
558 /*!< spi0 clock */
559 case BL_PERIPHERAL_CLOCK_SPI0:
560 clock = Clock_SPI_Clk_Mux_Output();
561 div = Clock_Get_SPI_Div_Val();
562 return clock / (div + 1);
563
564 /*!< i2c0 clock */
565 case BL_PERIPHERAL_CLOCK_I2C0:
566 clock = Clock_I2C_Clk_Mux_Output();
567 div = Clock_Get_I2C_Div_Val();
568 return clock / (div + 1);
569
570 /*!< GPADC clock */
571 case BL_PERIPHERAL_CLOCK_GPADC:
572 return Clock_GPADC_Clk_Mux_Output(Clock_Get_GPADC_Clk_Sel_Val());
573
574 /*!< GPDAC clock */
575 case BL_PERIPHERAL_CLOCK_GPDAC:
576 clock = Clock_GPDAC_Clk_Mux_Output(Clock_Get_GPDAC_Clk_Sel_Val());
577 div = Clock_Get_GPDAC_Div_Val();
578 return clock / (div + 1);
579
580 /*!< PWM clock */
581 // case BL_PERIPHERAL_CLOCK_PWM:
582 // clock = Clock_PWM_Clk_Mux_Output(Clock_Get_PWM_Clk_Sel_Val());
583 // div = Clock_Get_PWM_Div_Val();
584 // return clock / div;
585
586 /*!< IR clock */
587 case BL_PERIPHERAL_CLOCK_IR:
588 clock = Clock_IR_Clk_Mux_Output();
589 div = Clock_Get_IR_Div_Val();
590 return clock / (div + 1);
591
592 default:
593 return 0;
594 }
595 }
596
597 /*@} end of group CLOCK_Public_Functions */
598
599 /*@} end of group CLOCK */
600
601 /*@} end of group BL602_Peripheral_Driver */
602