FuSa 8-Bit Libraries Safety Framework
Loading...
Searching...
No Matches
midware_error_manager.c
Go to the documentation of this file.
1
22
23// Standard Library Includes
24#include <stddef.h>
25
26// Framework Includes
27#include <driver_cpuctrl.h>
28#include <driver_errctrl.h>
30
31// Device-specific Includes
32#include <xc.h>
33
34// Private function prototypes
35static errFlag_t ConfigAllChannels(const errChConfigs_t* configs);
36static uint8_t DetermineChannelConfig(errChConfig_t config);
37static errFlag_t ConfigVregfail(errChConfig_t config);
38static errFlag_t ConfigBuserr(errChConfig_t config);
39static errFlag_t ConfigRam2(errChConfig_t config);
40static errFlag_t ConfigFlash2(errChConfig_t config);
41static errFlag_t ConfigOpc(errChConfig_t config);
42static errFlag_t ConfigSplim(errChConfig_t config);
43static errFlag_t ConfigRam1(errChConfig_t config);
44static errFlag_t ConfigFlash1(errChConfig_t config);
45static errFlag_t ConfigVregwarn(errChConfig_t config);
46static errFlag_t ConfigCfd0(errChConfig_t config);
47static errFlag_t ConfigCfd1(errChConfig_t config);
48static errFlag_t ConfigCfm0(errChConfig_t config);
49static errFlag_t ConfigCfm1(errChConfig_t config);
50static errFlag_t ConfigSwdt(errChConfig_t config);
51static errFlag_t ConfigEeprom(errChConfig_t config);
52static errFlag_t ConfigEvsys0(errChConfig_t config);
53static errFlag_t ConfigEvsys1(errChConfig_t config);
54
56{
57 if (ch >= ERRCH_MAX)
58 {
59 /* cppcheck-suppress misra-c2012-15.5 */
60 return ERROR;
61 }
62
63 // Assumes channel number corresponds to bit position
64 const uint32_t channelMask = 1UL << (uint8_t)ch;
65 const uint32_t regVal = ERRCTRL_ReadChannelStatus();
66
67 const bool isChannelSet = ((regVal & channelMask) == channelMask);
68
69 errFlag_t flag = NO_ERROR;
70 if (isChannelSet)
71 {
72 flag = ERROR;
73 }
74
75 return flag;
76}
77
79{
80 if (ch >= ERRCH_MAX)
81 {
82 /* cppcheck-suppress misra-c2012-15.5 */
83 return ERROR;
84 }
85
86 // Assumes channel number corresponds to bit position
87 const uint32_t channelMask = 1UL << (uint8_t)ch;
88
89 // Channel is cleared by writing the channel bitmask
90 ERRCTRL_WriteChannelStatus(channelMask);
91
92 // Check if clear was successful
93 const uint32_t regVal = ERRCTRL_ReadChannelStatus();
94 const bool isNotCleared = ((regVal & channelMask) == channelMask);
95
96 errFlag_t flag = NO_ERROR;
97 if (isNotCleared)
98 {
99 flag = ERROR;
100 }
101
102 return flag;
103}
104
106{
107 const uint8_t regVal = ERRCTRL_ReadStatusA();
108 const uint8_t ioSafeMask = (uint8_t)ERRCTRL_IOSAFE_bm;
109 const bool isIoSafe = ((regVal & ioSafeMask) == ioSafeMask);
110
111 errFlag_t flag = ERROR;
112 if (isIoSafe)
113 {
114 flag = NO_ERROR;
115 }
116
117 return flag;
118}
119
121{
122 ERRCTRL_SetControlA((uint8_t)ERRCTRL_FORCEFLOAT_bm);
123}
124
126{
127 ERRCTRL_ClearControlA((uint8_t)ERRCTRL_FORCEFLOAT_bm);
128
129 // Check if clear was successful
130 uint8_t regVal = ERRCTRL_ReadControlA();
131 const uint8_t forcefloatMask = (uint8_t)ERRCTRL_FORCEFLOAT_bm;
132 const bool isNotCleared = ((regVal & forcefloatMask) == forcefloatMask);
133
134 errFlag_t flag = NO_ERROR;
135 if (isNotCleared)
136 {
137 flag = ERROR;
138 }
139
140 return flag;
141}
142
144{
145 ERRCTRL_SetControlA((uint8_t)ERRCTRL_HEART_bm);
146}
147
149{
150 ERRCTRL_ClearControlA((uint8_t)ERRCTRL_HEART_bm);
151}
152
153errFlag_t MW_ConfigErrorChannels(const errChConfigs_t* configs, uint8_t timeout)
154{
155 const bool isTimeoutDisabled = (timeout == 0U); // Timeout mechanism should not be disabled
156 const bool isConfigsNull = (configs == NULL);
157
158 // Cannot go into CONFIG state if error controller is not in NORMAL state
159 const uint8_t regVal = ERRCTRL_ReadControlA();
160 const uint8_t stateMask = (uint8_t)ERRCTRL_STATE_gm;
161 const uint8_t normalStateConfig = (uint8_t)ERRCTRL_STATE_NORMAL_gc;
162 const bool isStateNormal = ((regVal & stateMask) == normalStateConfig);
163
164 if (isTimeoutDisabled || isConfigsNull || !isStateNormal)
165 {
166 /* cppcheck-suppress misra-c2012-15.5 */
167 return ERROR;
168 }
169
170 // Disable global interrupts to avoid timeout while the error controller is in CONFIG state
171 const uint8_t cpuStatusRegVal = CPUCTRL_ReadStatusRegister();
172 const uint8_t gieMask = (uint8_t)CPU_I_bm; // Global Interrupt Enable status bit
173 const bool wasInterruptsEnabled = ((cpuStatusRegVal & gieMask) == gieMask);
175
176 // Error Controller must be in CONFIG state to be able to configure error channels and timeout
177 ERRCTRL_ModifyControlA(stateMask, (uint8_t)ERRCTRL_STATE_CONFIG_gc);
178
179 errFlag_t configErrorFlag = ConfigAllChannels(configs);
180
182
183 ERRCTRL_ModifyControlA(stateMask, normalStateConfig);
184
185 // Restore global interrupt configuration
186 if (wasInterruptsEnabled)
187 {
189 }
190
191 return configErrorFlag;
192}
193
194static errFlag_t ConfigAllChannels(const errChConfigs_t* configs)
195{
196 const uint8_t noErrorFlagVal = (uint8_t)NO_ERROR;
197 uint8_t combinedFlags = noErrorFlagVal; // Default to NO_ERROR
198
199 // Use bitwise 'OR' to combine return flags (assumes ERROR and NO_ERROR are nonzero complements)
200 combinedFlags |= (uint8_t)ConfigVregfail(configs->vregfail);
201 combinedFlags |= (uint8_t)ConfigBuserr(configs->buserr);
202 combinedFlags |= (uint8_t)ConfigRam2(configs->ram2);
203 combinedFlags |= (uint8_t)ConfigFlash2(configs->flash2);
204 combinedFlags |= (uint8_t)ConfigOpc(configs->opc);
205 combinedFlags |= (uint8_t)ConfigSplim(configs->splim);
206 combinedFlags |= (uint8_t)ConfigRam1(configs->ram1);
207 combinedFlags |= (uint8_t)ConfigFlash1(configs->flash1);
208 combinedFlags |= (uint8_t)ConfigVregwarn(configs->vregwarn);
209 combinedFlags |= (uint8_t)ConfigCfd0(configs->cfd0);
210 combinedFlags |= (uint8_t)ConfigCfd1(configs->cfd1);
211 combinedFlags |= (uint8_t)ConfigCfm0(configs->cfm0);
212 combinedFlags |= (uint8_t)ConfigCfm1(configs->cfm1);
213 combinedFlags |= (uint8_t)ConfigSwdt(configs->swdt);
214 combinedFlags |= (uint8_t)ConfigEeprom(configs->eeprom);
215 combinedFlags |= (uint8_t)ConfigEvsys0(configs->evsys0);
216 combinedFlags |= (uint8_t)ConfigEvsys1(configs->evsys1);
217
218 // Check if any channel configs returned ERROR
219 errFlag_t retFlag = NO_ERROR;
220 if (combinedFlags != noErrorFlagVal)
221 {
222 retFlag = ERROR;
223 }
224 return retFlag;
225}
226
227static uint8_t DetermineChannelConfig(errChConfig_t config)
228{
229 uint8_t floatIoConfig = 0U; // Float disabled
230
231 if (config.floatIo)
232 {
233 floatIoConfig = (uint8_t)ERRCTRL_FLOAT_bm;
234 }
235
236 uint8_t severityConfig = (uint8_t)config.severity << ERRCTRL_ERRLVL_gp;
237
238 return floatIoConfig | severityConfig;
239}
240
241static errFlag_t ConfigVregfail(errChConfig_t config)
242{
243 // Ensure severity is valid
244 if (config.severity >= ERRCH_SEVERITY_MAX)
245 {
246 /* cppcheck-suppress misra-c2012-15.5 */
247 return ERROR;
248 }
249
250 uint8_t channelConfig = DetermineChannelConfig(config);
251
252 ERRCTRL_WriteConfigVregfail(channelConfig);
253
254 return NO_ERROR;
255}
256
257static errFlag_t ConfigBuserr(errChConfig_t config)
258{
259 // Ensure severity is valid
260 if (config.severity >= ERRCH_SEVERITY_MAX)
261 {
262 /* cppcheck-suppress misra-c2012-15.5 */
263 return ERROR;
264 }
265
266 uint8_t channelConfig = DetermineChannelConfig(config);
267
268 ERRCTRL_WriteConfigBuserr(channelConfig);
269
270 return NO_ERROR;
271}
272
273static errFlag_t ConfigRam2(errChConfig_t config)
274{
275 // Ensure severity is valid
276 if (config.severity >= ERRCH_SEVERITY_MAX)
277 {
278 /* cppcheck-suppress misra-c2012-15.5 */
279 return ERROR;
280 }
281
282 uint8_t channelConfig = DetermineChannelConfig(config);
283
284 ERRCTRL_WriteConfigRam2(channelConfig);
285
286 return NO_ERROR;
287}
288
289static errFlag_t ConfigFlash2(errChConfig_t config)
290{
291 // Ensure severity is valid
292 if (config.severity >= ERRCH_SEVERITY_MAX)
293 {
294 /* cppcheck-suppress misra-c2012-15.5 */
295 return ERROR;
296 }
297
298 uint8_t channelConfig = DetermineChannelConfig(config);
299
300 ERRCTRL_WriteConfigFlash2(channelConfig);
301
302 return NO_ERROR;
303}
304
305static errFlag_t ConfigOpc(errChConfig_t config)
306{
307 // Ensure severity is valid
308 if (config.severity >= ERRCH_SEVERITY_MAX)
309 {
310 /* cppcheck-suppress misra-c2012-15.5 */
311 return ERROR;
312 }
313
314 uint8_t channelConfig = DetermineChannelConfig(config);
315
316 ERRCTRL_WriteConfigOpc(channelConfig);
317
318 return NO_ERROR;
319}
320
321static errFlag_t ConfigSplim(errChConfig_t config)
322{
323 // Ensure severity is valid
324 if (config.severity >= ERRCH_SEVERITY_MAX)
325 {
326 /* cppcheck-suppress misra-c2012-15.5 */
327 return ERROR;
328 }
329
330 uint8_t channelConfig = DetermineChannelConfig(config);
331
332 ERRCTRL_WriteConfigSplim(channelConfig);
333
334 return NO_ERROR;
335}
336
337static errFlag_t ConfigRam1(errChConfig_t config)
338{
339 // Ensure severity is valid
340 if (config.severity >= ERRCH_SEVERITY_MAX)
341 {
342 /* cppcheck-suppress misra-c2012-15.5 */
343 return ERROR;
344 }
345
346 uint8_t channelConfig = DetermineChannelConfig(config);
347
348 ERRCTRL_WriteConfigRam1(channelConfig);
349
350 return NO_ERROR;
351}
352
353static errFlag_t ConfigFlash1(errChConfig_t config)
354{
355 // Ensure severity is valid
356 if (config.severity >= ERRCH_SEVERITY_MAX)
357 {
358 /* cppcheck-suppress misra-c2012-15.5 */
359 return ERROR;
360 }
361
362 uint8_t channelConfig = DetermineChannelConfig(config);
363
364 ERRCTRL_WriteConfigFlash1(channelConfig);
365
366 return NO_ERROR;
367}
368
369static errFlag_t ConfigVregwarn(errChConfig_t config)
370{
371 // Ensure severity is valid
372 if (config.severity >= ERRCH_SEVERITY_MAX)
373 {
374 /* cppcheck-suppress misra-c2012-15.5 */
375 return ERROR;
376 }
377
378 uint8_t channelConfig = DetermineChannelConfig(config);
379
380 ERRCTRL_WriteConfigVregwarn(channelConfig);
381
382 return NO_ERROR;
383}
384
385static errFlag_t ConfigCfd0(errChConfig_t config)
386{
387 // Ensure severity is valid
388 if (config.severity >= ERRCH_SEVERITY_MAX)
389 {
390 /* cppcheck-suppress misra-c2012-15.5 */
391 return ERROR;
392 }
393
394 uint8_t channelConfig = DetermineChannelConfig(config);
395
396 ERRCTRL_WriteConfigCfd0(channelConfig);
397
398 return NO_ERROR;
399}
400
401static errFlag_t ConfigCfd1(errChConfig_t config)
402{
403 // Ensure severity is valid
404 if (config.severity >= ERRCH_SEVERITY_MAX)
405 {
406 /* cppcheck-suppress misra-c2012-15.5 */
407 return ERROR;
408 }
409
410 uint8_t channelConfig = DetermineChannelConfig(config);
411
412 ERRCTRL_WriteConfigCfd1(channelConfig);
413
414 return NO_ERROR;
415}
416
417static errFlag_t ConfigCfm0(errChConfig_t config)
418{
419 // Ensure severity is valid
420 if (config.severity >= ERRCH_SEVERITY_MAX)
421 {
422 /* cppcheck-suppress misra-c2012-15.5 */
423 return ERROR;
424 }
425
426 uint8_t channelConfig = DetermineChannelConfig(config);
427
428 ERRCTRL_WriteConfigCfm0(channelConfig);
429
430 return NO_ERROR;
431}
432
433static errFlag_t ConfigCfm1(errChConfig_t config)
434{
435 // Ensure severity is valid
436 if (config.severity >= ERRCH_SEVERITY_MAX)
437 {
438 /* cppcheck-suppress misra-c2012-15.5 */
439 return ERROR;
440 }
441
442 uint8_t channelConfig = DetermineChannelConfig(config);
443
444 ERRCTRL_WriteConfigCfm1(channelConfig);
445
446 return NO_ERROR;
447}
448
449static errFlag_t ConfigSwdt(errChConfig_t config)
450{
451 // Ensure severity is valid
452 if (config.severity >= ERRCH_SEVERITY_MAX)
453 {
454 /* cppcheck-suppress misra-c2012-15.5 */
455 return ERROR;
456 }
457
458 uint8_t channelConfig = DetermineChannelConfig(config);
459
460 ERRCTRL_WriteConfigSwdt(channelConfig);
461
462 return NO_ERROR;
463}
464
465static errFlag_t ConfigEeprom(errChConfig_t config)
466{
467 // Ensure severity is valid
468 if (config.severity >= ERRCH_SEVERITY_MAX)
469 {
470 /* cppcheck-suppress misra-c2012-15.5 */
471 return ERROR;
472 }
473
474 uint8_t channelConfig = DetermineChannelConfig(config);
475
476 ERRCTRL_WriteConfigEeprom(channelConfig);
477
478 return NO_ERROR;
479}
480
481static errFlag_t ConfigEvsys0(errChConfig_t config)
482{
483 // Ensure severity is valid
484 if (config.severity >= ERRCH_SEVERITY_MAX)
485 {
486 /* cppcheck-suppress misra-c2012-15.5 */
487 return ERROR;
488 }
489
490 uint8_t channelConfig = DetermineChannelConfig(config);
491
492 ERRCTRL_WriteConfigEvsys0(channelConfig);
493
494 return NO_ERROR;
495}
496
497static errFlag_t ConfigEvsys1(errChConfig_t config)
498{
499 // Ensure severity is valid
500 if (config.severity >= ERRCH_SEVERITY_MAX)
501 {
502 /* cppcheck-suppress misra-c2012-15.5 */
503 return ERROR;
504 }
505
506 uint8_t channelConfig = DetermineChannelConfig(config);
507
508 ERRCTRL_WriteConfigEvsys1(channelConfig);
509
510 return NO_ERROR;
511}
errFlag_t
Defines the error flag used by Middleware services to indicate error detection.
@ NO_ERROR
uint8_t CPUCTRL_ReadStatusRegister(void)
Reads the SREG register value.
void CPUCTRL_ClearStatusRegister(uint8_t bitmask)
Clears specific bits in the SREG register.
void CPUCTRL_SetStatusRegister(uint8_t bitmask)
Sets specific bits in the SREG register.
uint8_t ERRCTRL_ReadControlA(void)
Reads the CTRLA register value.
void ERRCTRL_WriteConfigRam1(uint8_t value)
Overwrites the ESCRAM1 register value.
void ERRCTRL_WriteConfigSplim(uint8_t value)
Overwrites the ESCSPLIM register value.
void ERRCTRL_ClearControlA(uint8_t bitmask)
Clears specific bits in the CTRLA register.
void ERRCTRL_WriteConfigEeprom(uint8_t value)
Overwrites the ESCEEPROM register value.
void ERRCTRL_WriteConfigCfd0(uint8_t value)
Overwrites the ESCCFD0 register value.
void ERRCTRL_WriteConfigBuserr(uint8_t value)
Overwrites the ESCBUSERR register value.
void ERRCTRL_WriteConfigEvsys1(uint8_t value)
Overwrites the ESCEVSYS1 register value.
void ERRCTRL_WriteConfigCfd1(uint8_t value)
Overwrites the ESCCFD1 register value.
uint32_t ERRCTRL_ReadChannelStatus(void)
Reads the ESF register value.
void ERRCTRL_WriteConfigCfm1(uint8_t value)
Overwrites the ESCCFM1 register value.
void ERRCTRL_WriteConfigRam2(uint8_t value)
Overwrites the ESCRAM2 register value.
void ERRCTRL_WriteConfigVregfail(uint8_t value)
Overwrites the ESCVREGFAIL register value.
void ERRCTRL_WriteConfigFlash2(uint8_t value)
Overwrites the ESCFLASH2 register value.
void ERRCTRL_WriteConfigSwdt(uint8_t value)
Overwrites the ESCSWDT register value.
void ERRCTRL_WriteConfigFlash1(uint8_t value)
Overwrites the ESCFLASH1 register value.
void ERRCTRL_WriteConfigEvsys0(uint8_t value)
Overwrites the ESCEVSYS0 register value.
void ERRCTRL_WriteTimeoutValue(uint8_t value)
Overwrites the TIMEOUT register value.
void ERRCTRL_WriteConfigVregwarn(uint8_t value)
Overwrites the ESCVREGWARN register value.
uint8_t ERRCTRL_ReadStatusA(void)
Reads the STATUSA register value.
void ERRCTRL_SetControlA(uint8_t bitmask)
Sets specific bits in the CTRLA register.
void ERRCTRL_WriteConfigCfm0(uint8_t value)
Overwrites the ESCCFM0 register value.
void ERRCTRL_WriteConfigOpc(uint8_t value)
Overwrites the ESCOPC register value.
void ERRCTRL_WriteChannelStatus(uint32_t value)
Overwrites the ESF register value.
void ERRCTRL_ModifyControlA(uint8_t groupMask, uint8_t groupConfig)
Modifies specific bit field(s) in the CTRLA register.
errFlag_t MW_ClearErrorChannel(errCh_t ch)
Clears the specified error channel and confirms that the channel is cleared.
void MW_StopHeartbeat(void)
Stops the Heartbeat output signal.
errFlag_t MW_ConfigErrorChannels(const errChConfigs_t *configs, uint8_t timeout)
Sets the error controller timeout duration and configures all error channels with the provided settin...
errFlag_t MW_GetErrorChannel(errCh_t ch)
Reads the status of the specified error channel.
errFlag_t MW_DisableForceFloat(void)
Disables forced floating (tri-stating) of all I/O pins.
errCh_t
Hardware error channels found in the Error Controller.
void MW_StartHeartbeat(void)
Starts the Heartbeat output signal.
errFlag_t MW_CheckIoSafe(void)
Checks if all I/O pins are floated (tri-stated).
void MW_EnableForceFloat(void)
Enables forced floating (tri-stating) of all I/O pins.
@ ERRCH_SEVERITY_MAX
Holds an error channel configuration for configuring the ERRCTRL.
errChSeverity_t severity
Holds configurations for all error channels.