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)
5 ; Date/Time: 04/01/2021 23:47:39
6 ; **********************************************************************************
7 ; 3P3Z 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 + #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
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
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
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
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
92 ;------------------------------------------------------------------------------
93 ; Setup pointers to A-Term data arrays
94 mov [w0 + #ptrACoefficients], w8 ; load pointer to first index of A coefficients array
96 ;------------------------------------------------------------------------------
97 ; Load pointer to first element of control history array
98 mov [w0 + #ptrControlHistory], w10 ; load pointer address into working register
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
117 ;------------------------------------------------------------------------------
118 ; Controller Anti-Windup (control output value clamping)
119 mov w4, w1 ; save copy of most recent control output in unused working register
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:
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
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:
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
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
157 ;------------------------------------------------------------------------------
158 ; Load pointer to first element of control history array
159 mov [w0 + #ptrControlHistory], w10 ; load pointer address into working register
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
165 mov [w10 + #0], w6 ; move entry (n-1) one tick down the delay line
167 mov w1, [w10] ; add copy of unlimited most recent control output to history
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
179 ;------------------------------------------------------------------------------
181 return ; end of function; return to caller
183 ;------------------------------------------------------------------------------
186 ;------------------------------------------------------------------------------
187 ; Global function declaration v_loop_Reset
188 ; This function clears control and error histories enforcing a reset
189 ;------------------------------------------------------------------------------
191 .global _v_loop_Reset ; provide global scope to routine
192 _v_loop_Reset: ; local function label
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
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
213 ;------------------------------------------------------------------------------
215 return ; end of function; return to caller
217 ;------------------------------------------------------------------------------
220 ;------------------------------------------------------------------------------
221 ; Global function declaration v_loop_Precharge
222 ; This function loads user-defined default values into control and error histories
223 ;------------------------------------------------------------------------------
225 .global _v_loop_Precharge ; provide global scope to routine
226 _v_loop_Precharge: ; local function label
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
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
251 ;------------------------------------------------------------------------------
253 return ; end of function; return to caller
255 ;------------------------------------------------------------------------------
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 ;------------------------------------------------------------------------------
264 .global _v_loop_PTermUpdate ; provide global scope to routine
265 _v_loop_PTermUpdate: ; local function label
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
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
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
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
296 ;------------------------------------------------------------------------------
297 ; Controller Anti-Windup (control output value clamping)
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:
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:
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
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
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
340 ;------------------------------------------------------------------------------
342 return ; end of function; return to caller
344 ;------------------------------------------------------------------------------
347 ;------------------------------------------------------------------------------
349 .end ; end of file v_loop_asm.s
351 ;------------------------------------------------------------------------------
354 ; **********************************************************************************
355 ; Download latest version of this tool here: https://areiter128.github.io/DCLD
356 ; **********************************************************************************