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