Digital Power Starter Kit 3 Firmware  DM330017-3, Rev.3.0
dsPIC33C Buck Converter Peak Current Mode Control Example
v_loop_asm.s
1 ; **********************************************************************************
2 ; SDK Version: PowerSmartâ„¢ Digital Control Library Designer v0.9.14.678
3 ; CGS Version: Code Generator Script v3.0.8 (03/12/2021)
4 ; Author: M91406
5 ; Date/Time: 04/25/2021 13:39:05
6 ; **********************************************************************************
7 ; 2P2Z 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 + #2], w6 ; move entry (n-2) into buffer
47  mov w6, [w10 + #4] ; move buffered value one tick down the delay line
48  mov [w10 + #0], w6 ; move entry (n-1) into buffer
49  mov w6, [w10 + #2] ; move buffered value one tick down the delay line
50 
51 ;------------------------------------------------------------------------------
52 ; Read data from input source
53  mov [w0 + #ptrSourceRegister], w2 ; load pointer to input source register
54  mov [w2], w1 ; move value from input source into working register
55  mov [w0 + #ptrDProvControlInputComp], w2 ; load pointer address of target buffer of most recent, compensated controller input from data structure
56  mov w1, [w2] ; copy most recent controller input value to given data buffer target
57 
58 ;------------------------------------------------------------------------------
59 ; Load reference and calculate error input to transfer function
60  mov [w0 + #ptrControlReference], w2 ; move pointer to control reference into working register
61  subr w1, [w2], w1 ; calculate error (=reference - input)
62  mov [w0 + #normPreShift], w2 ; move error input scaler into working register
63  sl w1, w2, w1 ; normalize error result to fractional number format
64 
65 ;------------------------------------------------------------------------------
66 ; Setup pointers to B-Term data arrays
67  mov [w0 + #ptrBCoefficients], w8 ; load pointer to first index of B coefficients array
68  mov w1, [w10] ; add most recent error input to history array
69 
70 ;------------------------------------------------------------------------------
71 ; Compute compensation filter B-term
72  clr b, [w8]+=2, w5 ; clear accumulator B and prefetch first error operand
73  clr a, [w8]+=4, w4, [w10]+=2, w6 ; clear accumulator A and prefetch first coefficient operand including number scaler
74  mpy w4*w6, a, [w8]+=4, w4, [w10]+=2, w6 ; multiply first control output of the delay line with first coefficient
75  sftac a, w5 ; shift accumulator to post-scale floating number
76  add b ; add accumulator a to accumulator b
77  mov [w8 - #6], w5 ; load scaler into working register
78  mpy w4*w6, a, [w8]+=4, w4, [w10]+=2, w6 ; multiply control output (n-1) from the delay line with coefficient B1
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 ; multiply & accumulate last control output with coefficient of the delay line (no more prefetch)
83  sftac a, w5 ; shift accumulator to post-scale floating number
84  add b ; add accumulator a to accumulator b
85 
86 ;------------------------------------------------------------------------------
87 ; Setup pointers to A-Term data arrays
88  mov [w0 + #ptrACoefficients], w8 ; load pointer to first index of A coefficients array
89 
90 ;------------------------------------------------------------------------------
91 ; Load pointer to first element of control history array
92  mov [w0 + #ptrControlHistory], w10 ; load pointer address into working register
93 
94 ;------------------------------------------------------------------------------
95 ; Compute compensation filter A-term
96  movsac b, [w8]+=2, w5 ; leave contents of accumulator B unchanged
97  clr a, [w8]+=4, w4, [w10]+=2, w6 ; clear accumulator A and prefetch first coefficient operand including number scaler
98  mpy w4*w6, a, [w8]+=4, w4, [w10]+=2, w6 ; multiply first control output of the delay line with first coefficient
99  sftac a, w5 ; shift accumulator to post-scale floating number
100  add b ; add accumulator a to accumulator b
101  mov [w8 - #6], w5 ; load scaler into working register
102  mpy w4*w6, a ; multiply & accumulate last control output with coefficient of the delay line (no more prefetch)
103  sftac a, w5 ; shift accumulator to post-scale floating number
104  add b ; add accumulator a to accumulator b
105  sac.r b, w4 ; store most recent accumulator result in working register
106 
107 ;------------------------------------------------------------------------------
108 ; Controller Anti-Windup (control output value clamping)
109 
110 ; Check for lower limit violation
111  mov [w0 + #MinOutput], w6 ; load lower limit value
112  cpsgt w4, w6 ; compare values and skip next instruction if control output is within operating range (control output > lower limit)
113  mov w6, w4 ; override most recent controller output
114  V_LOOP_CLAMP_MIN_EXIT:
115 
116 ; Check for upper limit violation
117  mov [w0 + #MaxOutput], w6 ; load upper limit value
118  cpslt w4, w6 ; compare values and skip next instruction if control output is within operating range (control output < upper limit)
119  mov w6, w4 ; override most recent controller output
120  V_LOOP_CLAMP_MAX_EXIT:
121 
122 ;------------------------------------------------------------------------------
123 ; Call user function before the most recent controller result is written to target
124  mov [w0 + #ptrExtHookPreTargetWriteFunction], w12 ; load function pointer to extern user function
125  call w12 ; call function
126 
127 ;------------------------------------------------------------------------------
128 ; Write control output value to target
129  mov [w0 + #ptrTargetRegister], w8 ; capture pointer to target in working register
130  mov w4, [w8] ; move control output to target address
131  mov [w0 + #ptrDProvControlOutput], w2 ; load pointer address of target buffer of most recent controller output value from data structure
132  mov w4, [w2] ; copy most recent controller output value to given data buffer target
133 
134 ;------------------------------------------------------------------------------
135 ; Load pointer to first element of control history array
136  mov [w0 + #ptrControlHistory], w10 ; load pointer address into working register
137 
138 ;------------------------------------------------------------------------------
139 ; Update control output history (move entries one tick down the delay line)
140  mov [w10 + #0], w6 ; move entry (n-1) one tick down the delay line
141  mov w6, [w10 + #2]
142  mov w4, [w10] ; add most recent control output to history
143 
144 ;------------------------------------------------------------------------------
145 ; Enable/Disable bypass branch target with dummy read of source buffer
146  goto V_LOOP_LOOP_EXIT ; when enabled, step over dummy read and go straight to EXIT
147  V_LOOP_LOOP_BYPASS: ; Enable/Disable bypass branch target to perform dummy read of source to clear the source buffer
148  mov [w0 + #ptrSourceRegister], w2 ; load pointer to input source register
149  mov [w2], w1 ; move value from input source into working register
150  mov [w0 + #ptrDProvControlInputComp], w2 ; load pointer address of target buffer of most recent, compensated controller input from data structure
151  mov w1, [w2] ; copy most recent controller input value to given data buffer target
152  mov [w0 + #ptrDProvControlOutput], w2 ; load pointer address of target buffer of most recent controller output value from data structure
153  clr [w2] ; copy most recent controller output value to given data buffer target
154  V_LOOP_LOOP_EXIT: ; Exit control loop branch target
155 
156 ;------------------------------------------------------------------------------
157 ; End of routine
158  return ; end of function; return to caller
159 
160 ;------------------------------------------------------------------------------
161 
162 
163 ;------------------------------------------------------------------------------
164 ; Global function declaration v_loop_Reset
165 ; This function clears control and error histories enforcing a reset
166 ;------------------------------------------------------------------------------
167 
168  .global _v_loop_Reset ; provide global scope to routine
169  _v_loop_Reset: ; local function label
170 
171 ;------------------------------------------------------------------------------
172 ; Clear control history array
173  push w0 ; save contents of working register WREG0
174  mov [w0 + #ptrControlHistory], w0 ; set pointer to the base address of control history array
175  clr [w0++] ; clear next address of control history array
176  clr [w0] ; clear last address of control history array
177  pop w0 ; restore contents of working register WREG0
178 
179 ;------------------------------------------------------------------------------
180 ; Clear error history array
181  push w0 ; save contents of working register WREG0
182  mov [w0 + #ptrErrorHistory], w0 ; set pointer to the base address of error history array
183  clr [w0++] ; Clear next address of error history array
184  clr [w0++] ; Clear next address of error history array
185  clr [w0] ; clear last address of error history array
186  pop w0 ; restore contents of working register WREG0
187 
188 ;------------------------------------------------------------------------------
189 ; End of routine
190  return ; end of function; return to caller
191 
192 ;------------------------------------------------------------------------------
193 
194 
195 ;------------------------------------------------------------------------------
196 ; Global function declaration v_loop_Precharge
197 ; This function loads user-defined default values into control and error histories
198 ;------------------------------------------------------------------------------
199 
200  .global _v_loop_Precharge ; provide global scope to routine
201  _v_loop_Precharge: ; local function label
202 
203 ;------------------------------------------------------------------------------
204 ; Charge error history array with defined value
205  push w0 ; save contents of working register WREG0
206  push w1 ; save contents of working register WREG1
207  mov [w0 + #ptrErrorHistory], w0 ; set pointer to the base address of error history array
208  mov w1, [w0++] ; Load user value into next address of error history array
209  mov w1, [w0++] ; Load user value into next address of error history array
210  mov w1, [w0] ; load user value into last address of error history array
211  pop w1 ; restore contents of working register WREG1
212  pop w0 ; restore contents of working register WREG0
213 
214 ;------------------------------------------------------------------------------
215 ; Charge control history array with defined value
216  push w0 ; save contents of working register WREG0
217  push w2 ; save contents of working register WREG2
218  mov [w0 + #ptrControlHistory], w0 ; set pointer to the base address of control history array
219  mov w2, [w0++] ; Load user value into next address of control history array
220  mov w2, [w0] ; Load user value into last address of control history array
221  pop w2 ; restore contents of working register WREG2
222  pop w0 ; restore contents of working register WREG0
223 
224 ;------------------------------------------------------------------------------
225 ; End of routine
226  return ; end of function; return to caller
227 
228 ;------------------------------------------------------------------------------
229 
230 
231 ;------------------------------------------------------------------------------
232 ; Global function declaration v_loop_PTermUpdate
233 ; This function executes a P-Term based control loop used for plant measurements only.
234 ; THIS LOOP IS NOT SUITED FOR STABLE OPERATION
235 ;------------------------------------------------------------------------------
236 
237  .global _v_loop_PTermUpdate ; provide global scope to routine
238  _v_loop_PTermUpdate: ; local function label
239 
240 ;------------------------------------------------------------------------------
241 ; Check status word for Enable/Disable flag and bypass computation when disabled
242  btss [w0], #NPNZ16_STATUS_ENABLED ; check ENABLED bit state, skip (do not execute) next instruction if set
243  bra V_LOOP_PTERM_LOOP_BYPASS ; if ENABLED bit is cleared, jump to end of control code
244 
245 ;------------------------------------------------------------------------------
246 ; Read data from input source
247  mov [w0 + #ptrSourceRegister], w2 ; load pointer to input source register
248  mov [w2], w1 ; move value from input source into working register
249  mov [w0 + #ptrDProvControlInputComp], w2 ; load pointer address of target buffer of most recent, compensated controller input from data structure
250  mov w1, [w2] ; copy most recent controller input value to given data buffer target
251 
252 ;------------------------------------------------------------------------------
253 ; Load reference and calculate error input to transfer function
254  mov [w0 + #ptrControlReference], w2 ; move pointer to control reference into working register
255  subr w1, [w2], w1 ; calculate error (=reference - input)
256  mov [w0 + #normPreShift], w2 ; move error input scaler into working register
257  sl w1, w2, w1 ; normalize error result to fractional number format
258 
259 ;------------------------------------------------------------------------------
260 ; Load P-gain factor from data structure
261  mov [w0 + #PTermFactor], w6 ; move P-coefficient fractional into working register
262  mov [w0 + #PTermScaler], w2 ; move P-coefficient scaler into working register
263  mov w1, w4 ; move error to MPY working register
264  ; calculate P-control result
265  mpy w4*w6, a ; multiply most recent error with P-coefficient
266  sftac a, w2 ; shift accumulator to post-scale floating number
267  sac.r a, w4 ; store accumulator result to working register
268 
269 ;------------------------------------------------------------------------------
270 ; Controller Anti-Windup (control output value clamping)
271 
272 ; Check for lower limit violation
273  mov [w0 + #MinOutput], w6 ; load lower limit value
274  cpsgt w4, w6 ; compare values and skip next instruction if control output is within operating range (control output > lower limit)
275  mov w6, w4 ; override most recent controller output
276  V_LOOP_PTERM_CLAMP_MIN_EXIT:
277 
278 ; Check for upper limit violation
279  mov [w0 + #MaxOutput], w6 ; load upper limit value
280  cpslt w4, w6 ; compare values and skip next instruction if control output is within operating range (control output < upper limit)
281  mov w6, w4 ; override most recent controller output
282  V_LOOP_PTERM_CLAMP_MAX_EXIT:
283 
284 ;------------------------------------------------------------------------------
285 ; Call user function before the most recent controller result is written to target
286  mov [w0 + #ptrExtHookPreTargetWriteFunction], w12 ; load function pointer to extern user function
287  mov [w0 + #ExtHookPreTargetWriteFunctionParam], w13 ; load single parameter or pointer to parameter data structure
288  call w12 ; call function
289 
290 ;------------------------------------------------------------------------------
291 ; Write control output value to target
292  mov [w0 + #ptrTargetRegister], w8 ; capture pointer to target in working register
293  mov w4, [w8] ; move control output to target address
294  mov [w0 + #ptrDProvControlOutput], w2 ; load pointer address of target buffer of most recent controller output value from data structure
295  mov w4, [w2] ; copy most recent controller output value to given data buffer target
296 
297 ;------------------------------------------------------------------------------
298 ; Enable/Disable bypass branch target with dummy read of source buffer
299  goto V_LOOP_PTERM_LOOP_EXIT ; when enabled, step over dummy read and go straight to EXIT
300  V_LOOP_PTERM_LOOP_BYPASS: ; Enable/Disable bypass branch target to perform dummy read of source to clear the source buffer
301  mov [w0 + #ptrSourceRegister], w2 ; load pointer to input source register
302  mov [w2], w1 ; move value from input source into working register
303  mov [w0 + #ptrDProvControlInputComp], w2 ; load pointer address of target buffer of most recent, compensated controller input from data structure
304  mov w1, [w2] ; copy most recent controller input value to given data buffer target
305  mov [w0 + #ptrDProvControlOutput], w2 ; load pointer address of target buffer of most recent controller output value from data structure
306  clr [w2] ; copy most recent controller output value to given data buffer target
307  V_LOOP_PTERM_LOOP_EXIT: ; Exit P-Term control loop branch target
308 
309 ;------------------------------------------------------------------------------
310 ; End of routine
311  return ; end of function; return to caller
312 
313 ;------------------------------------------------------------------------------
314 
315 
316 ;------------------------------------------------------------------------------
317 ; End of file
318  .end ; end of file v_loop_asm.s
319 
320 ;------------------------------------------------------------------------------
321 
322 
323 ; **********************************************************************************
324 ; Download latest version of this tool here: https://microchip-pic-avr-tools.github.io/powersmart-dcld/
325 ; **********************************************************************************