1 /***************************************************************************//** 2 * @file 3 * @brief System Peripheral API 4 ******************************************************************************* 5 * # License 6 * <b>Copyright 2018 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 "em_system.h" 32 #include "sl_assert.h" 33 #include <stddef.h> 34 #if defined(SYSCFG_PRESENT) 35 #include "em_syscfg.h" 36 #endif 37 /***************************************************************************//** 38 * @addtogroup system 39 * @{ 40 ******************************************************************************/ 41 42 /******************************************************************************* 43 ********************************* DEFINES ********************************* 44 ******************************************************************************/ 45 46 /** @cond DO_NOT_INCLUDE_WITH_DOXYGEN */ 47 48 /* Bit mask used to extract the part number value without the new naming 49 * bitfield. */ 50 #define SYSCFG_CHIPREV_PARTNUMBER1 0xFE0 51 #define SYSCFG_CHIPREV_PARTNUMBER0 0xF 52 53 /* Bit mask to convert NON-SECURE to SECURE */ 54 #define CONVERT_NS_TO_S (~(1 << 28U)) 55 56 /** @endcond */ 57 58 /******************************************************************************* 59 ************************** GLOBAL FUNCTIONS ******************************* 60 ******************************************************************************/ 61 62 /***************************************************************************//** 63 * @brief 64 * Get a chip major/minor revision. 65 * 66 * @param[out] rev 67 * A location to place the chip revision information. 68 ******************************************************************************/ SYSTEM_ChipRevisionGet(SYSTEM_ChipRevision_TypeDef * rev)69void SYSTEM_ChipRevisionGet(SYSTEM_ChipRevision_TypeDef *rev) 70 { 71 #if defined(_SYSCFG_CHIPREV_FAMILY_MASK) || defined(_SYSCFG_CHIPREV_PARTNUMBER_MASK) 72 /* On series-2 (and higher) the revision info is in the SYSCFG->CHIPREV register. */ 73 #if defined(CMU_CLKEN0_SYSCFG) 74 CMU->CLKEN0_SET = CMU_CLKEN0_SYSCFG; 75 #endif 76 uint32_t chiprev = SYSCFG_readChipRev(); 77 #if defined(_SYSCFG_CHIPREV_PARTNUMBER_MASK) 78 rev->partNumber = ((chiprev & SYSCFG_CHIPREV_PARTNUMBER1) >> 5) | (chiprev & SYSCFG_CHIPREV_PARTNUMBER0); 79 #else 80 rev->family = (chiprev & _SYSCFG_CHIPREV_FAMILY_MASK) >> _SYSCFG_CHIPREV_FAMILY_SHIFT; 81 #endif 82 rev->major = (chiprev & _SYSCFG_CHIPREV_MAJOR_MASK) >> _SYSCFG_CHIPREV_MAJOR_SHIFT; 83 rev->minor = (chiprev & _SYSCFG_CHIPREV_MINOR_MASK) >> _SYSCFG_CHIPREV_MINOR_SHIFT; 84 #else 85 uint8_t tmp; 86 87 EFM_ASSERT(rev); 88 89 /* CHIP FAMILY bit [5:2] */ 90 tmp = (uint8_t)(((ROMTABLE->PID1 & _ROMTABLE_PID1_FAMILYMSB_MASK) 91 >> _ROMTABLE_PID1_FAMILYMSB_SHIFT) << 2); 92 /* CHIP FAMILY bit [1:0] */ 93 tmp |= (uint8_t)((ROMTABLE->PID0 & _ROMTABLE_PID0_FAMILYLSB_MASK) 94 >> _ROMTABLE_PID0_FAMILYLSB_SHIFT); 95 rev->family = tmp; 96 97 /* CHIP MAJOR bit [3:0] */ 98 rev->major = (uint8_t)((ROMTABLE->PID0 & _ROMTABLE_PID0_REVMAJOR_MASK) 99 >> _ROMTABLE_PID0_REVMAJOR_SHIFT); 100 101 /* CHIP MINOR bit [7:4] */ 102 tmp = (uint8_t)(((ROMTABLE->PID2 & _ROMTABLE_PID2_REVMINORMSB_MASK) 103 >> _ROMTABLE_PID2_REVMINORMSB_SHIFT) << 4); 104 /* CHIP MINOR bit [3:0] */ 105 tmp |= (uint8_t)((ROMTABLE->PID3 & _ROMTABLE_PID3_REVMINORLSB_MASK) 106 >> _ROMTABLE_PID3_REVMINORLSB_SHIFT); 107 rev->minor = tmp; 108 #endif 109 } 110 111 /***************************************************************************//** 112 * @brief 113 * Get a factory calibration value for a given peripheral register. 114 * 115 * @param[in] regAddress 116 * The peripheral calibration register address to get a calibration value for. If 117 * the calibration value is found, this register is updated with the 118 * calibration value. 119 * 120 * @return 121 * True if a calibration value exists, false otherwise. 122 ******************************************************************************/ SYSTEM_GetCalibrationValue(volatile uint32_t * regAddress)123bool SYSTEM_GetCalibrationValue(volatile uint32_t *regAddress) 124 { 125 SYSTEM_CalAddrVal_TypeDef * p, * end; 126 127 uint32_t s_regAddress = (uint32_t)regAddress; 128 s_regAddress = s_regAddress & CONVERT_NS_TO_S; 129 130 #if defined(MSC_FLASH_CHIPCONFIG_MEM_BASE) 131 p = (SYSTEM_CalAddrVal_TypeDef *)MSC_FLASH_CHIPCONFIG_MEM_BASE; 132 end = (SYSTEM_CalAddrVal_TypeDef *)MSC_FLASH_CHIPCONFIG_MEM_END; 133 #else 134 p = (SYSTEM_CalAddrVal_TypeDef *)(DEVINFO_BASE & 0xFFFFF000U); 135 end = (SYSTEM_CalAddrVal_TypeDef *)DEVINFO_BASE; 136 #endif 137 138 for (; p < end; p++) { 139 if (p->address == 0) { 140 /* p->address == 0 marks the end of the table */ 141 return false; 142 } 143 if (p->address == s_regAddress) { 144 *regAddress = p->calValue; 145 return true; 146 } 147 } 148 /* Nothing found for regAddress. */ 149 return false; 150 } 151 152 /***************************************************************************//** 153 * @brief 154 * Get family security capability. 155 * 156 * @note 157 * This function retrieves the family security capability based on the 158 * device number. The device number is one letter and 3 digits: 159 * DEVICENUMBER = (alpha-'A')*1000 + numeric. i.e. 0d = "A000"; 1123d = "B123". 160 * The security capabilities are represented by ::SYSTEM_SecurityCapability_TypeDef. 161 * 162 * @return 163 * Security capability of MCU. 164 ******************************************************************************/ SYSTEM_GetSecurityCapability(void)165SYSTEM_SecurityCapability_TypeDef SYSTEM_GetSecurityCapability(void) 166 { 167 SYSTEM_SecurityCapability_TypeDef sc; 168 169 #if (_SILICON_LABS_32B_SERIES == 0) 170 sc = securityCapabilityNA; 171 #elif (_SILICON_LABS_32B_SERIES == 1) 172 sc = securityCapabilityBasic; 173 #else 174 sc = securityCapabilityUnknown; 175 #endif 176 177 #if (_SILICON_LABS_32B_SERIES == 2) 178 uint16_t mcuFeatureSetMajor; 179 uint16_t deviceNumber; 180 deviceNumber = SYSTEM_GetPartNumber(); 181 mcuFeatureSetMajor = 'A' + (deviceNumber / 1000); 182 #if defined(_SILICON_LABS_32B_SERIES_2_CONFIG_2) 183 // override feature set since BRD4182A Rev A00 -> rev B02 are marked "A" 184 mcuFeatureSetMajor = 'C'; 185 #endif 186 187 switch (mcuFeatureSetMajor) { 188 case 'A': 189 sc = securityCapabilitySE; 190 break; 191 192 case 'B': 193 sc = securityCapabilityVault; 194 break; 195 196 case 'C': 197 sc = securityCapabilityRoT; 198 break; 199 200 default: 201 sc = securityCapabilityUnknown; 202 break; 203 } 204 #endif 205 206 return sc; 207 } 208 209 /** @} (end addtogroup system) */ 210