1 /***************************************************************************//**
2 * @file
3 * @brief Universal asynchronous receiver/transmitter (EUSART) peripheral API
4 *******************************************************************************
5 * # License
6 * <b>Copyright 2023 Silicon Laboratories Inc. www.silabs.com</b>
7 *******************************************************************************
8 *
9 * SPDX-License-Identifier: Zlib
10 *
11 * The licensor of this software is Silicon Laboratories Inc.
12 *
13 * This software is provided 'as-is', without any express or implied
14 * warranty. In no event will the authors be held liable for any damages
15 * arising from the use of this software.
16 *
17 * Permission is granted to anyone to use this software for any purpose,
18 * including commercial applications, and to alter it and redistribute it
19 * freely, subject to the following restrictions:
20 *
21 * 1. The origin of this software must not be misrepresented; you must not
22 * claim that you wrote the original software. If you use this software
23 * in a product, an acknowledgment in the product documentation would be
24 * appreciated but is not required.
25 * 2. Altered source versions must be plainly marked as such, and must not be
26 * misrepresented as being the original software.
27 * 3. This notice may not be removed or altered from any source distribution.
28 *
29 ******************************************************************************/
30
31 #include "sl_hal_system.h"
32 #include "sl_hal_syscfg.h"
33 #include "em_device.h"
34 #include <stdbool.h>
35 #if defined(_SILICON_LABS_32B_SERIES_3_CONFIG_301)
36 #include "sl_se_manager.h"
37 #include "sli_se_manager_device_data.h"
38 #endif
39 #include "sl_status.h"
40 #include "sl_assert.h"
41 /***************************************************************************//**
42 * @addtogroup system
43 * @{
44 ******************************************************************************/
45
46 /*******************************************************************************
47 ************************** DEFINES *******************************
48 ******************************************************************************/
49
50 /** @cond DO_NOT_INCLUDE_WITH_DOXYGEN */
51
52 /* Bit mask used to extract the part number value without the new naming
53 * bitfield. */
54 #define SYSCFG_CHIPREV_PARTNUMBER1 0xFE0
55 #define SYSCFG_CHIPREV_PARTNUMBER0 0xF
56
57 /** @endcond */
58
59 #define HFRCO_DPLL_FREQUENCY_TABLE_SIZE 11
60
61 #define DEVINFO_TEMPERATURE_CALTEMP_INTEGER_SHIFT 4
62
63 /*******************************************************************************
64 ******************************* TYPEDEF ***********************************
65 ******************************************************************************/
66
67 #if defined(_SILICON_LABS_32B_SERIES_3_CONFIG_301)
68 typedef struct hfrco_dpll_cal_element {
69 uint32_t min_freq;
70 uint32_t max_freq;
71 } hfrco_dpll_cal_element_t;
72 #endif
73
74 /*******************************************************************************
75 ****************************** CONSTANTS **********************************
76 ******************************************************************************/
77 const sl_hal_system_devinfo_adc_t SL_HAL_SYSTEM_DEVINFO_ADC_RESET_VALUES = {
78 .cal_data = {
79 .trim_vros0 = 0,
80 .trim_vros1 = 0,
81 .trim_gain_4x = 0,
82 .trim_gain_0x3_int = 0
83 },
84 .offset = {
85 .trim_off_1x = 0,
86 .trim_off_2x = 0,
87 .trim_off_4x = 0
88 }
89 };
90
91 const sl_hal_system_devinfo_temperature_t SL_HAL_SYSTEM_DEVINFO_TEMPERATURE_RESET_VALUES = {
92 .emu_temp_room = 0,
93 .cal_temp = 0
94 };
95
96 #if defined(_SILICON_LABS_32B_SERIES_3_CONFIG_301)
97 static const hfrco_dpll_cal_element_t HFRCO_DPLL_FREQUENCY_TABLE[HFRCO_DPLL_FREQUENCY_TABLE_SIZE] = {
98 { .min_freq = 16000000, .max_freq = 20000000 }, // 18MHz calibration central frequency
99 { .min_freq = 20000000, .max_freq = 24500000 }, // 22MHz calibration central frequency
100 { .min_freq = 24500000, .max_freq = 30000000 }, // 27MHz calibration central frequency
101 { .min_freq = 30000000, .max_freq = 36000000 }, // 33MHz calibration central frequency
102 { .min_freq = 36000000, .max_freq = 42500000 }, // 39MHz calibration central frequency
103 { .min_freq = 42500000, .max_freq = 50500000 }, // 46MHz calibration central frequency
104 { .min_freq = 50500000, .max_freq = 60000000 }, // 55MHz calibration central frequency
105 { .min_freq = 60000000, .max_freq = 70000000 }, // 65MHz calibration central frequency
106 { .min_freq = 70000000, .max_freq = 80000000 }, // 75MHz calibration central frequency
107 { .min_freq = 80000000, .max_freq = 90000000 }, // 85MHz calibration central frequency
108 { .min_freq = 90000000, .max_freq = 100000000 } // 95MHz calibration central frequency
109 };
110 #endif
111
112 /*******************************************************************************
113 ****************************** UTILITY *************************************
114 ******************************************************************************/
115
116 #if defined(_SILICON_LABS_32B_SERIES_2)
117 /***************************************************************************//**
118 * @brief Get the nth ASCII character of a specified number.
119 *
120 * @param[in] input_number
121 * The number where the digit will be taken.
122 *
123 * @param[in] position
124 * The digit position.
125 *
126 * @return
127 * The ASCII value of the specified digit.
128 ******************************************************************************/
sli_get_n_digit(uint16_t input_number,uint8_t position)129 char sli_get_n_digit(uint16_t input_number, uint8_t position)
130 {
131 uint32_t exp[] = { 10, 100, 1000, 10000, 100000 };
132 uint32_t number = input_number;
133
134 if (position > 4) {
135 EFM_ASSERT(false);
136 return '0';
137 }
138
139 number = (number % exp[position]);
140
141 if (position != 0) {
142 number = number / (exp[position - 1]);
143 }
144
145 return (char)number + '0';
146 }
147 #endif
148
149 #if defined(_DEVINFO_PART0_DIECODE0_MASK) && defined(_SILICON_LABS_SECURITY_FEATURE_VAULT)
150 /***************************************************************************//**
151 * @brief Convert hexadecimal ASCII character to integer value.
152 *
153 * @param[in] character
154 * The character to be coverted to a number.
155 *
156 * @return
157 * The uint8_t value of the character given in parameter.
158 ******************************************************************************/
sli_hex_ascii_to_value(char character)159 uint8_t sli_hex_ascii_to_value(char character)
160 {
161 if (character >= '0' && character <= '9') {
162 return character - '0';
163 } else if (character >= 'A' && character <= 'F') {
164 return character - 'A';
165 }
166
167 return 0U;
168 }
169 #endif
170
171 /*******************************************************************************
172 ************************** GLOBAL FUNCTIONS *******************************
173 ******************************************************************************/
174
175 /*******************************************************************************
176 * @brief Get CHIPREV register.
177 ******************************************************************************/
sl_hal_system_get_chip_revision(sl_hal_system_chip_revision_t * rev)178 void sl_hal_system_get_chip_revision(sl_hal_system_chip_revision_t *rev)
179 {
180 #if defined(CMU_CLKEN0_SYSCFG)
181 CMU->CLKEN0_SET = CMU_CLKEN0_SYSCFG;
182 #endif
183
184 uint32_t chip_rev = sl_hal_syscfg_read_chip_rev();
185
186 rev->minor = (chip_rev & _SYSCFG_CHIPREV_MINOR_MASK) >> _SYSCFG_CHIPREV_MINOR_SHIFT;
187 rev->major = (chip_rev & _SYSCFG_CHIPREV_MAJOR_MASK) >> _SYSCFG_CHIPREV_MAJOR_SHIFT;
188 #if defined(_SYSCFG_CHIPREV_PARTNUMBER_MASK)
189 rev->part_number = ((chip_rev & SYSCFG_CHIPREV_PARTNUMBER1) >> 5) | (chip_rev & SYSCFG_CHIPREV_PARTNUMBER0);
190 rev->family = (uint16_t)0xFFFF;
191 #elif defined(_SYSCFG_CHIPREV_FAMILY_MASK)
192 rev->part_number = (uint16_t)0xFFFF;
193 rev->family = (chip_rev & _SYSCFG_CHIPREV_FAMILY_MASK) >> _SYSCFG_CHIPREV_FAMILY_SHIFT;
194 #else
195 #error No Chip Revision Part Number or Family
196 #endif
197 }
198
199 /***************************************************************************//**
200 * @brief Get the MCU family identifier.
201 ******************************************************************************/
sl_hal_system_get_family(void)202 sl_hal_system_part_family_t sl_hal_system_get_family(void)
203 {
204 #if defined(_DEVINFO_PART_FAMILY_MASK)
205 return (DEVINFO->PART & (_DEVINFO_PART_FAMILY_MASK
206 | _DEVINFO_PART_FAMILYNUM_MASK));
207 #else
208 return (DEVINFO->PART0 & (_DEVINFO_PART0_PROTOCOL_MASK
209 | _DEVINFO_PART0_SERIES_MASK
210 | _DEVINFO_PART0_DIECODE0_MASK));
211 #endif
212 }
213
214 /***************************************************************************//**
215 * @brief Get DEVINFO revision.
216 ******************************************************************************/
sl_hal_system_get_devinfo_rev(void)217 uint8_t sl_hal_system_get_devinfo_rev(void)
218 {
219 #if defined(_DEVINFO_INFO_DEVINFOREV_MASK)
220 return (uint8_t)((DEVINFO->INFO & _DEVINFO_INFO_DEVINFOREV_MASK)
221 >> _DEVINFO_INFO_DEVINFOREV_SHIFT);
222 #elif defined(_DEVINFO_REVISION_DEVINFOREV_MASK)
223 return (uint8_t)((DEVINFO->REVISION & _DEVINFO_REVISION_DEVINFOREV_MASK)
224 >> _DEVINFO_REVISION_DEVINFOREV_SHIFT);
225 #else
226 #error (sl_hal_system.c): Location of devinfo revision is not defined.
227 #endif
228 }
229
230 /***************************************************************************//**
231 * @brief Get the default factory calibration value for HFRCO oscillator.
232 ******************************************************************************/
sl_hal_system_get_hfrco_default_calibration(void)233 uint32_t sl_hal_system_get_hfrco_default_calibration(void)
234 {
235 #if defined(_DEVINFO_HFRCOCALDEFAULT_MASK)
236 return DEVINFO->HFRCOCALDEFAULT;
237 #else
238 return 0;
239 #endif
240 }
241
242 /***************************************************************************//**
243 * @brief Get the speed factory calibration value for HFRCO oscillator.
244 ******************************************************************************/
sl_hal_system_get_hfrco_speed_calibration(void)245 uint32_t sl_hal_system_get_hfrco_speed_calibration(void)
246 {
247 #if defined(_DEVINFO_HFRCOCALSPEED_MASK)
248 return DEVINFO->HFRCOCALSPEED;
249 #else
250 return 0;
251 #endif
252 }
253
254 /***************************************************************************//**
255 * @brief Get the HFRCO calibration based on the frequency band.
256 ******************************************************************************/
sl_hal_system_get_hfrcodpll_band_calibration(uint32_t frequency)257 uint32_t sl_hal_system_get_hfrcodpll_band_calibration(uint32_t frequency)
258 {
259 #if defined(_SILICON_LABS_32B_SERIES_3_CONFIG_301)
260 sl_status_t status;
261 uint8_t band_index = 0xFF;
262 sl_se_command_context_t se_command_ctx;
263 sli_se_device_data_t otp_section_id = (sli_se_device_data_t)(SLI_SE_DEVICE_DATA_DI0 + DEVINFO_GP_FRAGMENT_INDEX);
264 uint32_t offset;
265 uint32_t calibration_value = 0;
266
267 for (uint8_t i = 0; i < HFRCO_DPLL_FREQUENCY_TABLE_SIZE; i++) {
268 if ((frequency >= HFRCO_DPLL_FREQUENCY_TABLE[i].min_freq)
269 && (frequency <= HFRCO_DPLL_FREQUENCY_TABLE[i].max_freq)) {
270 band_index = i;
271 break;
272 }
273 }
274
275 if (band_index >= HFRCO_DPLL_FREQUENCY_TABLE_SIZE) {
276 return 0;
277 }
278
279 // Calculate memory offset based on the band index we want.
280 offset = (band_index * 4) + DEVINFO_GP_HFRCODPLLBAND0_OFFSET;
281
282 // Initialize command context
283 status = sl_se_init_command_context(&se_command_ctx);
284 if (status != SL_STATUS_OK) {
285 return 0;
286 }
287
288 // Send the SE command to retrieve the HFRCODPLL calibration for a given band from the DEVINFO OTP section
289 status = sli_se_device_data_read_word(&se_command_ctx, otp_section_id, offset, &calibration_value);
290 if (status != SL_STATUS_OK) {
291 return 0;
292 }
293
294 return calibration_value;
295 #else
296 (void)frequency;
297 return 0;
298 #endif
299 }
300
301 /***************************************************************************//**
302 * Get a factory calibration value for HFRCOCEM23 oscillator.
303 ******************************************************************************/
sl_hal_system_get_hfrcoem23_calibration(void)304 uint32_t sl_hal_system_get_hfrcoem23_calibration(void)
305 {
306 #if defined(_SILICON_LABS_32B_SERIES_3_CONFIG_301)
307 sl_status_t status;
308 sl_se_command_context_t se_command_ctx;
309 sli_se_device_data_t otp_section_id = (sli_se_device_data_t)(SLI_SE_DEVICE_DATA_DI0 + DEVINFO_GP_FRAGMENT_INDEX);
310 uint32_t offset = DEVINFO_GP_HFRCOEM23DEFAULT_OFFSET;
311 uint32_t calibration_value = 0;
312
313 // Initialize command context
314 status = sl_se_init_command_context(&se_command_ctx);
315 if (status != SL_STATUS_OK) {
316 return 0;
317 }
318
319 // Send the SE command to retrieve the HFRCOEM23 calibration from the DEVINFO OTP section
320 status = sli_se_device_data_read_word(&se_command_ctx, otp_section_id, offset, &calibration_value);
321 if (status != SL_STATUS_OK) {
322 return 0;
323 }
324
325 return calibration_value;
326 #else
327 return 0;
328 #endif
329 }
330
331 /***************************************************************************//**
332 * @brief Get a factory calibration value for HFXOCAL.
333 ******************************************************************************/
sl_hal_system_get_hfxocal(void)334 uint32_t sl_hal_system_get_hfxocal(void)
335 {
336 #if defined(_DEVINFO_HFXOCAL_MASK)
337 return DEVINFO->HFXOCAL;
338 #else
339 return 0;
340 #endif
341 }
342
343 /***************************************************************************//**
344 * @brief Get family security capability.
345 ******************************************************************************/
sl_hal_system_get_security_capability(void)346 sl_hal_system_security_capability_t sl_hal_system_get_security_capability(void)
347 {
348 sl_hal_system_security_capability_t sc = SL_SYSTEM_SECURITY_CAPABILITY_UNKNOWN;
349
350 uint16_t mcu_feature_set_major;
351 uint16_t device_number;
352 device_number = sl_hal_system_get_part_number();
353 mcu_feature_set_major = 'A' + (device_number / 1000);
354 #if defined(_SILICON_LABS_32B_SERIES_2_CONFIG_2)
355 // override feature set since BRD4182A Rev A00 -> rev B02 are marked "A"
356 mcu_feature_set_major = 'C';
357 #endif
358
359 switch (mcu_feature_set_major) {
360 case 'A':
361 sc = SL_SYSTEM_SECURITY_CAPABILITY_SE;
362 break;
363
364 case 'B':
365 sc = SL_SYSTEM_SECURITY_CAPABILITY_VAULT;
366 break;
367
368 case 'C':
369 sc = SL_SYSTEM_SECURITY_CAPABILITY_ROT;
370 break;
371
372 default:
373 sc = SL_SYSTEM_SECURITY_CAPABILITY_UNKNOWN;
374 break;
375 }
376
377 return sc;
378 }
379
380 /***************************************************************************//**
381 * @brief Get the unique number for this device.
382 ******************************************************************************/
sl_hal_system_get_unique(void)383 uint64_t sl_hal_system_get_unique(void)
384 {
385 uint32_t tmp = DEVINFO->EUI64L;
386 return ((uint64_t)DEVINFO->EUI64H << 32) | tmp;
387 }
388
389 /***************************************************************************//**
390 * @brief Get the production revision for this part.
391 ******************************************************************************/
sl_hal_system_get_prod_rev(void)392 uint8_t sl_hal_system_get_prod_rev(void)
393 {
394 #if defined(_DEVINFO_INFO_PRODREV_MASK)
395 return (uint8_t)((DEVINFO->INFO & _DEVINFO_INFO_PRODREV_MASK)
396 >> _DEVINFO_INFO_PRODREV_SHIFT);
397 #elif defined(_DEVINFO_REVISION_PRODREV_MASK)
398 return (uint8_t)((DEVINFO->REVISION & _DEVINFO_REVISION_PRODREV_MASK)
399 >> _DEVINFO_REVISION_PRODREV_SHIFT);
400 #else
401 #error (sl_hal_system.c): Location of production revision is not defined.
402 #endif
403 }
404
405 /***************************************************************************//**
406 * @brief Get the SRAM Base Address.
407 ******************************************************************************/
sl_hal_system_get_sram_base_address(void)408 uint32_t sl_hal_system_get_sram_base_address(void)
409 {
410 return SRAM_BASE;
411 }
412
413 /***************************************************************************//**
414 * @brief Get the SRAM size (in KB).
415 ******************************************************************************/
sl_hal_system_get_sram_size(void)416 uint16_t sl_hal_system_get_sram_size(void)
417 {
418 #if defined(_DEVINFO_MSIZE_SRAM_MASK)
419 return (uint16_t)((DEVINFO->MSIZE & _DEVINFO_MSIZE_SRAM_MASK)
420 >> _DEVINFO_MSIZE_SRAM_SHIFT);
421 #elif defined(_DEVINFO_EMBSIZE_RAM_MASK)
422 return (uint16_t)((DEVINFO->EMBSIZE & _DEVINFO_EMBSIZE_RAM_MASK)
423 >> _DEVINFO_EMBSIZE_RAM_SHIFT);
424 #else
425 #error (sl_hal_system.c): Location of SRAM Size is not defined.
426 #endif
427 }
428
429 /***************************************************************************//**
430 * @brief Get the flash size (in KB).
431 ******************************************************************************/
sl_hal_system_get_flash_size(void)432 uint16_t sl_hal_system_get_flash_size(void)
433 {
434 #if defined(_DEVINFO_MSIZE_FLASH_MASK)
435 return (uint16_t)((DEVINFO->MSIZE & _DEVINFO_MSIZE_FLASH_MASK)
436 >> _DEVINFO_MSIZE_FLASH_SHIFT);
437 #elif defined(_DEVINFO_STACKMSIZE_FLASH_MASK)
438 uint16_t stacked_flach_size = (uint16_t)((DEVINFO->STACKMSIZE & _DEVINFO_STACKMSIZE_FLASH_MASK)
439 >> _DEVINFO_STACKMSIZE_FLASH_SHIFT);
440
441 if (stacked_flach_size == 0) {
442 // Defined in linker script for external flash provided by customers.
443 extern uint32_t __flash_size__;
444 // Get flash size in kB.
445 stacked_flach_size = (uint16_t)(uintptr_t)&__flash_size__ / 1024;
446 }
447
448 return stacked_flach_size;
449 #endif
450 }
451
452 /***************************************************************************//**
453 * @brief Get the flash page size in bytes.
454 ******************************************************************************/
sl_hal_system_get_flash_page_size(void)455 uint32_t sl_hal_system_get_flash_page_size(void)
456 {
457 #if defined(_DEVINFO_MEMINFO_FLASHPAGESIZE_MASK)
458 uint32_t tmp;
459 tmp = (DEVINFO->MEMINFO & _DEVINFO_MEMINFO_FLASHPAGESIZE_MASK)
460 >> _DEVINFO_MEMINFO_FLASHPAGESIZE_SHIFT;
461 return 1UL << ((tmp + 10UL) & 0x1FUL);
462 #else
463 // Defined in linker script for external flash provided by customers.
464 extern uint32_t __flash_page_size__;
465 return (uintptr_t)&__flash_page_size__;
466 #endif
467 }
468
469 /***************************************************************************//**
470 * @brief Get the MCU part number.
471 ******************************************************************************/
sl_hal_system_get_part_number(void)472 uint16_t sl_hal_system_get_part_number(void)
473 {
474 #if defined(_DEVINFO_PART_DEVICENUM_MASK)
475 return (uint16_t)((DEVINFO->PART & _DEVINFO_PART_DEVICENUM_MASK)
476 >> _DEVINFO_PART_DEVICENUM_SHIFT);
477 #elif defined(_DEVINFO_PART0_DIECODE0_MASK) && defined(_SILICON_LABS_SECURITY_FEATURE_VAULT)
478 // Encode features to the series 2 format.
479 // Add security level vault high for SIxG301.
480 uint16_t device_number = 1000;
481 uint32_t register_value = (DEVINFO->PART1 & _DEVINFO_PART1_FEATURE1_MASK) >> _DEVINFO_PART1_FEATURE1_SHIFT;
482
483 device_number = sli_hex_ascii_to_value((char)register_value) * 100;
484
485 register_value = (DEVINFO->PART1 & _DEVINFO_PART1_FEATURE2_MASK) >> _DEVINFO_PART1_FEATURE2_SHIFT;
486 device_number += sli_hex_ascii_to_value((char)register_value) * 10;
487
488 register_value = (DEVINFO->PART2 & _DEVINFO_PART2_FEATURE3_MASK) >> _DEVINFO_PART2_FEATURE3_SHIFT;
489 device_number += sli_hex_ascii_to_value((char)register_value);
490
491 return device_number;
492 #else
493 #error (em_system.c): Location of device part number is not defined.
494 #endif
495 }
496
497 /***************************************************************************//**
498 * @brief Get the SoC or MCU features.
499 ******************************************************************************/
sl_hal_system_get_part_features(void)500 sl_hal_system_features_t sl_hal_system_get_part_features(void)
501 {
502 sl_hal_system_features_t part_features = { .feature1 = '0', .feature2 = '0', .feature3 = '0' };
503
504 #if defined(_SILICON_LABS_32B_SERIES_2)
505 uint16_t device_number = ((DEVINFO->PART & _DEVINFO_PART_DEVICENUM_MASK) >> _DEVINFO_PART_DEVICENUM_SHIFT);
506
507 part_features.feature1 = sli_get_n_digit(device_number, 2);
508 part_features.feature2 = sli_get_n_digit(device_number, 1);
509 part_features.feature3 = sli_get_n_digit(device_number, 0);
510
511 #elif defined(_SILICON_LABS_32B_SERIES_3)
512
513 part_features.feature1 = (DEVINFO->PART1 & _DEVINFO_PART1_FEATURE1_MASK) >> _DEVINFO_PART1_FEATURE1_SHIFT;
514 part_features.feature2 = (DEVINFO->PART1 & _DEVINFO_PART1_FEATURE2_MASK) >> _DEVINFO_PART1_FEATURE2_SHIFT;
515 part_features.feature3 = (DEVINFO->PART2 & _DEVINFO_PART2_FEATURE3_MASK) >> _DEVINFO_PART2_FEATURE3_SHIFT;
516
517 #else
518 #error Not defined for this die.
519 #endif
520
521 return part_features;
522 }
523
524 /***************************************************************************//**
525 * @brief Get the temperature information.
526 ******************************************************************************/
sl_hal_system_get_temperature_info(sl_hal_system_devinfo_temperature_t * info)527 void sl_hal_system_get_temperature_info(sl_hal_system_devinfo_temperature_t *info)
528 {
529 #if defined(_DEVINFO_CALTEMP_MASK) || defined(_DEVINFO_EMUTEMP_MASK)
530 #if defined(_DEVINFO_CALTEMP_TEMP_MASK)
531 info->cal_temp = ((DEVINFO->CALTEMP & _DEVINFO_CALTEMP_TEMP_MASK)
532 >> _DEVINFO_CALTEMP_TEMP_SHIFT);
533 #else
534 info->cal_temp = 0;
535 #endif
536 #if defined(_DEVINFO_EMUTEMP_EMUTEMPROOM_MASK)
537 info->emu_temp_room = ((DEVINFO->EMUTEMP & _DEVINFO_EMUTEMP_EMUTEMPROOM_MASK)
538 >> _DEVINFO_EMUTEMP_EMUTEMPROOM_SHIFT);
539 #else
540 info->emu_temp_room = 0;
541 #endif
542 #elif defined (_SILICON_LABS_32B_SERIES_3_CONFIG_301)
543 sl_status_t status;
544 sl_se_command_context_t se_command_ctx;
545 sli_se_device_data_t otp_section_id = (sli_se_device_data_t)(SLI_SE_DEVICE_DATA_DI0 + DEVINFO_GP_FRAGMENT_INDEX);
546 uint32_t offset = DEVINFO_GP_TEMPERATURE_OFFSET;
547
548 // Initialize command context
549 status = sl_se_init_command_context(&se_command_ctx);
550 if (status != SL_STATUS_OK) {
551 *info = SL_HAL_SYSTEM_DEVINFO_TEMPERATURE_RESET_VALUES;
552 return;
553 }
554
555 // Send the SE command to retrieve the temperature information from the DEVINFO OTP section
556 status = sli_se_device_data_read_word(&se_command_ctx, otp_section_id, offset, (uint32_t*)info);
557 if (status != SL_STATUS_OK) {
558 *info = SL_HAL_SYSTEM_DEVINFO_TEMPERATURE_RESET_VALUES;
559 return;
560 }
561
562 // Divide the temperature by 16 to retrieve only the integer part of the temperature value.
563 info->cal_temp = info->cal_temp >> DEVINFO_TEMPERATURE_CALTEMP_INTEGER_SHIFT;
564 #else
565 (void)info;
566 #endif
567 }
568
569 /*******************************************************************************
570 * @brief Reads CHIPREV register.
571 ******************************************************************************/
sl_hal_syscfg_read_chip_rev(void)572 uint32_t sl_hal_syscfg_read_chip_rev(void)
573 {
574 #if defined(SL_TRUSTZONE_NONSECURE)
575 return sli_tz_syscfg_read_chiprev_register();
576 #else
577 return SYSCFG->CHIPREV;
578 #endif
579 }
580
581 /*******************************************************************************
582 * @brief Set SYSTICEXTCLKEN bit in CFGSYSTIC to one.
583 ******************************************************************************/
sl_hal_syscfg_set_systicextclken_cfgsystic(void)584 void sl_hal_syscfg_set_systicextclken_cfgsystic(void)
585 {
586 #if defined(SL_TRUSTZONE_NONSECURE)
587 sli_tz_syscfg_set_systicextclken_cfgsystic();
588 #else
589 SYSCFG->CFGSYSTIC = (SYSCFG->CFGSYSTIC | _SYSCFG_CFGSYSTIC_SYSTICEXTCLKEN_MASK);
590 #endif
591 }
592
593 /*******************************************************************************
594 * @brief Clear SYSTICEXTCLKEN bit in CFGSYSTIC to zero.
595 ******************************************************************************/
sl_hal_syscfg_clear_systicextclken_cfgsystic(void)596 void sl_hal_syscfg_clear_systicextclken_cfgsystic(void)
597 {
598 #if defined(SL_TRUSTZONE_NONSECURE)
599 sli_tz_syscfg_clear_systicextclken_cfgsystic();
600 #else
601 SYSCFG->CFGSYSTIC = (SYSCFG->CFGSYSTIC & ~_SYSCFG_CFGSYSTIC_SYSTICEXTCLKEN_MASK);
602 #endif
603 }
604
605 #if defined(__FPU_PRESENT) && (__FPU_PRESENT == 1)
606 /***************************************************************************//**
607 * @brief Set floating point co-processor (FPU) access mode.
608 ******************************************************************************/
sl_hal_system_fpu_set_access_mode(sl_hal_system_fpu_access_t access_mode)609 void sl_hal_system_fpu_set_access_mode(sl_hal_system_fpu_access_t access_mode)
610 {
611 SCB->CPACR = (SCB->CPACR & ~(0xFUL << 20)) | access_mode;
612 }
613 #endif
614
615 /***************************************************************************//**
616 * @brief Get the ADC calibration info.
617 ******************************************************************************/
sl_hal_system_get_adc_calibration_info(sl_hal_system_devinfo_adc_t * info)618 void sl_hal_system_get_adc_calibration_info(sl_hal_system_devinfo_adc_t *info)
619 {
620 #if defined(_SILICON_LABS_32B_SERIES_3_CONFIG_301)
621 sl_status_t status;
622 sl_se_command_context_t se_command_ctx;
623 sli_se_device_data_t otp_section_id = (sli_se_device_data_t)(SLI_SE_DEVICE_DATA_DI0 + DEVINFO_GP_FRAGMENT_INDEX);
624 uint32_t offset = DEVINFO_GP_ADC0CALDATA_OFFSET;
625 EFM_ASSERT(info != NULL);
626
627 // Initialize command context
628 status = sl_se_init_command_context(&se_command_ctx);
629 if (status != SL_STATUS_OK) {
630 *info = SL_HAL_SYSTEM_DEVINFO_ADC_RESET_VALUES;
631 return;
632 }
633
634 // Send the SE command to retrieve the ADC calibration from the DEVINFO OTP section
635 status = sli_se_device_data_read_chunk(&se_command_ctx,
636 otp_section_id,
637 offset,
638 sizeof(sl_hal_system_devinfo_adc_offset_t),
639 info);
640 if (status != SL_STATUS_OK) {
641 *info = SL_HAL_SYSTEM_DEVINFO_ADC_RESET_VALUES;
642 return;
643 }
644 #else
645 *info = SL_HAL_SYSTEM_DEVINFO_ADC_RESET_VALUES;
646 #endif
647 }
648
649 /** @} (end addtogroup system) */
650