EFM32 Gecko Software Documentation  efm32g-doc-5.1.2
em_chip.h
Go to the documentation of this file.
1 /***************************************************************************/
33 #ifndef EM_CHIP_H
34 #define EM_CHIP_H
35 
36 #include "em_device.h"
37 #include "em_system.h"
38 #include "em_gpio.h"
39 #include "em_bus.h"
40 
41 #ifdef __cplusplus
42 extern "C" {
43 #endif
44 
45 /***************************************************************************/
50 /***************************************************************************/
58 /**************************************************************************/
70 __STATIC_INLINE void CHIP_Init(void)
71 {
72 #if defined(_SILICON_LABS_32B_SERIES_0) && defined(_EFM32_GECKO_FAMILY)
73  uint32_t rev;
75  volatile uint32_t *reg;
76 
77  rev = *(volatile uint32_t *)(0x0FE081FC);
78  /* Engineering Sample calibration setup */
79  if ((rev >> 24) == 0)
80  {
81  reg = (volatile uint32_t *)0x400CA00C;
82  *reg &= ~(0x70UL);
83  /* DREG */
84  reg = (volatile uint32_t *)0x400C6020;
85  *reg &= ~(0xE0000000UL);
86  *reg |= ~(7UL << 25);
87  }
88  if ((rev >> 24) <= 3)
89  {
90  /* DREG */
91  reg = (volatile uint32_t *)0x400C6020;
92  *reg &= ~(0x00001F80UL);
93  /* Update CMU reset values */
94  reg = (volatile uint32_t *)0x400C8040;
95  *reg = 0;
96  reg = (volatile uint32_t *)0x400C8044;
97  *reg = 0;
98  reg = (volatile uint32_t *)0x400C8058;
99  *reg = 0;
100  reg = (volatile uint32_t *)0x400C8060;
101  *reg = 0;
102  reg = (volatile uint32_t *)0x400C8078;
103  *reg = 0;
104  }
105 
106  SYSTEM_ChipRevisionGet(&chipRev);
107  if (chipRev.major == 0x01)
108  {
109  /* Rev A errata handling for EM2/3. Must enable DMA clock in order for EM2/3 */
110  /* to work. This will be fixed in later chip revisions, so only do for rev A. */
111  if (chipRev.minor == 00)
112  {
113  reg = (volatile uint32_t *)0x400C8040;
114  *reg |= 0x2;
115  }
116 
117  /* Rev A+B errata handling for I2C when using EM2/3. USART0 clock must be enabled */
118  /* after waking up from EM2/EM3 in order for I2C to work. This will be fixed in */
119  /* later chip revisions, so only do for rev A+B. */
120  if (chipRev.minor <= 0x01)
121  {
122  reg = (volatile uint32_t *)0x400C8044;
123  *reg |= 0x1;
124  }
125  }
126  /* Ensure correct ADC/DAC calibration value */
127  rev = *(volatile uint32_t *)0x0FE081F0;
128  if (rev < 0x4C8ABA00)
129  {
130  uint32_t cal;
131 
132  /* Enable ADC/DAC clocks */
133  reg = (volatile uint32_t *)0x400C8044UL;
134  *reg |= (1 << 14 | 1 << 11);
135 
136  /* Retrive calibration values */
137  cal = ((*(volatile uint32_t *)(0x0FE081B4UL) & 0x00007F00UL) >>
138  8) << 24;
139 
140  cal |= ((*(volatile uint32_t *)(0x0FE081B4UL) & 0x0000007FUL) >>
141  0) << 16;
142 
143  cal |= ((*(volatile uint32_t *)(0x0FE081B4UL) & 0x00007F00UL) >>
144  8) << 8;
145 
146  cal |= ((*(volatile uint32_t *)(0x0FE081B4UL) & 0x0000007FUL) >>
147  0) << 0;
148 
149  /* ADC0->CAL = 1.25 reference */
150  reg = (volatile uint32_t *)0x40002034UL;
151  *reg = cal;
152 
153  /* DAC0->CAL = 1.25 reference */
154  reg = (volatile uint32_t *)(0x4000402CUL);
155  cal = *(volatile uint32_t *)0x0FE081C8UL;
156  *reg = cal;
157 
158  /* Turn off ADC/DAC clocks */
159  reg = (volatile uint32_t *)0x400C8044UL;
160  *reg &= ~(1 << 14 | 1 << 11);
161  }
162 #endif
163 
164 #if defined(_SILICON_LABS_32B_SERIES_0) && defined(_EFM32_GIANT_FAMILY)
165 
166  /****************************/
167  /* Fix for errata CMU_E113. */
168 
169  uint8_t prodRev;
171 
172  prodRev = SYSTEM_GetProdRev();
173  SYSTEM_ChipRevisionGet(&chipRev);
174 
175  if ((prodRev >= 16) && (chipRev.minor >= 3))
176  {
177  /* This fixes an issue with the LFXO on high temperatures. */
178  *(volatile uint32_t*)0x400C80C0 =
179  ( *(volatile uint32_t*)0x400C80C0 & ~(1 << 6) ) | (1 << 4);
180  }
181 #endif
182 
183 #if defined(_SILICON_LABS_32B_SERIES_0) && defined(_EFM32_HAPPY_FAMILY)
184 
185  uint8_t prodRev;
186  prodRev = SYSTEM_GetProdRev();
187 
188  if (prodRev <= 129)
189  {
190  /* This fixes a mistaken internal connection between PC0 and PC4 */
191  /* This disables an internal pulldown on PC4 */
192  *(volatile uint32_t*)(0x400C6018) = (1 << 26) | (5 << 0);
193  /* This disables an internal LDO test signal driving PC4 */
194  *(volatile uint32_t*)(0x400C80E4) &= ~(1 << 24);
195  }
196 #endif
197 
198 #if defined(_SILICON_LABS_GECKO_INTERNAL_SDID_80)
199 
200  /****************************
201  * Fixes for errata GPIO_E201 (slewrate) and
202  * HFXO high temperature oscillator startup robustness fix */
203 
204  uint32_t port;
205  uint32_t clkEn;
206  uint8_t prodRev;
207  const uint32_t setVal = (0x5 << _GPIO_P_CTRL_SLEWRATEALT_SHIFT)
208  | (0x5 << _GPIO_P_CTRL_SLEWRATE_SHIFT);
209  const uint32_t resetVal = _GPIO_P_CTRL_RESETVALUE
210  & ~(_GPIO_P_CTRL_SLEWRATE_MASK
211  | _GPIO_P_CTRL_SLEWRATEALT_MASK);
212 
213  prodRev = SYSTEM_GetProdRev();
215  SYSTEM_ChipRevisionGet(&chipRev);
216 
217  /* This errata is fixed in hardware from PRODREV 0x8F. */
218  if (prodRev < 0x8F)
219  {
220  /* Fixes for errata GPIO_E201 (slewrate) */
221 
222  /* Save HFBUSCLK enable state and enable GPIO clock. */
223  clkEn = CMU->HFBUSCLKEN0;
224  CMU->HFBUSCLKEN0 = clkEn | CMU_HFBUSCLKEN0_GPIO;
225 
226  /* Update slewrate */
227  for(port = 0; port <= GPIO_PORT_MAX; port++)
228  {
229  GPIO->P[port].CTRL = setVal | resetVal;
230  }
231 
232  /* Restore HFBUSCLK enable state. */
233  CMU->HFBUSCLKEN0 = clkEn;
234  }
235 
236  /* This errata is fixed in hardware from PRODREV 0x90. */
237  if (prodRev < 0x90)
238  {
239  /* HFXO high temperature oscillator startup robustness fix */
240  CMU->HFXOSTARTUPCTRL =
241  (CMU->HFXOSTARTUPCTRL & ~_CMU_HFXOSTARTUPCTRL_IBTRIMXOCORE_MASK)
242  | (0x20 << _CMU_HFXOSTARTUPCTRL_IBTRIMXOCORE_SHIFT);
243  }
244 
245  if (chipRev.major == 0x01)
246  {
247  /* Fix for errata EMU_E210 - Potential Power-Down When Entering EM2 */
248  *(volatile uint32_t *)(EMU_BASE + 0x164) |= 0x4;
249  }
250 #endif
251 
252 #if defined(_SILICON_LABS_GECKO_INTERNAL_SDID_84)
253 
254  uint8_t prodRev = SYSTEM_GetProdRev();
255 
256  /* EM2 current fixes for early samples */
257  if (prodRev == 0)
258  {
259  *(volatile uint32_t *)(EMU_BASE + 0x190) = 0x0000ADE8UL;
260  *(volatile uint32_t *)(EMU_BASE + 0x198) |= (0x1 << 2);
261  *(volatile uint32_t *)(EMU_BASE + 0x190) = 0x0;
262  }
263  if (prodRev < 2)
264  {
265  *(volatile uint32_t *)(EMU_BASE + 0x164) |= (0x1 << 13);
266  }
267 
268  /* Set optimal LFRCOCTRL VREFUPDATE and enable duty cycling of vref */
269  CMU->LFRCOCTRL = (CMU->LFRCOCTRL & ~_CMU_LFRCOCTRL_VREFUPDATE_MASK)
270  | CMU_LFRCOCTRL_VREFUPDATE_64CYCLES
271  | CMU_LFRCOCTRL_ENVREF;
272 #endif
273 
274 #if defined(_EFR_DEVICE) && (_SILICON_LABS_GECKO_INTERNAL_SDID >= 84)
275  MSC->CTRL |= 0x1 << 8;
276 #endif
277 
278 
279 }
280 
284 #ifdef __cplusplus
285 }
286 #endif
287 
288 #endif /* EM_CHIP_H */
RAM and peripheral bit-field set and clear API.
void SYSTEM_ChipRevisionGet(SYSTEM_ChipRevision_TypeDef *rev)
Get chip major/minor revision.
Definition: em_system.c:58
__STATIC_INLINE void CHIP_Init(void)
Chip initialization routine for revision errata workarounds. This function must be called immediately...
Definition: em_chip.h:70
CMSIS Cortex-M Peripheral Access Layer for Silicon Laboratories microcontroller devices.
__STATIC_INLINE uint8_t SYSTEM_GetProdRev(void)
Get the production revision for this part.
Definition: em_system.h:303
#define EMU_BASE
#define MSC
General Purpose IO (GPIO) peripheral API.
#define GPIO
#define CMU
#define _GPIO_P_CTRL_RESETVALUE
Definition: efm32g_gpio.h:66
System API.