1 /***************************************************************************//**
2 * @file
3 * @brief Reset Management Unit (RMU) peripheral module 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_rmu.h"
32 #if (defined(RMU_COUNT) && (RMU_COUNT > 0)) || (_EMU_RSTCTRL_MASK)
33
34 #include "sl_common.h"
35 #include "em_emu.h"
36 #include "em_bus.h"
37
38 /***************************************************************************//**
39 * @addtogroup rmu RMU - Reset Management Unit
40 * @brief Reset Management Unit (RMU) Peripheral API
41 * @details
42 * This module contains functions to control the RMU peripheral of Silicon
43 * Labs 32-bit MCUs and SoCs. RMU ensures correct reset operation and is
44 * responsible for connecting the different reset sources to the reset lines of
45 * the MCU or SoC.
46 * @{
47 ******************************************************************************/
48
49 /*******************************************************************************
50 ***************************** DEFINES *********************************
51 ******************************************************************************/
52
53 /** @cond DO_NOT_INCLUDE_WITH_DOXYGEN */
54
55 #if defined(_RMU_RSTCAUSE_MASK)
56
57 /** Reset cause XMASKS for series-0 and series-1 devices.
58 Reset cause zero and "don't care" bit definitions (XMASKs).
59 An XMASK 1 bit marks a bit that must be zero in RMU_RSTCAUSE. A 0 in XMASK
60 is a "don't care" bit in RMU_RSTCAUSE if also 0 in resetCauseMask
61 in @ref RMU_ResetCauseMasks_Typedef. */
62
63 /* EFM32G */
64 #if (_RMU_RSTCAUSE_MASK == 0x0000007FUL)
65 #define RMU_RSTCAUSE_PORST_XMASK 0x00000000UL /** 0000000000000000 < Power On Reset */
66 #define RMU_RSTCAUSE_BODUNREGRST_XMASK 0x00000001UL /** 0000000000000001 < Brown Out Detector Unregulated Domain Reset */
67 #define RMU_RSTCAUSE_BODREGRST_XMASK 0x0000001BUL /** 0000000000011011 < Brown Out Detector Regulated Domain Reset */
68 #define RMU_RSTCAUSE_EXTRST_XMASK 0x00000003UL /** 0000000000000011 < External Pin Reset */
69 #define RMU_RSTCAUSE_WDOGRST_XMASK 0x00000003UL /** 0000000000000011 < Watchdog Reset */
70 #define RMU_RSTCAUSE_LOCKUPRST_XMASK 0x0000001FUL /** 0000000000011111 < LOCKUP Reset */
71 #define RMU_RSTCAUSE_SYSREQRST_XMASK 0x0000001FUL /** 0000000000011111 < System Request Reset */
72 #define NUM_RSTCAUSES 7
73
74 /* EFM32TG, EFM32HG, EZR32HG, EFM32ZG */
75 #elif (_RMU_RSTCAUSE_MASK == 0x000007FFUL)
76 #define RMU_RSTCAUSE_PORST_XMASK 0x00000000UL /** 0000000000000000 < Power On Reset */
77 #define RMU_RSTCAUSE_BODUNREGRST_XMASK 0x00000081UL /** 0000000010000001 < Brown Out Detector Unregulated Domain Reset */
78 #define RMU_RSTCAUSE_BODREGRST_XMASK 0x00000091UL /** 0000000010010001 < Brown Out Detector Regulated Domain Reset */
79 #define RMU_RSTCAUSE_EXTRST_XMASK 0x00000001UL /** 0000000000000001 < External Pin Reset */
80 #define RMU_RSTCAUSE_WDOGRST_XMASK 0x00000003UL /** 0000000000000011 < Watchdog Reset */
81 #define RMU_RSTCAUSE_LOCKUPRST_XMASK 0x0000EFDFUL /** 1110111111011111 < LOCKUP Reset */
82 #define RMU_RSTCAUSE_SYSREQRST_XMASK 0x0000EF9FUL /** 1110111110011111 < System Request Reset */
83 #define RMU_RSTCAUSE_EM4RST_XMASK 0x00000719UL /** 0000011100011001 < EM4 Reset */
84 #define RMU_RSTCAUSE_EM4WURST_XMASK 0x00000619UL /** 0000011000011001 < EM4 Wake-up Reset */
85 #define RMU_RSTCAUSE_BODAVDD0_XMASK 0x0000041FUL /** 0000010000011111 < AVDD0 Bod Reset. */
86 #define RMU_RSTCAUSE_BODAVDD1_XMASK 0x0000021FUL /** 0000001000011111 < AVDD1 Bod Reset. */
87 #define NUM_RSTCAUSES 11
88
89 /* EFM32GG, EFM32LG, EZR32LG, EFM32WG, EZR32WG */
90 #elif (_RMU_RSTCAUSE_MASK == 0x0000FFFFUL)
91 #define RMU_RSTCAUSE_PORST_XMASK 0x00000000UL /** 0000000000000000 < Power On Reset */
92 #define RMU_RSTCAUSE_BODUNREGRST_XMASK 0x00000081UL /** 0000000010000001 < Brown Out Detector Unregulated Domain Reset */
93 #define RMU_RSTCAUSE_BODREGRST_XMASK 0x00000091UL /** 0000000010010001 < Brown Out Detector Regulated Domain Reset */
94 #define RMU_RSTCAUSE_EXTRST_XMASK 0x00000001UL /** 0000000000000001 < External Pin Reset */
95 #define RMU_RSTCAUSE_WDOGRST_XMASK 0x00000003UL /** 0000000000000011 < Watchdog Reset */
96 #define RMU_RSTCAUSE_LOCKUPRST_XMASK 0x0000EFDFUL /** 1110111111011111 < LOCKUP Reset */
97 #define RMU_RSTCAUSE_SYSREQRST_XMASK 0x0000EF9FUL /** 1110111110011111 < System Request Reset */
98 #define RMU_RSTCAUSE_EM4RST_XMASK 0x00000719UL /** 0000011100011001 < EM4 Reset */
99 #define RMU_RSTCAUSE_EM4WURST_XMASK 0x00000619UL /** 0000011000011001 < EM4 Wake-up Reset */
100 #define RMU_RSTCAUSE_BODAVDD0_XMASK 0x0000041FUL /** 0000010000011111 < AVDD0 Bod Reset */
101 #define RMU_RSTCAUSE_BODAVDD1_XMASK 0x0000021FUL /** 0000001000011111 < AVDD1 Bod Reset */
102 #define RMU_RSTCAUSE_BUBODVDDDREG_XMASK 0x00000001UL /** 0000000000000001 < Backup Brown Out Detector, VDD_DREG */
103 #define RMU_RSTCAUSE_BUBODBUVIN_XMASK 0x00000001UL /** 0000000000000001 < Backup Brown Out Detector, BU_VIN */
104 #define RMU_RSTCAUSE_BUBODUNREG_XMASK 0x00000001UL /** 0000000000000001 < Backup Brown Out Detector Unregulated Domain */
105 #define RMU_RSTCAUSE_BUBODREG_XMASK 0x00000001UL /** 0000000000000001 < Backup Brown Out Detector Regulated Domain */
106 #define RMU_RSTCAUSE_BUMODERST_XMASK 0x00000001UL /** 0000000000000001 < Backup mode reset */
107 #define NUM_RSTCAUSES 16
108
109 /* EFM32xG1, EFM32xG12, EFM32xG13 */
110 #elif ((_RMU_RSTCAUSE_MASK & 0x0FFFFFFF) == 0x00010F1DUL)
111 #define RMU_RSTCAUSE_PORST_XMASK 0x00000000UL /** 0000000000000000 < Power On Reset */
112 #define RMU_RSTCAUSE_BODAVDD_XMASK 0x00000001UL /** 0000000000000001 < AVDD BOD Reset */
113 #define RMU_RSTCAUSE_BODDVDD_XMASK 0x00000001UL /** 0000000000000001 < DVDD BOD Reset */
114 #define RMU_RSTCAUSE_BODREGRST_XMASK 0x00000001UL /** 0000000000000001 < Regulated Domain (DEC) BOD Reset */
115 #define RMU_RSTCAUSE_EXTRST_XMASK 0x00000001UL /** 0000000000000001 < External Pin Reset */
116 #define RMU_RSTCAUSE_LOCKUPRST_XMASK 0x0000001DUL /** 0000000000011101 < LOCKUP Reset */
117 #define RMU_RSTCAUSE_SYSREQRST_XMASK 0x0000001DUL /** 0000000000011101 < System Request Reset */
118 #define RMU_RSTCAUSE_WDOGRST_XMASK 0x0000001DUL /** 0000000000011101 < Watchdog Reset */
119 #define RMU_RSTCAUSE_EM4RST_XMASK 0x0000001DUL /** 0000000000011101 < EM4H/S Reset */
120 #define NUM_RSTCAUSES 9
121
122 /* EFM32GG11 */
123 #elif ((_RMU_RSTCAUSE_MASK & 0x0FFFFFFF) == 0x00011F1DUL)
124 #define RMU_RSTCAUSE_PORST_XMASK 0x00000000UL /** 0000000000000000 < Power On Reset */
125 #define RMU_RSTCAUSE_BODAVDD_XMASK 0x00000001UL /** 0000000000000001 < AVDD BOD Reset */
126 #define RMU_RSTCAUSE_BODDVDD_XMASK 0x00000001UL /** 0000000000000001 < DVDD BOD Reset */
127 #define RMU_RSTCAUSE_BODREGRST_XMASK 0x00000001UL /** 0000000000000001 < Regulated Domain (DEC) BOD Reset */
128 #define RMU_RSTCAUSE_EXTRST_XMASK 0x00000001UL /** 0000000000000001 < External Pin Reset */
129 #define RMU_RSTCAUSE_LOCKUPRST_XMASK 0x0000001DUL /** 0000000000011101 < LOCKUP Reset */
130 #define RMU_RSTCAUSE_SYSREQRST_XMASK 0x0000001DUL /** 0000000000011101 < System Request Reset */
131 #define RMU_RSTCAUSE_WDOGRST_XMASK 0x0000001DUL /** 0000000000011101 < Watchdog Reset */
132 #define RMU_RSTCAUSE_BUMODERST_XMASK 0x0000001DUL /** 0000000000011101 < Backup mode reset */
133 #define RMU_RSTCAUSE_EM4RST_XMASK 0x0000001DUL /** 0000000000011101 < EM4H/S Reset */
134 #define NUM_RSTCAUSES 10
135
136 #else
137 #error "RMU_RSTCAUSE XMASKs are not defined for this family."
138 #endif
139
140 /* Pin reset definitions. */
141 #define LB_CLW0 (*((volatile uint32_t *)(LOCKBITS_BASE) +122))
142 #define LB_CLW0_PINRESETSOFT (1 << 2)
143
144 #if defined(_SILICON_LABS_GECKO_INTERNAL_SDID_80)
145 /* Fix for errata EMU_E208 - Occasional Full Reset After Exiting EM4H. */
146 #define ERRATA_FIX_EMU_E208_EN
147 #endif
148
149 #endif /* #if defined(_RMU_RSTCAUSE_MASK) */
150
151 /*******************************************************************************
152 ******************************* STRUCTS ***********************************
153 ******************************************************************************/
154
155 #if defined(_RMU_RSTCAUSE_MASK)
156 /** Reset cause mask type for series-0 and series-1 devices. */
157 typedef struct {
158 /** Reset cause 1 bits. */
159 uint32_t resetCauseMask;
160 /** Reset cause 0 and "don't care" bits. */
161 uint32_t resetCauseZeroXMask;
162 } RMU_ResetCauseMasks_Typedef;
163 #endif
164
165 /*******************************************************************************
166 ******************************* TYPEDEFS **********************************
167 ******************************************************************************/
168
169 #if defined(_RMU_RSTCAUSE_MASK)
170 /** Reset cause mask table. */
171 static const RMU_ResetCauseMasks_Typedef resetCauseMasks[NUM_RSTCAUSES] =
172 {
173 { RMU_RSTCAUSE_PORST, RMU_RSTCAUSE_PORST_XMASK },
174 #if defined(RMU_RSTCAUSE_BODUNREGRST)
175 { RMU_RSTCAUSE_BODUNREGRST, RMU_RSTCAUSE_BODUNREGRST_XMASK },
176 #endif
177 #if defined(RMU_RSTCAUSE_BODREGRST)
178 { RMU_RSTCAUSE_BODREGRST, RMU_RSTCAUSE_BODREGRST_XMASK },
179 #endif
180 #if defined(RMU_RSTCAUSE_AVDDBOD)
181 { RMU_RSTCAUSE_AVDDBOD, RMU_RSTCAUSE_BODAVDD_XMASK },
182 #endif
183 #if defined(RMU_RSTCAUSE_DVDDBOD)
184 { RMU_RSTCAUSE_DVDDBOD, RMU_RSTCAUSE_BODDVDD_XMASK },
185 #endif
186 #if defined(RMU_RSTCAUSE_DECBOD)
187 { RMU_RSTCAUSE_DECBOD, RMU_RSTCAUSE_BODREGRST_XMASK },
188 #endif
189 { RMU_RSTCAUSE_EXTRST, RMU_RSTCAUSE_EXTRST_XMASK },
190 { RMU_RSTCAUSE_WDOGRST, RMU_RSTCAUSE_WDOGRST_XMASK },
191 { RMU_RSTCAUSE_LOCKUPRST, RMU_RSTCAUSE_LOCKUPRST_XMASK },
192 { RMU_RSTCAUSE_SYSREQRST, RMU_RSTCAUSE_SYSREQRST_XMASK },
193 #if defined(RMU_RSTCAUSE_EM4RST)
194 { RMU_RSTCAUSE_EM4RST, RMU_RSTCAUSE_EM4RST_XMASK },
195 #endif
196 #if defined(RMU_RSTCAUSE_EM4WURST)
197 { RMU_RSTCAUSE_EM4WURST, RMU_RSTCAUSE_EM4WURST_XMASK },
198 #endif
199 #if defined(RMU_RSTCAUSE_BODAVDD0)
200 { RMU_RSTCAUSE_BODAVDD0, RMU_RSTCAUSE_BODAVDD0_XMASK },
201 #endif
202 #if defined(RMU_RSTCAUSE_BODAVDD1)
203 { RMU_RSTCAUSE_BODAVDD1, RMU_RSTCAUSE_BODAVDD1_XMASK },
204 #endif
205 #if defined(BU_PRESENT) && defined(_SILICON_LABS_32B_SERIES_0)
206 { RMU_RSTCAUSE_BUBODVDDDREG, RMU_RSTCAUSE_BUBODVDDDREG_XMASK },
207 { RMU_RSTCAUSE_BUBODBUVIN, RMU_RSTCAUSE_BUBODBUVIN_XMASK },
208 { RMU_RSTCAUSE_BUBODUNREG, RMU_RSTCAUSE_BUBODUNREG_XMASK },
209 { RMU_RSTCAUSE_BUBODREG, RMU_RSTCAUSE_BUBODREG_XMASK },
210 { RMU_RSTCAUSE_BUMODERST, RMU_RSTCAUSE_BUMODERST_XMASK },
211 #elif defined(RMU_RSTCAUSE_BUMODERST)
212 { RMU_RSTCAUSE_BUMODERST, RMU_RSTCAUSE_BUMODERST_XMASK },
213 #endif
214 };
215 #endif /* #if defined(_RMU_RSTCAUSE_MASK) */
216
217 /*******************************************************************************
218 ******************************** TEST ********************************
219 ******************************************************************************/
220 #if defined(EMLIB_REGRESSION_TEST)
221 /* A test variable that replaces the RSTCAUSE cause register when testing
222 the RMU_ResetCauseGet function. */
223 extern uint32_t rstCause;
224 #endif
225
226 /** @endcond */
227
228 /*******************************************************************************
229 ************************** GLOBAL FUNCTIONS *******************************
230 ******************************************************************************/
231
232 /***************************************************************************//**
233 * @brief
234 * Disable/enable reset for various peripherals and signal sources.
235 *
236 * @param[in] reset Reset types to enable/disable.s
237 *
238 * @param[in] mode Reset mode.
239 ******************************************************************************/
RMU_ResetControl(RMU_Reset_TypeDef reset,RMU_ResetMode_TypeDef mode)240 void RMU_ResetControl(RMU_Reset_TypeDef reset, RMU_ResetMode_TypeDef mode)
241 {
242 /* Note that the RMU supports bit-band access, but not peripheral bit-field set/clear. */
243 #if defined(_RMU_CTRL_PINRMODE_MASK)
244 uint32_t val;
245 #endif
246 uint32_t shift;
247
248 shift = SL_CTZ((uint32_t)reset);
249 #if defined(_EMU_RSTCTRL_MASK)
250 BUS_RegBitWrite(&EMU->RSTCTRL, (uint32_t)shift, mode ? 1 : 0);
251 #elif defined(_RMU_CTRL_PINRMODE_MASK)
252 val = (uint32_t)mode << shift;
253 RMU->CTRL = (RMU->CTRL & ~reset) | val;
254 #else
255 BUS_RegBitWrite(&RMU->CTRL, (uint32_t)shift, mode ? 1 : 0);
256 #endif
257 }
258
259 /***************************************************************************//**
260 * @brief
261 * Clear the reset cause register.
262 *
263 * @details
264 * This function clears all the reset cause bits of the RSTCAUSE register.
265 * The reset cause bits must be cleared by software before a new reset occurs.
266 * Otherwise, reset causes may accumulate. See @ref RMU_ResetCauseGet().
267 ******************************************************************************/
RMU_ResetCauseClear(void)268 void RMU_ResetCauseClear(void)
269 {
270 #if defined(_EMU_RSTCTRL_MASK)
271 EMU->CMD_SET = EMU_CMD_RSTCAUSECLR;
272 #else
273 RMU->CMD = RMU_CMD_RCCLR;
274 #endif
275
276 #if defined(EMU_AUXCTRL_HRCCLR)
277 {
278 uint32_t locked;
279
280 /* Clear reset causes not cleared with the RMU CMD register. */
281 /* (If EMU registers are locked, they must be unlocked first) */
282 locked = EMU->LOCK & EMU_LOCK_LOCKKEY_LOCKED;
283 if (locked) {
284 EMU_Unlock();
285 }
286
287 BUS_RegBitWrite(&(EMU->AUXCTRL), _EMU_AUXCTRL_HRCCLR_SHIFT, 1);
288 BUS_RegBitWrite(&(EMU->AUXCTRL), _EMU_AUXCTRL_HRCCLR_SHIFT, 0);
289
290 if (locked) {
291 EMU_Lock();
292 }
293 }
294 #endif
295 }
296
297 /***************************************************************************//**
298 * @brief
299 * Get the cause of the last reset.
300 *
301 * @details
302 * To be useful, the reset cause must be cleared by software before a new
303 * reset occurs. Otherwise, reset causes may accumulate. See @ref
304 * RMU_ResetCauseClear(). This function call will return the main cause for
305 * reset, which can be a bit mask (several causes) and clear away "noise".
306 *
307 * @return
308 * A reset cause mask. See the reference manual for a description
309 * of the reset cause mask.
310 ******************************************************************************/
RMU_ResetCauseGet(void)311 uint32_t RMU_ResetCauseGet(void)
312 {
313 #if defined(_EMU_RSTCAUSE_MASK)
314 #if defined(EMLIB_REGRESSION_TEST)
315 return rstCause;
316 #else
317 return EMU->RSTCAUSE;
318 #endif
319 #endif
320
321 #if defined(_RMU_RSTCAUSE_MASK)
322 #if !defined(EMLIB_REGRESSION_TEST)
323 uint32_t rstCause = RMU->RSTCAUSE;
324 #endif
325 uint32_t validRstCause = 0;
326 uint32_t zeroXMask;
327 uint32_t i;
328
329 for (i = 0; i < NUM_RSTCAUSES; i++) {
330 zeroXMask = resetCauseMasks[i].resetCauseZeroXMask;
331 #if defined(_SILICON_LABS_32B_SERIES_1)
332 /* Handle soft/hard pin reset. */
333 if (!(LB_CLW0 & LB_CLW0_PINRESETSOFT)) {
334 /* RSTCAUSE_EXTRST must be 0 if pin reset is configured as hard reset. */
335 switch (resetCauseMasks[i].resetCauseMask) {
336 case RMU_RSTCAUSE_LOCKUPRST:
337 /* Fallthrough */
338 case RMU_RSTCAUSE_SYSREQRST:
339 /* Fallthrough */
340 case RMU_RSTCAUSE_WDOGRST:
341 /* Fallthrough */
342 case RMU_RSTCAUSE_EM4RST:
343 zeroXMask |= RMU_RSTCAUSE_EXTRST;
344 break;
345 default:
346 /* MISRA requires a default case. */
347 break;
348 }
349 }
350 #endif
351
352 #if defined(_EMU_EM4CTRL_MASK) && defined(ERRATA_FIX_EMU_E208_EN)
353 /* Ignore BOD flags impacted by EMU_E208. */
354 if (*(volatile uint32_t *)(EMU_BASE + 0x88) & (0x1 << 8)) {
355 zeroXMask &= ~(RMU_RSTCAUSE_DECBOD
356 | RMU_RSTCAUSE_DVDDBOD
357 | RMU_RSTCAUSE_AVDDBOD);
358 }
359 #endif
360
361 /* Check reset cause requirements. Note that a bit is "don't care" if 0 in
362 both resetCauseMask and resetCauseZeroXMask. */
363 if ((rstCause & resetCauseMasks[i].resetCauseMask)
364 && !(rstCause & zeroXMask)) {
365 /* Add this reset-cause to the mask of qualified reset-causes. */
366 validRstCause |= resetCauseMasks[i].resetCauseMask;
367 }
368 }
369 #if defined(_EMU_EM4CTRL_MASK) && defined(ERRATA_FIX_EMU_E208_EN)
370 /* Clear BOD flags impacted by EMU_E208. */
371 if (validRstCause & RMU_RSTCAUSE_EM4RST) {
372 validRstCause &= ~(RMU_RSTCAUSE_DECBOD
373 | RMU_RSTCAUSE_DVDDBOD
374 | RMU_RSTCAUSE_AVDDBOD);
375 }
376 #endif
377 return validRstCause;
378 #endif
379 }
380
381 /** @} (end addtogroup rmu) */
382 #endif /* defined(RMU_COUNT) && (RMU_COUNT > 0) */
383