FuSa 8-Bit Libraries Safety Framework
Loading...
Searching...
No Matches
midware_memory_manager.c
Go to the documentation of this file.
1
22
23// Standard Library Includes
24#include <stdbool.h>
25#include <stdint.h>
26
27// Framework Includes
28#include <define_error_flags.h>
29#include <driver_cpuctrl.h>
30#include <driver_gpr.h>
31#include <driver_nvmctrl.h>
32#include <driver_ramctrl.h>
34
35// Device-specific Includes
36#include <xc.h>
37
38/*
39 * The GPR registers are utilized to store flags and values that needs to be persistent and kept
40 * through a non-POR/BOR device reset. The registers are shown below with bits and bit fields used
41 * to store the values. Each bit is defined with its own bitmask, and each bit field is defined with
42 * its own bit field position and group mask, except PVAL_ERRID_REASON in GPR0 as it occupies the
43 * entire register with it's value. All error flags are stored with two bits in redundant locations,
44 * where both bits need to be equal to be considered valid. The locations of the dual bits
45 * representing a flag are separated in the registers to minimize the probability of masking a
46 * corrupt flag should an unexpected reset occur. The bit fields are validated by a checksum which
47 * is calculated on each store operation and is checked for corruption using a dedicated function.
48 *
49 * | | Bit 7 | Bit 6 | Bit 5 | Bit 4 | Bit 3 | Bit 2 | Bit 1 | Bit 0 |
50 * |----|----------|----------|----------|----------|-----------|----------|-----------|----------|
51 * |GPR0| PVAL_ERRID_REASON [7:0] |
52 * |GPR1| PVAL_ERRINJ_REASON | PVAL_RESET_REASON [5:0] |
53 * |GPR2| PVAL_CHECKSUM [7:4] |IO_FLOAT0 |CPU_FAULT0|SWDT_FAULT0|WDT_FAULT0|
54 * |GPR3|IS_ERRINJ0|INV_INPUT0|IO_FAULT1 |CPU_FAULT1|SWDT_FAULT1|WDT_FAULT1|INV_INPUT1 |IS_ERRINJ1|
55 *
56 */
57
58// Used to store PVAL_ERRINJ_REASON
59#define GPR_ERRINJRSN_GP 6U
60#define GPR_ERRINJRSN_GM 0xC0U
61
62// Used to store PVAL_RESET_REASON
63#define GPR_RSTRSN_GP 0U
64#define GPR_RSTRSN_GM 0x3FU
65
66// Used to store PVAL_CHECKSUM
67#define GPR_CHECKSUM_GP 4U
68#define GPR_CHECKSUM_GM 0xF0U
69
70// Used to store PFLAG_IS_ERRINJ
71#define GPR_IS_ERRINJ0_BM 0x80U
72#define GPR_IS_ERRINJ1_BM 0x01U
73
74// Used to store PFLAG_CPU_INJ_FAULT
75#define GPR_CPU_FAULT0_BM 0x04U
76#define GPR_CPU_FAULT1_BM 0x10U
77
78// Used to store PFLAG_SWDT_INJ_FAULT
79#define GPR_SWDT_FAULT0_BM 0x02U
80#define GPR_SWDT_FAULT1_BM 0x08U
81
82// Used to store PFLAG_WDT_INJ_FAULT
83#define GPR_WDT_FAULT0_BM 0x01U
84#define GPR_WDT_FAULT1_BM 0x04U
85
86// Used to store PFLAG_IO_FLOAT_FAULT
87#define GPR_IO_FAULT0_BM 0x08U
88#define GPR_IO_FAULT1_BM 0x20U
89
90// Used to store INVALID_INPUT_FLAG
91#define GPR_INV_INPUT0_BM 0x40U
92#define GPR_INV_INPUT1_BM 0x02U
93
94// Private function prototypes
95static void SetFlagType(persistentFlag_t flagType);
96static void ClearFlagType(persistentFlag_t flagType);
97
98static void SetErrInjFlag(void);
99static void SetCpuInjFlag(void);
100static void SetWdtInjFlag(void);
101static void SetSwdtInjFlag(void);
102static void SetIoFloatFlag(void);
103static void SetInvalidInputFlag(void);
104
105static void ClearErrInjFlag(void);
106static void ClearCpuInjFlag(void);
107static void ClearWdtInjFlag(void);
108static void ClearSwdtInjFlag(void);
109static void ClearIoFloatFlag(void);
110
111static bool GetErrInjFlag(void);
112static bool GetCpuInjFlag(void);
113static bool GetWdtInjFlag(void);
114static bool GetSwdtInjFlag(void);
115static bool GetIoFloatFlag(void);
116static bool GetInvalidInputFlag(void);
117
118static bool IsErrInjFlagCorrupt(void);
119static bool IsCpuInjFlagCorrupt(void);
120static bool IsWdtInjFlagCorrupt(void);
121static bool IsSwdtInjFlagCorrupt(void);
122static bool IsIoFloatFlagCorrupt(void);
123static bool IsInvalidInputFlagCorrupt(void);
124
125static bool IsChecksumCorrupt(void);
126static void UpdateValsChecksum(void);
127static uint8_t CalculateChecksum(uint16_t value);
128static uint16_t ConcatPersistentVals(void);
129
131{
132 const uint8_t regVal = CPUCTRL_ReadIntFlags();
133 const uint8_t busErrMask = (uint8_t)CPU_BUSERR_bm;
134 const bool isBusError = ((regVal & busErrMask) == busErrMask);
135
136 errFlag_t flag = NO_ERROR;
137 if (isBusError)
138 {
139 flag = ERROR;
140 CPUCTRL_WriteIntFlags(busErrMask); // The flag is cleared by writing the flag bitmask
141 }
142
143 return flag;
144}
145
147{
148 const uint8_t regVal = CPUCTRL_ReadIntFlags();
149 const uint8_t dataParityMask = (uint8_t)CPU_PARITYD_bm;
150 const bool isParityError = ((regVal & dataParityMask) == dataParityMask);
151
152 errFlag_t flag = NO_ERROR;
153 if (isParityError)
154 {
155 flag = ERROR;
156 CPUCTRL_WriteIntFlags(dataParityMask); // The flag is cleared by writing the flag bitmask
157 }
158
159 return flag;
160}
161
163{
164 const uint8_t regVal = CPUCTRL_ReadIntFlags();
165 const uint8_t instrParityMask = (uint8_t)CPU_PARITYI_bm;
166 const bool isParityError = ((regVal & instrParityMask) == instrParityMask);
167
168 errFlag_t flag = NO_ERROR;
169 if (isParityError)
170 {
171 flag = ERROR;
172 CPUCTRL_WriteIntFlags(instrParityMask); // The flag is cleared by writing the flag bitmask
173 }
174
175 return flag;
176}
177
179{
180 const uint8_t regVal = CPUCTRL_ReadIntFlags();
181 const uint8_t opcodeMask = (uint8_t)CPU_OPC_bm;
182 const bool isOpcodeError = ((regVal & opcodeMask) == opcodeMask);
183
184 errFlag_t flag = NO_ERROR;
185 if (isOpcodeError)
186 {
187 flag = ERROR;
188 CPUCTRL_WriteIntFlags(opcodeMask); // The flag is cleared by writing the flag bitmask
189 }
190
191 return flag;
192}
193
195{
196 const uint8_t regVal = CPUCTRL_ReadIntFlags();
197 const uint8_t stackLimitMask = (uint8_t)CPU_SPLIM_bm;
198 const bool isStackError = ((regVal & stackLimitMask) == stackLimitMask);
199
200 errFlag_t flag = NO_ERROR;
201 if (isStackError)
202 {
203 flag = ERROR;
204 CPUCTRL_WriteIntFlags(stackLimitMask); // The flag is cleared by writing the flag bitmask
205 }
206
207 return flag;
208}
209
211{
212 const uint8_t regVal = RAMCTRL_ReadIntFlags();
213 const uint8_t eccCompMask = (uint8_t)RAMCTRL_COMP_bm;
214 const bool isEccError = ((regVal & eccCompMask) == eccCompMask);
215
216 errFlag_t flag = NO_ERROR;
217 if (isEccError)
218 {
219 flag = ERROR;
220 RAMCTRL_WriteIntFlags(eccCompMask); // The flag is cleared by writing the flag bitmask
221 }
222
223 return flag;
224}
225
227{
228 const uint8_t regVal = RAMCTRL_ReadIntFlags();
229 const uint8_t ecc1Mask = (uint8_t)RAMCTRL_ECC1_bm;
230 const bool isEcc1Error = ((regVal & ecc1Mask) == ecc1Mask);
231
232 errFlag_t flag = NO_ERROR;
233 if (isEcc1Error)
234 {
235 flag = ERROR;
236 RAMCTRL_WriteIntFlags(ecc1Mask); // The flag is cleared by writing the flag bitmask
237 }
238
239 return flag;
240}
241
243{
244 const uint8_t regVal = RAMCTRL_ReadIntFlags();
245 const uint8_t ecc2Mask = (uint8_t)RAMCTRL_ECC2_bm;
246 const bool isEcc2Error = ((regVal & ecc2Mask) == ecc2Mask);
247
248 errFlag_t flag = NO_ERROR;
249 if (isEcc2Error)
250 {
251 flag = ERROR;
252 RAMCTRL_WriteIntFlags(ecc2Mask); // The flag is cleared by writing the flag bitmask
253 }
254
255 return flag;
256}
257
259{
260 const uint8_t regVal = RAMCTRL_ReadIntFlags();
261 const uint8_t controlMask = (uint8_t)RAMCTRL_PARITYC_bm;
262 const uint8_t addressMask = (uint8_t)RAMCTRL_PARITYA_bm;
263 const uint8_t dataMask = (uint8_t)RAMCTRL_PARITYD_bm;
264 const uint8_t parityMask = (controlMask | addressMask | dataMask);
265 const bool isControlError = ((regVal & controlMask) == controlMask);
266 const bool isAddressError = ((regVal & addressMask) == addressMask);
267 const bool isDataError = ((regVal & dataMask) == dataMask);
268
269 errFlag_t flag = NO_ERROR;
270 if (isControlError || isAddressError || isDataError)
271 {
272 flag = ERROR;
273 RAMCTRL_WriteIntFlags(parityMask); // The flag is cleared by writing the flag bitmask
274 }
275
276 return flag;
277}
278
280{
281 const uint8_t regVal = NVMCTRL_ReadIntFlagsB();
282 const uint8_t eccCompMask = (uint8_t)NVMCTRL_COMP_bm;
283 const bool isCompError = ((regVal & eccCompMask) == eccCompMask);
284
285 errFlag_t flag = NO_ERROR;
286 if (isCompError)
287 {
288 flag = ERROR;
289 NVMCTRL_WriteIntFlagsB(eccCompMask); // The flag is cleared by writing the flag bitmask
290 }
291
292 return flag;
293}
294
296{
297 const uint8_t regVal = NVMCTRL_ReadIntFlagsB();
298 const uint8_t flashEcc1Mask = (uint8_t)NVMCTRL_FECC1_bm;
299 const bool isEcc1Error = ((regVal & flashEcc1Mask) == flashEcc1Mask);
300
301 errFlag_t flag = NO_ERROR;
302 if (isEcc1Error)
303 {
304 flag = ERROR;
305 NVMCTRL_WriteIntFlagsB(flashEcc1Mask); // The flag is cleared by writing the flag bitmask
306 }
307
308 return flag;
309}
310
312{
313 const uint8_t regVal = NVMCTRL_ReadIntFlagsB();
314 const uint8_t flashEcc2Mask = (uint8_t)NVMCTRL_FECC2_bm;
315 const bool isEcc2Error = ((regVal & flashEcc2Mask) == flashEcc2Mask);
316
317 errFlag_t flag = NO_ERROR;
318 if (isEcc2Error)
319 {
320 flag = ERROR;
321 NVMCTRL_WriteIntFlagsB(flashEcc2Mask); // The flag is cleared by writing the flag bitmask
322 }
323
324 return flag;
325}
326
328{
329 const uint8_t regVal = NVMCTRL_ReadIntFlagsB();
330 const uint8_t controlMask = (uint8_t)NVMCTRL_PARITYC_bm;
331 const uint8_t addressMask = (uint8_t)NVMCTRL_PARITYA_bm;
332 const uint8_t dataMask = (uint8_t)NVMCTRL_PARITYD_bm;
333 const uint8_t parityMask = (controlMask | addressMask | dataMask);
334 const bool isControlError = ((regVal & controlMask) == controlMask);
335 const bool isAddressError = ((regVal & addressMask) == addressMask);
336 const bool isDataError = ((regVal & dataMask) == dataMask);
337
338 errFlag_t flag = NO_ERROR;
339 if (isControlError || isAddressError || isDataError)
340 {
341 flag = ERROR;
342 NVMCTRL_WriteIntFlagsB(parityMask); // The flag is cleared by writing the flag bitmask
343 }
344
345 return flag;
346}
347
349{
350 const uint8_t regVal = NVMCTRL_ReadIntFlagsB();
351 const uint8_t eepromEcc1Mask = (uint8_t)NVMCTRL_EECC1_bm;
352 const bool isEcc1Error = ((regVal & eepromEcc1Mask) == eepromEcc1Mask);
353
354 errFlag_t flag = NO_ERROR;
355 if (isEcc1Error)
356 {
357 flag = ERROR;
358 NVMCTRL_WriteIntFlagsB(eepromEcc1Mask); // The flag is cleared by writing the flag bitmask
359 }
360
361 return flag;
362}
363
365{
366 const uint8_t regVal = NVMCTRL_ReadIntFlagsB();
367 const uint8_t eepromEcc2Mask = (uint8_t)NVMCTRL_EECC2_bm;
368 const bool isEcc2Error = ((regVal & eepromEcc2Mask) == eepromEcc2Mask);
369
370 errFlag_t flag = NO_ERROR;
371 if (isEcc2Error)
372 {
373 flag = ERROR;
374 NVMCTRL_WriteIntFlagsB(eepromEcc2Mask); // The flag is cleared by writing the flag bitmask
375 }
376
377 return flag;
378}
379
381{
382 if (config >= ECC_ALL_ONES_MAX)
383 {
384 /* cppcheck-suppress misra-c2012-15.5 */
385 return ERROR;
386 }
387
388 const uint8_t eccAllOnesMask = (uint8_t)NVMCTRL_ECCALL1_gm;
389 const uint8_t groupConfig = ((uint8_t)config << NVMCTRL_ECCALL1_gp);
390 NVMCTRL_ModifyControlC(eccAllOnesMask, groupConfig);
391
392 return NO_ERROR;
393}
394
395errFlag_t MW_SetRamStackLimit(uint16_t splimAddr, bool lockEnable)
396{
397 const uint16_t ramAddrStart = INTERNAL_SRAM_START;
398 const uint16_t ramAddrEnd = INTERNAL_SRAM_START + INTERNAL_SRAM_SIZE - 1U;
399 const bool isInvalidRamAddr = ((splimAddr < ramAddrStart) || (splimAddr > ramAddrEnd));
400 if (isInvalidRamAddr)
401 {
402 /* cppcheck-suppress misra-c2012-15.5 */
403 return ERROR;
404 }
405
406 CPUCTRL_WriteSplim(splimAddr);
407
408 if (lockEnable)
409 {
410 CPUCTRL_SetControlA((uint8_t)CPU_SPLOCK_bm);
411 }
412
413 return NO_ERROR;
414}
415
417{
418 if (flagType >= PFLAG_MAX)
419 {
420 // Set error flag indicating that function was called with invalid input
421 SetInvalidInputFlag();
422
423 /* cppcheck-suppress misra-c2012-15.5 */
424 return; // Invalid input flag is checked when checking persistent flag corruption later
425 }
426
427 if (flag)
428 {
429 SetFlagType(flagType);
430 }
431 else
432 {
433 ClearFlagType(flagType);
434 }
435}
436
437void MW_StorePersistentVal(persistentVal_t valueType, uint8_t value)
438{
439 if (valueType >= PVAL_MAX)
440 {
441 // Set error flag indicating that function was called with invalid input
442 SetInvalidInputFlag();
443
444 /* cppcheck-suppress misra-c2012-15.5 */
445 return; // Invalid input flag is checked when checking persistent value corruption later
446 }
447
448 if (IsChecksumCorrupt())
449 {
450 /* cppcheck-suppress misra-c2012-15.5 */
451 return; // Abort to prevent a new checksum to be calculated with corrupted data
452 }
453
454 uint8_t rstRsnConfig = value << GPR_RSTRSN_GP;
455 uint8_t errInjConfig = value << GPR_ERRINJRSN_GP;
456
457 if (PVAL_ERRID_REASON == valueType)
458 {
459 GPR_WriteRegister0(value);
460 }
461 else if (PVAL_RESET_REASON == valueType)
462 {
463
464 GPR_ModifyRegister1(GPR_RSTRSN_GM, rstRsnConfig);
465 }
466 else // PVAL_ERRINJ_REASON == valueType
467 {
469 }
470
471 // Calculate and store new checksum
472 UpdateValsChecksum();
473}
474
476{
477 bool isFlagSet = false; // Default to not set if invalid flag type
478
479 switch (flagType)
480 {
482 isFlagSet = GetErrInjFlag();
483 break;
485 isFlagSet = GetCpuInjFlag();
486 break;
488 isFlagSet = GetWdtInjFlag();
489 break;
491 isFlagSet = GetSwdtInjFlag();
492 break;
494 isFlagSet = GetIoFloatFlag();
495 break;
496 default:
497 SetInvalidInputFlag();
498 break;
499 }
500
501 return isFlagSet;
502}
503
505{
506 uint8_t persistentVal = 0xFFU; // Default to max type value if invalid value type is requested
507
508 if (valueType >= PVAL_MAX)
509 {
510 // Set error flag indicating that function was called with invalid input
511 SetInvalidInputFlag();
512
513 /* cppcheck-suppress misra-c2012-15.5 */
514 return persistentVal; // Invalid input flag is checked later
515 }
516
517 if (PVAL_ERRID_REASON == valueType)
518 {
519 persistentVal = GPR_ReadRegister0();
520 }
521 else
522 {
523 uint8_t gprRegVal1 = GPR_ReadRegister1();
524 if (PVAL_RESET_REASON == valueType)
525 {
526 persistentVal = gprRegVal1 >> GPR_RSTRSN_GP;
527 }
528 else // PVAL_ERRINJ_REASON == valueType
529 {
530 persistentVal = gprRegVal1 >> GPR_ERRINJRSN_GP;
531 }
532 }
533 return persistentVal;
534}
535
537{
538 // Persistent data was attempted accessed with invalid flag/value type, flags cannot be trusted
539 bool wasInvalidInput = IsInvalidInputFlagCorrupt() || GetInvalidInputFlag();
540 if (wasInvalidInput)
541 {
542 /* cppcheck-suppress misra-c2012-15.5 */
543 return true;
544 }
545
546 if (IsIoFloatFlagCorrupt())
547 {
548 /* cppcheck-suppress misra-c2012-15.5 */
549 return true;
550 }
551
552 if (IsErrInjFlagCorrupt())
553 {
554 /* cppcheck-suppress misra-c2012-15.5 */
555 return true;
556 }
557
558 if (IsCpuInjFlagCorrupt())
559 {
560 /* cppcheck-suppress misra-c2012-15.5 */
561 return true;
562 }
563
564 if (IsWdtInjFlagCorrupt())
565 {
566 /* cppcheck-suppress misra-c2012-15.5 */
567 return true;
568 }
569
570 if (IsSwdtInjFlagCorrupt())
571 {
572 /* cppcheck-suppress misra-c2012-15.5 */
573 return true;
574 }
575
576 return false;
577}
578
580{
581 // Persistent data was attempted accessed with invalid flag/value type, values cannot be trusted
582 bool wasInvalidInput = GetInvalidInputFlag();
583 bool isValsCorrupted = IsChecksumCorrupt();
584 bool isCorrupted = wasInvalidInput || isValsCorrupted;
585
586 return isCorrupted;
587}
588
590{
591 const uint8_t clearValue = 0x00U;
592 const uint8_t clearMask
594
595 GPR_ModifyRegister2(clearMask, clearValue); // Only clear flags in GPR2
596 GPR_WriteRegister3(clearValue);
597}
598
600{
601 const uint8_t clearValue = 0x00U;
602
603 GPR_WriteRegister0(clearValue);
604 GPR_WriteRegister1(clearValue);
606}
607
608// Sets the specified flag to true
609static void SetFlagType(persistentFlag_t flagType)
610{
611 switch (flagType)
612 {
614 SetErrInjFlag();
615 break;
617 SetCpuInjFlag();
618 break;
620 SetWdtInjFlag();
621 break;
623 SetSwdtInjFlag();
624 break;
626 default:
627 SetIoFloatFlag();
628 break;
629 }
630}
631
632// Sets the specified flag to false
633static void ClearFlagType(persistentFlag_t flagType)
634{
635 switch (flagType)
636 {
638 ClearErrInjFlag();
639 break;
641 ClearCpuInjFlag();
642 break;
644 ClearWdtInjFlag();
645 break;
647 ClearSwdtInjFlag();
648 break;
650 default:
651 ClearIoFloatFlag();
652 break;
653 }
654}
655
656// Stores PFLAG_IS_ERRINJ as true
657static void SetErrInjFlag(void)
658{
659 const uint8_t combinedMask = GPR_IS_ERRINJ0_BM | GPR_IS_ERRINJ1_BM;
660 GPR_SetRegister3(combinedMask);
661}
662
663// Stores PFLAG_CPU_INJ_FAULT as true
664static void SetCpuInjFlag(void)
665{
668}
669
670// Stores PFLAG_WDT_INJ_FAULT as true
671static void SetWdtInjFlag(void)
672{
675}
676
677// Stores PFLAG_SWDT_INJ_FAULT as true
678static void SetSwdtInjFlag(void)
679{
682}
683
684// Stores PFLAG_IO_FLOAT_FAULT as true
685static void SetIoFloatFlag(void)
686{
689}
690
691// Stores Invalid Input flag as true
692static void SetInvalidInputFlag(void)
693{
694 const uint8_t combinedMask = GPR_INV_INPUT0_BM | GPR_INV_INPUT1_BM;
695 GPR_SetRegister3(combinedMask);
696}
697
698// Stores PFLAG_IS_ERRINJ as false
699static void ClearErrInjFlag(void)
700{
701 const uint8_t combinedMask = GPR_IS_ERRINJ0_BM | GPR_IS_ERRINJ1_BM;
702 GPR_ClearRegister3(combinedMask);
703}
704
705// Stores PFLAG_CPU_INJ_FAULT as false
706static void ClearCpuInjFlag(void)
707{
710}
711
712// Stores PFLAG_WDT_INJ_FAULT as false
713static void ClearWdtInjFlag(void)
714{
717}
718
719// Stores PFLAG_SWDT_INJ_FAULT as false
720static void ClearSwdtInjFlag(void)
721{
724}
725
726// Stores PFLAG_IO_FLOAT_FAULT as false
727static void ClearIoFloatFlag(void)
728{
731}
732
733// Checks if PFLAG_IS_ERRINJ is stored as true or false
734static bool GetErrInjFlag(void)
735{
736 const uint8_t combinedMask = GPR_IS_ERRINJ0_BM | GPR_IS_ERRINJ1_BM;
737 uint8_t gprRegVal3 = GPR_ReadRegister3();
738 bool isBothBitsSet = ((gprRegVal3 & combinedMask) == combinedMask);
739
740 return isBothBitsSet;
741}
742
743// Checks if PFLAG_CPU_INJ_FAULT is true or false
744static bool GetCpuInjFlag(void)
745{
746 uint8_t gprRegVal2 = GPR_ReadRegister2();
747 uint8_t gprRegVal3 = GPR_ReadRegister3();
748 bool cpuInjFlag0 = ((gprRegVal2 & GPR_CPU_FAULT0_BM) == GPR_CPU_FAULT0_BM);
749 bool cpuInjFlag1 = ((gprRegVal3 & GPR_CPU_FAULT1_BM) == GPR_CPU_FAULT1_BM);
750
751 return (cpuInjFlag0 && cpuInjFlag1) == true;
752}
753
754// Checks if PFLAG_WDT_INJ_FAULT is true or false
755static bool GetWdtInjFlag(void)
756{
757 uint8_t gprRegVal2 = GPR_ReadRegister2();
758 uint8_t gprRegVal3 = GPR_ReadRegister3();
759 bool wdtInjFlag0 = ((gprRegVal2 & GPR_WDT_FAULT0_BM) == GPR_WDT_FAULT0_BM);
760 bool wdtInjFlag1 = ((gprRegVal3 & GPR_WDT_FAULT1_BM) == GPR_WDT_FAULT1_BM);
761
762 return (wdtInjFlag0 && wdtInjFlag1) == true;
763}
764
765// Checks if PFLAG_SWDT_INJ_FAULT is true or false
766static bool GetSwdtInjFlag(void)
767{
768 uint8_t gprRegVal2 = GPR_ReadRegister2();
769 uint8_t gprRegVal3 = GPR_ReadRegister3();
770 bool swdtInjFlag0 = ((gprRegVal2 & GPR_SWDT_FAULT0_BM) == GPR_SWDT_FAULT0_BM);
771 bool swdtInjFlag1 = ((gprRegVal3 & GPR_SWDT_FAULT1_BM) == GPR_SWDT_FAULT1_BM);
772
773 return (swdtInjFlag0 && swdtInjFlag1) == true;
774}
775
776// Checks if PFLAG_IO_FLOAT_FAULT is true or false
777static bool GetIoFloatFlag(void)
778{
779 uint8_t gprRegVal2 = GPR_ReadRegister2();
780 uint8_t gprRegVal3 = GPR_ReadRegister3();
781 bool ioFloatFlag0 = ((gprRegVal2 & GPR_IO_FAULT0_BM) == GPR_IO_FAULT0_BM);
782 bool ioFloatFlag1 = ((gprRegVal3 & GPR_IO_FAULT1_BM) == GPR_IO_FAULT1_BM);
783
784 return (ioFloatFlag0 && ioFloatFlag1) == true;
785}
786
787// Checks if Invalid Input flag is true or false
788static bool GetInvalidInputFlag(void)
789{
790 const uint8_t combinedMask = GPR_INV_INPUT0_BM | GPR_INV_INPUT1_BM;
791 uint8_t gprRegVal3 = GPR_ReadRegister3();
792 bool isBothBitsSet = ((gprRegVal3 & combinedMask) == combinedMask);
793
794 return isBothBitsSet;
795}
796
797// Checks whether the two PFLAG_IS_ERRINJ bits have the same value or is corrupt
798static bool IsErrInjFlagCorrupt(void)
799{
800 uint8_t gprRegVal3 = GPR_ReadRegister3();
801 bool isFlagBit0Set = ((gprRegVal3 & GPR_IS_ERRINJ0_BM) == GPR_IS_ERRINJ0_BM);
802 bool isFlagBit1Set = ((gprRegVal3 & GPR_IS_ERRINJ1_BM) == GPR_IS_ERRINJ1_BM);
803
804 bool isCorrupt = true;
805 if (isFlagBit0Set == isFlagBit1Set)
806 {
807 isCorrupt = false;
808 }
809
810 return isCorrupt;
811}
812
813// Checks whether the two PFLAG_CPU_INJ_FAULT bits have the same value or is corrupt
814static bool IsCpuInjFlagCorrupt(void)
815{
816 uint8_t gprRegVal2 = GPR_ReadRegister2();
817 uint8_t gprRegVal3 = GPR_ReadRegister3();
818 bool cpuInjFlag0 = ((gprRegVal2 & GPR_CPU_FAULT0_BM) == GPR_CPU_FAULT0_BM);
819 bool cpuInjFlag1 = ((gprRegVal3 & GPR_CPU_FAULT1_BM) == GPR_CPU_FAULT1_BM);
820
821 bool isCorrupt = true;
822 if (cpuInjFlag0 == cpuInjFlag1)
823 {
824 isCorrupt = false;
825 }
826
827 return isCorrupt;
828}
829
830// Checks whether the two PFLAG_WDT_INJ_FAULT bits have the same value or is corrupt
831static bool IsWdtInjFlagCorrupt(void)
832{
833 uint8_t gprRegVal2 = GPR_ReadRegister2();
834 uint8_t gprRegVal3 = GPR_ReadRegister3();
835 bool wdtInjFlag0 = ((gprRegVal2 & GPR_WDT_FAULT0_BM) == GPR_WDT_FAULT0_BM);
836 bool wdtInjFlag1 = ((gprRegVal3 & GPR_WDT_FAULT1_BM) == GPR_WDT_FAULT1_BM);
837
838 bool isCorrupt = true;
839 if (wdtInjFlag0 == wdtInjFlag1)
840 {
841 isCorrupt = false;
842 }
843
844 return isCorrupt;
845}
846
847// Checks whether the two PFLAG_SWDT_INJ_FAULT bits have the same value or is corrupt
848static bool IsSwdtInjFlagCorrupt(void)
849{
850 uint8_t gprRegVal2 = GPR_ReadRegister2();
851 uint8_t gprRegVal3 = GPR_ReadRegister3();
852 bool swdtInjFlag0 = ((gprRegVal2 & GPR_SWDT_FAULT0_BM) == GPR_SWDT_FAULT0_BM);
853 bool swdtInjFlag1 = ((gprRegVal3 & GPR_SWDT_FAULT1_BM) == GPR_SWDT_FAULT1_BM);
854
855 bool isCorrupt = true;
856 if (swdtInjFlag0 == swdtInjFlag1)
857 {
858 isCorrupt = false;
859 }
860
861 return isCorrupt;
862}
863
864// Checks whether the two PFLAG_IO_FLOAT_FAULT bits have the same value or is corrupt
865static bool IsIoFloatFlagCorrupt(void)
866{
867 uint8_t gprRegVal2 = GPR_ReadRegister2();
868 uint8_t gprRegVal3 = GPR_ReadRegister3();
869 bool ioFloatFlag0 = ((gprRegVal2 & GPR_IO_FAULT0_BM) == GPR_IO_FAULT0_BM);
870 bool ioFloatFlag1 = ((gprRegVal3 & GPR_IO_FAULT1_BM) == GPR_IO_FAULT1_BM);
871
872 bool isCorrupt = true;
873 if (ioFloatFlag0 == ioFloatFlag1)
874 {
875 isCorrupt = false;
876 }
877
878 return isCorrupt;
879}
880
881// Checks whether the two Invalid Input flag bits have the same value or is corrupt
882static bool IsInvalidInputFlagCorrupt(void)
883{
884 uint8_t gprRegVal3 = GPR_ReadRegister3();
885 bool invalidFlag0 = ((gprRegVal3 & GPR_INV_INPUT0_BM) == GPR_INV_INPUT0_BM);
886 bool invalidFlag1 = ((gprRegVal3 & GPR_INV_INPUT1_BM) == GPR_INV_INPUT1_BM);
887
888 bool isCorrupt = true;
889 if (invalidFlag0 == invalidFlag1)
890 {
891 isCorrupt = false;
892 }
893
894 return isCorrupt;
895}
896
897// Checks if stored checksum has been corrupted
898static bool IsChecksumCorrupt(void)
899{
900 uint16_t persistentVals = ConcatPersistentVals();
901
902 uint8_t currentChecksum = CalculateChecksum(persistentVals);
903 uint8_t regVal = GPR_ReadRegister2();
904 uint8_t storedChecksum = regVal >> GPR_CHECKSUM_GP;
905
906 bool isCorrupt = (currentChecksum != storedChecksum);
907
908 return isCorrupt;
909}
910
911// Stores new checksum in GPR2 register
912static void UpdateValsChecksum(void)
913{
914 uint16_t persistentVals = ConcatPersistentVals();
915
916 uint8_t newChecksum = CalculateChecksum(persistentVals);
917
918 uint8_t checksumConfig = newChecksum << GPR_CHECKSUM_GP;
919 GPR_ModifyRegister2(GPR_CHECKSUM_GM, checksumConfig);
920}
921
922// Calculates new checksum for GPR0 and GPR1 registers
923static uint8_t CalculateChecksum(uint16_t value)
924{
925 uint16_t shiftedVal = value;
926 uint8_t numOnes = 0U;
927
928 while (shiftedVal != 0U)
929 {
930 numOnes += (uint8_t)(shiftedVal & 1U);
931 shiftedVal = shiftedVal >> 1;
932 }
933
934 return numOnes;
935}
936
937// Concatenates the two 8-bit GPR0 (MSB) and GPR1 (LSB) registers to a 16-bit value
938static uint16_t ConcatPersistentVals(void)
939{
940 uint16_t concatVals = (uint16_t)GPR_ReadRegister0() << 8;
941 concatVals |= (uint16_t)GPR_ReadRegister1();
942 return concatVals;
943}
Defines error flag type for indicating detected errors in Middleware services.
errFlag_t
Defines the error flag used by Middleware services to indicate error detection.
@ NO_ERROR
void CPUCTRL_WriteSplim(uint16_t value)
Overwrites the SPLIM register value.
void CPUCTRL_SetControlA(uint8_t bitmask)
Sets specific bits in the CTRLA register.
uint8_t CPUCTRL_ReadIntFlags(void)
Reads the INTFLAGS register value.
void CPUCTRL_WriteIntFlags(uint8_t value)
Overwrites the INTFLAGS register value.
uint8_t GPR_ReadRegister2(void)
Reads the GPR2 register value.
Definition driver_gpr.c:62
void GPR_ModifyRegister1(uint8_t groupMask, uint8_t groupConfig)
Modifies specific bit field(s) in the GPR1 register.
Definition driver_gpr.c:52
void GPR_ClearRegister2(uint8_t bitmask)
Clears specific bits in the GPR2 register.
Definition driver_gpr.c:77
void GPR_ModifyRegister2(uint8_t groupMask, uint8_t groupConfig)
Modifies specific bit field(s) in the GPR2 register.
Definition driver_gpr.c:82
uint8_t GPR_ReadRegister1(void)
Reads the GPR1 register value.
Definition driver_gpr.c:42
void GPR_WriteRegister0(uint8_t value)
Overwrites the GPR0 register value.
Definition driver_gpr.c:37
void GPR_ClearRegister3(uint8_t bitmask)
Clears specific bits in the GPR3 register.
Definition driver_gpr.c:107
void GPR_WriteRegister3(uint8_t value)
Overwrites the GPR3 register value.
Definition driver_gpr.c:97
void GPR_SetRegister2(uint8_t bitmask)
Sets specific bits in the GPR2 register.
Definition driver_gpr.c:72
uint8_t GPR_ReadRegister3(void)
Reads the GPR3 register value.
Definition driver_gpr.c:92
uint8_t GPR_ReadRegister0(void)
Reads the GPR0 register value.
Definition driver_gpr.c:32
void GPR_SetRegister3(uint8_t bitmask)
Sets specific bits in the GPR3 register.
Definition driver_gpr.c:102
void GPR_WriteRegister1(uint8_t value)
Overwrites the GPR1 register value.
Definition driver_gpr.c:47
void MW_ClearPersistentVals(void)
Clears all stored persistent values in GPR.
void MW_StorePersistentVal(persistentVal_t valueType, uint8_t value)
Stores a value in General Purpose Registers (GPR) for perserving data between resets.
errFlag_t MW_SetRamStackLimit(uint16_t splimAddr, bool lockEnable)
Sets the Stack Pointer Limit value and optionally locks the value to prevent modification.
persistentVal_t
Enum for persistent values used to store data between non-POR/BOR device resets.
errFlag_t MW_GetClearRamParityError(void)
Reads and clears the flag indicating a bus parity error detected in the RAM controller.
errFlag_t MW_GetClearNvmEepromEcc2Error(void)
Reads and clears the flag indicating an ECC multi-bit error in EEPROM.
errFlag_t MW_GetClearNvmFlashEcc1Error(void)
Reads and clears the flag indicating a ECC single-bit error in Flash.
void MW_StorePersistentFlag(persistentFlag_t flagType, bool flag)
Stores two redundant boolean flags in General Purpose Registers (GPR) for perserving data between res...
bool MW_GetPersistentFlag(persistentFlag_t flagType)
Reads two redundant bits for each boolean flags in General Purpose Registers (GPR) that is stored for...
bool MW_IsPersistentFlagsCorrupt(void)
Compares two redundant bits for each boolean flags in General Purpose Registers (GPR) and checks if a...
errFlag_t MW_GetClearCpuDataParityError(void)
Reads and clears the flag indicating a data bus parity error in the CPU.
persistentFlag_t
Enum for persistent flags used to store data between non-POR/BOR device resets.
errFlag_t MW_GetClearNvmEccCompError(void)
Reads and clears the flag indicating a ECC comparator error in the NVM controller.
errFlag_t MW_SetNvmEccAllOnes(eccAllOnes_t config)
Sets ECC all Ones (ECCALL1) scheme.
void MW_ClearPersistentFlags(void)
Clears all stored persistent flags in GPR.
errFlag_t MW_GetClearCpuInstrParityError(void)
Reads and clears the flag indicating a instruction bus parity error in the CPU.
uint8_t MW_GetPersistentVal(persistentVal_t valueType)
Reads a value in General Purpose Registers (GPR) that is stored for preserving data between resets.
bool MW_IsPersistentValsCorrupt(void)
Checks if any of the stored persistent values are corrupted.
eccAllOnes_t
Type defines for available "ECC all ones" (ECCALL1) options.
errFlag_t MW_GetClearNvmEepromEcc1Error(void)
Reads and clears the flag indicating an ECC single-bit error in EEPROM.
errFlag_t MW_GetClearNvmParityError(void)
Reads and clears the flag indicating a bus parity error detected in the NVM controller.
errFlag_t MW_GetClearNvmFlashEcc2Error(void)
Reads and clears the flag indicating a ECC multi-bit error in Flash.
errFlag_t MW_GetClearCpuOpcodeError(void)
Reads and clears the flag indicating an illegal opcode error in the CPU.
errFlag_t MW_GetClearRamStackError(void)
Reads and clears the flag indicating a stack pointer limit error in SRAM.
errFlag_t MW_GetClearRamEccCompError(void)
Reads and clears the flag indicating a ECC comparator error in the RAM controller.
errFlag_t MW_GetClearRamEcc1Error(void)
Reads and clears the flag indicating an ECC single-bit error in SRAM.
errFlag_t MW_GetClearBusError(void)
Reads and clears the flag indicating an error in the Bus Matrix.
errFlag_t MW_GetClearRamEcc2Error(void)
Reads and clears the flag indicating an ECC multi-bit error in SRAM.
@ PVAL_RESET_REASON
@ PVAL_ERRID_REASON
@ PFLAG_WDT_INJ_FAULT
@ PFLAG_ERRINJ_ONGOING
@ PFLAG_IO_FLOAT_FAULT
@ PFLAG_CPU_INJ_FAULT
@ PFLAG_SWDT_INJ_FAULT
uint8_t NVMCTRL_ReadIntFlagsB(void)
Reads the INTFLAGSB register value.
void NVMCTRL_WriteIntFlagsB(uint8_t value)
Overwrites the INTFLAGSB register value.
void NVMCTRL_ModifyControlC(uint8_t groupMask, uint8_t groupConfig)
Modifies specific bit field(s) in the CTRLC register.
uint8_t RAMCTRL_ReadIntFlags(void)
Reads the INTFLAGS register value.
void RAMCTRL_WriteIntFlags(uint8_t value)
Overwrites the INTFLAGS register value.
#define GPR_CHECKSUM_GP
#define GPR_IO_FAULT0_BM
#define GPR_INV_INPUT0_BM
#define GPR_CPU_FAULT1_BM
#define GPR_WDT_FAULT1_BM
#define GPR_IS_ERRINJ0_BM
#define GPR_INV_INPUT1_BM
#define GPR_ERRINJRSN_GP
#define GPR_IS_ERRINJ1_BM
#define GPR_RSTRSN_GP
#define GPR_WDT_FAULT0_BM
#define GPR_CPU_FAULT0_BM
#define GPR_CHECKSUM_GM
#define GPR_SWDT_FAULT0_BM
#define GPR_SWDT_FAULT1_BM
#define GPR_ERRINJRSN_GM
#define GPR_IO_FAULT1_BM
#define GPR_RSTRSN_GM