Digital Power Starter Kit 3 Firmware
dsPIC33C Boost Converter Voltage Mode Control Example
dev_boost_opstates.c
1 /*
2  * File: dev_boost_opstates.c
3  * Author: M91406
4  * Created on October 9, 2020, 9:16 AM
5  */
6 
7 
8 #include <xc.h> // include processor files - each processor file is guarded.
9 #include <stdint.h> // include standard integer data types
10 #include <stdbool.h> // include standard boolean data types
11 
12 #include "dev_boost_pconfig.h" // include boost converter
13 #include "dev_boost_typedef.h" // include boost converter data object declarations
14 #include "dev_boost_substates.h" // include state machine sub-state declarations
15 #include "dev_boost_special_functions.h" // include boost converter special function declarations
16 
17 
18 // Private function prototypes of state functions
19 
20 volatile uint16_t __attribute__((always_inline)) State_Error(volatile struct BOOST_CONVERTER_s *boostInstance);
21 volatile uint16_t __attribute__((always_inline)) State_Initialize(volatile struct BOOST_CONVERTER_s *boostInstance);
22 volatile uint16_t __attribute__((always_inline)) State_Reset(volatile struct BOOST_CONVERTER_s *boostInstance);
23 volatile uint16_t __attribute__((always_inline)) State_Standby(volatile struct BOOST_CONVERTER_s *boostInstance);
24 volatile uint16_t __attribute__((always_inline)) State_RampUp(volatile struct BOOST_CONVERTER_s *boostInstance);
25 volatile uint16_t __attribute__((always_inline)) State_Online(volatile struct BOOST_CONVERTER_s *boostInstance);
26 
27 // Declaration of function pointer array listing op-state functions in order of execution
28 volatile uint16_t (*BoostConverterStateMachine[])(volatile struct BOOST_CONVERTER_s *boostInstance) =
29 {
30  State_Error,
31  State_Initialize,
32  State_Reset,
33  State_Standby,
34  State_RampUp,
35  State_Online
36 };
37 
38 // Declaration variable capturing the size of the sub-state function pointer array
39 volatile uint16_t BoostStateList_size = (sizeof(BoostConverterStateMachine)/sizeof(BoostConverterStateMachine[0]));
40 
41 /*******************************************************************************
42  * @fn uint16_t State_Initialize(volatile struct BOOST_CONVERTER_s *boostInstance)
43  * @ingroup lib-layer-boost-state-machine-functions
44  * @brief This function resets the counters and conditional flag bits.
45  * @param boostInstance Pointer to a Boost Converter data object of type struct BOOST_CONVERTER_s
46  * @return unsigned integer (0=failure, 1=success)
47  *
48  * @details
49  * If the controller has not been run yet, the POWER ON and POWER GOOD delay
50  * counters are reset and all conditional flag bits are cleared. Status of
51  * power source, ADC and current sensor calibration have to be set during
52  * runtime by system check routines.
53  *********************************************************************************/
54 volatile uint16_t State_Initialize(volatile struct BOOST_CONVERTER_s *boostInstance)
55 {
56  volatile uint16_t _i=0;
57 
58  boostInstance->startup.power_on_delay.counter = 0; // Reset power on counter
59  boostInstance->startup.power_good_delay.counter = 0; // Reset power good counter
60 
61  // Reset all status bits
62  boostInstance->status.bits.adc_active = false;
63 
64  // Initiate current sensor calibration flag bit
65  if (boostInstance->set_values.control_mode == BOOST_CONTROL_MODE_VMC)
66  boostInstance->status.bits.cs_calib_complete = true;
67  else if (boostInstance->status.bits.cs_calib_enable)
68  boostInstance->status.bits.cs_calib_complete = false;
69  else
70  boostInstance->status.bits.cs_calib_complete = true;
71 
72  // Disable control loops
73  boostInstance->v_loop.controller->status.bits.enabled = false; // Disable voltage loop
74 
75  if (boostInstance->set_values.control_mode == BOOST_CONTROL_MODE_ACMC) // In current mode...
76  {
77  for (_i=0; _i<boostInstance->set_values.no_of_phases; _i++) {
78  boostInstance->i_loop[_i].controller->status.bits.enabled = false; // Disable current loop
79  }
80  }
81 
82  // Clear busy bit
83  boostInstance->status.bits.busy = false; // Clear BUSY bit
84  boostInstance->status.bits.ready = true; // Set READY bit indicating state machine has passed INITIALIZED state
85 
86  // Transition to STATE_RESET
87  return(BOOST_OPSRET_COMPLETE);
88 
89 }
90 
91 /*******************************************************************************
92  * @fn uint16_t State_Reset(volatile struct BOOST_CONVERTER_s *boostInstance)
93  * @ingroup lib-layer-boost-state-machine-functions
94  * @brief This function resets the boost control operation by re-initiating the control mode,
95  * references and status bits.
96  * @param boostInstance Pointer to a Boost Converter data object of type struct BOOST_CONVERTER_s
97  * @return unsigned integer (0=failure, 1=success)
98  *
99  * @details
100  * After successful initialization or after an externally triggered state machine reset,
101  * the state machine returns to this RESET mode, re-initiating control mode, references
102  * and status bits before switching further into STANDBY mode.
103  *********************************************************************************/
104 volatile uint16_t State_Reset(volatile struct BOOST_CONVERTER_s *boostInstance)
105 {
106  volatile uint16_t retval=1;
107  volatile uint16_t _i=0;
108 
109  // Disable all PWM outputs & control loops (immediate power cut-off)
110  retval &= boostPWM_Suspend(boostInstance); // Disable PWM outputs
111 
112  // Disable voltage loop controller and reset control loop histories
113  boostInstance->v_loop.controller->status.bits.enabled = false; // disable voltage control loop
114  boostInstance->v_loop.ctrl_Reset(boostInstance->v_loop.controller); // Reset control histories of outer voltage controller
115  *boostInstance->v_loop.controller->Ports.Target.ptrAddress =
116  boostInstance->v_loop.controller->Limits.MinOutput;
117 
118  // Disable current loop controller and reset control loop histories
119  if (boostInstance->set_values.control_mode == BOOST_CONTROL_MODE_ACMC)
120  { // Disable all current control loops and reset control loop histories
121  for (_i=0; _i<boostInstance->set_values.no_of_phases; _i++) {
122  boostInstance->i_loop[_i].controller->status.bits.enabled = false;
123  boostInstance->i_loop[_i].ctrl_Reset(boostInstance->i_loop[_i].controller);
124  *boostInstance->i_loop[_i].controller->Ports.Target.ptrAddress =
125  boostInstance->i_loop[_i].controller->Limits.MinOutput;
126  }
127  }
128 
129  // Reset the bulk voltage settling counters
130  boostInstance->startup.power_on_delay.counter = 0; // Clear Power On Delay counter
131  boostInstance->startup.power_good_delay.counter = 0; // Clear Power Good Delay counter
132 
133  // Reset all status bits
134  boostInstance->status.bits.adc_active = false;
135  boostInstance->status.bits.busy = false; // Clear BUSY bit
136 
137  // If any sub-function call went unsuccessful, reset state machine
138  // else, move on to next state
139 
140  if (retval)
141  return(BOOST_OPSRET_COMPLETE);
142  else
143  return(BOOST_OPSRET_ERROR);
144 
145 }
146 
147 /*******************************************************************************
148  * @fn uint16_t State_Standby(volatile struct BOOST_CONVERTER_s *boostInstance)
149  * @ingroup lib-layer-boost-state-machine-functions
150  * @brief This function waits until all start-up conditions are met.
151  * @param boostInstance Pointer to a Boost Converter data object of type struct BOOST_CONVERTER_s
152  * @return unsigned integer (0=failure, 1=success)
153  *
154  * @details
155  * After a successful state machine reset, the state machine waits in
156  * STANDBY mode until all conditional flag bits are set/cleared allowing
157  * the converter to run.
158  *********************************************************************************/
159 volatile uint16_t State_Standby(volatile struct BOOST_CONVERTER_s *boostInstance)
160 {
161  volatile uint16_t retval=0;
162 
163  // if the 'autorun' option is set, automatically set the GO bit when the
164  // converter is enabled
165  if ((boostInstance->status.bits.enabled) && (boostInstance->status.bits.autorun))
166  { boostInstance->status.bits.GO = true; }
167 
168  // If current sense feedback offset calibration is enabled,
169  // call calibration sub-state routine
170  retval = drv_BoostConverter_SpecialFunctionExecute(boostInstance, CS_OFSET_CALIBRATION);
171 
172  switch (retval)
173  {
174  case BOOST_OPSRET_COMPLETE:
175  boostInstance->status.bits.cs_calib_complete = true; // Set CS Calibration Flag to COMPLETE
176  boostInstance->status.bits.busy = false; // Clear BUSY bit indicating on-going activity
177  break;
178  case BOOST_OPSRET_REPEAT:
179  boostInstance->status.bits.cs_calib_complete = false; // Set CS Calibration Flag to COMPLETE
180  boostInstance->status.bits.busy = true; // Set BUSY bit indicating on-going activity
181  return(BOOST_OPSRET_REPEAT);
182  break;
183  default:
184  boostInstance->status.bits.cs_calib_complete = false; // Set CS Calibration Flag to COMPLETE
185  boostInstance->status.bits.busy = false; // Clear BUSY bit indicating on-going activity
186  return(BOOST_OPSRET_ERROR);
187  break;
188  }
189 
190  // Wait for all startup conditions to be met
191  if ((boostInstance->status.bits.enabled) && // state machine needs to be enabled
192  (boostInstance->status.bits.GO) && // GO-bit needs to be set
193  (boostInstance->status.bits.adc_active) && // ADC needs to be running
194  (boostInstance->status.bits.pwm_active) && // PWM needs to be running
195  (!boostInstance->status.bits.fault_active) && // No active fault is present
196  (!boostInstance->status.bits.suspend) && // Power supply is not held in suspend mode
197  (boostInstance->status.bits.cs_calib_complete) // Current Sensor Calibration complete
198  )
199  {
200  boostInstance->status.bits.GO = false;
201  return(BOOST_OPSRET_COMPLETE);
202  }
203  else
204  // Remain in current state until bit-test becomes true
205  {
206  return(BOOST_OPSRET_REPEAT);
207  }
208 
209 }
210 
211 /*******************************************************************************
212  * @fn uint16_t State_RampUp(volatile struct BOOST_CONVERTER_s *boostInstance)
213  * @ingroup lib-layer-boost-state-machine-functions
214  * @brief This function ramps up the voltage/input to its nominal value
215  * @param boostInstance Pointer to a Boost Converter data object of type struct BOOST_CONVERTER_s
216  * @return 0 = BOOST_OPSRET_REPEAT
217  * @return 1 = BOOST_OPSRET_COMPLETE
218  * @return 2 = BOOST_OPSRET_REPEAT
219  *
220  * @details
221  * After a successful state machine Standby, the state machine executes the RAMPUP
222  * mode. In this mode, the voltage/current ramps up to the nominal value.
223  *********************************************************************************/
224 
225 volatile uint16_t State_RampUp(volatile struct BOOST_CONVERTER_s *boostInstance)
226 {
227  volatile uint16_t retval=0;
228 
229  // If sub-state pointer index is out of range, reset to ZERO
230  if ((uint16_t)(boostInstance->state_id.bits.substate_id) >= (uint16_t)(BoostRampUpSubStateList_size))
231  boostInstance->state_id.bits.substate_id = 0;
232 
233  // If selected sub-state index contains a NULL-pointer, exit here
234  if (BoostConverterRampUpSubStateMachine[boostInstance->state_id.bits.substate_id] == NULL)
235  return(BOOST_OPSRET_ERROR);
236 
237  // Execute ramp-up sub-state
238  retval = BoostConverterRampUpSubStateMachine[boostInstance->state_id.bits.substate_id](boostInstance);
239 
240  // Validate sub-state function return
241  switch (retval)
242  {
243  // If the sub-state returns a REPEAT, leave the sub-state pointer at the recent
244  // index and return REPEAT to the outer state machine to call State_RampUp again
245  case BOOST_OPSRET_REPEAT:
246 
247  retval = BOOST_OPSRET_REPEAT;
248 
249  break;
250 
251  // If the sub-state returns a COMPLETE, increment the sub-state pointer to call the
252  // next sub-state next time and return REPEAT to the outer state machine to call
253  // State_RampUp again
254  case BOOST_OPSRET_COMPLETE:
255 
256  // Increment sub-state pointer by one tick
257  boostInstance->state_id.bits.substate_id++;
258 
259  // CHeck if pointer is out of range
260  if ((uint16_t)(boostInstance->state_id.bits.substate_id) < (uint16_t)(BoostRampUpSubStateList_size))
261  { // if execution list is not complete yet, return op-state as REPEAT
262  retval = BOOST_OPSRET_REPEAT;
263 
264  if (boostInstance->state_id.bits.substate_id == BOOST_OPSTATE_I_RAMP_UP)
265  { // if the next state is set to "I Ramp-Up", check if converter supports
266  // this sub-state in its current configuration and step over it if not
267 
268  if (boostInstance->set_values.control_mode == BOOST_CONTROL_MODE_VMC)
269  boostInstance->state_id.bits.substate_id++; // Increment sub-state pointer
270 
271  }
272 
273  }
274  else
275  {
276  // if last item of execution list is complete. return op-state as COMPLETE
277  retval = BOOST_OPSRET_COMPLETE;
278  }
279 
280  break;
281 
282  // If the sub-state returns any other value, something went wrong. In this case
283  // return ERROR to outer state machine triggering a main state machine reset.
284  default:
285  // if any other return value is received, switch immediately to ERROR
286  retval = BOOST_OPSRET_ERROR;
287 
288  break;
289  }
290 
291  return(retval);
292 }
293 
294 /*******************************************************************************
295  * @fn uint16_t State_Online(volatile struct BOOST_CONVERTER_s *boostInstance)
296  * @ingroup lib-layer-boost-state-machine-functions
297  * @brief This function tunes the controller reference to the new user control reference level.
298  * @param boostInstance Pointer to a Boost Converter data object of type struct BOOST_CONVERTER_s
299  * @return unsigned integer (0=failure, 1=success)
300  *
301  * @details
302  * After soft-start and when state POWER_GOOD_DELAY has expired, the converter
303  * enters normal operation.
304  *
305  * During normal operation the state machine scans the user reference setting.
306  * Once a change between the user reference setting and the most recent controller
307  * reference has been detected, the state machine will tune the controller
308  * reference to the new user control reference level in incremental steps,
309  * applying the same ramp slope as during soft-start.
310  *
311  * While ramping the output voltage up or down, the BUSY bit will be set and any
312  * new changes to the reference will be ignored until the ramp up/down is complete.
313  *********************************************************************************/
314 
315 volatile uint16_t State_Online(volatile struct BOOST_CONVERTER_s *boostInstance)
316 {
317  if(boostInstance->set_values.v_ref != boostInstance->v_loop.reference)
318  {
319  // Set the BUSY bit indicating a delay/ramp period being executed
320  boostInstance->status.bits.busy = true;
321 
322  // New reference value is less than controller reference value => ramp down
323  if(boostInstance->set_values.v_ref < boostInstance->v_loop.reference){
324  // decrement reference until new reference level is reached
325  boostInstance->v_loop.reference -= boostInstance->startup.v_ramp.ref_inc_step; // decrement reference
326  if(boostInstance->v_loop.reference < boostInstance->set_values.v_ref) { // check if ramp is complete
327  boostInstance->v_loop.reference = boostInstance->set_values.v_ref; // clamp reference level to setting
328  }
329 
330  }
331  // New reference value is greater than controller reference value => ramp up
332  else if(boostInstance->set_values.v_ref > boostInstance->v_loop.reference){
333  // increment reference until new reference level is reached
334  boostInstance->v_loop.reference += boostInstance->startup.v_ramp.ref_inc_step; // increment reference
335  if(boostInstance->v_loop.reference > boostInstance->set_values.v_ref) { // check if ramp is complete
336  boostInstance->v_loop.reference = boostInstance->set_values.v_ref; // clamp reference level to setting
337  }
338 
339  }
340 
341  }
342  else{
343  // Clear the BUSY bit indicating "no state machine activity"
344  boostInstance->status.bits.busy = false;
345  }
346 
347  // remain in STATE_ONLINE
348  return(BOOST_OPSRET_REPEAT);
349 
350 }
351 
352 /*******************************************************************************
353  * @fn uint16_t State_Error(volatile struct BOOST_CONVERTER_s *boostInstance)
354  * @ingroup lib-layer-boost-state-machine-functions
355  * @brief If this function is called, the state machine is reset to INITIALIZE (URL=@ref State_Initialize).
356  * @param boostInstance Pointer to a Boost Converter data object of type struct BOOST_CONVERTER_s
357  * @return unsigned integer (0=failure, 1=success)
358  *
359  * @details
360  * This function is a default anchor in case task list index #0 is ever called.
361  * This is the equivalent of a switch case "default".
362  *********************************************************************************/
363 volatile uint16_t State_Error(volatile struct BOOST_CONVERTER_s *boostInstance)
364 {
365  volatile uint16_t retval=0;
366 
367  // If this function is ever called, bring state machine back on track
368  // by resetting it to INITIALIZE
369 
370  retval = boostPWM_Suspend(boostInstance); // Hold PWM output (turning off power)
371  boostInstance->status.bits.busy = false; // Reset busy bit
372 
373  if(retval)
374  retval = BOOST_OPSRET_COMPLETE;
375  else
376  retval = BOOST_OPSRET_ERROR;
377 
378 
379  return(retval);
380 }
381 
382 
383 // ______________________________________
384 // end of file
enum BOOST_CONTROL_MODE_e control_mode
Fundamental control mode.
volatile int16_t MinOutput
Minimum output value used for clamping (R/W)
Definition: npnz16b.h:329
volatile struct NPNZ_PORTS_s Ports
Controller input and output ports.
Definition: npnz16b.h:505
volatile struct NPNZ16b_s * controller
pointer to control loop object data structure
volatile struct BOOST_STARTUP_PERIOD_HANDLER_s v_ramp
Voltage Ramp-Up period deinitions.
volatile bool adc_active
Bit #1: indicating that ADC has been started and samples are taken.
volatile bool fault_active
Bit #5: Flag bit indicating system is in enforced shut down mode (usually due to a fault condition)
volatile uint16_t v_ref
User reference setting used to control the power converter controller.
volatile struct NPNZ_PORT_s Target
Primary data output port declaration.
Definition: npnz16b.h:263
volatile struct BOOST_LOOP_SETTINGS_s v_loop
BOOST voltage control loop object.
volatile struct NPNZ_LIMITS_s Limits
Input and output clamping values.
Definition: npnz16b.h:508
volatile uint16_t ref_inc_step
Size/value of one reference increment/decrement or this period.
volatile uint16_t no_of_phases
number of converter phases
volatile bool suspend
Bit #6: Control bit to put the converter in suspend mode (turned off while ENABLE bit is still on)
volatile bool enabled
Bit #15: Control bit enabling/disabling the charger port.
volatile struct BOOST_CONVERTER_STARTUP_s startup
BOOST startup timing settings.
void(* ctrl_Reset)(volatile struct NPNZ16b_s *)
Function pointer to RESET routine.
volatile bool busy
Bit #7: Flag bit indicating that the state machine is executing a process (e.g. startup-ramp)
volatile struct BOOST_STARTUP_PERIOD_HANDLER_s power_good_delay
Power-Good Delay period deinitions.
volatile bool ready
Bit #0: status bit, indicating boost converter is initialized and ready to run.
volatile bool pwm_active
Bit #2: indicating that PWM has been started and ADC triggers are generated.
struct BOOST_STATE_ID_s::@372::@373 bits
volatile uint16_t reference
Control loop reference variable.
volatile uint16_t counter
Soft-Start Execution Counter (read only)
volatile struct BOOST_LOOP_SETTINGS_s i_loop[BOOST_MPHASE_COUNT]
BOOST Current control loop objects.
volatile struct NPNZ_STATUS_s status
Control Loop Status and Control flags.
Definition: npnz16b.h:504
volatile bool cs_calib_complete
Bit #4: indicating that current sensor calibration has completed.
volatile uint16_t * ptrAddress
Pointer to register or variable where the value is read from (e.g. ADCBUFx) or written to (e....
Definition: npnz16b.h:228
volatile struct BOOST_CONVERTER_STATUS_s status
BOOST operation status bits.
volatile bool GO
Bit #13: When set, the GO-bit fires up the power supply.
volatile bool cs_calib_enable
Bit #8: Flag bit indicating that current sensors need to calibrated.
volatile struct BOOST_STARTUP_PERIOD_HANDLER_s power_on_delay
Power-On Delay period deinitions.
volatile struct BOOST_STATE_ID_s state_id
BOOST state machine operating state ID.
BOOST control & monitoring data structure.
volatile bool autorun
Bit #14: Control bit determining if charger is starting automatically or on command (using the GO bit...
volatile struct BOOST_CONVERTER_SETTINGS_s set_values
Control field for global access to references.
volatile bool enabled
Bit 15: enables/disables control loop execution.
Definition: npnz16b.h:202