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>&copy; 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