Digital Power Starter Kit 3 Firmware
dsPIC33C Buck Converter Voltage Mode Control Example
dev_buck_opstates.c
1 /*
2  * File: dev_buck_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_buck_pconfig.h" // include buck converter
13 #include "dev_buck_typedef.h" // include buck converter data object declarations
14 #include "dev_buck_substates.h" // include state machine sub-state declarations
15 #include "dev_buck_special_functions.h" // include buck 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 BUCK_CONVERTER_s *buckInstance);
21 volatile uint16_t __attribute__((always_inline)) State_Initialize(volatile struct BUCK_CONVERTER_s *buckInstance);
22 volatile uint16_t __attribute__((always_inline)) State_Reset(volatile struct BUCK_CONVERTER_s *buckInstance);
23 volatile uint16_t __attribute__((always_inline)) State_Standby(volatile struct BUCK_CONVERTER_s *buckInstance);
24 volatile uint16_t __attribute__((always_inline)) State_RampUp(volatile struct BUCK_CONVERTER_s *buckInstance);
25 volatile uint16_t __attribute__((always_inline)) State_Online(volatile struct BUCK_CONVERTER_s *buckInstance);
26 
27 // Declaration of function pointer array listing op-state functions in order of execution
28 volatile uint16_t (*BuckConverterStateMachine[])(volatile struct BUCK_CONVERTER_s *buckInstance) =
29 {
30  State_Error,
32  State_Reset,
34  State_RampUp,
36 };
37 
38 // Declaration variable capturing the size of the sub-state function pointer array
40 
41 
54 volatile uint16_t State_Initialize(volatile struct BUCK_CONVERTER_s *buckInstance)
55 {
56  volatile uint16_t _i=0;
57 
58  buckInstance->startup.power_on_delay.counter = 0; // Reset power on counter
59  buckInstance->startup.power_good_delay.counter = 0; // Reset power good counter
60 
61  // Reset all status bits
62  buckInstance->status.bits.adc_active = false;
63 
64  // Initiate current sensor calibration flag bit
65  if (buckInstance->set_values.control_mode == BUCK_CONTROL_MODE_VMC)
66  buckInstance->status.bits.cs_calib_complete = true;
67  else if (buckInstance->status.bits.cs_calib_enable)
68  buckInstance->status.bits.cs_calib_complete = false;
69  else
70  buckInstance->status.bits.cs_calib_complete = true;
71 
72  // Disable control loops
73  buckInstance->v_loop.controller->status.bits.enabled = false; // Disable voltage loop
74 
75  if (buckInstance->set_values.control_mode == BUCK_CONTROL_MODE_ACMC) // In current mode...
76  {
77  for (_i=0; _i<buckInstance->set_values.no_of_phases; _i++) {
78  buckInstance->i_loop[_i].controller->status.bits.enabled = false; // Disable current loop
79  }
80  }
81 
82  // Clear busy bit
83  buckInstance->status.bits.busy = false; // Clear BUSY bit
84  buckInstance->status.bits.ready = true; // Set READY bit indicating state machine has passed INITIALIZED state
85 
86  // Transition to STATE_RESET
87  return(BUCK_OPSRET_COMPLETE);
88 
89 }
90 
91 
104 volatile uint16_t State_Reset(volatile struct BUCK_CONVERTER_s *buckInstance)
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 &= buckPWM_Suspend(buckInstance); // Disable PWM outputs
111 
112  // Disable voltage loop controller and reset control loop histories
113  buckInstance->v_loop.controller->status.bits.enabled = false; // disable voltage control loop
114  buckInstance->v_loop.ctrl_Reset(buckInstance->v_loop.controller); // Reset control histories of outer voltage controller
115  *buckInstance->v_loop.controller->Ports.Target.ptrAddress =
116  buckInstance->v_loop.controller->Limits.MinOutput;
117 
118  // Disable current loop controller and reset control loop histories
119  if (buckInstance->set_values.control_mode == BUCK_CONTROL_MODE_ACMC)
120  { // Disable all current control loops and reset control loop histories
121  for (_i=0; _i<buckInstance->set_values.no_of_phases; _i++) {
122  buckInstance->i_loop[_i].controller->status.bits.enabled = false;
123  buckInstance->i_loop[_i].ctrl_Reset(buckInstance->i_loop[_i].controller);
124  *buckInstance->i_loop[_i].controller->Ports.Target.ptrAddress =
125  buckInstance->i_loop[_i].controller->Limits.MinOutput;
126  }
127  }
128 
129  // Reset the bulk voltage settling counters
130  buckInstance->startup.power_on_delay.counter = 0; // Clear Power On Delay counter
131  buckInstance->startup.power_good_delay.counter = 0; // Clear Power Good Delay counter
132 
133  // Reset all status bits
134  buckInstance->status.bits.adc_active = false;
135  buckInstance->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(BUCK_OPSRET_COMPLETE);
142  else
143  return(BUCK_OPSRET_ERROR);
144 
145 }
146 
147 
159 volatile uint16_t State_Standby(volatile struct BUCK_CONVERTER_s *buckInstance)
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 ((buckInstance->status.bits.enabled) && (buckInstance->status.bits.autorun))
166  { buckInstance->status.bits.GO = true; }
167 
168  // If current sense feedback offset calibration is enabled,
169  // call calibration sub-state routine
170  retval = drv_BuckConverter_SpecialFunctionExecute(buckInstance, CS_OFSET_CALIBRATION);
171 
172  switch (retval)
173  {
174  case BUCK_OPSRET_COMPLETE:
175  buckInstance->status.bits.cs_calib_complete = true; // Set CS Calibration Flag to COMPLETE
176  buckInstance->status.bits.busy = false; // Clear BUSY bit indicating on-going activity
177  break;
178  case BUCK_OPSRET_REPEAT:
179  buckInstance->status.bits.cs_calib_complete = false; // Set CS Calibration Flag to COMPLETE
180  buckInstance->status.bits.busy = true; // Set BUSY bit indicating on-going activity
181  return(BUCK_OPSRET_REPEAT);
182  break;
183  default:
184  buckInstance->status.bits.cs_calib_complete = false; // Set CS Calibration Flag to COMPLETE
185  buckInstance->status.bits.busy = false; // Clear BUSY bit indicating on-going activity
186  return(BUCK_OPSRET_ERROR);
187  break;
188  }
189 
190  // Wait for all startup conditions to be met
191  if ((buckInstance->status.bits.enabled) && // state machine needs to be enabled
192  (buckInstance->status.bits.GO) && // GO-bit needs to be set
193  (buckInstance->status.bits.adc_active) && // ADC needs to be running
194  (buckInstance->status.bits.pwm_active) && // PWM needs to be running
195  (!buckInstance->status.bits.fault_active) && // No active fault is present
196  (!buckInstance->status.bits.suspend) && // Power supply is not held in suspend mode
197  (buckInstance->status.bits.cs_calib_complete) // Current Sensor Calibration complete
198  )
199  {
200  buckInstance->status.bits.GO = false;
201  return(BUCK_OPSRET_COMPLETE);
202  }
203  else
204  // Remain in current state until bit-test becomes true
205  {
206  return(BUCK_OPSRET_REPEAT);
207  }
208 
209 }
210 
211 
225 volatile uint16_t State_RampUp(volatile struct BUCK_CONVERTER_s *buckInstance)
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)(buckInstance->state_id.bits.substate_id) >= (uint16_t)(BuckRampUpSubStateList_size))
231  buckInstance->state_id.bits.substate_id = 0;
232 
233  // If selected sub-state index contains a NULL-pointer, exit here
234  if (BuckConverterRampUpSubStateMachine[buckInstance->state_id.bits.substate_id] == NULL)
235  return(BUCK_OPSRET_ERROR);
236 
237  // Execute ramp-up sub-state
238  retval = BuckConverterRampUpSubStateMachine[buckInstance->state_id.bits.substate_id](buckInstance);
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 BUCK_OPSRET_REPEAT:
246 
247  retval = BUCK_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 BUCK_OPSRET_COMPLETE:
255 
256  // Increment sub-state pointer by one tick
257  buckInstance->state_id.bits.substate_id++;
258 
259  // CHeck if pointer is out of range
260  if ((uint16_t)(buckInstance->state_id.bits.substate_id) < (uint16_t)(BuckRampUpSubStateList_size))
261  { // if execution list is not complete yet, return op-state as REPEAT
262  retval = BUCK_OPSRET_REPEAT;
263 
264  if (buckInstance->state_id.bits.substate_id == BUCK_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 (buckInstance->set_values.control_mode == BUCK_CONTROL_MODE_VMC)
269  buckInstance->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 = BUCK_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 = BUCK_OPSRET_ERROR;
287 
288  break;
289  }
290 
291  return(retval);
292 }
293 
294 
315 volatile uint16_t State_Online(volatile struct BUCK_CONVERTER_s *buckInstance)
316 {
317  if(buckInstance->set_values.v_ref != buckInstance->v_loop.reference)
318  {
319  // Set the BUSY bit indicating a delay/ramp period being executed
320  buckInstance->status.bits.busy = true;
321 
322  // New reference value is less than controller reference value => ramp down
323  if(buckInstance->set_values.v_ref < buckInstance->v_loop.reference){
324  // decrement reference until new reference level is reached
325  buckInstance->v_loop.reference -= buckInstance->startup.v_ramp.ref_inc_step; // decrement reference
326  if(buckInstance->v_loop.reference < buckInstance->set_values.v_ref) { // check if ramp is complete
327  buckInstance->v_loop.reference = buckInstance->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(buckInstance->set_values.v_ref > buckInstance->v_loop.reference){
333  // increment reference until new reference level is reached
334  buckInstance->v_loop.reference += buckInstance->startup.v_ramp.ref_inc_step; // increment reference
335  if(buckInstance->v_loop.reference > buckInstance->set_values.v_ref) { // check if ramp is complete
336  buckInstance->v_loop.reference = buckInstance->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  buckInstance->status.bits.busy = false;
345  }
346 
347  // remain in STATE_ONLINE
348  return(BUCK_OPSRET_REPEAT);
349 
350 }
351 
352 
363 volatile uint16_t State_Error(volatile struct BUCK_CONVERTER_s *buckInstance)
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 = buckPWM_Suspend(buckInstance); // Hold PWM output (turning off power)
371  buckInstance->status.bits.busy = false; // Reset busy bit
372 
373  if(retval)
374  retval = BUCK_OPSRET_COMPLETE;
375  else
376  retval = BUCK_OPSRET_ERROR;
377 
378 
379  return(retval);
380 }
381 
382 
383 // ______________________________________
384 // end of file
BuckStateList_size
volatile uint16_t BuckStateList_size
Buck converter state machine function pointer array size
Definition: dev_buck_opstates.c:39
BuckConverterStateMachine
volatile uint16_t(* BuckConverterStateMachine[])(volatile struct BUCK_CONVERTER_s *buckInstance)
Buck converter state machine function pointer array.
BUCK_LOOP_SETTINGS_s::reference
volatile uint16_t reference
Control loop reference variable.
Definition: dev_buck_typedef.h:347
BUCK_CONVERTER_s::startup
volatile struct BUCK_CONVERTER_STARTUP_s startup
BUCK startup timing settings.
Definition: dev_buck_typedef.h:504
BUCK_STARTUP_PERIOD_HANDLER_s::counter
volatile uint16_t counter
Soft-Start Execution Counter (read only)
Definition: dev_buck_typedef.h:265
State_Error
volatile uint16_t State_Error(volatile struct BUCK_CONVERTER_s *buckInstance)
If this function is called, the state machine is reset to INITIALIZE (URL=State_Initialize).
Definition: dev_buck_opstates.c:363
BUCK_CONVERTER_STARTUP_s::v_ramp
volatile struct BUCK_STARTUP_PERIOD_HANDLER_s v_ramp
Definition: dev_buck_typedef.h:284
drv_BuckConverter_SpecialFunctionExecute
volatile uint16_t drv_BuckConverter_SpecialFunctionExecute(volatile struct BUCK_CONVERTER_s *buckInstance, volatile enum BUCK_SPECIAL_FUNCTIONS_e specialFunction)
This is the public function call access point to call dedicated special sub-functions.
Definition: dev_buck_special_functions.c:133
BUCK_CONVERTER_SETTINGS_s::control_mode
enum BUCK_CONTROL_MODE_e control_mode
Fundamental control mode.
Definition: dev_buck_typedef.h:324
buckPWM_Suspend
volatile uint16_t buckPWM_Suspend(volatile struct BUCK_CONVERTER_s *buckInstance)
This function disables the PWM generator IOs.
Definition: dev_buck_pconfig.c:327
BUCK_CONVERTER_s::i_loop
volatile struct BUCK_LOOP_SETTINGS_s i_loop[BUCK_MPHASE_COUNT]
BUCK Current control loop objects.
Definition: dev_buck_typedef.h:513
BUCK_CONVERTER_s::status
volatile struct BUCK_CONVERTER_STATUS_s status
BUCK operation status bits.
Definition: dev_buck_typedef.h:502
State_Reset
volatile uint16_t State_Reset(volatile struct BUCK_CONVERTER_s *buckInstance)
This function resets the buck control operation by re-initiating the control mode,...
Definition: dev_buck_opstates.c:104
BUCK_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_buck_typedef.h:215
NPNZ_PORTS_s::Target
volatile struct NPNZ_PORT_s Target
Primary data output port declaration.
Definition: npnz16b.h:263
BUCK_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_buck_typedef.h:213
State_Standby
volatile uint16_t State_Standby(volatile struct BUCK_CONVERTER_s *buckInstance)
This function waits until all start-up conditions are met.
Definition: dev_buck_opstates.c:159
BUCK_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_buck_typedef.h:214
NPNZ16b_s::status
volatile struct NPNZ_STATUS_s status
Control Loop Status and Control flags.
Definition: npnz16b.h:504
BUCK_CONVERTER_STARTUP_s::power_on_delay
volatile struct BUCK_STARTUP_PERIOD_HANDLER_s power_on_delay
Definition: dev_buck_typedef.h:281
NPNZ_LIMITS_s::MinOutput
volatile int16_t MinOutput
Minimum output value used for clamping (R/W)
Definition: npnz16b.h:329
NPNZ_STATUS_s::enabled
volatile bool enabled
Bit 15: enables/disables control loop execution.
Definition: npnz16b.h:202
BUCK_CONVERTER_STATUS_s::ready
volatile bool ready
Bit #0: status bit, indicating buck converter is initialized and ready to run.
Definition: dev_buck_typedef.h:208
BuckConverterRampUpSubStateMachine
volatile uint16_t(* BuckConverterRampUpSubStateMachine[])(volatile struct BUCK_CONVERTER_s *buckInstance)
Buck converter state machine function pointer array.
BUCK_LOOP_SETTINGS_s::ctrl_Reset
void(* ctrl_Reset)(volatile struct NPNZ16b_s *)
Function pointer to RESET routine.
Definition: dev_buck_typedef.h:356
BUCK_CONVERTER_SETTINGS_s::v_ref
volatile uint16_t v_ref
User reference setting used to control the power converter controller.
Definition: dev_buck_typedef.h:326
BUCK_CONVERTER_STATUS_s::cs_calib_enable
volatile bool cs_calib_enable
Bit #8: Flag bit indicating that current sensors need to calibrated.
Definition: dev_buck_typedef.h:217
BUCK_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_buck_typedef.h:268
BUCK_CONVERTER_s::set_values
volatile struct BUCK_CONVERTER_SETTINGS_s set_values
Control field for global access to references.
Definition: dev_buck_typedef.h:505
BUCK_CONVERTER_STATUS_s::cs_calib_complete
volatile bool cs_calib_complete
Bit #4: indicating that current sensor calibration has completed.
Definition: dev_buck_typedef.h:212
State_RampUp
volatile uint16_t State_RampUp(volatile struct BUCK_CONVERTER_s *buckInstance)
This function ramps up the voltage/input to its nominal value.
Definition: dev_buck_opstates.c:225
BUCK_CONVERTER_STATUS_s::pwm_active
volatile bool pwm_active
Bit #2: indicating that PWM has been started and ADC triggers are generated.
Definition: dev_buck_typedef.h:210
BuckRampUpSubStateList_size
volatile uint16_t BuckRampUpSubStateList_size
Buck converter sub-state machine function pointer array size.
Definition: dev_buck_substates.c:35
BUCK_LOOP_SETTINGS_s::controller
volatile struct NPNZ16b_s * controller
pointer to control loop object data structure
Definition: dev_buck_typedef.h:353
NPNZ16b_s::Limits
volatile struct NPNZ_LIMITS_s Limits
Input and output clamping values.
Definition: npnz16b.h:508
BUCK_CONVERTER_STATUS_s::adc_active
volatile bool adc_active
Bit #1: indicating that ADC has been started and samples are taken.
Definition: dev_buck_typedef.h:209
BUCK_CONVERTER_s
BUCK control & monitoring data structure.
Definition: dev_buck_typedef.h:501
BUCK_STATE_ID_s::bits
struct BUCK_STATE_ID_s::@3::@4 bits
BUCK_CONVERTER_s::state_id
volatile struct BUCK_STATE_ID_s state_id
BUCK state machine operating state ID.
Definition: dev_buck_typedef.h:503
BUCK_CONVERTER_STARTUP_s::power_good_delay
volatile struct BUCK_STARTUP_PERIOD_HANDLER_s power_good_delay
Definition: dev_buck_typedef.h:282
State_Initialize
volatile uint16_t State_Initialize(volatile struct BUCK_CONVERTER_s *buckInstance)
This function resets the counters and conditional flag bits.
Definition: dev_buck_opstates.c:54
BUCK_CONVERTER_s::v_loop
volatile struct BUCK_LOOP_SETTINGS_s v_loop
BUCK voltage control loop object.
Definition: dev_buck_typedef.h:512
BUCK_CONVERTER_STATUS_s::GO
volatile bool GO
Bit #13: When set, the GO-bit fires up the power supply.
Definition: dev_buck_typedef.h:222
NPNZ16b_s::Ports
volatile struct NPNZ_PORTS_s Ports
Controller input and output ports.
Definition: npnz16b.h:505
BUCK_CONVERTER_SETTINGS_s::no_of_phases
volatile uint16_t no_of_phases
number of converter phases
Definition: dev_buck_typedef.h:325
State_Online
volatile uint16_t State_Online(volatile struct BUCK_CONVERTER_s *buckInstance)
This function tunes the controller reference to the new user control reference level.
Definition: dev_buck_opstates.c:315
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
BUCK_CONVERTER_STATUS_s::enabled
volatile bool enabled
Bit #15: Control bit enabling/disabling the charger port.
Definition: dev_buck_typedef.h:224
BUCK_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_buck_typedef.h:223