Digital Power Starter Kit 3 Firmware
dsPIC33C Buck Converter Voltage Mode Control Example
v_loop_asm.s
1 ; **********************************************************************************
2 ; SDK Version: PowerSmartâ„¢ Digital Control Library Designer v0.9.12.672
3 ; CGS Version: Code Generator Script v3.0.7 (03/07/2021)
4 ; Author: M91406
5 ; Date/Time: 03/08/2021 12:42:58
6 ; **********************************************************************************
7 ; 4P4Z Control Library File (Fast Floating Point Coefficient Scaling Mode)
8 ; **********************************************************************************
9 
10 ;------------------------------------------------------------------------------
11 ;file start
12  .nolist ; (no external dependencies)
13  .list ; list of all external dependencies
14 
15 ;------------------------------------------------------------------------------
16 ;local inclusions.
17  .section .data ; place constant data in the data section
18 
19 ;------------------------------------------------------------------------------
20 ;include NPNZ16b_s data structure and global constants.
21  .include "./sources/power_control/drivers/npnz16b.inc" ; include NPNZ16b_s object data structure value offsets and status flag labels
22 
23 ;------------------------------------------------------------------------------
24 ;source code section.
25  .section .text ; place code in the text section
26 
27 ;------------------------------------------------------------------------------
28 ; Global function declaration
29 ; This function calls the z-domain controller processing the latest data point input
30 ;------------------------------------------------------------------------------
31 
32  .global _v_loop_Update ; provide global scope to routine
33  _v_loop_Update: ; local function label
34 
35 ;------------------------------------------------------------------------------
36 ; Check status word for Enable/Disable flag and bypass computation, if disabled
37  btss [w0], #NPNZ16_STATUS_ENABLED ; check ENABLED bit state, skip (do not execute) next instruction if set
38  bra V_LOOP_LOOP_BYPASS ; if ENABLED bit is cleared, jump to end of control code
39 
40 ;------------------------------------------------------------------------------
41 ; Setup pointer to first element of error history array
42  mov [w0 + #ptrErrorHistory], w10 ; load pointer address into working register
43 
44 ;------------------------------------------------------------------------------
45 ; Update error history (move error one tick down the delay line)
46  mov [w10 + #6], w6 ; move entry (n-4) into buffer
47  mov w6, [w10 + #8] ; move buffered value one tick down the delay line
48  mov [w10 + #4], w6 ; move entry (n-3) into buffer
49  mov w6, [w10 + #6] ; move buffered value one tick down the delay line
50  mov [w10 + #2], w6 ; move entry (n-2) into buffer
51  mov w6, [w10 + #4] ; move buffered value one tick down the delay line
52  mov [w10 + #0], w6 ; move entry (n-1) into buffer
53  mov w6, [w10 + #2] ; move buffered value one tick down the delay line
54 
55 ;------------------------------------------------------------------------------
56 ; Read data from input source
57  mov [w0 + #ptrSourceRegister], w2 ; load pointer to input source register
58  mov [w2], w1 ; move value from input source into working register
59  mov [w0 + #ptrDProvControlInputComp], w2 ; load pointer address of target buffer of most recent, compensated controller input from data structure
60  mov w1, [w2] ; copy most recent controller input value to given data buffer target
61 
62 ;------------------------------------------------------------------------------
63 ; Load reference and calculate error input to transfer function
64  mov [w0 + #ptrControlReference], w2 ; move pointer to control reference into working register
65  subr w1, [w2], w1 ; calculate error (=reference - input)
66  mov [w0 + #normPreShift], w2 ; move error input scaler into working register
67  sl w1, w2, w1 ; normalize error result to fractional number format
68 
69 ;------------------------------------------------------------------------------
70 ; Setup pointers to B-Term data arrays
71  mov [w0 + #ptrBCoefficients], w8 ; load pointer to first index of B coefficients array
72  mov w1, [w10] ; add most recent error input to history array
73 
74 ;------------------------------------------------------------------------------
75 ; Compute compensation filter B-term
76  clr b, [w8]+=2, w5 ; clear accumulator B and prefetch first error operand
77  clr a, [w8]+=4, w4, [w10]+=2, w6 ; clear accumulator A and prefetch first coefficient operand including number scaler
78  mpy w4*w6, a, [w8]+=4, w4, [w10]+=2, w6 ; multiply first control output of the delay line with first coefficient
79  sftac a, w5 ; shift accumulator to post-scale floating number
80  add b ; add accumulator a to accumulator b
81  mov [w8 - #6], w5 ; load scaler into working register
82  mpy w4*w6, a, [w8]+=4, w4, [w10]+=2, w6 ; multiply control output (n-1) from the delay line with coefficient B1
83  sftac a, w5 ; shift accumulator to post-scale floating number
84  add b ; add accumulator a to accumulator b
85  mov [w8 - #6], w5 ; load scaler into working register
86  mpy w4*w6, a, [w8]+=4, w4, [w10]+=2, w6 ; multiply control output (n-2) from the delay line with coefficient B2
87  sftac a, w5 ; shift accumulator to post-scale floating number
88  add b ; add accumulator a to accumulator b
89  mov [w8 - #6], w5 ; load scaler into working register
90  mpy w4*w6, a, [w8]+=4, w4, [w10]+=2, w6 ; multiply control output (n-3) from the delay line with coefficient B3
91  sftac a, w5 ; shift accumulator to post-scale floating number
92  add b ; add accumulator a to accumulator b
93  mov [w8 - #6], w5 ; load scaler into working register
94  mpy w4*w6, a ; multiply & accumulate last control output with coefficient of the delay line (no more prefetch)
95  sftac a, w5 ; shift accumulator to post-scale floating number
96  add b ; add accumulator a to accumulator b
97 
98 ;------------------------------------------------------------------------------
99 ; Setup pointers to A-Term data arrays
100  mov [w0 + #ptrACoefficients], w8 ; load pointer to first index of A coefficients array
101 
102 ;------------------------------------------------------------------------------
103 ; Load pointer to first element of control history array
104  mov [w0 + #ptrControlHistory], w10 ; load pointer address into working register
105 
106 ;------------------------------------------------------------------------------
107 ; Compute compensation filter A-term
108  movsac b, [w8]+=2, w5 ; leave contents of accumulator B unchanged
109  clr a, [w8]+=4, w4, [w10]+=2, w6 ; clear accumulator A and prefetch first coefficient operand including number scaler
110  mpy w4*w6, a, [w8]+=4, w4, [w10]+=2, w6 ; multiply first control output of the delay line with first coefficient
111  sftac a, w5 ; shift accumulator to post-scale floating number
112  add b ; add accumulator a to accumulator b
113  mov [w8 - #6], w5 ; load scaler into working register
114  mpy w4*w6, a, [w8]+=4, w4, [w10]+=2, w6 ; multiply control output (n-2) from the delay line with coefficient A2
115  sftac a, w5 ; shift accumulator to post-scale floating number
116  add b ; add accumulator a to accumulator b
117  mov [w8 - #6], w5 ; load scaler into working register
118  mpy w4*w6, a, [w8]+=4, w4, [w10]+=2, w6 ; multiply control output (n-3) from the delay line with coefficient A3
119  sftac a, w5 ; shift accumulator to post-scale floating number
120  add b ; add accumulator a to accumulator b
121  mov [w8 - #6], w5 ; load scaler into working register
122  mpy w4*w6, a ; multiply & accumulate last control output with coefficient of the delay line (no more prefetch)
123  sftac a, w5 ; shift accumulator to post-scale floating number
124  add b ; add accumulator a to accumulator b
125  sac.r b, w4 ; store most recent accumulator result in working register
126 
127 ;------------------------------------------------------------------------------
128 ; Controller Anti-Windup (control output value clamping)
129 
130 ; Check for lower limit violation
131  mov [w0 + #MinOutput], w6 ; load lower limit value
132  cpsgt w4, w6 ; compare values and skip next instruction if control output is within operating range (control output > lower limit)
133  mov w6, w4 ; override controller output
134  V_LOOP_CLAMP_MIN_EXIT:
135 
136 ; Check for upper limit violation
137  mov [w0 + #MaxOutput], w6 ; load upper limit value
138  cpslt w4, w6 ; compare values and skip next instruction if control output is within operating range (control output < upper limit)
139  mov w6, w4 ; override controller output
140  V_LOOP_CLAMP_MAX_EXIT:
141 
142 ;------------------------------------------------------------------------------
143 ; Write control output value to target
144  mov [w0 + #ptrTargetRegister], w8 ; capture pointer to target in working register
145  mov w4, [w8] ; move control output to target address
146  mov [w0 + #ptrDProvControlOutput], w2 ; load pointer address of target buffer of most recent controller output value from data structure
147  mov w4, [w2] ; copy most recent controller output value to given data buffer target
148 
149 ;------------------------------------------------------------------------------
150 ; Update ADC trigger locations
151  asr w4, #1, w6 ; half control output by shifting value one bit to the right
152  ; Update ADC trigger B position
153  mov [w0 + #ADCTriggerBOffset], w8 ; load user-defined ADC trigger B offset value into working register
154  add w6, w8, w10 ; add user-defined ADC trigger B offset to half of control output
155  mov [w0 + #ptrADCTriggerBRegister], w8 ; load pointer to ADC trigger B register into working register
156  mov w10, [w8] ; push new ADC trigger value to ADC trigger B register
157  ; Update ADC trigger A position
158  mov [w0 + #ADCTriggerAOffset], w8 ; load user-defined ADC trigger A offset value into working register
159  add w6, w8, w10 ; add user-defined ADC trigger A offset to half of control output
160  mov [w0 + #ptrADCTriggerARegister], w8 ; load pointer to ADC trigger A register into working register
161  mov w10, [w8] ; push new ADC trigger value to ADC trigger A register
162 
163 ;------------------------------------------------------------------------------
164 ; Load pointer to first element of control history array
165  mov [w0 + #ptrControlHistory], w10 ; load pointer address into working register
166 
167 ;------------------------------------------------------------------------------
168 ; Update control output history (move entries one tick down the delay line)
169  mov [w10 + #4], w6 ; move entry (n-3) one tick down the delay line
170  mov w6, [w10 + #6]
171  mov [w10 + #2], w6 ; move entry (n-2) one tick down the delay line
172  mov w6, [w10 + #4]
173  mov [w10 + #0], w6 ; move entry (n-1) one tick down the delay line
174  mov w6, [w10 + #2]
175  mov w4, [w10] ; add most recent control output to history
176 
177 ;------------------------------------------------------------------------------
178 ; Enable/Disable bypass branch target with dummy read of source buffer
179  goto V_LOOP_LOOP_EXIT ; when enabled, step over dummy read and go straight to EXIT
180  V_LOOP_LOOP_BYPASS: ; Enable/Disable bypass branch target to perform dummy read of source to clear the source buffer
181  mov [w0 + #ptrSourceRegister], w2 ; load pointer to input source register
182  mov [w2], w1 ; move value from input source into working register
183  mov [w0 + #ptrDProvControlInputComp], w2 ; load pointer address of target buffer of most recent, compensated controller input from data structure
184  mov w1, [w2] ; copy most recent controller input value to given data buffer target
185  mov [w0 + #ptrDProvControlOutput], w2 ; load pointer address of target buffer of most recent controller output value from data structure
186  clr [w2] ; copy most recent controller output value to given data buffer target
187  V_LOOP_LOOP_EXIT: ; Exit control loop branch target
188 
189 ;------------------------------------------------------------------------------
190 ; End of routine
191  return ; end of function; return to caller
192 
193 ;------------------------------------------------------------------------------
194 
195 
196 ;------------------------------------------------------------------------------
197 ; Global function declaration v_loop_Reset
198 ; This function clears control and error histories enforcing a reset
199 ;------------------------------------------------------------------------------
200 
201  .global _v_loop_Reset ; provide global scope to routine
202  _v_loop_Reset: ; local function label
203 
204 ;------------------------------------------------------------------------------
205 ; Clear control history array
206  push w0 ; save contents of working register WREG0
207  mov [w0 + #ptrControlHistory], w0 ; set pointer to the base address of control history array
208  clr [w0++] ; clear next address of control history array
209  clr [w0++] ; clear next address of control history array
210  clr [w0++] ; clear next address of control history array
211  clr [w0] ; clear last address of control history array
212  pop w0 ; restore contents of working register WREG0
213 
214 ;------------------------------------------------------------------------------
215 ; Clear error history array
216  push w0 ; save contents of working register WREG0
217  mov [w0 + #ptrErrorHistory], w0 ; set pointer to the base address of error history array
218  clr [w0++] ; Clear next address of error history array
219  clr [w0++] ; Clear next address of error history array
220  clr [w0++] ; Clear next address of error history array
221  clr [w0++] ; Clear next address of error history array
222  clr [w0] ; clear last address of error history array
223  pop w0 ; restore contents of working register WREG0
224 
225 ;------------------------------------------------------------------------------
226 ; End of routine
227  return ; end of function; return to caller
228 
229 ;------------------------------------------------------------------------------
230 
231 
232 ;------------------------------------------------------------------------------
233 ; Global function declaration v_loop_Precharge
234 ; This function loads user-defined default values into control and error histories
235 ;------------------------------------------------------------------------------
236 
237  .global _v_loop_Precharge ; provide global scope to routine
238  _v_loop_Precharge: ; local function label
239 
240 ;------------------------------------------------------------------------------
241 ; Charge error history array with defined value
242  push w0 ; save contents of working register WREG0
243  push w1 ; save contents of working register WREG1
244  mov [w0 + #ptrErrorHistory], w0 ; set pointer to the base address of error history array
245  mov w1, [w0++] ; Load user value into next address of error history array
246  mov w1, [w0++] ; Load user value into next address of error history array
247  mov w1, [w0++] ; Load user value into next address of error history array
248  mov w1, [w0++] ; Load user value into next address of error history array
249  mov w1, [w0] ; load user value into last address of error history array
250  pop w1 ; restore contents of working register WREG1
251  pop w0 ; restore contents of working register WREG0
252 
253 ;------------------------------------------------------------------------------
254 ; Charge control history array with defined value
255  push w0 ; save contents of working register WREG0
256  push w2 ; save contents of working register WREG2
257  mov [w0 + #ptrControlHistory], w0 ; set pointer to the base address of control history array
258  mov w2, [w0++] ; Load user value into next address of control history array
259  mov w2, [w0++] ; Load user value into next address of control history array
260  mov w2, [w0++] ; Load user value into next address of control history array
261  mov w2, [w0] ; Load user value into last address of control history array
262  pop w2 ; restore contents of working register WREG2
263  pop w0 ; restore contents of working register WREG0
264 
265 ;------------------------------------------------------------------------------
266 ; End of routine
267  return ; end of function; return to caller
268 
269 ;------------------------------------------------------------------------------
270 
271 
272 ;------------------------------------------------------------------------------
273 ; Global function declaration v_loop_PTermUpdate
274 ; This function executes a P-Term based control loop used for plant measurements only.
275 ; THIS LOOP IS NOT SUITED FOR STABLE OPERATION
276 ;------------------------------------------------------------------------------
277 
278  .global _v_loop_PTermUpdate ; provide global scope to routine
279  _v_loop_PTermUpdate: ; local function label
280 
281 ;------------------------------------------------------------------------------
282 ; Check status word for Enable/Disable flag and bypass computation when disabled
283  btss [w0], #NPNZ16_STATUS_ENABLED ; check ENABLED bit state, skip (do not execute) next instruction if set
284  bra V_LOOP_PTERM_LOOP_BYPASS ; if ENABLED bit is cleared, jump to end of control code
285 
286 ;------------------------------------------------------------------------------
287 ; Read data from input source
288  mov [w0 + #ptrSourceRegister], w2 ; load pointer to input source register
289  mov [w2], w1 ; move value from input source into working register
290  mov [w0 + #ptrDProvControlInputComp], w2 ; load pointer address of target buffer of most recent, compensated controller input from data structure
291  mov w1, [w2] ; copy most recent controller input value to given data buffer target
292 
293 ;------------------------------------------------------------------------------
294 ; Load reference and calculate error input to transfer function
295  mov [w0 + #ptrControlReference], w2 ; move pointer to control reference into working register
296  subr w1, [w2], w1 ; calculate error (=reference - input)
297  mov [w0 + #normPreShift], w2 ; move error input scaler into working register
298  sl w1, w2, w1 ; normalize error result to fractional number format
299 
300 ;------------------------------------------------------------------------------
301 ; Load P-gain factor from data structure
302  mov [w0 + #PTermFactor], w6 ; move P-coefficient fractional into working register
303  mov [w0 + #PTermScaler], w2 ; move P-coefficient scaler into working register
304  mov w1, w4 ; move error to MPY working register
305  ; calculate P-control result
306  mpy w4*w6, a ; multiply most recent error with P-coefficient
307  sftac a, w2 ; shift accumulator to post-scale floating number
308  sac.r a, w4 ; store accumulator result to working register
309 
310 ;------------------------------------------------------------------------------
311 ; Controller Anti-Windup (control output value clamping)
312 
313 ; Check for lower limit violation
314  mov [w0 + #MinOutput], w6 ; load lower limit value
315  cpsgt w4, w6 ; compare values and skip next instruction if control output is within operating range (control output > lower limit)
316  mov w6, w4 ; override controller output
317  V_LOOP_PTERM_CLAMP_MIN_EXIT:
318 
319 ; Check for upper limit violation
320  mov [w0 + #MaxOutput], w6 ; load upper limit value
321  cpslt w4, w6 ; compare values and skip next instruction if control output is within operating range (control output < upper limit)
322  mov w6, w4 ; override controller output
323  V_LOOP_PTERM_CLAMP_MAX_EXIT:
324 
325 ;------------------------------------------------------------------------------
326 ; Write control output value to target
327  mov [w0 + #ptrTargetRegister], w8 ; capture pointer to target in working register
328  mov w4, [w8] ; move control output to target address
329  mov [w0 + #ptrDProvControlOutput], w2 ; load pointer address of target buffer of most recent controller output value from data structure
330  mov w4, [w2] ; copy most recent controller output value to given data buffer target
331 
332 ;------------------------------------------------------------------------------
333 ; Update ADC trigger locations
334  asr w4, #1, w6 ; half control output by shifting value one bit to the right
335  ; Update ADC trigger B position
336  mov [w0 + #ADCTriggerBOffset], w8 ; load user-defined ADC trigger B offset value into working register
337  add w6, w8, w10 ; add user-defined ADC trigger B offset to half of control output
338  mov [w0 + #ptrADCTriggerBRegister], w8 ; load pointer to ADC trigger B register into working register
339  mov w10, [w8] ; push new ADC trigger value to ADC trigger B register
340  ; Update ADC trigger A position
341  mov [w0 + #ADCTriggerAOffset], w8 ; load user-defined ADC trigger A offset value into working register
342  add w6, w8, w10 ; add user-defined ADC trigger A offset to half of control output
343  mov [w0 + #ptrADCTriggerARegister], w8 ; load pointer to ADC trigger A register into working register
344  mov w10, [w8] ; push new ADC trigger value to ADC trigger A register
345 
346 ;------------------------------------------------------------------------------
347 ; Enable/Disable bypass branch target with dummy read of source buffer
348  goto V_LOOP_PTERM_LOOP_EXIT ; when enabled, step over dummy read and go straight to EXIT
349  V_LOOP_PTERM_LOOP_BYPASS: ; Enable/Disable bypass branch target to perform dummy read of source to clear the source buffer
350  mov [w0 + #ptrSourceRegister], w2 ; load pointer to input source register
351  mov [w2], w1 ; move value from input source into working register
352  mov [w0 + #ptrDProvControlInputComp], w2 ; load pointer address of target buffer of most recent, compensated controller input from data structure
353  mov w1, [w2] ; copy most recent controller input value to given data buffer target
354  mov [w0 + #ptrDProvControlOutput], w2 ; load pointer address of target buffer of most recent controller output value from data structure
355  clr [w2] ; copy most recent controller output value to given data buffer target
356  V_LOOP_PTERM_LOOP_EXIT: ; Exit P-Term control loop branch target
357 
358 ;------------------------------------------------------------------------------
359 ; End of routine
360  return ; end of function; return to caller
361 
362 ;------------------------------------------------------------------------------
363 
364 
365 ;------------------------------------------------------------------------------
366 ; End of file
367  .end ; end of file v_loop_asm.s
368 
369 ;------------------------------------------------------------------------------
370 
371 
372 ; **********************************************************************************
373 ; Download latest version of this tool here: https://areiter128.github.io/DCLD
374 ; **********************************************************************************