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