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_fpga.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 / 8;
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_SYSTICK:
215     case cmuClock_WDOG0:
216     case cmuClock_LESENSE:
217       return LFRCO_CLK_FREQ;
218     case cmuClock_SYSRTC:
219       // Fix for sleeptimer running on TIMER0. Clock enum not in sync with
220       // em_cmu.h !
221       return Get_Fpga_Core_freq();
222     case cmuClock_BURTC:
223 #if defined(ETAMPDET_PRESENT)
224     case cmuClock_ETAMPDET:
225 #endif
226 #if defined(WDOG1)
227     case cmuClock_WDOG1:
228 #endif
229       return ULFRCO_CLK_FREQ;
230 #if defined(EUART0)
231     case cmuClock_EUART0:
232       switch (cmu_euart0_clk_source) {
233         case cmuSelect_EM01GRPACLK:
234           freq = HFRCO_CLK_FREQ;
235           break;
236         case cmuSelect_EM23GRPACLK:
237           freq = LFRCO_CLK_FREQ;
238           break;
239         case cmuSelect_ULFRCO:
240           freq = ULFRCO_CLK_FREQ;
241           break;
242         case cmuSelect_HFRCODPLL:
243           freq = HFRCO_CLK_FREQ;
244           break;
245         default:
246           EFM_ASSERT(0);
247           break;
248       }
249       return freq;
250 #endif
251 #if defined(EUSART0)
252     case cmuClock_EUSART0:
253       switch (cmu_eusart0_clk_source) {
254         case cmuSelect_EM01GRPACLK:
255         case cmuSelect_EM01GRPCCLK:
256           freq = Get_Fpga_Core_freq();
257           break;
258         case cmuSelect_EM23GRPACLK:       // This is for Lynx
259 #if defined(LFRCO_PRESENT)
260         case cmuSelect_LFRCO:             // This is for Ocelot/Bobcat
261           freq = LFRCO_CLK_FREQ;
262           break;
263 #endif
264         case cmuSelect_ULFRCO:
265           freq = ULFRCO_CLK_FREQ;
266           break;
267         case cmuSelect_HFRCO:
268         case cmuSelect_HFRCODPLL:
269 #if defined(HFRCOEM23_PRESENT)
270         case cmuSelect_HFRCOEM23:
271 #endif
272           freq = Get_Fpga_Core_freq();
273           break;
274         default:
275           EFM_ASSERT(0);
276           break;
277       }
278       return freq;
279 #endif
280 
281     default:
282       return Get_Fpga_Core_freq();
283   }
284 }
285 
CMU_ClockSelectGet(CMU_Clock_TypeDef clock)286 CMU_Select_TypeDef CMU_ClockSelectGet(CMU_Clock_TypeDef clock)
287 {
288   CMU_Select_TypeDef clock_source = (CMU_Select_TypeDef) 0;
289 
290   switch (clock) {
291 #if defined(EUART0)
292     case cmuClock_EUART0:
293       if (cmu_euart0_clk_source == cmuSelect_EM01GRPACLK) {
294         clock_source = cmuSelect_HFRCO;
295       } else if (cmu_euart0_clk_source == cmuSelect_EM23GRPACLK) {
296         clock_source = cmuSelect_LFRCO;
297       }
298       break;
299 #endif
300 #if defined(EUSART0)
301     case cmuClock_EUSART0:
302       clock_source = cmu_eusart0_clk_source;
303       break;
304 #endif
305 #if defined(EUSART1)
306     case cmuClock_EUSART1:
307       clock_source = cmu_eusart1_clk_source;
308       break;
309 #endif
310 #if defined(EUSART2)
311     case cmuClock_EUSART2:
312       clock_source = cmu_eusart2_clk_source;
313       break;
314 #endif
315 #if defined(EUSART3)
316     case cmuClock_EUSART3:
317       clock_source = cmu_eusart3_clk_source;
318       break;
319 #endif
320 #ifdef EUSART4
321     case cmuClock_EUSART4:
322       clock_source = cmu_eusart4_clk_source;
323       break;
324 #endif
325     default:
326       clock_source = cmuSelect_HFRCO;
327       break;
328   }
329 
330   return clock_source;
331 }
332 
CMU_ClockSelectSet(CMU_Clock_TypeDef clock,CMU_Select_TypeDef ref)333 void CMU_ClockSelectSet(CMU_Clock_TypeDef clock, CMU_Select_TypeDef ref)
334 {
335   switch (clock) {
336 #if defined(EUART0)
337     case cmuClock_EUART0:
338       cmu_euart0_clk_source = ref;
339       break;
340 #endif
341 #if defined(EUSART0)
342     case cmuClock_EUSART0:
343     case cmuClock_EUSART0CLK:
344     case cmuClock_EM01GRPCCLK:
345       cmu_eusart0_clk_source = ref;
346       break;
347 #endif
348 #if defined(EUSART1)
349     case cmuClock_EUSART1:
350       cmu_eusart1_clk_source = ref;
351       break;
352 #endif
353 #if defined(EUSART2)
354     case cmuClock_EUSART2:
355       cmu_eusart2_clk_source = ref;
356       break;
357 #endif
358 #if defined(EUSART3)
359     case cmuClock_EUSART3:
360       cmu_eusart3_clk_source = ref;
361       break;
362 #endif
363 #ifdef EUSART4
364     case cmuClock_EUSART4:
365       cmu_eusart4_clk_source = ref;
366       break;
367 #endif
368     default:
369       break;
370   }
371 }
372 
CMU_FreezeEnable(bool enable)373 void CMU_FreezeEnable(bool enable)
374 {
375   (void) enable;
376 }
377 
CMU_HFRCOBandGet(void)378 CMU_HFRCOFreq_TypeDef CMU_HFRCOBandGet(void)
379 {
380   return (CMU_HFRCOFreq_TypeDef) Get_Fpga_Core_freq();
381 }
382 
CMU_HFRCOBandSet(CMU_HFRCOFreq_TypeDef setFreq)383 void CMU_HFRCOBandSet(CMU_HFRCOFreq_TypeDef setFreq)
384 {
385   (void) setFreq;
386 }
387 
CMU_HFRCODPLLBandGet(void)388 CMU_HFRCODPLLFreq_TypeDef  CMU_HFRCODPLLBandGet(void)
389 {
390   return (CMU_HFRCODPLLFreq_TypeDef) Get_Fpga_Core_freq();
391 }
392 
CMU_HFRCODPLLBandSet(CMU_HFRCODPLLFreq_TypeDef setFreq)393 void CMU_HFRCODPLLBandSet(CMU_HFRCODPLLFreq_TypeDef setFreq)
394 {
395   (void) setFreq;
396 }
397 
CMU_HFXOInit(const CMU_HFXOInit_TypeDef * hfxoInit)398 void CMU_HFXOInit(const CMU_HFXOInit_TypeDef *hfxoInit)
399 {
400   (void) hfxoInit;
401 }
402 
CMU_HFXOCTuneSet(uint32_t ctune)403 void CMU_HFXOCTuneSet(uint32_t ctune)
404 {
405   (void) ctune; /* Unused parameter */
406 }
407 
CMU_HFXOCTuneGet(void)408 uint32_t CMU_HFXOCTuneGet(void)
409 {
410   return 0;
411 }
412 
CMU_HFXOCTuneDeltaSet(int32_t delta)413 void CMU_HFXOCTuneDeltaSet(int32_t delta)
414 {
415   (void) delta; /* Unused parameter */
416 }
417 
CMU_HFXOCTuneDeltaGet(void)418 int32_t CMU_HFXOCTuneDeltaGet(void)
419 {
420   return 0;
421 }
422 
CMU_LCDClkFDIVGet(void)423 uint32_t CMU_LCDClkFDIVGet(void)
424 {
425   return 0;
426 }
427 
CMU_LCDClkFDIVSet(uint32_t div)428 void CMU_LCDClkFDIVSet(uint32_t div)
429 {
430   (void)div;  /* Unused parameter */
431 }
432 
CMU_LFXOInit(const CMU_LFXOInit_TypeDef * lfxoInit)433 void CMU_LFXOInit(const CMU_LFXOInit_TypeDef *lfxoInit)
434 {
435   (void) lfxoInit;
436 }
437 
CMU_OscillatorEnable(CMU_Osc_TypeDef osc,bool enable,bool wait)438 void CMU_OscillatorEnable(CMU_Osc_TypeDef osc, bool enable, bool wait)
439 {
440   (void) osc;
441   (void) enable;
442   (void) wait;
443 }
444 
CMU_OscillatorTuningGet(CMU_Osc_TypeDef osc)445 uint32_t CMU_OscillatorTuningGet(CMU_Osc_TypeDef osc)
446 {
447   (void) osc;
448   return 0;
449 }
450 
CMU_OscillatorTuningSet(CMU_Osc_TypeDef osc,uint32_t val)451 void CMU_OscillatorTuningSet(CMU_Osc_TypeDef osc, uint32_t val)
452 {
453   (void) osc;
454   (void) val;
455 }
456 
CMU_PCNTClockExternalGet(unsigned int instance)457 bool CMU_PCNTClockExternalGet(unsigned int instance)
458 {
459   (void) instance;
460   return false;
461 }
462 
CMU_PCNTClockExternalSet(unsigned int instance,bool external)463 void CMU_PCNTClockExternalSet(unsigned int instance, bool external)
464 {
465   (void)instance;  /* Unused parameter */
466   (void)external;  /* Unused parameter */
467 }
468 
CMU_UpdateWaitStates(uint32_t freq,int vscale)469 void CMU_UpdateWaitStates(uint32_t freq, int vscale)
470 {
471   (void)freq;
472   (void)vscale;
473 }
474 
CMU_LFXOPrecisionSet(uint16_t precision)475 void CMU_LFXOPrecisionSet(uint16_t precision)
476 {
477   (void)precision;
478 }
479 
480 /** @} (end addtogroup CMU) */
481 /** @} (end addtogroup emlib) */
482 #endif /* defined(CMU_PRESENT) && defined(FPGA) */
483