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
volatile bool Enabled
Bit 15: Control bit enabling/disabling monitoring of the fault object.
volatile uint16_t Counter
Fault event counter (controlled by FAULT HANDLER)
volatile uint16_t(* FaultRecovery)(void)
Function pointer to the common fault recovery function.
enum FLT_COMPARE_TYPE_e CompareType
Bit <10:8>: Fault check comparison type control bits.
volatile struct FLT_COMPARE_OBJECT_s ReferenceObject
Reference object the source should be compared with.
volatile struct FLT_OBJECT_STATUS_s Status
Status word of this fault object.
volatile uint16_t FaultStatusList
Status word encoding individual fault object states in order of their list index.
volatile uint16_t * ptrObject
Pointer to register or variable which should be monitored.
volatile uint16_t FaultRecoveryCounter
Most recent number of fault recovery attempts.
volatile struct FAULT_MONITOR_STATUS_s Status
Status word of the fault monitor.
volatile uint16_t eventThreshold
Bit mask will be &-ed with source as value (use 0xFFFF for full value comparison)
volatile bool FaultStatus
Bit 0: Flag bit indicating if FAULT has been tripped.
Generic fault object.
volatile uint16_t FaultLatchCount
Number of fault recovery attempts after which the system gets locked in a latched fault state.
volatile uint16_t compareThreshold
Signal level at which the fault condition will be detected.
volatile uint16_t(* ptrResponseFunction)(void)
pointer to a user-defined function called when a defined fault monitoring event is detected
volatile struct FLT_COMPARE_OBJECT_s SourceObject
Object which should be monitored.
volatile bool FaultLatch
Bit 1: Flag bit indicating if a latched FAULT condition has been enforced.
volatile uint16_t bitMask
Bit mask will be &-ed with source as value (use 0xFFFF for full value comparison)
volatile struct FLT_EVENT_RESPONSE_s TripResponse
Settings defining the fault trip event.
volatile bool FaultActive
Bit 1: Flag bit indicating if fault condition has been detected but FAULT has not been tripped yet.
volatile bool FaultStatus
Bit 0: Flag bit indicating if a FAULT condition has been tripped.
volatile struct FLT_EVENT_RESPONSE_s RecoveryResponse
Settings defining the fault recovery event.