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)
5 ; Date/Time: 03/08/2021 12:42:58
6 ; **********************************************************************************
7 ; 4P4Z Control Library File (Fast Floating Point Coefficient Scaling Mode)
8 ; **********************************************************************************
10 ;------------------------------------------------------------------------------
12 .nolist ; (no external dependencies)
13 .list ; list of all external dependencies
15 ;------------------------------------------------------------------------------
17 .section .data ; place constant data in the data section
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
23 ;------------------------------------------------------------------------------
25 .section .text ; place code in the text section
27 ;------------------------------------------------------------------------------
28 ; Global function declaration
29 ; This function calls the z-domain controller processing the latest data point input
30 ;------------------------------------------------------------------------------
32 .global _v_loop_Update ; provide global scope to routine
33 _v_loop_Update: ; local function label
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
40 ;------------------------------------------------------------------------------
41 ; Setup pointer to first element of error history array
42 mov [w0 + #ptrErrorHistory], w10 ; load pointer address into working register
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
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
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
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
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
98 ;------------------------------------------------------------------------------
99 ; Setup pointers to A-Term data arrays
100 mov [w0 + #ptrACoefficients], w8 ; load pointer to first index of A coefficients array
102 ;------------------------------------------------------------------------------
103 ; Load pointer to first element of control history array
104 mov [w0 + #ptrControlHistory], w10 ; load pointer address into working register
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
127 ;------------------------------------------------------------------------------
128 ; Controller Anti-Windup (control output value clamping)
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:
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:
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
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
163 ;------------------------------------------------------------------------------
164 ; Load pointer to first element of control history array
165 mov [w0 + #ptrControlHistory], w10 ; load pointer address into working register
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
171 mov [w10 + #2], w6 ; move entry (n-2) one tick down the delay line
173 mov [w10 + #0], w6 ; move entry (n-1) one tick down the delay line
175 mov w4, [w10] ; add most recent control output to history
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
189 ;------------------------------------------------------------------------------
191 return ; end of function; return to caller
193 ;------------------------------------------------------------------------------
196 ;------------------------------------------------------------------------------
197 ; Global function declaration v_loop_Reset
198 ; This function clears control and error histories enforcing a reset
199 ;------------------------------------------------------------------------------
201 .global _v_loop_Reset ; provide global scope to routine
202 _v_loop_Reset: ; local function label
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
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
225 ;------------------------------------------------------------------------------
227 return ; end of function; return to caller
229 ;------------------------------------------------------------------------------
232 ;------------------------------------------------------------------------------
233 ; Global function declaration v_loop_Precharge
234 ; This function loads user-defined default values into control and error histories
235 ;------------------------------------------------------------------------------
237 .global _v_loop_Precharge ; provide global scope to routine
238 _v_loop_Precharge: ; local function label
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
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
265 ;------------------------------------------------------------------------------
267 return ; end of function; return to caller
269 ;------------------------------------------------------------------------------
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 ;------------------------------------------------------------------------------
278 .global _v_loop_PTermUpdate ; provide global scope to routine
279 _v_loop_PTermUpdate: ; local function label
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
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
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
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
310 ;------------------------------------------------------------------------------
311 ; Controller Anti-Windup (control output value clamping)
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:
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:
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
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
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
358 ;------------------------------------------------------------------------------
360 return ; end of function; return to caller
362 ;------------------------------------------------------------------------------
365 ;------------------------------------------------------------------------------
367 .end ; end of file v_loop_asm.s
369 ;------------------------------------------------------------------------------
372 ; **********************************************************************************
373 ; Download latest version of this tool here: https://areiter128.github.io/DCLD
374 ; **********************************************************************************