1 /***************************************************************************//**
2  * @file em_cmu_fpga.c
3  * @brief Clock management unit (CMU) Peripheral API for FPGA
4  * @version 5.3.5
5  *******************************************************************************
6  * # License
7  * <b>Copyright 2018 Silicon Laboratories, Inc. www.silabs.com</b>
8  *******************************************************************************
9  *
10  * Permission is granted to anyone to use this software for any purpose,
11  * including commercial applications, and to alter it and redistribute it
12  * freely, subject to the following restrictions:
13  *
14  * 1. The origin of this software must not be misrepresented; you must not
15  *    claim that you wrote the original software.
16  * 2. Altered source versions must be plainly marked as such, and must not be
17  *    misrepresented as being the original software.
18  * 3. This notice may not be removed or altered from any source distribution.
19  *
20  * DISCLAIMER OF WARRANTY/LIMITATION OF REMEDIES: Silicon Labs has no
21  * obligation to support this Software. Silicon Labs is providing the
22  * Software "AS IS", with no express or implied warranties of any kind,
23  * including, but not limited to, any implied warranties of merchantability
24  * or fitness for any particular purpose or warranties against infringement
25  * of any proprietary rights of a third party.
26  *
27  * Silicon Labs will not be liable for any consequential, incidental, or
28  * special damages, or any other relief, or for any claim by any third party,
29  * arising from your use of this Software.
30  *
31  ******************************************************************************/
32 
33 #include "em_device.h"
34 
35 #if defined(CMU_PRESENT) && defined(FPGA)
36 
37 #include "em_cmu.h"
38 #include "sl_assert.h"
39 
40 /***************************************************************************//**
41  * @addtogroup emlib
42  * @{
43  ******************************************************************************/
44 
45 /***************************************************************************//**
46  * @addtogroup CMU
47  * @brief Clock management unit (CMU) Peripheral API
48  * @details
49  *  This module contains stubbed EM_CMU functions in order to run on FPGA
50  *  implementations of Silicon Labs 32-bit MCUs and SoCs.
51  * @{
52  ******************************************************************************/
53 
54 #if defined(HFRCO_STARTUP_FREQ)
55 #define HFRCO_CLK_FREQ HFRCO_STARTUP_FREQ
56 #else
57 #define HFRCO_CLK_FREQ 38400000    /* OTA FPGA image clock frequency */
58 #endif
59 #define LFRCO_CLK_FREQ 32768
60 #define ULFRCO_CLK_FREQ 1000
61 
62 CMU_Select_TypeDef cmu_euart0_clk_source = cmuSelect_HFRCO;
63 CMU_Select_TypeDef cmu_eusart0_clk_source = cmuSelect_HFRCO;
64 CMU_Select_TypeDef cmu_eusart1_clk_source = cmuSelect_HFRCO;
65 CMU_Select_TypeDef cmu_eusart2_clk_source = cmuSelect_HFRCO;
66 CMU_Select_TypeDef cmu_eusart3_clk_source = cmuSelect_HFRCO;
67 CMU_Select_TypeDef cmu_eusart4_clk_source = cmuSelect_HFRCO;
68 
sli_em_cmu_SYSCLKInitPreClockSelect(void)69 void sli_em_cmu_SYSCLKInitPreClockSelect(void)
70 {
71 }
72 
sli_em_cmu_SYSCLKInitPostClockSelect(bool optimize_divider)73 void sli_em_cmu_SYSCLKInitPostClockSelect(bool optimize_divider)
74 {
75 }
76 
Get_Fpga_Core_freq(void)77 uint32_t Get_Fpga_Core_freq(void)
78 {
79   if ((SYSCFG->FPGAIPOTHW & SYSCFG_FPGAIPOTHW_FPGA_FPGA) != 0U) {
80     if ((SYSCFG->FPGAIPOTHW & SYSCFG_FPGAIPOTHW_OTA_OTA) != 0U) {
81       return 38400000U;
82     } else {
83       return 9600000U;
84     }
85   } else {
86     return SystemHFXOClockGet();
87   }
88 }
89 
CMU_Calibrate(uint32_t HFCycles,CMU_Osc_TypeDef ref)90 uint32_t CMU_Calibrate(uint32_t HFCycles, CMU_Osc_TypeDef ref)
91 {
92   (void) HFCycles;
93   (void) ref;
94 
95   return 1;
96 }
97 
CMU_CalibrateConfig(uint32_t downCycles,CMU_Osc_TypeDef downSel,CMU_Osc_TypeDef upSel)98 void CMU_CalibrateConfig(uint32_t downCycles, CMU_Osc_TypeDef downSel,
99                          CMU_Osc_TypeDef upSel)
100 {
101   (void) downCycles;
102   (void) downSel;
103   (void) upSel;
104 }
105 
CMU_CalibrateCountGet(void)106 uint32_t CMU_CalibrateCountGet(void)
107 {
108   return 0;
109 }
110 
CMU_ClockDivGet(CMU_Clock_TypeDef clock)111 CMU_ClkDiv_TypeDef CMU_ClockDivGet(CMU_Clock_TypeDef clock)
112 {
113   uint32_t ret = 0U;
114 
115   switch (clock) {
116     case cmuClock_HCLK:
117     case cmuClock_CORE:
118       ret = (CMU->SYSCLKCTRL & _CMU_SYSCLKCTRL_HCLKPRESC_MASK)
119             >> _CMU_SYSCLKCTRL_HCLKPRESC_SHIFT;
120       if (ret == 2U ) {   // Unused value, illegal prescaler
121         EFM_ASSERT(false);
122       }
123       break;
124 
125     case cmuClock_EXPCLK:
126       ret = (CMU->EXPORTCLKCTRL & _CMU_EXPORTCLKCTRL_PRESC_MASK)
127             >> _CMU_EXPORTCLKCTRL_PRESC_SHIFT;
128       break;
129 
130     case cmuClock_PCLK:
131       ret = (CMU->SYSCLKCTRL & _CMU_SYSCLKCTRL_PCLKPRESC_MASK)
132             >> _CMU_SYSCLKCTRL_PCLKPRESC_SHIFT;
133       break;
134 
135     default:
136       EFM_ASSERT(false);
137       break;
138   }
139   return 1U + ret;
140 }
141 
CMU_ClockDivSet(CMU_Clock_TypeDef clock,CMU_ClkDiv_TypeDef div)142 void CMU_ClockDivSet(CMU_Clock_TypeDef clock, CMU_ClkDiv_TypeDef div)
143 {
144   (void) clock;
145   (void) div;
146 }
147 
CMU_ClockEnable(CMU_Clock_TypeDef clock,bool enable)148 void CMU_ClockEnable(CMU_Clock_TypeDef clock, bool enable)
149 {
150   (void) clock;
151   (void) enable;
152 }
153 
CMU_ClockFreqGet(CMU_Clock_TypeDef clock)154 uint32_t CMU_ClockFreqGet(CMU_Clock_TypeDef clock)
155 {
156   uint32_t freq = 0;
157   switch (clock) {
158     case cmuClock_SYSCLK:
159     case cmuClock_HCLK:
160     case cmuClock_LSPCLK:
161     case cmuClock_EXPCLK:
162     case cmuClock_EM01GRPACLK:
163     case cmuClock_EM23GRPACLK:
164     case cmuClock_EM4GRPACLK:
165     case cmuClock_WDOG0CLK:
166 #if defined(_CMU_TRACECLKCTRL_MASK)
167     case cmuClock_DPLLREFCLK:
168 #endif
169 #if defined(_CMU_TRACECLKCTRL_MASK)
170     case cmuClock_TRACECLK:
171 #endif
172     case cmuClock_ACMP0:
173     case cmuClock_ACMP1:
174     case cmuClock_CORE:
175     case cmuClock_GPCRC:
176     case cmuClock_GPIO:
177     case cmuClock_LDMA:
178     case cmuClock_PRS:
179     case cmuClock_TIMER0:
180     case cmuClock_TIMER1:
181     case cmuClock_TIMER2:
182     case cmuClock_TIMER3:
183     case cmuClock_TIMER4:
184 #if defined(cmuClock_TIMER7)
185     case cmuClock_TIMER5:
186     case cmuClock_TIMER6:
187     case cmuClock_TIMER7:
188 #endif
189     case cmuClock_BURAM:
190     case cmuClock_KEYSCAN:
191 #if defined(USART0)
192     case cmuClock_USART0:
193 #endif
194 #if defined(USART1)
195     case cmuClock_USART1:
196 #endif
197 #if defined(USART2)
198     case cmuClock_USART2:
199 #endif
200       return Get_Fpga_Core_freq();
201     case cmuClock_IADC0:
202       return 40000000u; // Hard coded to pass test
203     case cmuClock_PCLK:
204 #if defined(INCLUDE_I2C_TEST)
205       return 28000000u;// Hard coded to pass I2C test
206 #else
207       return Get_Fpga_Core_freq(); // actual frequency.
208 #endif
209     case cmuClock_I2C0:
210     case cmuClock_I2C1:
211       return 28000000u; // Hard coded to pass test
212     case cmuClock_LETIMER0:
213     case cmuClock_RTCC:
214     case cmuClock_SYSRTC:
215     case cmuClock_SYSTICK:
216     case cmuClock_WDOG0:
217     case cmuClock_LESENSE:
218       return LFRCO_CLK_FREQ;
219     case cmuClock_BURTC:
220 #if defined(ETAMPDET_PRESENT)
221     case cmuClock_ETAMPDET:
222 #endif
223 #if defined(WDOG1)
224     case cmuClock_WDOG1:
225 #endif
226       return ULFRCO_CLK_FREQ;
227 #if defined(EUART0)
228     case cmuClock_EUART0:
229       switch (cmu_euart0_clk_source) {
230         case cmuSelect_EM01GRPACLK:
231           freq = HFRCO_CLK_FREQ;
232           break;
233         case cmuSelect_EM23GRPACLK:
234           freq = LFRCO_CLK_FREQ;
235           break;
236         case cmuSelect_ULFRCO:
237           freq = ULFRCO_CLK_FREQ;
238           break;
239         case cmuSelect_HFRCODPLL:
240           freq = HFRCO_CLK_FREQ;
241           break;
242         default:
243           EFM_ASSERT(0);
244           break;
245       }
246       return freq;
247 #endif
248 #if defined(EUSART0)
249     case cmuClock_EUSART0:
250       switch (cmu_eusart0_clk_source) {
251         case cmuSelect_EM01GRPACLK:
252         case cmuSelect_EM01GRPCCLK:
253           freq = Get_Fpga_Core_freq();
254           break;
255         case cmuSelect_EM23GRPACLK:       // This is for Lynx
256 #if defined(LFRCO_PRESENT)
257         case cmuSelect_LFRCO:             // This is for Ocelot/Bobcat
258           freq = LFRCO_CLK_FREQ;
259           break;
260 #endif
261         case cmuSelect_ULFRCO:
262           freq = ULFRCO_CLK_FREQ;
263           break;
264         case cmuSelect_HFRCO:
265         case cmuSelect_HFRCODPLL:
266 #if defined(HFRCOEM23_PRESENT)
267         case cmuSelect_HFRCOEM23:
268 #endif
269           freq = Get_Fpga_Core_freq();
270           break;
271         default:
272           EFM_ASSERT(0);
273           break;
274       }
275       return freq;
276 #endif
277 
278     default:
279       return Get_Fpga_Core_freq();
280   }
281 }
282 
CMU_ClockSelectGet(CMU_Clock_TypeDef clock)283 CMU_Select_TypeDef CMU_ClockSelectGet(CMU_Clock_TypeDef clock)
284 {
285   CMU_Select_TypeDef clock_source = (CMU_Select_TypeDef) 0;
286 
287   switch (clock) {
288 #if defined(EUART0)
289     case cmuClock_EUART0:
290       if (cmu_euart0_clk_source == cmuSelect_EM01GRPACLK) {
291         clock_source = cmuSelect_HFRCO;
292       } else if (cmu_euart0_clk_source == cmuSelect_EM23GRPACLK) {
293         clock_source = cmuSelect_LFRCO;
294       }
295       break;
296 #endif
297 #if defined(EUSART0)
298     case cmuClock_EUSART0:
299       clock_source = cmu_eusart0_clk_source;
300       break;
301 #endif
302 #if defined(EUSART1)
303     case cmuClock_EUSART1:
304       clock_source = cmu_eusart1_clk_source;
305       break;
306 #endif
307 #if defined(EUSART2)
308     case cmuClock_EUSART2:
309       clock_source = cmu_eusart2_clk_source;
310       break;
311 #endif
312 #if defined(EUSART3)
313     case cmuClock_EUSART3:
314       clock_source = cmu_eusart3_clk_source;
315       break;
316 #endif
317 #ifdef EUSART4
318     case cmuClock_EUSART4:
319       clock_source = cmu_eusart4_clk_source;
320       break;
321 #endif
322     default:
323       clock_source = cmuSelect_HFRCO;
324       break;
325   }
326 
327   return clock_source;
328 }
329 
CMU_ClockSelectSet(CMU_Clock_TypeDef clock,CMU_Select_TypeDef ref)330 void CMU_ClockSelectSet(CMU_Clock_TypeDef clock, CMU_Select_TypeDef ref)
331 {
332   switch (clock) {
333 #if defined(EUART0)
334     case cmuClock_EUART0:
335       cmu_euart0_clk_source = ref;
336       break;
337 #endif
338 #if defined(EUSART0)
339     case cmuClock_EUSART0:
340     case cmuClock_EUSART0CLK:
341     case cmuClock_EM01GRPCCLK:
342       cmu_eusart0_clk_source = ref;
343       break;
344 #endif
345 #if defined(EUSART1)
346     case cmuClock_EUSART1:
347       cmu_eusart1_clk_source = ref;
348       break;
349 #endif
350 #if defined(EUSART2)
351     case cmuClock_EUSART2:
352       cmu_eusart2_clk_source = ref;
353       break;
354 #endif
355 #if defined(EUSART3)
356     case cmuClock_EUSART3:
357       cmu_eusart3_clk_source = ref;
358       break;
359 #endif
360 #ifdef EUSART4
361     case cmuClock_EUSART4:
362       cmu_eusart4_clk_source = ref;
363       break;
364 #endif
365     default:
366       break;
367   }
368 }
369 
CMU_FreezeEnable(bool enable)370 void CMU_FreezeEnable(bool enable)
371 {
372   (void) enable;
373 }
374 
CMU_HFRCOBandGet(void)375 CMU_HFRCOFreq_TypeDef CMU_HFRCOBandGet(void)
376 {
377   return (CMU_HFRCOFreq_TypeDef) Get_Fpga_Core_freq();
378 }
379 
CMU_HFRCOBandSet(CMU_HFRCOFreq_TypeDef setFreq)380 void CMU_HFRCOBandSet(CMU_HFRCOFreq_TypeDef setFreq)
381 {
382   (void) setFreq;
383 }
384 
CMU_HFRCODPLLBandGet(void)385 CMU_HFRCODPLLFreq_TypeDef  CMU_HFRCODPLLBandGet(void)
386 {
387   return (CMU_HFRCODPLLFreq_TypeDef) Get_Fpga_Core_freq();
388 }
389 
CMU_HFRCODPLLBandSet(CMU_HFRCODPLLFreq_TypeDef setFreq)390 void CMU_HFRCODPLLBandSet(CMU_HFRCODPLLFreq_TypeDef setFreq)
391 {
392   (void) setFreq;
393 }
394 
CMU_HFXOInit(const CMU_HFXOInit_TypeDef * hfxoInit)395 void CMU_HFXOInit(const CMU_HFXOInit_TypeDef *hfxoInit)
396 {
397   (void) hfxoInit;
398 }
399 
CMU_HFXOCTuneSet(uint32_t ctune)400 void CMU_HFXOCTuneSet(uint32_t ctune)
401 {
402   (void) ctune; /* Unused parameter */
403 }
404 
CMU_HFXOCTuneGet(void)405 uint32_t CMU_HFXOCTuneGet(void)
406 {
407   return 0;
408 }
409 
CMU_HFXOCTuneDeltaSet(int32_t delta)410 void CMU_HFXOCTuneDeltaSet(int32_t delta)
411 {
412   (void) delta; /* Unused parameter */
413 }
414 
CMU_HFXOCTuneDeltaGet(void)415 int32_t CMU_HFXOCTuneDeltaGet(void)
416 {
417   return 0;
418 }
419 
CMU_LCDClkFDIVGet(void)420 uint32_t CMU_LCDClkFDIVGet(void)
421 {
422   return 0;
423 }
424 
CMU_LCDClkFDIVSet(uint32_t div)425 void CMU_LCDClkFDIVSet(uint32_t div)
426 {
427   (void)div;  /* Unused parameter */
428 }
429 
CMU_LFXOInit(const CMU_LFXOInit_TypeDef * lfxoInit)430 void CMU_LFXOInit(const CMU_LFXOInit_TypeDef *lfxoInit)
431 {
432   (void) lfxoInit;
433 }
434 
CMU_OscillatorEnable(CMU_Osc_TypeDef osc,bool enable,bool wait)435 void CMU_OscillatorEnable(CMU_Osc_TypeDef osc, bool enable, bool wait)
436 {
437   (void) osc;
438   (void) enable;
439   (void) wait;
440 }
441 
CMU_OscillatorTuningGet(CMU_Osc_TypeDef osc)442 uint32_t CMU_OscillatorTuningGet(CMU_Osc_TypeDef osc)
443 {
444   (void) osc;
445   return 0;
446 }
447 
CMU_OscillatorTuningSet(CMU_Osc_TypeDef osc,uint32_t val)448 void CMU_OscillatorTuningSet(CMU_Osc_TypeDef osc, uint32_t val)
449 {
450   (void) osc;
451   (void) val;
452 }
453 
CMU_PCNTClockExternalGet(unsigned int instance)454 bool CMU_PCNTClockExternalGet(unsigned int instance)
455 {
456   (void) instance;
457   return false;
458 }
459 
CMU_PCNTClockExternalSet(unsigned int instance,bool external)460 void CMU_PCNTClockExternalSet(unsigned int instance, bool external)
461 {
462   (void)instance;  /* Unused parameter */
463   (void)external;  /* Unused parameter */
464 }
465 
CMU_UpdateWaitStates(uint32_t freq,int vscale)466 void CMU_UpdateWaitStates(uint32_t freq, int vscale)
467 {
468   (void)freq;
469   (void)vscale;
470 }
471 
CMU_LFXOPrecisionSet(uint16_t precision)472 void CMU_LFXOPrecisionSet(uint16_t precision)
473 {
474   (void)precision;
475 }
476 
477 /** @} (end addtogroup CMU) */
478 /** @} (end addtogroup emlib) */
479 #endif /* defined(CMU_PRESENT) && defined(FPGA) */
480