FuSa 8-Bit Libraries Safety Framework
Loading...
Searching...
No Matches
midware_reset_manager.c
Go to the documentation of this file.
1
22
23// Standard Library Includes
24#include <stdbool.h>
25
26// Framework includes
27#include <driver_errctrl.h>
28#include <driver_rstctrl.h>
29#include <driver_wdt.h>
31
32// Device-specific Includes
33#include <xc.h>
34
35// Private function prototypes
36static uint8_t GetClearResetFlagPosition(void);
37static resetReason_t GetClearMachineCheckReason(void);
38static uint8_t GetClearMachineCheckMask(void);
39static resetReason_t GetErrorControllerReason(void);
40static resetReason_t GetWatchdogReason(void);
41
43{
44 RSTCTRL_WriteSoftwareResetRegister((uint8_t)RSTCTRL_SWRST_bm);
45}
46
48{
49 const uint8_t flagPos = GetClearResetFlagPosition();
50 const uint8_t machineCheckPos = (uint8_t)RSTCTRL_MCRF_bp;
51 const uint8_t errorControllerPos = (uint8_t)RSTCTRL_ECRF_bp;
52 const uint8_t watchdogPos = (uint8_t)RSTCTRL_WDRF_bp;
53
54 resetReason_t resetReason = RSTRSN_UNKNOWN;
55 if (flagPos == machineCheckPos) // Check if machine check reset
56 {
57 resetReason = GetClearMachineCheckReason();
58 }
59 else if (flagPos == errorControllerPos) // Check if error controller reset
60 {
61 resetReason = GetErrorControllerReason();
62 }
63 else if (flagPos == watchdogPos) // Check if watchdog reset
64 {
65 resetReason = GetWatchdogReason();
66 }
67 else
68 {
69 const uint8_t msb = 7U;
70 if (flagPos <= msb) // Ensure the flag position is within the valid range
71 {
72 // Calculate the reset reason enum value based on the flag position
73 const uint8_t flagOffset = (uint8_t)RSTRSN_POWER_ON;
74 const uint8_t reasonVal = flagOffset + flagPos;
75
76 /* Intentional misra-c2012-10.5 deviation */
77 resetReason = (resetReason_t)(reasonVal);
78 }
79 }
80
81 return resetReason;
82}
83
84// Locates first set bit and returns its corresponding bit position
85static uint8_t GetClearResetFlagPosition(void)
86{
87 const uint8_t allFlagsMask = 0xFFU;
88 const uint8_t resetFlags = RSTCTRL_ReadResetFlagRegister();
89 RSTCTRL_WriteResetFlagRegister(allFlagsMask); // Clear all flags
90 uint8_t flagPosition = 0xFFU; // Default to invalid position in case none are set
91
92 // Check from most significant bit (MSb) to least significant bit (LSb)
93 const int8_t msb = 7;
94 for (int8_t bitPos = msb; bitPos >= 0; bitPos--)
95 {
96 // Check if bit is set
97 uint8_t flagMask = ((uint8_t)1 << (uint8_t)bitPos);
98 if ((resetFlags & flagMask) == flagMask)
99 {
100 // Store flag position, exit loop
101 flagPosition = (uint8_t)bitPos;
102 break;
103 }
104 }
105 return flagPosition;
106}
107
108static resetReason_t GetClearMachineCheckReason(void)
109{
111 uint8_t machineCheckPosition = GetClearMachineCheckMask();
112
113 const uint8_t msb = 9U;
114 if (machineCheckPosition <= msb) // Check if the flag position is within valid range
115 {
116 // Calculate the reset reason based on the flag position
117 const uint8_t machineCheckOffset = (uint8_t)RSTRSN_MCHK_OCD;
118 const uint8_t reasonVal = machineCheckOffset + machineCheckPosition;
119
120 /* Intentional misra-c2012-10.5 deviation */
121 resetReason = (resetReason_t)(reasonVal);
122 }
123
124 return resetReason;
125}
126
127static uint8_t GetClearMachineCheckMask(void)
128{
129 const uint8_t allFlagsMask = 0xFFU;
130 uint16_t resetFlags = (uint16_t)RSTCTRL_ReadMachineCheckFlagsA();
131 resetFlags |= (uint16_t)RSTCTRL_ReadMachineCheckFlagsB() << 8;
133 RSTCTRL_WriteMachineCheckFlagsB((uint8_t)RSTCTRL_UPDI_bm | (uint8_t)RSTCTRL_CFD_bm);
134 uint8_t machineCheckPosition = 0xFFU; // Default to invalid position in case none are set
135
136 // Check from most significant bit (msb) to least significant bit (lsb)
137 const int8_t msb = 9;
138 for (int8_t bitPos = msb; bitPos >= 0; bitPos--)
139 {
140 // Check if bit is set
141 const uint16_t flagMask = (uint16_t)1U << (uint8_t)bitPos;
142 if ((resetFlags & flagMask) == flagMask)
143 {
144 // Store flag position, exit loop
145 machineCheckPosition = (uint8_t)bitPos;
146 break;
147 }
148 }
149 return machineCheckPosition;
150}
151
152static resetReason_t GetErrorControllerReason(void)
153{
155 const uint8_t cause = ERRCTRL_ReadResetCause();
156 const uint8_t maxCause = (uint8_t)ERRCTRL_CAUSE_EVSYS1_gc;
157 if (cause <= maxCause) // Check if the identified cause is within valid range
158 {
159 // Calculate the reset reason enum value based on the cause value
160 const uint8_t errorChannelOffset = (uint8_t)RSTRSN_ERRCH_VREGFAIL;
161 const uint8_t reasonVal = errorChannelOffset + cause;
162
163 /* Intentional misra-c2012-10.5 deviation */
164 resetReason = (resetReason_t)(reasonVal);
165 }
166 return resetReason;
167}
168
169static resetReason_t GetWatchdogReason(void)
170{
171 const uint8_t status = WDT_ReadStatus();
172 const uint8_t causeMask = (uint8_t)WDT_CAUSE_bm;
173 const bool isTimeoutCause = ((status & causeMask) == causeMask);
174
175 resetReason_t resetReason = RSTRSN_WDT_OUTSIDE;
176 if (isTimeoutCause)
177 {
178 resetReason = RSTRSN_WDT_TIMEOUT;
179 }
180
181 return resetReason;
182}
uint8_t ERRCTRL_ReadResetCause(void)
Reads the CAUSE register value.
resetReason_t MW_GetClearResetReason(void)
Reads and clears the reset flag registers.
resetReason_t
Type defines for all possible reset sources.
void MW_ResetDevice(void)
Issues a software reset request to reset the device.
@ RSTRSN_MCHK_OCD
@ RSTRSN_MCHK_UNKNOWN
@ RSTRSN_WDT_TIMEOUT
@ RSTRSN_WDT_OUTSIDE
@ RSTRSN_ERRCH_UNKNOWN
@ RSTRSN_POWER_ON
@ RSTRSN_ERRCH_VREGFAIL
@ RSTRSN_UNKNOWN
uint8_t RSTCTRL_ReadResetFlagRegister(void)
Reads the RSTFR register value.
uint8_t RSTCTRL_ReadMachineCheckFlagsA(void)
Reads the MCFLAGSA register value.
void RSTCTRL_WriteMachineCheckFlagsA(uint8_t value)
Overwrites the MCFLAGSA register value.
uint8_t RSTCTRL_ReadMachineCheckFlagsB(void)
Reads the MCFLAGSB register value.
void RSTCTRL_WriteMachineCheckFlagsB(uint8_t value)
Overwrites the MCFLAGSB register value.
void RSTCTRL_WriteResetFlagRegister(uint8_t value)
Overwrites the RSTFR register value.
void RSTCTRL_WriteSoftwareResetRegister(uint8_t value)
Overwrites the SWRR register value.
uint8_t WDT_ReadStatus(void)
Reads the STATUS register value.
Definition driver_wdt.c:38