Callisto4Bootloader: lib/c4_watchdog.c Source File

Callisto4Bootloader

c4_watchdog.c
Go to the documentation of this file.
1
22 /*******************************************************************************
23 * Includes
24 ******************************************************************************/
25 #include "c4_watchdog_types.h"
26
27 #include "c4_watchdog.h"
28 #include "bl_api.h"
29 #include "fsl_wdog.h"
30 #include <stdbool.h>
31
32 /*******************************************************************************
33 * Defines
34 ******************************************************************************/
35
37 static const uint16_t WDOG_MAX_TO = 1280U;
38
40 static const uint16_t WDOG_MIN_TO = 5U;
41
43 static const uint16_t WDOG_MAX_INT = 1275U;
44
46 static const uint16_t WDOG_MIN_INT = 0U;
47
56 #define PRINT_BIT(base, reg) \
57 printf("\t "#base"."#reg" : %s\n", (base.B.reg ? "TRUE" : "false"))
58
59 /*******************************************************************************
60 * Structures
61 ******************************************************************************/
62
63 /*******************************************************************************
64 * Prototypes
65 ******************************************************************************/
66
77 void WDOG1_IRQHandler(void);
78
79 /*******************************************************************************
80 * Variables
81 ******************************************************************************/
82
84 wdog_config_t sWdogConfig[C4_NUM_WDOG];
85
89 c4_WDOG_reg_t * const sWdogRegisters[C4_NUM_WDOG] = \
90 {(c4_WDOG_reg_t *)WDOG1_BASE,
91 (c4_WDOG_reg_t *)WDOG2_BASE};
92
94 static bool WDOG_INITIALISED = false;
95
96 /*******************************************************************************
97 * Public Functions
98 ******************************************************************************/
99
114 exit_code_t c4_initWatchdog(c4_wdog_t wdog, uint16_t to, uint16_t ito)
115 {
116 exit_code_t rc = C4_ERR_OK;
117 if (false == WDOG_INITIALISED)
118 {
119 bl_api_init();
120 WDOG_INITIALISED = true;
121 }
122
123 if ((C4_WDOG1 > wdog) || (C4_WDOG2 < wdog))
124 {
125 rc = C4_ERR_RANGE;
126 }
127 else
128 {
129 /* The following sequence should be performed for WDOG initialization.
130 * • PDE bit of Watchdog Miscellaneous Control (WMCR) should be cleared to disable
131 * the power down counter.
132 * • WT field of Watchdog Control (WCR) should be programmed for sufficient timeout
133 * value.
134 * • WDOG should be enabled by setting WDE bit of Watchdog Control (WCR) so that
135 * the timeout counter loads the WT field value of Watchdog Control (WCR) and starts
136 * counting.
137 */
138 WDOG_GetDefaultConfig(sWdogConfig+wdog);
139
140 /* Timeout value is specified in the register in half-seconds and 0 represents a half-second
141 * timeout.
142 *
143 * The timeout is specified in deci-seconds, so divide by five and subtract one to
144 * convert to register setting.
145 *
146 * e.g. if the timeout is set to 0xF, the watchdog will expire after (0xF+1)/2 = 8 sec. */
147 sWdogConfig[wdog].timeoutValue = to/5U - 1U;
148
149 // Set interrupt ante-delay if it is less than the timeout value.
150 if (ito <= to)
151 {
152 c4_setWdogInterrupt(wdog, ito);
153 }
154
155 /* Cast from our bitfield representation of WDOG registers to shift and mask used in FreeRTOS functions. */
156 WDOG_Init((WDOG_Type *)sWdogRegisters[wdog], sWdogConfig+wdog);
157
158 }
159 return rc;
160 }
161
162 /*******************************************************************************/
163
164 exit_code_t c4_disableWdog(c4_wdog_t wdog)
165 {
166 exit_code_t rc = C4_ERR_OK;
167
168 if ((C4_WDOG1 > wdog) || (C4_WDOG2 < wdog))
169 {
170 rc = C4_ERR_RANGE;
171 }
172 else
173 {
174 sWdogRegisters[wdog]->WCR.B.WDE = false;
175 }
176 return rc;
177 }
178
179 /*******************************************************************************/
180
181 exit_code_t c4_enableWdog(c4_wdog_t wdog)
182 {
183 exit_code_t rc = C4_ERR_OK;
184
185 if ((C4_WDOG1 > wdog) || (C4_WDOG2 < wdog))
186 {
187 rc = C4_ERR_RANGE;
188 }
189 else
190 {
191 sWdogRegisters[wdog]->WCR.B.WDE = true;
192 }
193 return rc;
194 }
195
196 /*******************************************************************************/
197
198 exit_code_t c4_setWdogTimeout(c4_wdog_t wdog, uint16_t to)
199 {
200 exit_code_t rc = C4_ERR_OK;
201
202 if ((C4_WDOG1 > wdog) || (C4_WDOG2 < wdog) || (to > WDOG_MAX_TO) || (to < WDOG_MIN_TO))
203 {
204 rc = C4_ERR_RANGE;
205 }
206 else
207 {
208 sWdogRegisters[wdog]->WCR.B.WT = (to/5 - 1);
209 }
210 return rc;
211 }
212
213 /*******************************************************************************/
214
218 exit_code_t c4_setWdogInterrupt(c4_wdog_t wdog, uint16_t to)
219 {
220 exit_code_t rc = C4_ERR_OK;
221
222 if ((C4_WDOG1 > wdog) || (C4_WDOG2 < wdog) || (to > WDOG_MAX_INT) || (to < WDOG_MIN_INT))
223 rc = C4_ERR_RANGE;
224 // After reset WIE is 0 (interrupt disabled) and WICT is 4 (2 seconds)
225 else if ((sWdogRegisters[wdog]->WICR.B.WIE) ||
226 (4 != sWdogRegisters[wdog]->WICR.B.WICT))
227 rc = C4_ERR_ALREADY_SET;
228 else if (sWdogRegisters[wdog]->WCR.B.WDE)
229 rc = C4_ERR_ALREADY_SET;
230 else
231 {
232 switch (wdog)
233 {
234 case C4_WDOG1:
235 NVIC_EnableIRQ(WDOG1_IRQn);
236 break;
237 case C4_WDOG2:
238 NVIC_EnableIRQ(WDOG2_IRQn);
239 break;
240 default:
241 rc = C4_ERR_RANGE;
242 }
243 if (C4_ERR_OK == rc)
244 {
245 // Set up a local copy of the register.
246 union c4_WDOG_wicr wicr;
247 wicr.R = sWdogRegisters[wdog]->WICR.R;
248
249 wicr.B.WIE = true;
250 /* Set interrupt to occur before the interrupt expires. Specify in half-seconds.
251 * e.g. if interrupt is set to 0x4, the interrupt will occur (0x4)/2 = 2 sec before WDOG timeout. */
252 wicr.B.WICT = to/5U;
253
254 // now copy it into the real register
255 sWdogRegisters[wdog]->WICR.R = wicr.R;
256 }
257 }
258 return rc;
259 }
260
261 /*******************************************************************************/
262
263 exit_code_t c4_getResetHistory()
264 {
265 /* inspect the SCR.SRSR and the WDOG1.WRSR registers and reset them.
266 */
267 if (false == WDOG_INITIALISED)
268 {
269 printf("Watchdog uninitialised!!\n");
270 }
271 else
272 {
273 printf("Watchdog1 : WRSRS 0x%08x\n", sWdogRegisters[C4_WDOG1]->WRSR.R);
274 PRINT_BIT(sWdogRegisters[C4_WDOG1]->WRSR, SFTW);
275 PRINT_BIT(sWdogRegisters[C4_WDOG1]->WRSR, TOUT);
276 PRINT_BIT(sWdogRegisters[C4_WDOG1]->WRSR, POR);
277
278 printf("Watchdog2 : WRSRS 0x%08x\n", sWdogRegisters[C4_WDOG2]->WRSR.R);
279 PRINT_BIT(sWdogRegisters[C4_WDOG2]->WRSR, SFTW);
280 PRINT_BIT(sWdogRegisters[C4_WDOG2]->WRSR, TOUT);
281 PRINT_BIT(sWdogRegisters[C4_WDOG2]->WRSR, POR);
282
283 c4_SRC_reg_t *SRC_reg = (c4_SRC_reg_t *)SRC_BASE;
284 printf("SCR : SRSR 0x%08lx\n", SRC_reg->SRSR.R);
285 PRINT_BIT(SRC_reg->SRSR, ippResetB);
286 PRINT_BIT(SRC_reg->SRSR, lockupSysResetReq);
287 PRINT_BIT(SRC_reg->SRSR, csuResetB);
288 PRINT_BIT(SRC_reg->SRSR, ippUserResetB);
289 PRINT_BIT(SRC_reg->SRSR, wdogRstB);
290 PRINT_BIT(SRC_reg->SRSR, jtagRstB);
291 PRINT_BIT(SRC_reg->SRSR, jtagSwRst);
292 PRINT_BIT(SRC_reg->SRSR, wdog3RstB);
293 PRINT_BIT(SRC_reg->SRSR, tempSenseRstB);
294 // Clear all bits.
295 SRC_reg->SRSR.R = SRC_reg->SRSR.R;
296 printf("SCR : SRSR 0x%08lx\n", SRC_reg->SRSR.R);
297
298 }
299 return C4_ERR_OK;
300 }
301
302 /*******************************************************************************
303 * Internal functions
304 ******************************************************************************/
305
306 void WDOG1_IRQHandler(void)
307 {
308 printf("%s", __FUNCTION__);
309 /*
310 * WDOG_WCR_WDE_MASK 0x0004U Watchdog Enable
311 * WDOG_WRSR_POR_MASK 0x0010U Power-On Reset
312 * WDOG_WRSR_TOUT_MASK 0x0002U Time-OUT reset
313 * WDOG_WRSR_SFTW_MASK 0x0001U SoftWare Reset
314 * WDOG_WICR_WTIS_MASK 0x4000U Interrupt has occurred
315 */
316 /* Cast from our bitfield representation of WDOG registers to shift and mask used in FreeRTOS functions. */
317 uint16_t status = WDOG_GetStatusFlags((WDOG_Type *)sWdogRegisters[C4_WDOG1]);
318 printf(" statusflags 0x%04x\n", status);
319
320 /* Cast from our bitfield representation of WDOG registers to shift and mask used in FreeRTOS functions. */
321 WDOG_ClearInterruptStatus((WDOG_Type *)sWdogRegisters[C4_WDOG1], kWDOG_InterruptFlag);
322 /* User code. User can do urgent case before timeout reset.
323 * IE. user can backup the ram data or ram log to flash.
324 * the period is set by config.interruptTimeValue, user need to
325 * check the period between interrupt and timeout.
326 */
327 }
c4_wdog_t
c4_wdog_t
Enumeration of watchdogs.
Definition: c4_watchdog.h:34
c4_initWatchdog
exit_code_t c4_initWatchdog(c4_wdog_t wdog, uint16_t to, uint16_t ito)
Initialise watchdog subsystem.
Definition: c4_watchdog.c:109
c4_SRC_reg_t::R
uint32_t R
Definition: c4_watchdog_types.h:342
WDOG_MAX_TO
static const uint16_t WDOG_MAX_TO
Maximum watchdog timeout in deciseconds (ds).
Definition: c4_watchdog.c:36
c4_enableWdog
exit_code_t c4_enableWdog(c4_wdog_t wdog)
enables the watchdog.
Definition: c4_watchdog.c:176
WDOG_GetStatusFlags
uint16_t WDOG_GetStatusFlags(WDOG_Type *base)
Gets the WDOG all reset status flags.
Definition: bl_api.c:298
c4_WDOG_reg_t::c4_WDOG_wicr::WICT
uint16_t WICT
Watchdog Interrupt Count Time-out field This determines how long before the counter time-out must the...
Definition: c4_watchdog_types.h:217
WDOG2_BASE
#define WDOG2_BASE
Definition: MIMXRT1062.h:46494
WDOG_MIN_TO
static const uint16_t WDOG_MIN_TO
Minimum watchdog timeout in deciseconds (ds).
Definition: c4_watchdog.c:39
c4_WDOG_reg_t::WCR
union c4_WDOG_reg_t::@92 WCR
The Watchdog Control Register (WDOG_WCR) controls the WDOG operation.
bl_api_init
void bl_api_init(void)
Definition: bl_api.c:20
sWdogConfig
wdog_config_t sWdogConfig[C4_NUM_WDOG]
Watchdog configuration structures.
Definition: c4_watchdog.c:80
fsl_wdog.h
c4_watchdog_types.h
Definition of types to aid manipulation of watchdog registers.
c4_setWdogTimeout
exit_code_t c4_setWdogTimeout(c4_wdog_t wdog, uint16_t to)
Set timeout on watchdog.
Definition: c4_watchdog.c:193
PRINT_BIT
#define PRINT_BIT(base, reg)
Macro to print specified bit as boolean.
Definition: c4_watchdog.c:55
kWDOG_InterruptFlag
Definition: fsl_wdog.h:72
SRC_BASE
#define SRC_BASE
Definition: MIMXRT1062.h:39463
WDOG_INITIALISED
static bool WDOG_INITIALISED
Flag to prevent reinitialisation of watchdogs.
Definition: c4_watchdog.c:90
WDOG_Type
Definition: MIMXRT1062.h:46321
c4_WDOG_reg_t::B
struct c4_WDOG_reg_t::@92::@96 B
c4_WDOG_reg_t
Structure to overlay on the watchdog registers.
Definition: c4_watchdog_types.h:32
WDOG_GetDefaultConfig
void WDOG_GetDefaultConfig(wdog_config_t *config)
Initializes the WDOG configuration structure.
Definition: bl_api.c:283
c4_disableWdog
exit_code_t c4_disableWdog(c4_wdog_t wdog)
disables the watchdog.
Definition: c4_watchdog.c:159
exit_code_t
exit_code_t
Enumeration of error codes.
Definition: c4_error_codes.h:96
c4_SRC_reg_t
System Reset Controller (SRC)
Definition: c4_watchdog_types.h:282
c4_setWdogInterrupt
exit_code_t c4_setWdogInterrupt(c4_wdog_t wdog, uint16_t to)
Enable interrupt on watchdog before expiry.
Definition: c4_watchdog.c:213
WDOG1_IRQn
Definition: MIMXRT1062.h:182
WDOG2_IRQn
Definition: MIMXRT1062.h:135
c4_WDOG_reg_t::WICR
union c4_WDOG_reg_t::c4_WDOG_wicr WICR
WDOG_MAX_INT
static const uint16_t WDOG_MAX_INT
Maximum watchdog interrupt delay in deciseconds (ds).
Definition: c4_watchdog.c:42
c4_WDOG_reg_t::c4_WDOG_wicr::B
struct c4_WDOG_reg_t::c4_WDOG_wicr::@99 B
_wdog_config::timeoutValue
uint16_t timeoutValue
Definition: fsl_wdog.h:44
c4_SRC_reg_t::SRSR
union c4_SRC_reg_t::@103 SRSR
c4_WDOG_reg_t::c4_WDOG_wicr::R
uint16_t R
Definition: c4_watchdog_types.h:250
WDOG_MIN_INT
static const uint16_t WDOG_MIN_INT
Minimum timeout in deciseconds (ds).
Definition: c4_watchdog.c:45
WDOG_ClearInterruptStatus
void WDOG_ClearInterruptStatus(WDOG_Type *base, uint16_t mask)
Clears the WDOG flag.
Definition: bl_api.c:303
_wdog_config
Describes WDOG configuration structure.
Definition: fsl_wdog.h:39
WDOG1_BASE
#define WDOG1_BASE
Definition: MIMXRT1062.h:46490
C4_WDOG2
Watchdog 2 - for SNVS secure world.
Definition: c4_watchdog.h:40
C4_WDOG1
Watchdog 1 - resets processor.
Definition: c4_watchdog.h:39
WDOG_Init
void WDOG_Init(WDOG_Type *base, const wdog_config_t *config)
Initializes the WDOG.
Definition: bl_api.c:288
c4_watchdog.h
Interface to enable watchdog functions.
c4_WDOG_reg_t::R
uint16_t R
Definition: c4_watchdog_types.h:146
NVIC_EnableIRQ
#define NVIC_EnableIRQ
Definition: core_armv81mml.h:2119
C4_NUM_WDOG
Number of watchdogs.
Definition: c4_watchdog.h:41
c4_getResetHistory
exit_code_t c4_getResetHistory()
Retrieve reset history from watchdog registers and from System Register.
Definition: c4_watchdog.c:258
sWdogRegisters
c4_WDOG_reg_t *const sWdogRegisters[C4_NUM_WDOG]
Watchdog control registers.
Definition: c4_watchdog.c:85
WDOG1_IRQHandler
void WDOG1_IRQHandler(void)
Watchdog interrupt handler function.
Definition: c4_watchdog.c:300
bl_api.h