| 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
BOOST_CONVERTER_SETTINGS_s::control_mode
enum BOOST_CONTROL_MODE_e control_mode
Fundamental control mode.
Definition: dev_boost_typedef.h:350
NPNZ_LIMITS_s::MinOutput
volatile int16_t MinOutput
Minimum output value used for clamping (R/W)
Definition: npnz16b.h:329
NPNZ16b_s::Ports
volatile struct NPNZ_PORTS_s Ports
Controller input and output ports.
Definition: npnz16b.h:505
BOOST_LOOP_SETTINGS_s::controller
volatile struct NPNZ16b_s * controller
pointer to control loop object data structure
Definition: dev_boost_typedef.h:380
BOOST_CONVERTER_STARTUP_s::v_ramp
volatile struct BOOST_STARTUP_PERIOD_HANDLER_s v_ramp
Voltage Ramp-Up period deinitions.
Definition: dev_boost_typedef.h:309
BOOST_CONVERTER_STATUS_s::adc_active
volatile bool adc_active
Bit #1: indicating that ADC has been started and samples are taken.
Definition: dev_boost_typedef.h:210
BOOST_CONVERTER_STATUS_s::fault_active
volatile bool fault_active
Bit #5: Flag bit indicating system is in enforced shut down mode (usually due to a fault condition)
Definition: dev_boost_typedef.h:214
BOOST_CONVERTER_SETTINGS_s::v_ref
volatile uint16_t v_ref
User reference setting used to control the power converter controller.
Definition: dev_boost_typedef.h:352
NPNZ_PORTS_s::Target
volatile struct NPNZ_PORT_s Target
Primary data output port declaration.
Definition: npnz16b.h:263
BOOST_CONVERTER_s::v_loop
volatile struct BOOST_LOOP_SETTINGS_s v_loop
BOOST voltage control loop object.
Definition: dev_boost_typedef.h:539
NPNZ16b_s::Limits
volatile struct NPNZ_LIMITS_s Limits
Input and output clamping values.
Definition: npnz16b.h:508
BOOST_STARTUP_PERIOD_HANDLER_s::ref_inc_step
volatile uint16_t ref_inc_step
Size/value of one reference increment/decrement or this period.
Definition: dev_boost_typedef.h:269
BOOST_CONVERTER_SETTINGS_s::no_of_phases
volatile uint16_t no_of_phases
number of converter phases
Definition: dev_boost_typedef.h:351
BOOST_CONVERTER_STATUS_s::suspend
volatile bool suspend
Bit #6: Control bit to put the converter in suspend mode (turned off while ENABLE bit is still on)
Definition: dev_boost_typedef.h:215
BOOST_CONVERTER_STATUS_s::enabled
volatile bool enabled
Bit #15: Control bit enabling/disabling the charger port.
Definition: dev_boost_typedef.h:225
BOOST_CONVERTER_s::startup
volatile struct BOOST_CONVERTER_STARTUP_s startup
BOOST startup timing settings.
Definition: dev_boost_typedef.h:531
BOOST_LOOP_SETTINGS_s::ctrl_Reset
void(* ctrl_Reset)(volatile struct NPNZ16b_s *)
Function pointer to RESET routine.
Definition: dev_boost_typedef.h:383
BOOST_CONVERTER_STATUS_s::busy
volatile bool busy
Bit #7: Flag bit indicating that the state machine is executing a process (e.g. startup-ramp)
Definition: dev_boost_typedef.h:216
BOOST_CONVERTER_STARTUP_s::power_good_delay
volatile struct BOOST_STARTUP_PERIOD_HANDLER_s power_good_delay
Power-Good Delay period deinitions.
Definition: dev_boost_typedef.h:307
BOOST_CONVERTER_STATUS_s::ready
volatile bool ready
Bit #0: status bit, indicating boost converter is initialized and ready to run.
Definition: dev_boost_typedef.h:209
BOOST_CONVERTER_STATUS_s::pwm_active
volatile bool pwm_active
Bit #2: indicating that PWM has been started and ADC triggers are generated.
Definition: dev_boost_typedef.h:211
BOOST_STATE_ID_s::bits
struct BOOST_STATE_ID_s::@372::@373 bits
BOOST_LOOP_SETTINGS_s::reference
volatile uint16_t reference
Control loop reference variable.
Definition: dev_boost_typedef.h:374
BOOST_STARTUP_PERIOD_HANDLER_s::counter
volatile uint16_t counter
Soft-Start Execution Counter (read only)
Definition: dev_boost_typedef.h:266
BOOST_CONVERTER_s::i_loop
volatile struct BOOST_LOOP_SETTINGS_s i_loop[BOOST_MPHASE_COUNT]
BOOST Current control loop objects.
Definition: dev_boost_typedef.h:540
NPNZ16b_s::status
volatile struct NPNZ_STATUS_s status
Control Loop Status and Control flags.
Definition: npnz16b.h:504
BOOST_CONVERTER_STATUS_s::cs_calib_complete
volatile bool cs_calib_complete
Bit #4: indicating that current sensor calibration has completed.
Definition: dev_boost_typedef.h:213
NPNZ_PORT_s::ptrAddress
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
BOOST_CONVERTER_s::status
volatile struct BOOST_CONVERTER_STATUS_s status
BOOST operation status bits.
Definition: dev_boost_typedef.h:529
BOOST_CONVERTER_STATUS_s::GO
volatile bool GO
Bit #13: When set, the GO-bit fires up the power supply.
Definition: dev_boost_typedef.h:223
BOOST_CONVERTER_STATUS_s::cs_calib_enable
volatile bool cs_calib_enable
Bit #8: Flag bit indicating that current sensors need to calibrated.
Definition: dev_boost_typedef.h:218
BOOST_CONVERTER_STARTUP_s::power_on_delay
volatile struct BOOST_STARTUP_PERIOD_HANDLER_s power_on_delay
Power-On Delay period deinitions.
Definition: dev_boost_typedef.h:306
BOOST_CONVERTER_s::state_id
volatile struct BOOST_STATE_ID_s state_id
BOOST state machine operating state ID.
Definition: dev_boost_typedef.h:530
BOOST_CONVERTER_s
BOOST control & monitoring data structure.
Definition: dev_boost_typedef.h:527
BOOST_CONVERTER_STATUS_s::autorun
volatile bool autorun
Bit #14: Control bit determining if charger is starting automatically or on command (using the GO bit...
Definition: dev_boost_typedef.h:224
BOOST_CONVERTER_s::set_values
volatile struct BOOST_CONVERTER_SETTINGS_s set_values
Control field for global access to references.
Definition: dev_boost_typedef.h:532
NPNZ_STATUS_s::enabled
volatile bool enabled
Bit 15: enables/disables control loop execution.
Definition: npnz16b.h:202