| Digital Power Starter Kit 3 Firmware dsPIC33C Boost Converter Voltage Mode Control Example |

drv_fault_handler.c
1 /*
2 * File: fault_handler.c
3 * Author: M91406
4 *
5 * Created on December 27, 2019, 12:21 PM
6 */
39 #include <xc.h> // include processor files - each processor file is guarded.
40 #include <stdint.h> // include standard integer data types
41 #include <stdbool.h> // include standard boolean data types
42 #include <stdlib.h> // include standard library data types and macros
43
44 #include "drv_fault_handler.h" // include fault handler device driver header file
45
46
47 /*******************************************************************************
48 * @var FAULT_OBJECT_s fltObjectClear
49 * @ingroup lib-layer-fault-properties-private-variables
50 * @brief Clears the fault objects
51 * @details
52 * The fltObjectClear object is used during pre-initialization of user-defined
53 * fault pbjects, clearing all settings and setting the FaultActive and
54 * FaultStatus fault object status flag bts.
55 *****************************************************************************/
56 volatile struct FAULT_OBJECT_s fltObjectClear =
57 {
58 .Status.bits.CompareType = FLTCMP_NONE,
59 .Status.bits.Enabled = false,
60 .Status.bits.FaultActive = true,
61 .Status.bits.FaultStatus = true,
62 .Counter = 0,
63 .SourceObject.ptrObject = NULL,
64 .SourceObject.bitMask = 0xFFFF,
65 .ReferenceObject.ptrObject = NULL,
66 .ReferenceObject.bitMask = 0xFFFF,
67 .TripResponse.compareThreshold = 0,
68 .TripResponse.eventThreshold = 0,
69 .TripResponse.ptrResponseFunction = NULL,
70 .RecoveryResponse.compareThreshold = 0,
71 .RecoveryResponse.eventThreshold = 0,
72 .RecoveryResponse.ptrResponseFunction = NULL,
73 };
74
75 // Public fault monitor object
76 volatile struct FAULT_MONITOR_s FaultMonitor;
77
78 /*******************************************************************************
79 * @fn uint16_t drv_FaultHandler_CheckObject(volatile struct FAULT_OBJECT_s* fltObject)
80 * @ingroup lib-layer-fault-functions-private
81 * @param fltObject Pointer to a Fault Monitoring Object of type struct FAULT_OBJECT_s
82 * @return unsigned integer (0=failure, 1=success)
83 *
84 * @brief Check current fault status of a user-defined fault object
85 *
86 * @details
87 * This routine compares the most recent value of a global variable or SFR
88 * (SOURCE) against user-defined thresholds. If the value violates/exceeds
89 * one or more of the user defined conditions, a fault counter is incremented.
90 *
91 * When this fault counter exceeds the user-defined maximum, a fault condition
92 * is tripped and the fault_status flag bit is set.
93 *
94 * When a fault condition has been tripped and the fault status is set (=true),
95 * the fault check monitors for the source value triggering a recovery event.
96 * The recovery process works like the fault trip event by comparing the most
97 * recent source value against the user-defined RECOVERY_LEVEL. Once the value
98 * has been RSTCNT_MAX times below the RECOVERY_LEVEL threshold, the fault
99 * will automatically be cleared.
100 *
101 * a) Comparison Types
102 *
103 * The fault handler offers the following different comparison methods:
104 * - Greater Than:
105 * - performs comparison SOURCE > TRIP_LEVEL
106 *
107 * - TRIP_LEVEL is greater than RECOVERY_LEVEL. The difference between
108 * TRIP_LEVEL and RECOVERY_LEVEL is the hysteresis of the defined
109 * threshold.
110 *
111 * - Less Than:
112 * - performs comparison SOURCE < TRIP_LEVEL
113 *
114 * - TRIP_LEVEL is less than RECOVERY_LEVEL. The difference between
115 * TRIP_LEVEL and RECOVERY_LEVEL is the hysteresis of the defined
116 * threshold.
117 *
118 * - Is Equal:
119 * - performs comparison SOURCE == TRIP_LEVEL
120 *
121 * - RECOVERY_LEVEL is ignored.
122 *
123 * - Is Not Equal:
124 * - performs comparison SOURCE != TRIP_LEVEL
125 *
126 * - RECOVERY_LEVEL is ignored.
127 *
128 * - Between:
129 * - performs comparison RECOVERY_LEVEL < SOURCE < TRIP_LEVEL
130 *
131 * - min/max of the FAULT range is defined by the range between
132 * RECOVERY_LEVEL (min) and TRIP_LEVEL (max)
133 *
134 * - Outside:
135 * - performs comparison (SOURCE < RECOVERY_LEVEL) or (TRIP_LEVEL < SOURCE)
136 *
137 * - min/max of the allowed operating range is defined by the range
138 * between RECOVERY_LEVEL (min) and TRIP_LEVEL (max)
139 *
140 * b) Value Filtering
141 *
142 * A bit-mask filter can be used to monitor individual register bits or filter
143 * on specific bits within a 16-bit wide value. The bit-mask is always applied
144 * the source value. If no bit-mask is required, set bitmask = 0xFFFF;
145 *
146 * c) Comparison of two dynamic values
147 *
148 * When dynamic values of two variables need to be compared, the fault object
149 * offers a second pointer to a so-called reference object "ref_obj". When this
150 * pointer is != NULL, the absolute value of the difference between SOURCE and
151 * REFERNCE is compared against the user-defined TRIP and RECOVERY thresholds.
152 * When no second value is used, set ref_obj = NULL (NULL-pointer). This
153 * will force the fault check to ignore this value.
154 *
155 * d) User defined responses
156 *
157 * Function pointers "trip_response" and "reset_response" can be used
158 * to assign user-defined functions which should be called when a fault
159 * condition has been tripped or reset.
160 * I no user-defined function should be called, these pointers can be
161 * set = NULL (NULL-pointer)
162 *
163 * @note If the value is within normal operating conditions, the fault
164 * counter will be cleared. Thus fault events must occur successively
165 * incrementing the fault event counter high enough to eventually
166 * trip a fault event. Thus the fault event counter can be used to
167 * adjust the sensitivity of the fault response.
168 *
169 *****************************************************************************/
170
171 static volatile uint16_t drv_FaultHandler_CheckObject(volatile struct FAULT_OBJECT_s* fltObject) {
172
173 volatile uint16_t retval=1;
174 volatile uint16_t source=0;
175
176 // If the fault object is not initialized, exit here with error
177 if (fltObject == NULL)
178 return(0);
179
180 // If the source object is not initialized, exit here with error
181 if (fltObject->SourceObject.ptrObject == NULL)
182 return(0);
183
184 // Read most recent fault object value with bit-mask
185 source = (*fltObject->SourceObject.ptrObject & fltObject->SourceObject.bitMask);
186
187 // If a reference object has been defined, read reference object value and override source with
188 // absolute value of difference between source and reference object values
189 if(fltObject->ReferenceObject.ptrObject != NULL) {
190
191 uint16_t reference = (*fltObject->ReferenceObject.ptrObject & fltObject->ReferenceObject.bitMask);
192 source = (volatile uint16_t)
193 abs((volatile int32_t)source - (volatile int32_t)reference); // Load most recent value
194 }
195
196 // Check fault condition
197
198 switch(fltObject->Status.bits.CompareType) {
199
200 case FLTCMP_GREATER_THAN: // Check if SOURCE > TRIP_LEVEL
201
202 if (source > fltObject->TripResponse.compareThreshold) // Check if SOURCE > TRIP_LEVEL
203 fltObject->Status.bits.FaultActive = true; // Set FAULT_ACTIVE status flag bit
204 else if (source < fltObject->RecoveryResponse.compareThreshold) // Check if SOURCE < RECOVERY_LEVEL
205 fltObject->Status.bits.FaultActive = false; // Clear FAULT_ACTIVE status flag bit
206 break;
207
208 case FLTCMP_LESS_THAN:
209 if(source < fltObject->TripResponse.compareThreshold) // Check if SOURCE < TRIP_LEVEL
210 fltObject->Status.bits.FaultActive = true; // Set FAULT_ACTIVE status flag bit
211 else if(source > fltObject->RecoveryResponse.compareThreshold) // Check if SOURCE > RECOVERY_LEVEL
212 fltObject->Status.bits.FaultActive = false; // Clear FAULT_ACTIVE status flag bit
213 break;
214
215 case FLTCMP_IS_EQUAL:
216 if(source == fltObject->TripResponse.compareThreshold) // Check if SOURCE == TRIP_LEVEL
217 fltObject->Status.bits.FaultActive = true; // Set FAULT_ACTIVE status flag bit
218 else if(source != fltObject->TripResponse.compareThreshold) // Check if SOURCE != TRIP_LEVEL
219 fltObject->Status.bits.FaultActive = false; // Clear FAULT_ACTIVE status flag bit
220 break;
221
222 case FLTCMP_IS_NOT_EQUAL:
223 if(source != fltObject->TripResponse.compareThreshold) // Check if SOURCE != TRIP_LEVEL
224 fltObject->Status.bits.FaultActive = true; // Set FAULT_ACTIVE status flag bit
225 else if(source == fltObject->TripResponse.compareThreshold) // Check if SOURCE == TRIP_LEVEL
226 fltObject->Status.bits.FaultActive = false; // Clear FAULT_ACTIVE status flag bit
227 break;
228
229 case FLTCMP_BETWEEN:
230 // Check if SOURCE is between "RECOVERY_LEVEL ti TRIP_LEVEL"
231 if((fltObject->RecoveryResponse.compareThreshold < source) && (source < fltObject->TripResponse.compareThreshold))
232 fltObject->Status.bits.FaultActive = true; // Set FAULT_ACTIVE status flag bit
233 else
234 fltObject->Status.bits.FaultActive = false; // Clear FAULT_ACTIVE status flag bit
235 break;
236
237 case FLTCMP_OUTSIDE:
238 // Check if SOURCE is outside "RECOVERY_LEVEL to TRIP_LEVEL"
239 if((source < fltObject->RecoveryResponse.compareThreshold) || (fltObject->TripResponse.compareThreshold < source))
240 fltObject->Status.bits.FaultActive = true; // Set FAULT_ACTIVE status flag bit
241 else
242 fltObject->Status.bits.FaultActive = false; // Clear FAULT_ACTIVE status flag bit
243 break;
244
245 default:
246 return(0); // Return=>Error (Ignore fault check if compare type is not defined)
247 break;
248
249 }
250
251 // If a fault condition has been detected while no FAULT has been tripped....
252 if ((fltObject->Status.bits.FaultActive) && (!fltObject->Status.bits.FaultStatus) &&
253 (fltObject->Status.bits.Enabled)) {
254
255 fltObject->Counter++; // Increment fault event counter
256
257 // Trigger on FAULT conditions
258 if (fltObject->Counter >= fltObject->TripResponse.eventThreshold)
259 {
260 fltObject->Status.bits.FaultStatus = true; // Set FAULT STATUS FLAG BIT
261 fltObject->Counter = fltObject->TripResponse.eventThreshold; // Set fault event counter to threshold level
262 if (fltObject->TripResponse.ptrResponseFunction != NULL) // If a user function has been defined,
263 retval = fltObject->TripResponse.ptrResponseFunction(); // => call this function and capture return value
264 }
265
266 }
267 // If a FAULT has been tripped but no fault condition has been detected anymore....
268 else if (((fltObject->Status.bits.FaultStatus) && (!fltObject->Status.bits.FaultActive)) ||
269 (!fltObject->Status.bits.Enabled))
270 {
271
272 fltObject->Counter++; // Increment fault event counter
273
274 // Trigger on RECOVERY conditions
275 if (fltObject->Counter >= fltObject->RecoveryResponse.eventThreshold)
276 {
277 fltObject->Status.bits.FaultStatus = false; // Clear FAULT STATUS FLAG BIT
278 fltObject->Counter = fltObject->RecoveryResponse.eventThreshold; // Set fault event counter to threshold level
279 if (fltObject->RecoveryResponse.ptrResponseFunction != NULL) // If a user function has been defined,
280 retval = fltObject->RecoveryResponse.ptrResponseFunction(); // => call this function and capture return value
281 }
282
283 }
284 // If everything is OK, reset counter
285 else
286 {
287 fltObject->Counter = 0; // clear fault event counter
288 }
289
290
291 return (retval); // Fault handler executed successfully
292 }
293
294 /*********************************************************************************
295 * @ingroup lib-layer-fault-functions-public
296 * @fn volatile uint16_t drv_FaultHandler_ScanObjects(volatile struct FAULT_OBJECT_s* fltObjectList[], volatile uint16_t size)
297 * @brief Scans a list of user-defined fault objects
298 * @param fltObjectList[] Pointer array of user defined fault objects of type struct FAULT_OBJECT_s
299 * @param size Size of the pointer array of user defined fault objects of type unsigned integer
300 * @return unsigned integer (0=failure, 1=success)
301 * @details
302 * This function scans through a list of user defined fault objects of type
303 * FAULT_OBECT_s executing the check of declared fault conditions. Each fault
304 * object is capable of raising an individual fault response and fault reset
305 * function call, which can be considered as the equivalent of a software
306 * triggered interrupt.
307 *
308 * During the scan the status of each individual fault object is logged and
309 * merged into one common fault condition flag bit FaultMonitor.Status.bits.FaultStatus.
310 * This common fault condition flag is also use to detect a Fault Recovery condition.
311 * Users can specify a global function used to reset the system wide fault condition
312 * triggering a system-wide recovery procedure.
313 *
314 * The fault scan also allows to specify if the system should be locked in a
315 * latched fault state if a given number of successive restart attempts failed.
316 * The maximum number of restart attempts can be specified by setting the fault
317 * monitor property FaultMonitor.FaultLatchCount to a value greater than one. If the
318 * property FaultMonitor.FaultLatchCount is set to zero, no latched fault condition
319 * will be triggered then the system will initiate an unlimited number of recovery
320 * attempts.
321 *
322 * This function requires users to declare a list (array) of pointers to
323 * individually declared fault objects, like shown in the following code
324 * example:
325 *
326 * <p><b>Example:</b></p>
327 * @code{.c}
328 * volatile struct FAULT_OBJECT_s* FaultObjectList[] = {
329 * &fltobj_Object_1,
330 * &fltobj_Object_2,
331 * (...),
332 * &fltobj_Object_n
333 * };
334 * @endcode
335 *
336 * @note
337 * The size of this list can be determined by using the following declaration
338 * example:
339 *
340 * @code{.c}
341 * volatile uint16_t FaultObjectList_size = (sizeof(FaultObjectList)/sizeof(FaultObjectList[0]));
342 * @endcode
343 *
344 **********************************************************************************/
345
346 volatile uint16_t drv_FaultHandler_ScanObjects(volatile struct FAULT_OBJECT_s* fltObjectList[], volatile uint16_t size)
347 {
348 volatile uint16_t retval=1;
349 volatile uint16_t _i=0;
350 volatile uint16_t _fltlog=0;
351 volatile bool _fltstate=false;
352 static bool _pre_fltstate=false;
353
354 // Scan through all defined fault objects and log their state in common fault state flag
355 for (_i=size; _i>0; _i--)
356 {
357 retval &= drv_FaultHandler_CheckObject(fltObjectList[(_i-1)]);
358 _fltstate |= fltObjectList[(_i-1)]->Status.bits.FaultStatus;
359 _fltlog <<= _i;
360 _fltlog |= fltObjectList[(_i-1)]->Status.bits.FaultStatus;
361 }
362
363 // Update common fault state flag status
364 FaultMonitor.Status.bits.FaultStatus = _fltstate;
365 FaultMonitor.FaultStatusList = _fltlog;
366
367 if ((_pre_fltstate) && (!_fltstate))
368 {
369 if (FaultMonitor.FaultRecoveryCounter++ < FaultMonitor.FaultLatchCount)
370 { if (FaultMonitor.FaultRecovery != NULL) // Check if recovery function has been assigned
371 retval &= FaultMonitor.FaultRecovery(); // Initiate fault recovery attempt
372 }
373 else
374 { // Latch system-wide Fault Condition
375 if(FaultMonitor.FaultLatchCount > 0) {
376 FaultMonitor.Status.bits.FaultStatus = true;
377 FaultMonitor.Status.bits.FaultLatch = true;
378 FaultMonitor.FaultRecoveryCounter = FaultMonitor.FaultLatchCount;
379 }
380 }
381 }
382
383 // Track global fault bit transitions
384 _pre_fltstate = _fltstate;
385
386 return(retval);
387
388 }
389
390 /*********************************************************************************
391 * @ingroup lib-layer-fault-functions-public
392 * @fn volatile uint16_t drv_FaultHandler_Dispose(volatile struct FAULT_OBJECT_s* fltObjectList[], volatile uint16_t size)
393 * @brief Disposes a list of user-defined fault objects
394 * @param fltObjectList[] Pointer array of user defined fault objects of type struct FAULT_OBJECT_s
395 * @param size Size of the pointer array of user defined fault objects of type unsigned integer
396 * @return unsigned integer (0=failure, 1=success)
397 * @details
398 * This function disposes a list of user defined fault objects of type
399 * FAULT_OBECT_s by clearing all settings.
400 *
401 * This function requires users to declare a list (array) of pointers to
402 * individually declared fault objects, like shown in the following code
403 * example:
404 *
405 * <p><b>Example:</b></p>
406 * @code{.c}
407 * volatile struct FAULT_OBJECT_s* FaultObjectList[] = {
408 * &fltobj_Object_1,
409 * &fltobj_Object_2,
410 * (...),
411 * &fltobj_Object_n
412 * };
413 * @endcode
414 *
415 * @note
416 * The size of this list can be determined by using the following declaration
417 * example:
418 *
419 * @code{.c}
420 * volatile uint16_t FaultObjectList_size = (sizeof(FaultObjectList)/sizeof(FaultObjectList[0]));
421 * @endcode
422 *
423 **********************************************************************************/
424
425 volatile uint16_t drv_FaultHandler_Dispose(volatile struct FAULT_OBJECT_s* fltObjectList[], volatile uint16_t size)
426 {
427 volatile uint16_t retval=1;
428 volatile uint16_t _i=0;
429
430 for (_i=0; _i<size; _i++)
431 { *fltObjectList[_i] = fltObjectClear; }
432
433 return(retval);
434
435 }
436
437
438
439 // end of file
FLT_OBJECT_STATUS_s::Enabled
volatile bool Enabled
Bit 15: Control bit enabling/disabling monitoring of the fault object.
Definition: drv_fault_handler.h:89
FAULT_OBJECT_s::Counter
volatile uint16_t Counter
Fault event counter (controlled by FAULT HANDLER)
Definition: drv_fault_handler.h:134
FAULT_MONITOR_s::FaultRecovery
volatile uint16_t(* FaultRecovery)(void)
Function pointer to the common fault recovery function.
Definition: drv_fault_handler.h:164
FLT_OBJECT_STATUS_s::CompareType
enum FLT_COMPARE_TYPE_e CompareType
Bit <10:8>: Fault check comparison type control bits.
Definition: drv_fault_handler.h:87
FAULT_OBJECT_s::ReferenceObject
volatile struct FLT_COMPARE_OBJECT_s ReferenceObject
Reference object the source should be compared with.
Definition: drv_fault_handler.h:136
FAULT_OBJECT_s::Status
volatile struct FLT_OBJECT_STATUS_s Status
Status word of this fault object.
Definition: drv_fault_handler.h:133
FAULT_MONITOR_s::FaultStatusList
volatile uint16_t FaultStatusList
Status word encoding individual fault object states in order of their list index.
Definition: drv_fault_handler.h:161
FLT_COMPARE_OBJECT_s::ptrObject
volatile uint16_t * ptrObject
Pointer to register or variable which should be monitored.
Definition: drv_fault_handler.h:106
FAULT_MONITOR_s::FaultRecoveryCounter
volatile uint16_t FaultRecoveryCounter
Most recent number of fault recovery attempts.
Definition: drv_fault_handler.h:162
FAULT_MONITOR_s::Status
volatile struct FAULT_MONITOR_STATUS_s Status
Status word of the fault monitor.
Definition: drv_fault_handler.h:160
FLT_EVENT_RESPONSE_s::eventThreshold
volatile uint16_t eventThreshold
Bit mask will be &-ed with source as value (use 0xFFFF for full value comparison)
Definition: drv_fault_handler.h:121
FLT_OBJECT_STATUS_s::FaultStatus
volatile bool FaultStatus
Bit 0: Flag bit indicating if FAULT has been tripped.
Definition: drv_fault_handler.h:84
FAULT_OBJECT_s
Generic fault object.
Definition: drv_fault_handler.h:131
FAULT_MONITOR_s::FaultLatchCount
volatile uint16_t FaultLatchCount
Number of fault recovery attempts after which the system gets locked in a latched fault state.
Definition: drv_fault_handler.h:163
FLT_EVENT_RESPONSE_s::compareThreshold
volatile uint16_t compareThreshold
Signal level at which the fault condition will be detected.
Definition: drv_fault_handler.h:120
FLT_EVENT_RESPONSE_s::ptrResponseFunction
volatile uint16_t(* ptrResponseFunction)(void)
pointer to a user-defined function called when a defined fault monitoring event is detected
Definition: drv_fault_handler.h:122
FAULT_OBJECT_s::SourceObject
volatile struct FLT_COMPARE_OBJECT_s SourceObject
Object which should be monitored.
Definition: drv_fault_handler.h:135
FAULT_MONITOR_STATUS_s::FaultLatch
volatile bool FaultLatch
Bit 1: Flag bit indicating if a latched FAULT condition has been enforced.
Definition: drv_fault_handler.h:147
FAULT_MONITOR_s
Definition: drv_fault_handler.h:159
FLT_COMPARE_OBJECT_s::bitMask
volatile uint16_t bitMask
Bit mask will be &-ed with source as value (use 0xFFFF for full value comparison)
Definition: drv_fault_handler.h:107
FAULT_OBJECT_s::TripResponse
volatile struct FLT_EVENT_RESPONSE_s TripResponse
Settings defining the fault trip event.
Definition: drv_fault_handler.h:137
FLT_OBJECT_STATUS_s::FaultActive
volatile bool FaultActive
Bit 1: Flag bit indicating if fault condition has been detected but FAULT has not been tripped yet.
Definition: drv_fault_handler.h:85
FAULT_MONITOR_STATUS_s::FaultStatus
volatile bool FaultStatus
Bit 0: Flag bit indicating if a FAULT condition has been tripped.
Definition: drv_fault_handler.h:146
FAULT_OBJECT_s::RecoveryResponse
volatile struct FLT_EVENT_RESPONSE_s RecoveryResponse
Settings defining the fault recovery event.
Definition: drv_fault_handler.h:138