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