1 /***************************************************************************//**
2 * @file
3 * @brief Chip Initialization API
4 * @author Energy Micro AS
5 * @version 3.0.0
6 *******************************************************************************
7 * @section License
8 * <b>(C) Copyright 2012 Energy Micro AS, http://www.energymicro.com</b>
9 *******************************************************************************
10 *
11 * Permission is granted to anyone to use this software for any purpose,
12 * including commercial applications, and to alter it and redistribute it
13 * freely, subject to the following restrictions:
14 *
15 * 1. The origin of this software must not be misrepresented; you must not
16 * claim that you wrote the original software.
17 * 2. Altered source versions must be plainly marked as such, and must not be
18 * misrepresented as being the original software.
19 * 3. This notice may not be removed or altered from any source distribution.
20 *
21 * DISCLAIMER OF WARRANTY/LIMITATION OF REMEDIES: Energy Micro AS has no
22 * obligation to support this Software. Energy Micro AS is providing the
23 * Software "AS IS", with no express or implied warranties of any kind,
24 * including, but not limited to, any implied warranties of merchantability
25 * or fitness for any particular purpose or warranties against infringement
26 * of any proprietary rights of a third party.
27 *
28 * Energy Micro AS will not be liable for any consequential, incidental, or
29 * special damages, or any other relief, or for any claim by any third party,
30 * arising from your use of this Software.
31 *
32 ******************************************************************************/
33 #ifndef __EM_CHIP_H
34 #define __EM_CHIP_H
35
36 #include "em_part.h"
37 #include "em_system.h"
38
39 #ifdef __cplusplus
40 extern "C" {
41 #endif
42
43 /***************************************************************************//**
44 * @addtogroup EM_Library
45 * @{
46 ******************************************************************************/
47
48 /***************************************************************************//**
49 * @addtogroup CHIP
50 * @brief Chip Initialization API
51 * @{
52 ******************************************************************************/
53
54 /**************************************************************************//**
55 * @brief
56 * Chip initialization routine for revision errata workarounds
57 *
58 * This init function will configure the EFM32 device to a state where it is
59 * as similar as later revisions as possible, to improve software compatibility
60 * with newer parts. See the device specific errata for details.
61 *****************************************************************************/
CHIP_Init(void)62 __STATIC_INLINE void CHIP_Init(void)
63 {
64 /* Currently only run time changes for Gecko devices */
65 #if defined(_EFM32_GECKO_FAMILY)
66 uint32_t rev;
67 SYSTEM_ChipRevision_TypeDef chipRev;
68 volatile uint32_t *reg;
69
70 rev = *(volatile uint32_t *)(0x0FE081FC);
71 /* Engineering Sample calibration setup */
72 if ((rev >> 24) == 0)
73 {
74 reg = (volatile uint32_t *)0x400CA00C;
75 *reg &= ~(0x70UL);
76 /* DREG */
77 reg = (volatile uint32_t *)0x400C6020;
78 *reg &= ~(0xE0000000UL);
79 *reg |= ~(7UL << 25);
80 }
81 if ((rev >> 24) <= 3)
82 {
83 /* DREG */
84 reg = (volatile uint32_t *)0x400C6020;
85 *reg &= ~(0x00001F80UL);
86 /* Update CMU reset values */
87 reg = (volatile uint32_t *)0x400C8040;
88 *reg = 0;
89 reg = (volatile uint32_t *)0x400C8044;
90 *reg = 0;
91 reg = (volatile uint32_t *)0x400C8058;
92 *reg = 0;
93 reg = (volatile uint32_t *)0x400C8060;
94 *reg = 0;
95 reg = (volatile uint32_t *)0x400C8078;
96 *reg = 0;
97 }
98
99 SYSTEM_ChipRevisionGet(&chipRev);
100 if (chipRev.major == 0x01)
101 {
102 /* Rev A errata handling for EM2/3. Must enable DMA clock in order for EM2/3 */
103 /* to work. This will be fixed in later chip revisions, so only do for rev A. */
104 if (chipRev.minor == 00)
105 {
106 reg = (volatile uint32_t *)0x400C8040;
107 *reg |= 0x2;
108 }
109
110 /* Rev A+B errata handling for I2C when using EM2/3. USART0 clock must be enabled */
111 /* after waking up from EM2/EM3 in order for I2C to work. This will be fixed in */
112 /* later chip revisions, so only do for rev A+B. */
113 if (chipRev.minor <= 0x01)
114 {
115 reg = (volatile uint32_t *)0x400C8044;
116 *reg |= 0x1;
117 }
118 }
119 /* Ensure correct ADC/DAC calibration value */
120 rev = *(volatile uint32_t *)0x0FE081F0;
121 if (rev < 0x4C8ABA00)
122 {
123 uint32_t cal;
124
125 /* Enable ADC/DAC clocks */
126 reg = (volatile uint32_t *)0x400C8044UL;
127 *reg |= (1 << 14 | 1 << 11);
128
129 /* Retrive calibration values */
130 cal = ((*(volatile uint32_t *)(0x0FE081B4UL) & 0x00007F00UL) >>
131 8) << 24;
132
133 cal |= ((*(volatile uint32_t *)(0x0FE081B4UL) & 0x0000007FUL) >>
134 0) << 16;
135
136 cal |= ((*(volatile uint32_t *)(0x0FE081B4UL) & 0x00007F00UL) >>
137 8) << 8;
138
139 cal |= ((*(volatile uint32_t *)(0x0FE081B4UL) & 0x0000007FUL) >>
140 0) << 0;
141
142 /* ADC0->CAL = 1.25 reference */
143 reg = (volatile uint32_t *)0x40002034UL;
144 *reg = cal;
145
146 /* DAC0->CAL = 1.25 reference */
147 reg = (volatile uint32_t *)(0x4000402CUL);
148 cal = *(volatile uint32_t *)0x0FE081C8UL;
149 *reg = cal;
150
151 /* Turn off ADC/DAC clocks */
152 reg = (volatile uint32_t *)0x400C8044UL;
153 *reg &= ~(1 << 14 | 1 << 11);
154 }
155 #endif
156 }
157
158 /** @} (end addtogroup CHIP) */
159 /** @} (end addtogroup EM_Library) */
160
161 #ifdef __cplusplus
162 }
163 #endif
164
165 #endif /* __EM_CHIP_H */
166