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 ; **********************************************************************************