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