diff options
Diffstat (limited to 'example/apps/icssg_pwm/firmware/src/iepPwm.c')
-rw-r--r-- | example/apps/icssg_pwm/firmware/src/iepPwm.c | 2770 |
1 files changed, 2770 insertions, 0 deletions
diff --git a/example/apps/icssg_pwm/firmware/src/iepPwm.c b/example/apps/icssg_pwm/firmware/src/iepPwm.c new file mode 100644 index 0000000..a1a999a --- /dev/null +++ b/example/apps/icssg_pwm/firmware/src/iepPwm.c | |||
@@ -0,0 +1,2770 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2019 Texas Instruments Incorporated - http://www.ti.com/ | ||
3 | * | ||
4 | * | ||
5 | * Redistribution and use in source and binary forms, with or without | ||
6 | * modification, are permitted provided that the following conditions | ||
7 | * are met: | ||
8 | * | ||
9 | * * Redistributions of source code must retain the above copyright | ||
10 | * notice, this list of conditions and the following disclaimer. | ||
11 | * | ||
12 | * * Redistributions in binary form must reproduce the above copyright | ||
13 | * notice, this list of conditions and the following disclaimer in the | ||
14 | * documentation and/or other materials provided with the | ||
15 | * distribution. | ||
16 | * | ||
17 | * * Neither the name of Texas Instruments Incorporated nor the names of | ||
18 | * its contributors may be used to endorse or promote products derived | ||
19 | * from this software without specific prior written permission. | ||
20 | * | ||
21 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | ||
22 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | ||
23 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | ||
24 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT | ||
25 | * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | ||
26 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT | ||
27 | * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | ||
28 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | ||
29 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||
30 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | ||
31 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
32 | */ | ||
33 | |||
34 | #include <string.h> | ||
35 | #include <ti/csl/soc.h> | ||
36 | #include "icssg_iep_pwm.h" | ||
37 | #include "iepPwmFwRegs.h" | ||
38 | #include "iepPwmHwRegs.h" | ||
39 | #include "iepPwm.h" | ||
40 | |||
41 | /* Define to synchronize IEP0 & 1 clocks. */ | ||
42 | //#define IEP_SYNC_CLK_EN | ||
43 | /* Define to enable Tx Host interrupt on IEP0 CMP0 */ | ||
44 | //#define TX_HOST_INT | ||
45 | |||
46 | |||
47 | #define CLK_TO_COUNT(x) ( DEF_COUNT_INC_PER_CLK * x ) /* For default increment per clock, compute count corresponding to number of IEP clocks */ | ||
48 | #define COUNT_TO_CLK(x) ( x / DEF_COUNT_INC_PER_CLK ) /* For default increment per clock, compute IEP clocks corresponding to count */ | ||
49 | |||
50 | #define CMP_SR_EARLY_VAL ( DEF_COUNT_INC_PER_CLK ) /* CMP "Early in Period" value */ | ||
51 | |||
52 | /* Index of "sacrificial" PWM in set */ | ||
53 | #define SACR_PWM_IDX ( 0 ) | ||
54 | |||
55 | /* Single-Ended PWM Initial State Configuration register */ | ||
56 | /* Active state Toggle:0000, Trip state HiZ:0000, Initial state L/L:0101 */ | ||
57 | #define SNGL_PWM_STATE_INIT \ | ||
58 | ((PWM_ACT_TOGGLE<<10) | (PWM_ACT_TOGGLE<<8) | (PWM_TRIP_HIZ<<6) | (PWM_TRIP_HIZ<<4) | (PWM_INIT_LO<<2) | (PWM_INIT_LO<<0)) | ||
59 | /* Differential PWM Initial State Configuration register */ | ||
60 | /* Active state Toggle:0000, Trip state HiZ:0000, Initial state H/L:1001 */ | ||
61 | #define DIFF_PWM_STATE_INIT \ | ||
62 | ((PWM_ACT_TOGGLE<<10) | (PWM_ACT_TOGGLE<<8) | (PWM_TRIP_HIZ<<6) | (PWM_TRIP_HIZ<<4) | (PWM_INIT_HI<<2) | (PWM_INIT_LO<<0)) | ||
63 | |||
64 | /* Action Table Rows. | ||
65 | * Each Action Table Row corresponds to a requested Duty Cycle update. | ||
66 | * DC_old: latched (current) Duty Cycle | ||
67 | * DC_new: requested (new) Duty Cycle | ||
68 | */ | ||
69 | typedef enum IepPwmActionTableRow_e | ||
70 | { | ||
71 | AT_Row01_DcOldX_DcNewX = 0, /* DC_old=x, DC_new=x */ | ||
72 | AT_Row02_DcOldX_DcNewY = 1, /* DC_old=x, DC_new=y */ | ||
73 | AT_Row03_DcOldX_DcNew0 = 2, /* DC old=x, DC_new=0 */ | ||
74 | AT_Row04_DcOldX_DcNew100 = 3, /* DC_old=x, DC_new=100 */ | ||
75 | AT_Row05_DcOld0_DcNewY = 4, /* DC_old=0, DC_new=y */ | ||
76 | AT_Row06_DcOld0_DcNew0 = 5, /* DC_old=0, DC_new=0 */ | ||
77 | AT_Row07_DcOld0_DcNew100 = 6, /* DC_old=0, DC_new=100 */ | ||
78 | AT_Row08_DcOld100_DcNewY = 7, /* DC_old=100, DC_new=y */ | ||
79 | AT_Row09_DcOld100_DcNew0 = 8, /* DC_old=100, DC_new=0 */ | ||
80 | AT_Row10_DcOld100_DcNew100 = 9, /* DC_old=100, DC_new=100 */ | ||
81 | AT_NROW | ||
82 | } IepPwmActionTableRow; | ||
83 | |||
84 | /* Action Table Entry. | ||
85 | * Latch, Left-Hand Side, and Right-Hand Side actions to take | ||
86 | * for a requested Duty Cycle update. | ||
87 | */ | ||
88 | typedef struct IepPwmActionTableEntry_s | ||
89 | { | ||
90 | IepLatchAction latchAction; | ||
91 | IepPwmLhsAction lhsAction; | ||
92 | IepPwmRhsAction rhsAction; | ||
93 | } IepPwmActionTableEntry; | ||
94 | |||
95 | /* Action Table: no Enable reconfiguration & En_old==Disabled */ | ||
96 | static const IepPwmActionTableEntry gActT1_EnRecfgNo_EnOldDisable[AT_NROW] = | ||
97 | { | ||
98 | /* DC_old = DC_new = x */ | ||
99 | {LATCH_ACTION_None, | ||
100 | LHS_ACTION_None, | ||
101 | RHS_ACTION_None}, | ||
102 | /* DC_old = x, DC_new = y */ | ||
103 | {LATCH_ACTION_Latch_New, | ||
104 | LHS_ACTION_None, | ||
105 | RHS_ACTION_None}, | ||
106 | /* DC_old = x, DC_new = 0 */ | ||
107 | {LATCH_ACTION_Latch_0, | ||
108 | LHS_ACTION_None, | ||
109 | RHS_ACTION_None}, | ||
110 | /* DC_old = x, DC_new = 100 */ | ||
111 | {LATCH_ACTION_Latch_100, | ||
112 | LHS_ACTION_None, | ||
113 | RHS_ACTION_None}, | ||
114 | /* DC_old = 0, DC_new = y */ | ||
115 | {LATCH_ACTION_Latch_New, | ||
116 | LHS_ACTION_None, | ||
117 | RHS_ACTION_None}, | ||
118 | /* DC_old = 0, DC_new = 0 */ | ||
119 | {LATCH_ACTION_None, | ||
120 | LHS_ACTION_None, | ||
121 | RHS_ACTION_None}, | ||
122 | /* DC_old = 0, DC_new = 100 */ | ||
123 | {LATCH_ACTION_Latch_100, | ||
124 | LHS_ACTION_None, | ||
125 | RHS_ACTION_None}, | ||
126 | /* DC_old = 100, DC_new = y */ | ||
127 | {LATCH_ACTION_Latch_New, | ||
128 | LHS_ACTION_None, | ||
129 | RHS_ACTION_None}, | ||
130 | /* DC_old = 100, DC_new = 0 */ | ||
131 | {LATCH_ACTION_Latch_0, | ||
132 | LHS_ACTION_None, | ||
133 | RHS_ACTION_None}, | ||
134 | /* DC_old = 100, DC_new = 100 */ | ||
135 | {LATCH_ACTION_None, | ||
136 | LHS_ACTION_None, | ||
137 | RHS_ACTION_None}, | ||
138 | }; | ||
139 | |||
140 | /* Action table: no Enable reconfiguration, En_old==Enabled */ | ||
141 | static const IepPwmActionTableEntry gActT2_EnRecfgNo_EnOldEnable[AT_NROW] = | ||
142 | { | ||
143 | /* DC_old = DC_new = x */ | ||
144 | {LATCH_ACTION_None, | ||
145 | LHS_ACTION_None, | ||
146 | RHS_ACTION_None}, | ||
147 | /* DC_old = x, DC_new = y */ | ||
148 | {LATCH_ACTION_Latch_New, | ||
149 | LHS_ACTION_Set_CmpSr_DcLhsY, | ||
150 | RHS_ACTION_None}, | ||
151 | /* DC_old = x, DC_new = 0 */ | ||
152 | {LATCH_ACTION_Latch_0, | ||
153 | LHS_ACTION_Set_CmpSr_GtPrd_And_DisableSrUpdate, | ||
154 | RHS_ACTION_None}, | ||
155 | /* DC_old = x, DC_new = 100 */ | ||
156 | {LATCH_ACTION_Latch_100, | ||
157 | LHS_ACTION_None, | ||
158 | RHS_ACTION_Set_CmpSr_GtPrd_And_DisableSrUpdate}, | ||
159 | /* DC_old = 0, DC_new = y */ | ||
160 | {LATCH_ACTION_Latch_New, | ||
161 | LHS_ACTION_Set_CmpSr_DcLhsY_And_EnableSrUpdate, | ||
162 | RHS_ACTION_None}, | ||
163 | /* DC_old = 0, DC_new = 0 */ | ||
164 | {LATCH_ACTION_None, | ||
165 | LHS_ACTION_None, | ||
166 | RHS_ACTION_None}, | ||
167 | /* DC_old = 0, DC_new = 100 */ | ||
168 | {LATCH_ACTION_Latch_100, | ||
169 | LHS_ACTION_Set_CmpSr_EarlyInPrd_And_EnableSrUpdate, | ||
170 | RHS_ACTION_Set_CmpSr_GtPrd_And_DisableSrUpdate}, | ||
171 | /* DC_old = 100, DC_new = y */ | ||
172 | {LATCH_ACTION_Latch_New, | ||
173 | LHS_ACTION_None, | ||
174 | RHS_ACTION_Set_CmpSr_DcRhsY_And_EnableSrUpdate}, | ||
175 | /* DC_old = 100, DC_new = 0 */ | ||
176 | {LATCH_ACTION_Latch_0, | ||
177 | LHS_ACTION_Set_CmpSr_EarlyInPrd_And_EnableSrUpdate, | ||
178 | RHS_ACTION_Set_CmpSr_GtPrd_And_DisableSrUpdate}, | ||
179 | /* DC_old = 100, DC_new = 100 */ | ||
180 | {LATCH_ACTION_None, | ||
181 | LHS_ACTION_None, | ||
182 | RHS_ACTION_None} | ||
183 | }; | ||
184 | |||
185 | /* Action table: Enable reconfiguration, En_new==Enabled */ | ||
186 | static const IepPwmActionTableEntry gActT3_EnRecfgYes_EnNewEnable[AT_NROW] = | ||
187 | { | ||
188 | /* DC_old = DC_new = x */ | ||
189 | {LATCH_ACTION_None, | ||
190 | LHS_ACTION_Set_CmpSr_DcLhsX_And_EnableSrUpdate, | ||
191 | RHS_ACTION_None}, | ||
192 | /* DC_old = x, DC_new = y */ | ||
193 | {LATCH_ACTION_Latch_New, | ||
194 | LHS_ACTION_Set_CmpSr_DcLhsY_And_EnableSrUpdate, | ||
195 | RHS_ACTION_None}, | ||
196 | /* DC_old = x, DC_new = 0 */ | ||
197 | {LATCH_ACTION_Latch_0, | ||
198 | LHS_ACTION_None, | ||
199 | RHS_ACTION_None}, | ||
200 | /* DC_old = x, DC_new = 100 */ | ||
201 | {LATCH_ACTION_Latch_100, | ||
202 | LHS_ACTION_Set_CmpSr_EarlyInPrd_And_EnableSrUpdate, | ||
203 | RHS_ACTION_Set_CmpSr_GtPrd_And_DisableSrUpdate}, | ||
204 | /* DC_old = 0, DC_new = y */ | ||
205 | {LATCH_ACTION_Latch_New, | ||
206 | LHS_ACTION_Set_CmpSr_DcLhsY_And_EnableSrUpdate, | ||
207 | RHS_ACTION_None}, | ||
208 | /* DC_old = 0, DC_new = 0 */ | ||
209 | {LATCH_ACTION_None, | ||
210 | LHS_ACTION_None, | ||
211 | RHS_ACTION_None}, | ||
212 | /* DC_old = 0, DC_new = 100 */ | ||
213 | {LATCH_ACTION_Latch_100, | ||
214 | LHS_ACTION_Set_CmpSr_EarlyInPrd_And_EnableSrUpdate, | ||
215 | RHS_ACTION_Set_CmpSr_GtPrd_And_DisableSrUpdate}, | ||
216 | /* DC_old = 100, DC_new = y */ | ||
217 | {LATCH_ACTION_Latch_New, | ||
218 | LHS_ACTION_Set_CmpSr_DcLhsY_And_EnableSrUpdate, | ||
219 | RHS_ACTION_None}, | ||
220 | /* DC_old = 100, DC_new = 0 */ | ||
221 | {LATCH_ACTION_Latch_0, | ||
222 | LHS_ACTION_None, | ||
223 | RHS_ACTION_None}, | ||
224 | /* DC_old = 100, DC_new = 100 */ | ||
225 | {LATCH_ACTION_None, | ||
226 | LHS_ACTION_Set_CmpSr_EarlyInPrd_And_EnableSrUpdate, | ||
227 | RHS_ACTION_Set_CmpSr_GtPrd_And_DisableSrUpdate} | ||
228 | }; | ||
229 | |||
230 | /* Action table: Enable reconfiguration, En_new==Enabled */ | ||
231 | static const IepPwmActionTableEntry gActT4_EnRecfgYes_EnNewDisable[AT_NROW] = | ||
232 | { | ||
233 | /* DC_old = DC_new = x */ | ||
234 | {LATCH_ACTION_None, | ||
235 | LHS_ACTION_Set_CmpSr_GtPrd_And_DisableSrUpdate, | ||
236 | RHS_ACTION_None}, | ||
237 | /* DC_old = x, DC_new = y */ | ||
238 | {LATCH_ACTION_Latch_New, | ||
239 | LHS_ACTION_Set_CmpSr_GtPrd_And_DisableSrUpdate, | ||
240 | RHS_ACTION_None}, | ||
241 | /* DC_old = x, DC_new = 0 */ | ||
242 | {LATCH_ACTION_Latch_0, | ||
243 | LHS_ACTION_Set_CmpSr_GtPrd_And_DisableSrUpdate, | ||
244 | RHS_ACTION_None}, | ||
245 | /* DC_old = x, DC_new = 100 */ | ||
246 | {LATCH_ACTION_Latch_100, | ||
247 | LHS_ACTION_Set_CmpSr_GtPrd_And_DisableSrUpdate, | ||
248 | RHS_ACTION_None}, | ||
249 | /* DC_old = 0, DC_new = y */ | ||
250 | {LATCH_ACTION_Latch_New, | ||
251 | LHS_ACTION_None, | ||
252 | RHS_ACTION_None}, | ||
253 | /* DC_old = 0, DC_new = 0 */ | ||
254 | {LATCH_ACTION_None, | ||
255 | LHS_ACTION_None, | ||
256 | RHS_ACTION_None}, | ||
257 | /* DC_old = 0, DC_new = 100 */ | ||
258 | {LATCH_ACTION_Latch_100, | ||
259 | LHS_ACTION_None, | ||
260 | RHS_ACTION_None}, | ||
261 | /* DC_old = 100, DC_new = y */ | ||
262 | {LATCH_ACTION_Latch_New, | ||
263 | LHS_ACTION_Set_CmpSr_GtPrd_And_DisableSrUpdate, | ||
264 | RHS_ACTION_Set_CmpSr_GtPrd_And_DisableSrUpdate}, | ||
265 | /* DC_old = 100, DC_new = 0 */ | ||
266 | {LATCH_ACTION_Latch_0, | ||
267 | LHS_ACTION_Set_CmpSr_GtPrd_And_DisableSrUpdate, | ||
268 | RHS_ACTION_Set_CmpSr_GtPrd_And_DisableSrUpdate}, | ||
269 | /* DC_old = 100, DC_new = 100 */ | ||
270 | {LATCH_ACTION_None, | ||
271 | LHS_ACTION_Set_CmpSr_GtPrd_And_DisableSrUpdate, | ||
272 | RHS_ACTION_Set_CmpSr_GtPrd_And_DisableSrUpdate} | ||
273 | }; | ||
274 | |||
275 | |||
276 | IcssgIepPwmCtrlObj gIcssgIepPwmCtrlObj; /* IEP PWM control object */ | ||
277 | IcssgIepPwmObj gIcssgIep0PwmObj; /* IEP 0 PWM object */ | ||
278 | IcssgIepPwmObj gIcssgIep1PwmObj; /* IEP 1 PWM object */ | ||
279 | |||
280 | /* State Machine function, perform LHS processing */ | ||
281 | static void iepPwmLhs( | ||
282 | IcssgIepPwmObj *pIcssgIepPwmObj | ||
283 | ); | ||
284 | |||
285 | /* State Machine function, perform RHS processing */ | ||
286 | static void iepPwmRhs( | ||
287 | IcssgIepPwmObj *pIcssgIepPwmObj | ||
288 | ); | ||
289 | |||
290 | /* State Machine function, perform LHS reconfiguration. | ||
291 | Check Host reconfiguration request. | ||
292 | Perform Initialization reconfiguration. */ | ||
293 | static Int32 iepPwmConfigLhs( | ||
294 | IcssgIepPwmObj *pIcssgIepPwmObj | ||
295 | ); | ||
296 | |||
297 | /* State Machine Function, perform RHS reconfiguration. | ||
298 | Apply pending Host reconfiguration request. | ||
299 | Perform Initialization reconfiguration. | ||
300 | |||
301 | IEP PWM object has private information required to perform RHS update. | ||
302 | This information is set appropriately in LHS (Host) Reconfiguration. */ | ||
303 | static Int32 iepPwmConfigRhs( | ||
304 | IcssgIepPwmObj *pIcssgIepPwmObj | ||
305 | ); | ||
306 | |||
307 | /* Latch IEP PWM mode. | ||
308 | IEP PWM mode can't change after Initialization. */ | ||
309 | static void latchIepPwmMode( | ||
310 | IcssgIepPwmObj *pIcssgIepPwmObj | ||
311 | ); | ||
312 | |||
313 | /* Update IEP Period Count */ | ||
314 | static void updateIepPwmPeriodCount( | ||
315 | IcssgIepPwmObj *pIcssgIepPwmObj | ||
316 | ); | ||
317 | |||
318 | /* Reset IEP CMPx. | ||
319 | - Set CMPx inside CMP0 period for 1/6 of PWMs in each Set. This forces PWM Set Initial->Active State. | ||
320 | - Set CMPx outside CMP0 period for other 5/6 PWMs in each Set. */ | ||
321 | static void resetIepPwmCmpx( | ||
322 | IcssgIepPwmObj *pIcssgIepPwmObj | ||
323 | ); | ||
324 | |||
325 | /* Initialize PWMs */ | ||
326 | static void initPwm( | ||
327 | IcssgIepPwmObj *pIcssgIepPwmObj | ||
328 | ); | ||
329 | |||
330 | /* Reinitialize PWMs */ | ||
331 | static void reinitPwm( | ||
332 | IcssgIepPwmObj *pIcssgIepPwmObj | ||
333 | ); | ||
334 | |||
335 | /* Latch IEP PWM Enable */ | ||
336 | static void latchIepPwmEn( | ||
337 | IcssgIepPwmObj *pIcssgIepPwmObj | ||
338 | ); | ||
339 | |||
340 | /* Latch IEP PWM Period Count */ | ||
341 | static void latchIepPwmPeriodCount( | ||
342 | IcssgIepPwmObj *pIcssgIepPwmObj | ||
343 | ); | ||
344 | |||
345 | /* Latch IEP PWM Duty Cycle Counts */ | ||
346 | static void latchIepPwmDcCounts( | ||
347 | IcssgIepPwmObj *pIcssgIepPwmObj, | ||
348 | Bool recfgFlag | ||
349 | ); | ||
350 | |||
351 | /* Latch IEP PWM Deadband Counts */ | ||
352 | static void latchIepPwmDbCount( | ||
353 | IcssgIepPwmObj *pIcssgIepPwmObj, | ||
354 | Bool recfgFlag | ||
355 | ); | ||
356 | |||
357 | /* Calculate IEP PWM Single-Ended and Differential Enable | ||
358 | * | ||
359 | * pIcssgIepPwmObj (I): Pointer to IEP PWM object | ||
360 | * pIepPwmSnglEn (O): Pointer to IEP PWM single-ended enable | ||
361 | * pIepPwmDiffEn (O): Pointer to IEP PWM differential enable | ||
362 | * | ||
363 | * IEP_PWM_MODE & IEP_PWM_EN: Host I/F FW Regs. | ||
364 | * iepPwmSnglEn & iepPwmDiffEn: FW private Regs (or PRU registers), used for processing PWMs. | ||
365 | * | ||
366 | */ | ||
367 | static void calcIepPwmSnglDiffEn( | ||
368 | IcssgIepPwmObj *pIcssgIepPwmObj, | ||
369 | Uint16 *pIepPwmSnglEn, | ||
370 | Uint8 *pIepPwmDiffEn | ||
371 | ); | ||
372 | |||
373 | /* Latch IEP PWM Single-Ended and Differential Enable */ | ||
374 | static void latchIepPwmSnglDiffEn( | ||
375 | IcssgIepPwmObj *pIcssgIepPwmObj, | ||
376 | Uint16 iepPwmSnglEn, | ||
377 | Uint8 iepPwmDiffEn | ||
378 | ); | ||
379 | |||
380 | /* Calculate & Latch IEP PWM LHS/RHS Duty Cycle Counts */ | ||
381 | static Int32 calcAndLatchIepPwmDcLhsRhsCount( | ||
382 | IcssgIepPwmObj *pIcssgIepPwmObj, | ||
383 | Bool recfgFlag | ||
384 | ); | ||
385 | |||
386 | /* Initialize IEP PWM CMPx Shadow Registers */ | ||
387 | static Int32 initIepPwmCmpxShReg( | ||
388 | IcssgIepPwmObj *pIcssgIepPwmObj | ||
389 | ); | ||
390 | |||
391 | /* Determine initial LHS/RHS actions */ | ||
392 | static Int32 getInitLhsAction( | ||
393 | Bool initToActPwm, | ||
394 | Bool pwmEn, | ||
395 | Uint32 iepPwmDcCount, | ||
396 | Uint32 pwmPeriodCount, | ||
397 | IepPwmLhsAction *pActionLhs, | ||
398 | IepPwmRhsAction *pActionRhs | ||
399 | ); | ||
400 | |||
401 | /* Initial update IEP PWM CMPx Shadow Register, Single-Ended Mode */ | ||
402 | static void execInitLhsActionSngl( | ||
403 | IepPwmLhsAction actionLhs, | ||
404 | Uint32 iepPwmPeriodCount, | ||
405 | Uint32 iepPwmDcCountLhs, | ||
406 | volatile uint32_t **pIepCmpSrAddr, | ||
407 | Uint16 *pIepPwmSnglUpdEn, | ||
408 | Uint8 pwmIdx | ||
409 | ); | ||
410 | |||
411 | /* Initial update IEP PWM CMPx Shadow Registers, Differential Mode */ | ||
412 | static void execInitLhsActionDiff( | ||
413 | IepPwmLhsAction actionLhs, | ||
414 | Uint32 iepPwmPeriodCount, | ||
415 | Uint32 iepPwmDcCountLhs, | ||
416 | volatile uint32_t **pIepCmpSrAddr, | ||
417 | Uint8 *pIepPwmDiffUpdEn, | ||
418 | Uint8 dPwmIdx | ||
419 | ); | ||
420 | |||
421 | /* Update IEP PWM CMPx Shadow Registers. | ||
422 | PWM Enable and DC Count reconfiguration handled jointly. */ | ||
423 | static Int32 updateIepPwmCmpxShRegPwmEnDc( | ||
424 | IcssgIepPwmObj *pIcssgIepPwmObj | ||
425 | ); | ||
426 | |||
427 | /* Stash RHS action */ | ||
428 | static void stashRhsAction( | ||
429 | IepPwmRhsAction actionRhs, | ||
430 | Bool *pIepPwmRhsRecfgFlag, | ||
431 | IepPwmRhsAction *pIepPwmRhsAction | ||
432 | ); | ||
433 | |||
434 | /* Get Action Table row, Single-Ended PWM | ||
435 | * recfgIepPwmDcCount : (I) IEP PWM DC count reconfiguration mask | ||
436 | * iepPwmDcCountOld : (I) Old (latched) IEP PWM DC count | ||
437 | * iepPwmDcCountNew : (I) New (input) IEP PWM DC count | ||
438 | * pwmIdx : (I) Single-Ended PWM index, 0...IEP_PWM_MODE_SNGL-1 | ||
439 | * pwmPeriodCount : (I) PWM period count | ||
440 | * pRowIdx : (O) address of row index | ||
441 | */ | ||
442 | static Int32 getActionTableRowSngl( | ||
443 | Uint16 recfgDcCount, | ||
444 | Uint8 pwmIdx, | ||
445 | Uint32 iepPwmDcCountOld, | ||
446 | Uint32 iepPwmDcCountNew, | ||
447 | Uint32 pwmPeriodCount, | ||
448 | Uint8 *pRowIdx | ||
449 | ); | ||
450 | |||
451 | /* Get Action Table row, Differential PWM | ||
452 | * recfgDcCount : (I) IEP PWM DC count reconfiguration mask | ||
453 | * iepPwmDcCountOld : (I) Old (latched) IEP PWM DC count | ||
454 | * iepPwmDcCountNew : (I) New (input) IEP PWM DC count | ||
455 | * pwmIdx : (I) Differential PWM index, 0...IEP_PWM_MODE_DIFF-1 | ||
456 | * pwmPeriodCount : (I) PWM period | ||
457 | * pRowIdx : (O) address of row index | ||
458 | */ | ||
459 | static Int32 getActionTableRowDiff( | ||
460 | Uint16 recfgDcCount, | ||
461 | Uint8 dPwmIdx, | ||
462 | Uint32 iepPwmDcCountOld, | ||
463 | Uint32 iepPwmDcCountNew, | ||
464 | Uint32 pwmPeriodCount, | ||
465 | Uint8 *pRowIdx | ||
466 | ); | ||
467 | |||
468 | /* Calculate IEP PWM LHS/RHS Duty Cycle Counts | ||
469 | * actionLatch : (I) Latch Action | ||
470 | * iepPwmDcCountNew : (I) New (input) IEP PWM DC count | ||
471 | * pIepPwmDcCountLhsNew : (O) IEP PWM DC LHS count | ||
472 | * pIepPwmDcCountRhsNew : (O) IEP PWM DC RHS count | ||
473 | */ | ||
474 | static void calcDcLatchAction( | ||
475 | IepLatchAction actionLatch, | ||
476 | Uint32 iepPwmDcCountNew, | ||
477 | Uint32 *pIepPwmDcCountLhsNew, | ||
478 | Uint32 *pIepPwmDcCountRhsNew | ||
479 | ); | ||
480 | |||
481 | /* Calculate DC LHS/RHS for DC */ | ||
482 | static void calcDcLhsRhs( | ||
483 | Uint32 dcCount, | ||
484 | Uint32 *pDcCountLhs, | ||
485 | Uint32 *pDcCountRhs | ||
486 | ); | ||
487 | |||
488 | /* Execute LHS action, Single-Ended PWM | ||
489 | * iepPwmDcCountLhsOld : (I) scalar, old DC LHS | ||
490 | * iepPwmDcCountLhsNew : (I) scalar, new DC LHS | ||
491 | * pIepCmpSrBase : (I) base pointer for CMP SRs | ||
492 | * pIepPwmSnglUpdEn : (I) single-ended signal update enable | ||
493 | * pwmIdx : (I) 0...IEP_MAX_NUM_SNGL_PWM-1 | ||
494 | * iepPwmPeriodCount : (I) IEP CMP0 period count | ||
495 | */ | ||
496 | static void execLhsActionSngl( | ||
497 | IepPwmLhsAction lhsAction, | ||
498 | Uint32 iepPwmDcCountLhsOld, | ||
499 | Uint32 iepPwmDcCountLhsNew, | ||
500 | volatile uint32_t **pIepCmpSrAddr, | ||
501 | Uint16 *pIepPwmSnglUpdEn, | ||
502 | Uint8 pwmIdx, | ||
503 | Uint32 iepPwmPeriodCount | ||
504 | ); | ||
505 | |||
506 | /* Execute LHS action, Differential PWM | ||
507 | * iepPwmDcCountLhsOld : (I) scalar, old DC LHS | ||
508 | * iepPwmDcCountLhsNew : (I) scalar, new DC LHS | ||
509 | * pIepCmpSrBase : (I) base pointer for CMP SRs | ||
510 | * pIepPwmDiffUpdEn : (I) single-ended signal update enable | ||
511 | * dPwmIdx : (I) 0...IEP_MAX_NUM_DIFF_PWM-1 | ||
512 | * iepPwmPeriodCount : (I) IEP CMP0 period count | ||
513 | */ | ||
514 | static void execLhsActionDiff( | ||
515 | IepPwmLhsAction lhsAction, | ||
516 | Uint32 iepPwmDcCountLhsOld, | ||
517 | Uint32 iepPwmDcCountLhsNew, | ||
518 | volatile uint32_t **pIepCmpSrAddr, | ||
519 | Uint8 *pIepPwmDiffUpdEn, | ||
520 | Uint8 dPwmIdx, | ||
521 | Uint32 iepPwmPeriodCount | ||
522 | ); | ||
523 | |||
524 | |||
525 | /* Execute (LHS) DC latch action | ||
526 | * actionLatch : (I) Latch Action | ||
527 | * pIepPwmDcCountOld : (I) Pointer to old (latched) IEP PWM DC count | ||
528 | * pIepPwmDcCountLhsOld : (I) Pointer to IEP PWM DC LHS count | ||
529 | * pIepPwmDcCountRhsOld : (I) Pointer to IEP PWM DC RHS count | ||
530 | * iepPwmDcCountNew : (I) new IEP PWM DC count | ||
531 | * iepPwmDcCountLhsNew : (I) new IEP PWM DC LHS count | ||
532 | * iepPwmDcCountRhsNew : (I) new IEP PWM DC RHS count | ||
533 | */ | ||
534 | static void execDcLatchAction( | ||
535 | IepLatchAction actionLatch, | ||
536 | Uint32 *pIepPwmDcCountOld, | ||
537 | Uint32 *pIepPwmDcCountLhsOld, | ||
538 | Uint32 *pIepPwmDcCountRhsOld, | ||
539 | Uint32 iepPwmDcCountNew, | ||
540 | Uint32 iepPwmDcCountLhsNew, | ||
541 | Uint32 iepPwmDcCountRhsNew | ||
542 | ); | ||
543 | |||
544 | /* Execute stashed RHS actions */ | ||
545 | static void execRhsActionStash( | ||
546 | IcssgIepPwmObj *pIcssgIepPwmObj | ||
547 | ); | ||
548 | |||
549 | /* Update IEP PWM CMPx Shadow Registers for DB reconfiguration. */ | ||
550 | static Int32 updateIepPwmCmpxShRegDb( | ||
551 | IcssgIepPwmObj *pIcssgIepPwmObj | ||
552 | ); | ||
553 | |||
554 | #ifdef TX_HOST_INT | ||
555 | volatile register uint32_t __R31; | ||
556 | #endif | ||
557 | |||
558 | /* ------------------------------------------------------------------------- * | ||
559 | * External Functions * | ||
560 | * ------------------------------------------------------------------------- */ | ||
561 | |||
562 | /* Reset PWM FW control object */ | ||
563 | Int32 resetPwmCtrlObj( | ||
564 | IcssgIepPwmCtrlObj *pIcssgIepPwmCtrlObj | ||
565 | ) | ||
566 | { | ||
567 | Uint8 i; | ||
568 | |||
569 | for (i = 0; i < ICSSG_NUM_IEP; i++) | ||
570 | { | ||
571 | pIcssgIepPwmCtrlObj->iepPwmGblEn[i] = FALSE; | ||
572 | } | ||
573 | |||
574 | pIcssgIepPwmCtrlObj->pIcssgCfgHwRegs = (CSL_icss_g_pr1_cfg_slvRegs *)CSL_ICSS_CFG_BASE; | ||
575 | pIcssgIepPwmCtrlObj->pIepPwmCtrlFwRegs = (IepPwmCtrlFwRegs *)ICSSG_IEPPWM_PWM_CTRL_ADDR; | ||
576 | return IEP_STS_NERR; | ||
577 | } | ||
578 | |||
579 | /* Reset IEP PWM object */ | ||
580 | Int32 resetIepPwmObj( | ||
581 | IcssgIepPwmObj *pIcssgIepPwmObj, | ||
582 | IepId iepId | ||
583 | ) | ||
584 | { | ||
585 | CSL_icss_g_pr1_cfg_slvRegs *pruIcssgCfg = (CSL_icss_g_pr1_cfg_slvRegs *)CSL_ICSS_CFG_BASE; | ||
586 | CSL_icss_g_pr1_iep1_slvRegs *pIepHwRegs; | ||
587 | volatile uint32_t *pIepCmpSr; | ||
588 | Uint8 pwmIdx; | ||
589 | |||
590 | memset(pIcssgIepPwmObj, 0, sizeof(IcssgIepPwmObj)); | ||
591 | pIcssgIepPwmObj->iepId = iepId; | ||
592 | if (iepId == IEP_ID_0) { | ||
593 | pIcssgIepPwmObj->pIepPwmFwRegs = (IepPwmFwRegs *)ICSSG_PWM_IEP0_PWM_BASE_ADDR; | ||
594 | pIcssgIepPwmObj->pIepHwRegs = (CSL_icss_g_pr1_iep1_slvRegs *)ICSS_IEP0_CFG_BASE; | ||
595 | pIcssgIepPwmObj->pIepPwmTripHwRegs = (IepPwmTripHwRegs *)(&pruIcssgCfg->PWM0); | ||
596 | pIcssgIepPwmObj->pPwmStateCfgHwRegs = (IepPwmStateCfgHwRegs *)(&pruIcssgCfg->PWM0_0); | ||
597 | } | ||
598 | else if (iepId == IEP_ID_1) { | ||
599 | pIcssgIepPwmObj->pIepPwmFwRegs = (IepPwmFwRegs *)ICSSG_PWM_IEP1_PWM_BASE_ADDR; | ||
600 | pIcssgIepPwmObj->pIepHwRegs = (CSL_icss_g_pr1_iep1_slvRegs *)ICSS_IEP1_CFG_BASE; | ||
601 | pIcssgIepPwmObj->pIepPwmTripHwRegs = (IepPwmTripHwRegs *)(&pruIcssgCfg->PWM2); | ||
602 | pIcssgIepPwmObj->pPwmStateCfgHwRegs = (IepPwmStateCfgHwRegs *)(&pruIcssgCfg->PWM2_0); | ||
603 | } | ||
604 | else { | ||
605 | return IEP_STS_ERR_INV_IEP_ID; | ||
606 | } | ||
607 | |||
608 | pIepHwRegs = pIcssgIepPwmObj->pIepHwRegs; | ||
609 | |||
610 | /* Initialize CMP Shadow Register address table */ | ||
611 | /* CMP1-6 */ | ||
612 | pIepCmpSr = &pIepHwRegs->CMP1_REG1; | ||
613 | for (pwmIdx = 0; pwmIdx < SNGL_PWM_PER_SET; pwmIdx++) | ||
614 | { | ||
615 | pIcssgIepPwmObj->iepCmpSrAddr[pwmIdx] = pIepCmpSr; | ||
616 | pIepCmpSr += 2; /* CMP regs are 64 bit */ | ||
617 | } | ||
618 | pIcssgIepPwmObj->iepCmpSrAddr[pwmIdx] = pIepCmpSr; /* CMP7 SR */ | ||
619 | pIepCmpSr += 4; /* account for 64-bit gap in CMP register MM */ | ||
620 | /* CMP7-12 */ | ||
621 | for (pwmIdx = SNGL_PWM_PER_SET+1; pwmIdx < IEP_MAX_NUM_SNGL_PWM; pwmIdx++) | ||
622 | { | ||
623 | pIcssgIepPwmObj->iepCmpSrAddr[pwmIdx] = pIepCmpSr; | ||
624 | pIepCmpSr += 2; /* CMP regs are 64 bit */ | ||
625 | } | ||
626 | |||
627 | return IEP_STS_NERR; | ||
628 | } | ||
629 | |||
630 | /* Wait for PWM enable flag from Host. | ||
631 | Flag indicates to FW that initialization can commence. */ | ||
632 | Int32 waitPwmEnFlag( | ||
633 | IcssgIepPwmCtrlObj *pIcssgIepPwmCtrlObj | ||
634 | ) | ||
635 | { | ||
636 | IepPwmCtrlFwRegs *pIepPwmCtrlFwRegs = pIcssgIepPwmCtrlObj->pIepPwmCtrlFwRegs; | ||
637 | Uint8 pwmEn; | ||
638 | |||
639 | do { | ||
640 | pwmEn = (pIepPwmCtrlFwRegs->PWM_CTRL & PWM_CTRL_PWM_EN_MASK) >> PWM_CTRL_PWM_EN_SHIFT; | ||
641 | } while (pwmEn == BF_PWM_EN_DISABLE); | ||
642 | |||
643 | pIepPwmCtrlFwRegs->PWM_STAT |= BF_PWM_EN_ACK_ENABLE << PWM_STAT_PWM_EN_ACK_SHIFT; /* PWM_STAT:PWM_EN_ACK=1 */ | ||
644 | |||
645 | return IEP_STS_NERR; | ||
646 | } | ||
647 | |||
648 | /* Initialize PWM FW control */ | ||
649 | Int32 initPwmCtrl( | ||
650 | IcssgIepPwmCtrlObj *pIcssgIepPwmCtrlObj | ||
651 | ) | ||
652 | { | ||
653 | IepPwmCtrlFwRegs *pIepPwmCtrlFwRegs = pIcssgIepPwmCtrlObj->pIepPwmCtrlFwRegs; | ||
654 | volatile Uint32 iepClkReg; | ||
655 | Uint8 i; | ||
656 | #ifdef IEP_SYNC_CLK_EN | ||
657 | Bool iepSync; | ||
658 | #endif | ||
659 | |||
660 | for (i = 0; i < ICSSG_NUM_IEP; i++) | ||
661 | { | ||
662 | /* Latch IEP PWM global enable. | ||
663 | Global enable can't change after Initialization. */ | ||
664 | pIcssgIepPwmCtrlObj->iepPwmGblEn[i] = | ||
665 | (Bool)((pIepPwmCtrlFwRegs->PWM_CTRL >> (PWM_CTRL_IEP0_PWM_GBL_EN_SHIFT+i) ) & IEP_PWM_GBL_EN_MASK); | ||
666 | /* Acknowledge IEP PWM global enable */ | ||
667 | pIepPwmCtrlFwRegs->PWM_STAT |= (Uint32)pIcssgIepPwmCtrlObj->iepPwmGblEn[i] << (PWM_CTRL_IEP0_PWM_GBL_EN_SHIFT+i); | ||
668 | } | ||
669 | |||
670 | #ifdef IEP_SYNC_CLK_EN | ||
671 | iepSync = TRUE; | ||
672 | for (i = 0; i < ICSSG_NUM_IEP; i++) | ||
673 | { | ||
674 | /* Update IEP clock synchronization flag. | ||
675 | All IEPs must be enabled for IEP clock synchronization to be enabled. */ | ||
676 | iepSync = iepSync && pIcssgIepPwmCtrlObj->iepPwmGblEn[i]; | ||
677 | } | ||
678 | if (iepSync == TRUE) { | ||
679 | /* Set IEP0 & 1 synchronization */ | ||
680 | |||
681 | /* Read ICSSG_IEPCLK_REG HW register */ | ||
682 | iepClkReg = pIcssgIepPwmCtrlObj->pIcssgCfgHwRegs->IEPCLK_REG; | ||
683 | /* ICSSG_IEPCLK_REG:IEP1_SLV_EN=0 */ | ||
684 | iepClkReg &= ~CSL_ICSS_G_PR1_CFG_SLV_IEPCLK_REG_IEP1_SLV_EN_MASK; | ||
685 | /* ICSSG_IEPCLK_REG:IEP1_SLV_EN=1, | ||
686 | IEP1 Master Counter Slave enable is Enabled */ | ||
687 | iepClkReg |= 1<< CSL_ICSS_G_PR1_CFG_SLV_IEPCLK_REG_IEP1_SLV_EN_SHIFT; | ||
688 | /* Write ICSSG_IEPCLK_REG HW register */ | ||
689 | pIcssgIepPwmCtrlObj->pIcssgCfgHwRegs->IEPCLK_REG = iepClkReg; | ||
690 | } | ||
691 | #endif | ||
692 | |||
693 | return IEP_STS_NERR; | ||
694 | } | ||
695 | |||
696 | /* Initialize IEP PWM object | ||
697 | * | ||
698 | * Initial Configuration is located in Host I/F FW Regs. | ||
699 | * Default Initial Configuration is loaded in DMEM load (static data). | ||
700 | * Host can overwrite Default Initial Configuration *before* FW execution. | ||
701 | * | ||
702 | * Initial Configuration Applied whether Host_RECFG != 0 or not, i.e. Host_RECFG not checked. | ||
703 | * Initial Configuration is only place PWM MODE is configured. | ||
704 | */ | ||
705 | Int32 initIepPwm( | ||
706 | IcssgIepPwmCtrlObj *pIcssgIepPwmCtrlObj, | ||
707 | IcssgIepPwmObj *pIcssgIepPwmObj | ||
708 | ) | ||
709 | { | ||
710 | IepId iepId = pIcssgIepPwmObj->iepId; | ||
711 | IepPwmFwRegs *pIepPwmFwRegs = pIcssgIepPwmObj->pIepPwmFwRegs; | ||
712 | Uint16 iepPwmSnglEn; | ||
713 | Uint8 iepPwmDiffEn; | ||
714 | Int32 status = IEP_STS_NERR; | ||
715 | |||
716 | /* Latch IEP PWM global enable. | ||
717 | Global enable can't change after Initialization. */ | ||
718 | /* Acknowledge IEP PWM global enable */ | ||
719 | |||
720 | /* Configure PWMs */ | ||
721 | |||
722 | if (pIcssgIepPwmCtrlObj->iepPwmGblEn[iepId] == TRUE) { | ||
723 | /* Latch IEP PWM mode. | ||
724 | IEP PWM mode can't change after Initialization. */ | ||
725 | latchIepPwmMode(pIcssgIepPwmObj); | ||
726 | |||
727 | /* Update IEP Period Count */ | ||
728 | updateIepPwmPeriodCount(pIcssgIepPwmObj); | ||
729 | |||
730 | /* Reset IEP0 CMPx. | ||
731 | - Set CMPx inside CMP0 period for 1/6 of PWMs in each Set. This forces PWM Set Initial->Active State. | ||
732 | - Set CMPx outside CMP0 period for other 5/6 PWMs in each Set. */ | ||
733 | resetIepPwmCmpx(pIcssgIepPwmObj); | ||
734 | |||
735 | /* Initialize PWMs */ | ||
736 | initPwm(pIcssgIepPwmObj); | ||
737 | |||
738 | /* Latch IEP PWM Enable */ | ||
739 | latchIepPwmEn(pIcssgIepPwmObj); | ||
740 | |||
741 | /* Latch Period Count */ | ||
742 | latchIepPwmPeriodCount(pIcssgIepPwmObj); | ||
743 | |||
744 | /* Latch IEP PWM Duty Cycle Counts */ | ||
745 | latchIepPwmDcCounts(pIcssgIepPwmObj, FALSE); | ||
746 | |||
747 | /* Latch IEP PWM Deadband Counts */ | ||
748 | latchIepPwmDbCount(pIcssgIepPwmObj, FALSE); | ||
749 | |||
750 | /* Calculate & Latch Single-Ended and Differential PWM Enable */ | ||
751 | calcIepPwmSnglDiffEn(pIcssgIepPwmObj, &iepPwmSnglEn, &iepPwmDiffEn); | ||
752 | latchIepPwmSnglDiffEn(pIcssgIepPwmObj, iepPwmSnglEn, iepPwmDiffEn); | ||
753 | |||
754 | /* Calculate & Latch LHS/RHS Duty Cycle Counts */ | ||
755 | calcAndLatchIepPwmDcLhsRhsCount(pIcssgIepPwmObj, FALSE); | ||
756 | |||
757 | /* Clear reconfiguration flags whether set or not */ | ||
758 | pIepPwmFwRegs->IEP_PWM_RECFG = 0; | ||
759 | } | ||
760 | |||
761 | return status; | ||
762 | } | ||
763 | |||
764 | /* Set PWM FW initialization flag. | ||
765 | Flag indicates to Host that FW initialization is complete. */ | ||
766 | Int32 setPwmFwInitFlag( | ||
767 | IcssgIepPwmCtrlObj *pIcssgIepPwmCtrlObj | ||
768 | ) | ||
769 | { | ||
770 | IepPwmCtrlFwRegs *pIepPwmCtrlFwRegs = pIcssgIepPwmCtrlObj->pIepPwmCtrlFwRegs; | ||
771 | pIepPwmCtrlFwRegs->PWM_STAT |= BF_PWM_FW_INIT_INIT << PWM_STAT_FW_INIT_SHIFT; /* PWM_STAT:FW_INIT=1 */ | ||
772 | |||
773 | return IEP_STS_NERR; | ||
774 | } | ||
775 | |||
776 | /* Get IEP PWM State Machine configuration: | ||
777 | - IEP0 disabled, IEP1 disabled | ||
778 | - IEP0 disabled, IEP1 enabled | ||
779 | - IEP0 enabled, IEP1 disabled | ||
780 | - IEP0 enabled, IEP1 enabled */ | ||
781 | IepSm_Config getIepPwmSmConfig( | ||
782 | IcssgIepPwmCtrlObj *pIcssgIepPwmCtrlObj | ||
783 | ) | ||
784 | { | ||
785 | Bool iep0PwmGblEn, iep1PwmGblEn; | ||
786 | IepSm_Config ret; | ||
787 | |||
788 | |||
789 | iep0PwmGblEn = pIcssgIepPwmCtrlObj->iepPwmGblEn[0]; | ||
790 | iep1PwmGblEn = pIcssgIepPwmCtrlObj->iepPwmGblEn[1]; | ||
791 | |||
792 | if (iep0PwmGblEn == FALSE) { | ||
793 | ret = (iep1PwmGblEn == FALSE) ? IEP_SM_CONFIG_NONE : IEP_SM_CONFIG_IEP1; | ||
794 | } | ||
795 | else { | ||
796 | ret = (iep1PwmGblEn == FALSE) ? IEP_SM_CONFIG_IEP0 : IEP_SM_CONFIG_IEP0_1; | ||
797 | } | ||
798 | |||
799 | return ret; | ||
800 | } | ||
801 | |||
802 | /* Initialize IEP PWM State Machine */ | ||
803 | void initIepPwmSm( | ||
804 | IcssgIepPwmObj *pIcssgIepPwmObj | ||
805 | ) | ||
806 | { | ||
807 | pIcssgIepPwmObj->iepPwmState = IEP_SM_STATE_INIT; | ||
808 | |||
809 | /* Enable IEP Counter */ | ||
810 | pIcssgIepPwmObj->pIepHwRegs->GLOBAL_CFG_REG |= 0x1; | ||
811 | } | ||
812 | |||
813 | /* Execute IEP PWM State Machine */ | ||
814 | Int32 execIepPwmSm( | ||
815 | IcssgIepPwmObj *pIcssgIepPwmObj, | ||
816 | Bool txHostEvt | ||
817 | ) | ||
818 | { | ||
819 | CSL_icss_g_pr1_iep1_slvRegs *pIepHwRegs = pIcssgIepPwmObj->pIepHwRegs; | ||
820 | uint32_t cmpStatus; | ||
821 | Int32 status = IEP_STS_NERR; | ||
822 | |||
823 | cmpStatus = pIepHwRegs->CMP_STATUS_REG; | ||
824 | if (pIcssgIepPwmObj->iepPwmState == IEP_SM_STATE_INIT) { | ||
825 | if ((cmpStatus & IEP_CMP_STATUS_CMP0_MASK) == IEP_CMP_STATUS_CMP0_MASK) { /* CMP0 event has occurred */ | ||
826 | pIepHwRegs->CMP_STATUS_REG = IEP_CMP_STATUS_CMP0_12_MASK; /* clear CMP0-12 events */ | ||
827 | #ifdef TX_HOST_INT | ||
828 | if (txHostEvt == TRUE) { | ||
829 | __R31 = 16 + TRIGGER_HOST_EVT; /* trigger Host interrupt on IEP CMP0 event */ | ||
830 | } | ||
831 | #endif | ||
832 | |||
833 | /* Initialize IEP PWM CMPx Shadow Registers */ | ||
834 | status = initIepPwmCmpxShReg(pIcssgIepPwmObj); | ||
835 | |||
836 | if (status == IEP_STS_NERR) { | ||
837 | /* Update State to Left-Hand Side */ | ||
838 | pIcssgIepPwmObj->iepPwmState = IEP_SM_STATE_LHS; | ||
839 | } | ||
840 | else { | ||
841 | /* Update state to Left-Hand Side (Host) Reconfiguration */ | ||
842 | pIcssgIepPwmObj->iepPwmState = IEP_SM_STATE_LHS_RECFG; | ||
843 | } | ||
844 | } | ||
845 | } | ||
846 | if (pIcssgIepPwmObj->iepPwmState == IEP_SM_STATE_LHS) { | ||
847 | if ((cmpStatus & IEP_CMP_STATUS_CMP0_MASK) == IEP_CMP_STATUS_CMP0_MASK) { /* CMP0 event has occurred */ | ||
848 | pIepHwRegs->CMP_STATUS_REG = IEP_CMP_STATUS_CMP0_12_MASK; /* clear CMP0-12 events */ | ||
849 | #ifdef TX_HOST_INT | ||
850 | if (txHostEvt == TRUE) { | ||
851 | __R31 = 16 + TRIGGER_HOST_EVT; /* trigger Host interrupt on IEP CMP0 event */ | ||
852 | } | ||
853 | #endif | ||
854 | /* Perform LHS processing */ | ||
855 | iepPwmLhs(pIcssgIepPwmObj); | ||
856 | |||
857 | /* Update state to Left-Hand Side (Host) Reconfiguration */ | ||
858 | pIcssgIepPwmObj->iepPwmState = IEP_SM_STATE_LHS_RECFG; | ||
859 | } | ||
860 | } | ||
861 | else if (pIcssgIepPwmObj->iepPwmState == IEP_SM_STATE_RHS) { | ||
862 | if ((cmpStatus & IEP_CMP_STATUS_CMP0_MASK) == IEP_CMP_STATUS_CMP0_MASK) { /* CMP0 event has occurred */ | ||
863 | pIepHwRegs->CMP_STATUS_REG = IEP_CMP_STATUS_CMP0_12_MASK; /* clear CMP0-12 events */ | ||
864 | #ifdef TX_HOST_INT | ||
865 | if (txHostEvt == TRUE) { | ||
866 | __R31 = 16 + TRIGGER_HOST_EVT; /* trigger Host interrupt on IEP CMP0 event */ | ||
867 | } | ||
868 | #endif | ||
869 | |||
870 | /* Perform RHS processing */ | ||
871 | iepPwmRhs(pIcssgIepPwmObj); | ||
872 | |||
873 | /* Update state to Right-Hand Side Reconfiguration */ | ||
874 | pIcssgIepPwmObj->iepPwmState = IEP_SM_STATE_RHS_RECFG; | ||
875 | } | ||
876 | } | ||
877 | else if (pIcssgIepPwmObj->iepPwmState == IEP_SM_STATE_LHS_RECFG) { | ||
878 | /* Perform PWM reconfiguration, if requested by Host. | ||
879 | Reconfiguration can only occur at start of PWM cycle after LHS. | ||
880 | Reconfiguration actions: | ||
881 | - PRU FW updates internal state using information in Host I/F FW Regs corresponding to RECFG bit mask. | ||
882 | - PRU FW performs required writes to HW registers. | ||
883 | */ | ||
884 | |||
885 | /* Perform LHS reconfiguration */ | ||
886 | status = iepPwmConfigLhs(pIcssgIepPwmObj); | ||
887 | |||
888 | if (status < 0) { | ||
889 | /* Update state to Left-Hand Side (Host) Reconfiguration */ | ||
890 | pIcssgIepPwmObj->iepPwmState = IEP_SM_STATE_LHS_RECFG; | ||
891 | } | ||
892 | else if (status == IEP_STS_NERR) { | ||
893 | /* Update state to Right-Hand Side */ | ||
894 | pIcssgIepPwmObj->iepPwmState = IEP_SM_STATE_RHS; | ||
895 | } | ||
896 | else { /* IEP_STS_RECFG_PRD_COUNT */ | ||
897 | /* Update State to Init */ | ||
898 | pIcssgIepPwmObj->iepPwmState = IEP_SM_STATE_INIT; | ||
899 | } | ||
900 | } | ||
901 | else if (pIcssgIepPwmObj->iepPwmState == IEP_SM_STATE_RHS_RECFG) { | ||
902 | /* Perform PWM RHS reconfiguration, if required by pending Host reconfiguration request. | ||
903 | Reconfiguration can only occur in middle of PWM cycle before RHS. | ||
904 | Reconfiguration actions: | ||
905 | - PRU FW updates internal state. | ||
906 | - PRU FW performs required writes to HW registers. | ||
907 | */ | ||
908 | |||
909 | /* Perform RHS reconfiguration */ | ||
910 | status = iepPwmConfigRhs(pIcssgIepPwmObj); | ||
911 | |||
912 | if (status == IEP_STS_NERR) { | ||
913 | /* Update State to Left-Hand Side */ | ||
914 | pIcssgIepPwmObj->iepPwmState = IEP_SM_STATE_LHS; | ||
915 | } | ||
916 | else { | ||
917 | /* Update state to Left-Hand Side (Host) Reconfiguration */ | ||
918 | pIcssgIepPwmObj->iepPwmState = IEP_SM_STATE_LHS_RECFG; | ||
919 | } | ||
920 | } | ||
921 | |||
922 | return status; | ||
923 | } | ||
924 | |||
925 | |||
926 | /* ------------------------------------------------------------------------- * | ||
927 | * Private Functions * | ||
928 | * ------------------------------------------------------------------------- */ | ||
929 | |||
930 | /* State Machine function, perform LHS processing */ | ||
931 | static void iepPwmLhs( | ||
932 | IcssgIepPwmObj *pIcssgIepPwmObj | ||
933 | ) | ||
934 | { | ||
935 | Uint32 *pIepPwmDcCount; | ||
936 | Uint16 *pIepPwmDbCount; | ||
937 | volatile uint32_t *pShadowReg; | ||
938 | Uint8 pwmIdx, dPwmIdx; | ||
939 | |||
940 | /* Process Left-Hand Side CMP Shadow Registers */ | ||
941 | |||
942 | /* Process Single-Ended PWMs */ | ||
943 | pIepPwmDcCount = &pIcssgIepPwmObj->iepPwmDcCountLhs[0]; /* init pointer to PWM Duty Cycle Count */ | ||
944 | for (pwmIdx = 0; pwmIdx < IEP_MAX_NUM_SNGL_PWM; pwmIdx++) | ||
945 | { | ||
946 | if (((pIcssgIepPwmObj->iepPwmSnglUpdEn >> pwmIdx) & 0x1) == 1) { /* check PWM update enabled */ | ||
947 | /* Write to CMP SR for PWM */ | ||
948 | pShadowReg = pIcssgIepPwmObj->iepCmpSrAddr[pwmIdx]; /* set pointer to CMP Shadow Register */ | ||
949 | *pShadowReg = pIcssgIepPwmObj->iepPwmPeriodCount - *pIepPwmDcCount; | ||
950 | } | ||
951 | pIepPwmDcCount++; | ||
952 | } | ||
953 | |||
954 | /* Process Differential PWMs */ | ||
955 | pIepPwmDcCount = &pIcssgIepPwmObj->iepPwmDcCountLhs[0]; /* init pointer to PWM Duty Cycle Count */ | ||
956 | pIepPwmDbCount = &pIcssgIepPwmObj->iepPwmDbCount[0]; /* init pointer to PWM Deadband Count */ | ||
957 | for (dPwmIdx = 0; dPwmIdx < IEP_MAX_NUM_DIFF_PWM; dPwmIdx++) | ||
958 | { | ||
959 | if (((pIcssgIepPwmObj->iepPwmDiffUpdEn >> dPwmIdx) & 0x1) == 1) { /* check PWM update enabled */ | ||
960 | /* Write CMP SR for POS PWM */ | ||
961 | pwmIdx = dPwmIdx << 1; | ||
962 | pShadowReg = pIcssgIepPwmObj->iepCmpSrAddr[pwmIdx]; /* set pointer to CMP Shadow Register */ | ||
963 | *pShadowReg = pIcssgIepPwmObj->iepPwmPeriodCount - *pIepPwmDcCount; | ||
964 | /* Write CMP SR for NEG PWM. | ||
965 | Increment CMP SR pointer by 2 since CMP registers are 64 bit. */ | ||
966 | pwmIdx++; | ||
967 | pShadowReg = pIcssgIepPwmObj->iepCmpSrAddr[pwmIdx]; /* set pointer to CMP Shadow Register */ | ||
968 | *pShadowReg = pIcssgIepPwmObj->iepPwmPeriodCount - *pIepPwmDcCount - *pIepPwmDbCount; | ||
969 | } | ||
970 | pIepPwmDcCount += 2; /* differential pair use same Duty Cycle Count */ | ||
971 | pIepPwmDbCount++; | ||
972 | } | ||
973 | } | ||
974 | |||
975 | /* State Machine function, perform RHS processing */ | ||
976 | static void iepPwmRhs( | ||
977 | IcssgIepPwmObj *pIcssgIepPwmObj | ||
978 | ) | ||
979 | { | ||
980 | Uint32 *pIepPwmDcCount; | ||
981 | Uint16 *pIepPwmDbCount; | ||
982 | volatile uint32_t *pShadowReg; | ||
983 | Uint8 pwmIdx, dPwmIdx; | ||
984 | |||
985 | /* Process Right-Hand Side CMP Shadow Registers */ | ||
986 | |||
987 | /* Process Single-Ended PWMs */ | ||
988 | pIepPwmDcCount = &pIcssgIepPwmObj->iepPwmDcCountRhs[0]; /* init pointer to PWM Duty Cycle Count */ | ||
989 | for (pwmIdx = 0; pwmIdx < IEP_MAX_NUM_SNGL_PWM; pwmIdx++) | ||
990 | { | ||
991 | if (((pIcssgIepPwmObj->iepPwmSnglUpdEn >> pwmIdx) & 0x1) == 1) { /* check PWM update enabled */ | ||
992 | /* Write to CMP SR for PWM */ | ||
993 | pShadowReg = pIcssgIepPwmObj->iepCmpSrAddr[pwmIdx]; /* set pointer to CMP Shadow Register */ | ||
994 | *pShadowReg = *pIepPwmDcCount; | ||
995 | } | ||
996 | pIepPwmDcCount++; | ||
997 | pShadowReg += 2; /* CMP registers are 64 bit */ | ||
998 | } | ||
999 | |||
1000 | /* Process Differential PWMs */ | ||
1001 | pIepPwmDcCount = &pIcssgIepPwmObj->iepPwmDcCountRhs[0]; /* init pointer to PWM Duty Cycle Count */ | ||
1002 | pIepPwmDbCount = &pIcssgIepPwmObj->iepPwmDbCount[0]; /* init pointer to PWM Deadband Count */ | ||
1003 | for (dPwmIdx = 0; dPwmIdx < IEP_MAX_NUM_DIFF_PWM; dPwmIdx++) | ||
1004 | { | ||
1005 | if (((pIcssgIepPwmObj->iepPwmDiffUpdEn >> dPwmIdx) & 0x1) == 1) { /* check PWM update enabled */ | ||
1006 | /* Write CMP SR for POS PWM */ | ||
1007 | pwmIdx = dPwmIdx << 1; | ||
1008 | pShadowReg = pIcssgIepPwmObj->iepCmpSrAddr[pwmIdx]; /* set pointer to CMP Shadow Register */ | ||
1009 | *pShadowReg = *pIepPwmDcCount; | ||
1010 | /* Write CMP SR for NEG PWM. | ||
1011 | Increment CMP SR pointer by 2 since CMP registers are 64 bit. */ | ||
1012 | pwmIdx++; | ||
1013 | pShadowReg = pIcssgIepPwmObj->iepCmpSrAddr[pwmIdx]; /* set pointer to CMP Shadow Register */ | ||
1014 | *pShadowReg = *pIepPwmDcCount + *pIepPwmDbCount; | ||
1015 | } | ||
1016 | pIepPwmDcCount += 2; /* differential pair use same Duty Cycle Count */ | ||
1017 | pIepPwmDbCount++; | ||
1018 | } | ||
1019 | } | ||
1020 | |||
1021 | /* State Machine function, perform LHS reconfiguration. | ||
1022 | Check Host reconfiguration request. | ||
1023 | Perform Initialization reconfiguration. */ | ||
1024 | static Int32 iepPwmConfigLhs( | ||
1025 | IcssgIepPwmObj *pIcssgIepPwmObj | ||
1026 | ) | ||
1027 | { | ||
1028 | IepPwmFwRegs *pIepPwmFwRegs = pIcssgIepPwmObj->pIepPwmFwRegs; | ||
1029 | CSL_icss_g_pr1_iep1_slvRegs *pIepHwRegs = pIcssgIepPwmObj->pIepHwRegs; | ||
1030 | Uint16 iepPwmSnglEn; | ||
1031 | Uint8 iepPwmDiffEn; | ||
1032 | Int32 status = IEP_STS_NERR; | ||
1033 | |||
1034 | /* Check for Host reconfiguration request. | ||
1035 | Host reconfiguration isn't allowed during Initialization. */ | ||
1036 | |||
1037 | if (pIepPwmFwRegs->IEP_PWM_RECFG != 0) { | ||
1038 | /* Perform LHS Reconfiguration */ | ||
1039 | |||
1040 | if (pIepPwmFwRegs->IEP_PWM_RECFG & IEP_PWM_RECFG_RECFG_IEP_PWM_PRD_COUNT_MASK) { | ||
1041 | /* PWM Period Count reconfiguration -- affects all PWM for IEP. | ||
1042 | Note: reconfiguration flag is cleared below because of | ||
1043 | dependencies on other reconfigurations on Period Count | ||
1044 | reconfiguration. | ||
1045 | */ | ||
1046 | |||
1047 | /* Update IEP PWM Period Count */ | ||
1048 | updateIepPwmPeriodCount(pIcssgIepPwmObj); | ||
1049 | |||
1050 | /* Reset IEP0 CMPx. | ||
1051 | - Set CMPx inside CMP0 period for 1/6 of PWMs in each Set. This forces PWM Set Initial->Active State. | ||
1052 | - Set CMPx outside CMP0 period for other 5/6 PWMs in each Set. */ | ||
1053 | resetIepPwmCmpx(pIcssgIepPwmObj); | ||
1054 | |||
1055 | /* Re-initialize PWMs. | ||
1056 | Place PWMs in Init State. */ | ||
1057 | reinitPwm(pIcssgIepPwmObj); | ||
1058 | |||
1059 | if (pIepPwmFwRegs->IEP_PWM_RECFG & IEP_PWM_RECFG_RECFG_IEP_PWM_EN_MASK) { | ||
1060 | |||
1061 | /* Latch IEP PWM Enable */ | ||
1062 | latchIepPwmEn(pIcssgIepPwmObj); | ||
1063 | |||
1064 | /* Calculate & Latch Single-Ended and Differential PWM Enable */ | ||
1065 | calcIepPwmSnglDiffEn(pIcssgIepPwmObj, &iepPwmSnglEn, &iepPwmDiffEn); | ||
1066 | latchIepPwmSnglDiffEn(pIcssgIepPwmObj, iepPwmSnglEn, iepPwmDiffEn); | ||
1067 | |||
1068 | pIepPwmFwRegs->IEP_PWM_RECFG &= ~IEP_PWM_RECFG_RECFG_IEP_PWM_EN_MASK; | ||
1069 | } | ||
1070 | |||
1071 | if (pIepPwmFwRegs->IEP_PWM_RECFG & IEP_PWM_RECFG_RECFG_IEP_PWM_DC_COUNT_MASK) { | ||
1072 | /* Latch IEP PWM Duty Cycle Counts */ | ||
1073 | latchIepPwmDcCounts(pIcssgIepPwmObj, TRUE); | ||
1074 | |||
1075 | /* Calculate & Latch LHS/RHS Duty Cycle Counts */ | ||
1076 | calcAndLatchIepPwmDcLhsRhsCount(pIcssgIepPwmObj, FALSE); | ||
1077 | |||
1078 | pIepPwmFwRegs->IEP_PWM_RECFG &= ~IEP_PWM_RECFG_RECFG_IEP_PWM_DC_COUNT_MASK; | ||
1079 | } | ||
1080 | |||
1081 | /* Set return status so State Machine executes INIT state */ | ||
1082 | status = IEP_STS_RECFG_PRD_COUNT; | ||
1083 | } | ||
1084 | else { | ||
1085 | /* Enable/Disable & DC Count reconfiguration. | ||
1086 | Enable and DC Count reconfiguration must be handled jointly. | ||
1087 | |||
1088 | Skip this reconfiguration if Period Count reconfigured | ||
1089 | since all CMPx already updated as part of Period Count reconfiguration. | ||
1090 | */ | ||
1091 | if (pIepPwmFwRegs->IEP_PWM_RECFG & (IEP_PWM_RECFG_RECFG_IEP_PWM_EN_MASK | IEP_PWM_RECFG_RECFG_IEP_PWM_DC_COUNT_MASK)) { | ||
1092 | /* PWM Enable and Duty Cycle Count reconfiguration. | ||
1093 | Update IEP PWM CMPx Shadow Registers. */ | ||
1094 | updateIepPwmCmpxShRegPwmEnDc(pIcssgIepPwmObj); | ||
1095 | |||
1096 | if (pIepPwmFwRegs->IEP_PWM_RECFG & IEP_PWM_RECFG_RECFG_IEP_PWM_EN_MASK) { | ||
1097 | pIepPwmFwRegs->IEP_PWM_RECFG &= ~IEP_PWM_RECFG_RECFG_IEP_PWM_EN_MASK; | ||
1098 | } | ||
1099 | if (pIepPwmFwRegs->IEP_PWM_RECFG & IEP_PWM_RECFG_RECFG_IEP_PWM_DC_COUNT_MASK) { | ||
1100 | pIepPwmFwRegs->IEP_PWM_RECFG &= ~IEP_PWM_RECFG_RECFG_IEP_PWM_DC_COUNT_MASK; | ||
1101 | } | ||
1102 | } | ||
1103 | } | ||
1104 | |||
1105 | if (pIepPwmFwRegs->IEP_PWM_RECFG & IEP_PWM_RECFG_RECFG_IEP_PWM_DB_COUNT_MASK) { | ||
1106 | /* PWM Deadband Count reconfiguration. | ||
1107 | Update IEP PWM CMPx Shadow Registers. */ | ||
1108 | updateIepPwmCmpxShRegDb(pIcssgIepPwmObj); | ||
1109 | |||
1110 | pIepPwmFwRegs->IEP_PWM_RECFG &= ~IEP_PWM_RECFG_RECFG_IEP_PWM_DB_COUNT_MASK; | ||
1111 | } | ||
1112 | |||
1113 | if (pIepPwmFwRegs->IEP_PWM_RECFG & IEP_PWM_RECFG_RECFG_IEP_PWM_PRD_COUNT_MASK) { | ||
1114 | /* Latch Period */ | ||
1115 | latchIepPwmPeriodCount(pIcssgIepPwmObj); | ||
1116 | /* Enable IEP0 Counter */ | ||
1117 | pIepHwRegs->GLOBAL_CFG_REG |= 0x1; | ||
1118 | |||
1119 | pIepPwmFwRegs->IEP_PWM_RECFG &= ~IEP_PWM_RECFG_RECFG_IEP_PWM_PRD_COUNT_MASK; | ||
1120 | } | ||
1121 | } | ||
1122 | |||
1123 | return status; | ||
1124 | } | ||
1125 | |||
1126 | /* State Machine Function, perform RHS reconfiguration. | ||
1127 | Apply pending Host reconfiguration request. | ||
1128 | Perform Initialization reconfiguration. | ||
1129 | |||
1130 | IEP PWM object has private information required to perform RHS update. | ||
1131 | This information is set appropriately in LHS (Host) Reconfiguration. */ | ||
1132 | static Int32 iepPwmConfigRhs( | ||
1133 | IcssgIepPwmObj *pIcssgIepPwmObj | ||
1134 | ) | ||
1135 | { | ||
1136 | Int32 status = IEP_STS_NERR; | ||
1137 | |||
1138 | if (pIcssgIepPwmObj->iepPwmRhsRecfgFlag == TRUE) { | ||
1139 | /* Perform RHS Reconfiguration for pending Host reconfiguration */ | ||
1140 | execRhsActionStash(pIcssgIepPwmObj); | ||
1141 | |||
1142 | pIcssgIepPwmObj->iepPwmRhsRecfgFlag = FALSE; | ||
1143 | } | ||
1144 | |||
1145 | return status; | ||
1146 | } | ||
1147 | |||
1148 | /* Latch IEP PWM mode. | ||
1149 | IEP PWM mode can't change after Initialization. */ | ||
1150 | static void latchIepPwmMode( | ||
1151 | IcssgIepPwmObj *pIcssgIepPwmObj | ||
1152 | ) | ||
1153 | { | ||
1154 | IepPwmFwRegs *pIepPwmFwRegs = pIcssgIepPwmObj->pIepPwmFwRegs; | ||
1155 | pIcssgIepPwmObj->iepPwmMode = pIepPwmFwRegs->IEP_PWM_MODE; | ||
1156 | } | ||
1157 | |||
1158 | /* Update IEP Period Count */ | ||
1159 | static void updateIepPwmPeriodCount( | ||
1160 | IcssgIepPwmObj *pIcssgIepPwmObj | ||
1161 | ) | ||
1162 | { | ||
1163 | IepPwmFwRegs *pIepPwmFwRegs = pIcssgIepPwmObj->pIepPwmFwRegs; | ||
1164 | CSL_icss_g_pr1_iep1_slvRegs *pIepHwRegs = pIcssgIepPwmObj->pIepHwRegs; | ||
1165 | |||
1166 | /* Disable IEP Counter */ | ||
1167 | pIepHwRegs->GLOBAL_CFG_REG &= ~(0x1); | ||
1168 | //HW_WR_FIELD32(pIepHwRegs->GLOBAL_CFG_REG, CSL_ICSS_G_PR1_IEP1_SLV_GLOBAL_CFG_REG_CNT_ENABLE, ~(0x1)); // *** CSL call | ||
1169 | |||
1170 | /* Set Counter value to 1 */ | ||
1171 | pIepHwRegs->COUNT_REG0 = 0x1; | ||
1172 | pIepHwRegs->COUNT_REG1 = 0; | ||
1173 | //HW_WR_REG32(pIepHwRegs->COUNT_REG0, 0x1); // *** CSL call | ||
1174 | //HW_WR_REG32(pIepHwRegs->COUNT_REG1, 0x0); // *** CSL call | ||
1175 | |||
1176 | /* Clear shadow mode in order to be able to write to the Active registers */ | ||
1177 | pIepHwRegs->CMP_CFG_REG &= ~(0x1 << CSL_ICSS_G_PR1_IEP1_SLV_CMP_CFG_REG_SHADOW_EN_SHIFT); | ||
1178 | |||
1179 | /* Load the Period Shadow/Active registers */ | ||
1180 | pIepHwRegs->CMP0_REG0 = pIepPwmFwRegs->IEP_PWM_PRD_COUNT - DEF_COUNT_INC_PER_CLK; | ||
1181 | pIepHwRegs->CMP0_REG1 = pIepPwmFwRegs->IEP_PWM_PRD_COUNT - DEF_COUNT_INC_PER_CLK; | ||
1182 | |||
1183 | /* Enable Shadow Mode */ | ||
1184 | pIepHwRegs->CMP_CFG_REG |= (0x1 << CSL_ICSS_G_PR1_IEP1_SLV_CMP_CFG_REG_SHADOW_EN_SHIFT); | ||
1185 | |||
1186 | /* Clear CMP0 Compare Events */ | ||
1187 | pIepHwRegs->CMP_STATUS_REG = 0x1; | ||
1188 | |||
1189 | /* Enable Counter Reset on CMP0 event */ | ||
1190 | /* Enable CMP0 Compare Events */ | ||
1191 | pIepHwRegs->CMP_CFG_REG |= (0x1 << CSL_ICSS_G_PR1_IEP1_SLV_CMP_CFG_REG_CMP0_RST_CNT_EN_SHIFT | ||
1192 | | (0x1 << CSL_ICSS_G_PR1_IEP1_SLV_CMP_CFG_REG_CMP_EN_SHIFT)); | ||
1193 | } | ||
1194 | |||
1195 | /* Reset IEP CMPx. | ||
1196 | - Set CMPx inside CMP0 period for 1/6 of PWMs in each Set. This forces PWM Set Initial->Active State. | ||
1197 | - Set CMPx outside CMP0 period for other 5/6 PWMs in each Set. */ | ||
1198 | static void resetIepPwmCmpx( | ||
1199 | IcssgIepPwmObj *pIcssgIepPwmObj | ||
1200 | ) | ||
1201 | { | ||
1202 | IepPwmFwRegs *pIepPwmFwRegs = pIcssgIepPwmObj->pIepPwmFwRegs; | ||
1203 | CSL_icss_g_pr1_iep1_slvRegs *pIepHwRegs = pIcssgIepPwmObj->pIepHwRegs; | ||
1204 | volatile Uint32 *pIepCmpReg; | ||
1205 | Uint8 pwmIdx; | ||
1206 | |||
1207 | /* Clear shadow mode in order to be able to write to the Active registers */ | ||
1208 | pIepHwRegs->CMP_CFG_REG &= ~(0x1 << CSL_ICSS_G_PR1_IEP1_SLV_CMP_CFG_REG_SHADOW_EN_SHIFT); | ||
1209 | |||
1210 | /* Set 0 PWMs */ | ||
1211 | pIepCmpReg = &pIepHwRegs->CMP1_REG0; | ||
1212 | for (pwmIdx = 0; pwmIdx < SNGL_PWM_PER_SET; pwmIdx++) | ||
1213 | { | ||
1214 | *pIepCmpReg = pIepPwmFwRegs->IEP_PWM_PRD_COUNT+5; /* outside period */ | ||
1215 | pIepCmpReg++; | ||
1216 | *pIepCmpReg = pIepPwmFwRegs->IEP_PWM_PRD_COUNT+5; /* outside period */ | ||
1217 | pIepCmpReg++; | ||
1218 | } | ||
1219 | pIepCmpReg = &pIepHwRegs->CMP1_REG0 + (SACR_PWM_IDX << 1); | ||
1220 | *pIepCmpReg = pIepPwmFwRegs->IEP_PWM_PRD_COUNT/2; /* inside period for "sacrificial" toggle */ | ||
1221 | pIepCmpReg++; | ||
1222 | *pIepCmpReg = pIepPwmFwRegs->IEP_PWM_PRD_COUNT/2; /* inside period for "sacrificial" toggle */ | ||
1223 | |||
1224 | /* Set 1 PWMs */ | ||
1225 | pIepHwRegs->CMP7_REG0 = pIepPwmFwRegs->IEP_PWM_PRD_COUNT+5; /* inside period for "sacrificial" toggle */ | ||
1226 | pIepHwRegs->CMP7_REG1 = pIepPwmFwRegs->IEP_PWM_PRD_COUNT+5; /* inside period for "sacrificial" toggle */ | ||
1227 | pIepCmpReg = &pIepHwRegs->CMP8_REG0; | ||
1228 | for (pwmIdx = 1; pwmIdx < SNGL_PWM_PER_SET; pwmIdx++) | ||
1229 | { | ||
1230 | *pIepCmpReg = pIepPwmFwRegs->IEP_PWM_PRD_COUNT+5; /* outside period */ | ||
1231 | pIepCmpReg++; | ||
1232 | *pIepCmpReg = pIepPwmFwRegs->IEP_PWM_PRD_COUNT+5; /* outside period */ | ||
1233 | pIepCmpReg++; | ||
1234 | } | ||
1235 | if (SACR_PWM_IDX != 0) { | ||
1236 | pIepCmpReg = &pIepHwRegs->CMP8_REG0 + ((SACR_PWM_IDX-1) << 1); | ||
1237 | } | ||
1238 | else { | ||
1239 | pIepCmpReg = &pIepHwRegs->CMP7_REG0; | ||
1240 | } | ||
1241 | *pIepCmpReg = pIepPwmFwRegs->IEP_PWM_PRD_COUNT/2; /* inside period for "sacrificial" toggle */ | ||
1242 | pIepCmpReg++; | ||
1243 | *pIepCmpReg = pIepPwmFwRegs->IEP_PWM_PRD_COUNT/2; /* inside period for "sacrificial" toggle */ | ||
1244 | |||
1245 | /* Enable Shadow Mode */ | ||
1246 | pIepHwRegs->CMP_CFG_REG |= (0x1 << CSL_ICSS_G_PR1_IEP1_SLV_CMP_CFG_REG_SHADOW_EN_SHIFT); | ||
1247 | |||
1248 | /* Clear CMP1-12 Compare Events */ | ||
1249 | pIepHwRegs->CMP_STATUS_REG = 0x1FFE; | ||
1250 | |||
1251 | /* Enable CMP1-12 Compare Events */ | ||
1252 | pIepHwRegs->CMP_CFG_REG |= (0x1FFE << 1); | ||
1253 | |||
1254 | /* Reset Single-Ended and Differential PWM Update Enable */ | ||
1255 | pIcssgIepPwmObj->iepPwmDiffUpdEn = 0; | ||
1256 | pIcssgIepPwmObj->iepPwmSnglUpdEn = 0; | ||
1257 | } | ||
1258 | |||
1259 | /* Initialize PWMs */ | ||
1260 | static void initPwm( | ||
1261 | IcssgIepPwmObj *pIcssgIepPwmObj | ||
1262 | ) | ||
1263 | { | ||
1264 | IepPwmTripHwRegs *pIepPwmTripHwRegs = pIcssgIepPwmObj->pIepPwmTripHwRegs; | ||
1265 | IepPwmStateCfgHwRegs *pPwmStateCfgHwRegs = pIcssgIepPwmObj->pPwmStateCfgHwRegs; | ||
1266 | volatile Uint32 *pPwmStateCfgReg; | ||
1267 | Uint8 i, j, dPwmIdx; | ||
1268 | Uint8 offset, regOffset; | ||
1269 | Uint32 pwmStateCfgReg; | ||
1270 | |||
1271 | /* Default state */ | ||
1272 | pIepPwmTripHwRegs->ICSSG_PWM0 = 0; /* PWM 0-5 */ | ||
1273 | pIepPwmTripHwRegs->ICSSG_PWM1 = 0; /* PWM 6-11 */ | ||
1274 | |||
1275 | /* Configure PWM (Active, Trip, Init) State. | ||
1276 | - ICSSG_PWM0_0,1,2 | ||
1277 | - ICSSG_PWM1_0,1,2 */ | ||
1278 | pPwmStateCfgReg = &pPwmStateCfgHwRegs->ICSSG_PWM0_0; | ||
1279 | for (i = 0; i < IEP_NUM_PWM_SET; i++) | ||
1280 | { | ||
1281 | dPwmIdx = i * DIFF_PWM_PER_SET; | ||
1282 | for (j = 0; j < DIFF_PWM_PER_SET; j++) | ||
1283 | { | ||
1284 | if ((pIcssgIepPwmObj->iepPwmMode >> (dPwmIdx+j)) & 0x1) { | ||
1285 | /* Differential PWMs */ | ||
1286 | *pPwmStateCfgReg = DIFF_PWM_STATE_INIT; | ||
1287 | } | ||
1288 | else { | ||
1289 | /* Single-Ended PWMs */ | ||
1290 | *pPwmStateCfgReg = SNGL_PWM_STATE_INIT; | ||
1291 | } | ||
1292 | pPwmStateCfgReg++; | ||
1293 | } | ||
1294 | } | ||
1295 | |||
1296 | /* Update PWM State configuration for "sacrificial" PWMs. | ||
1297 | * Index of sacrificial PWM is the same for both PWM Sets. | ||
1298 | * Sacrificial PWM initial state is normal PWM state inverted. | ||
1299 | * | ||
1300 | * Index Sacrificial PWM PWM State Config Reg Bits in Config Reg Bits to Write, SE PWM Bits to Write, Diff PWM | ||
1301 | * 0 0 0-1 10b (INIT HI) 10b (INIT HI) | ||
1302 | * 1 0 2-3 10b (INIT HI) 01b (INIT LO) | ||
1303 | * 2 1 0-1 10b (INIT HI) 10b (INIT HI) | ||
1304 | * 3 1 2-3 10b (INIT HI) 01b (INIT LO) | ||
1305 | * 4 2 0-1 10b (INIT HI) 10b (INIT HI) | ||
1306 | * 5 2 2-3 10b (INIT HI) 01b (INIT LO) | ||
1307 | */ | ||
1308 | /* Set 0 */ | ||
1309 | dPwmIdx = SACR_PWM_IDX/2; | ||
1310 | offset = SACR_PWM_IDX & 0x1; | ||
1311 | regOffset = offset << 1; | ||
1312 | pPwmStateCfgReg = &pPwmStateCfgHwRegs->ICSSG_PWM0_0 + dPwmIdx; | ||
1313 | pwmStateCfgReg = *pPwmStateCfgReg; | ||
1314 | pwmStateCfgReg &= ~(0x3 << regOffset); | ||
1315 | if ((pIcssgIepPwmObj->iepPwmMode >> dPwmIdx) & 0x1) { | ||
1316 | /* Differential PWM */ | ||
1317 | if (offset & 0x1) { | ||
1318 | pwmStateCfgReg |= (PWM_INIT_LO << regOffset); | ||
1319 | } | ||
1320 | else { | ||
1321 | pwmStateCfgReg |= (PWM_INIT_HI << regOffset); | ||
1322 | } | ||
1323 | } | ||
1324 | else { | ||
1325 | /* Single-Ended PWM */ | ||
1326 | pwmStateCfgReg |= (PWM_INIT_HI << regOffset); | ||
1327 | } | ||
1328 | *pPwmStateCfgReg = pwmStateCfgReg; /* write config */ | ||
1329 | /* Set 1 */ | ||
1330 | dPwmIdx = DIFF_PWM_PER_SET + SACR_PWM_IDX/2; | ||
1331 | offset = SACR_PWM_IDX & 0x1; | ||
1332 | regOffset = offset << 1; | ||
1333 | pPwmStateCfgReg = &pPwmStateCfgHwRegs->ICSSG_PWM0_0 + dPwmIdx; | ||
1334 | pwmStateCfgReg = *pPwmStateCfgReg; | ||
1335 | pwmStateCfgReg &= ~(0x3 << regOffset); | ||
1336 | if ((pIcssgIepPwmObj->iepPwmMode >> dPwmIdx) & 0x1) { | ||
1337 | /* Differential PWM */ | ||
1338 | if (offset & 0x1) { | ||
1339 | pwmStateCfgReg |= (PWM_INIT_LO << regOffset); | ||
1340 | } | ||
1341 | else { | ||
1342 | pwmStateCfgReg |= (PWM_INIT_HI << regOffset); | ||
1343 | } | ||
1344 | } | ||
1345 | else { | ||
1346 | /* Single-Ended PWM */ | ||
1347 | pwmStateCfgReg |= (PWM_INIT_HI << regOffset); | ||
1348 | } | ||
1349 | *pPwmStateCfgReg = pwmStateCfgReg; /* write config */ | ||
1350 | |||
1351 | /* Create a trip reset event to put all signals into the Init state */ | ||
1352 | pIepPwmTripHwRegs->ICSSG_PWM0 = PWM_TRIP_RESET_MASK; /* PWM 0-5 */ | ||
1353 | pIepPwmTripHwRegs->ICSSG_PWM1 = PWM_TRIP_RESET_MASK; /* PWM 6-11 */ | ||
1354 | /* Clear the trip event to allow signals to leave the init state (when a CMP occurs) */ | ||
1355 | pIepPwmTripHwRegs->ICSSG_PWM0 = 0; /* PWM 0-5 */ | ||
1356 | pIepPwmTripHwRegs->ICSSG_PWM1 = 0; /* PWM 6-11 */ | ||
1357 | } | ||
1358 | |||
1359 | /* Reinitialize PWMs */ | ||
1360 | static void reinitPwm( | ||
1361 | IcssgIepPwmObj *pIcssgIepPwmObj | ||
1362 | ) | ||
1363 | { | ||
1364 | IepPwmTripHwRegs *pIepPwmTripHwRegs = pIcssgIepPwmObj->pIepPwmTripHwRegs; | ||
1365 | |||
1366 | /* Create a trip reset event to put all signals into the Init state */ | ||
1367 | pIepPwmTripHwRegs->ICSSG_PWM0 = PWM_TRIP_RESET_MASK; /* PWM 0-5 */ | ||
1368 | pIepPwmTripHwRegs->ICSSG_PWM1 = PWM_TRIP_RESET_MASK; /* PWM 6-11 */ | ||
1369 | /* Clear the trip event to allow signals to leave the init state (when a CMP occurs) */ | ||
1370 | pIepPwmTripHwRegs->ICSSG_PWM0 = 0; /* PWM 0-5 */ | ||
1371 | pIepPwmTripHwRegs->ICSSG_PWM1 = 0; /* PWM 6-11 */ | ||
1372 | } | ||
1373 | |||
1374 | /* Latch IEP PWM Enable */ | ||
1375 | static void latchIepPwmEn( | ||
1376 | IcssgIepPwmObj *pIcssgIepPwmObj | ||
1377 | ) | ||
1378 | { | ||
1379 | IepPwmFwRegs *pIepPwmFwRegs = pIcssgIepPwmObj->pIepPwmFwRegs; | ||
1380 | pIcssgIepPwmObj->iepPwmEn = pIepPwmFwRegs->IEP_PWM_EN; | ||
1381 | } | ||
1382 | |||
1383 | /* Latch IEP PWM Period Count */ | ||
1384 | static void latchIepPwmPeriodCount( | ||
1385 | IcssgIepPwmObj *pIcssgIepPwmObj | ||
1386 | ) | ||
1387 | { | ||
1388 | IepPwmFwRegs *pIepPwmFwRegs = pIcssgIepPwmObj->pIepPwmFwRegs; | ||
1389 | pIcssgIepPwmObj->iepPwmPeriodCount = pIepPwmFwRegs->IEP_PWM_PRD_COUNT; | ||
1390 | } | ||
1391 | |||
1392 | /* Latch IEP PWM Duty Cycle Counts */ | ||
1393 | static void latchIepPwmDcCounts( | ||
1394 | IcssgIepPwmObj *pIcssgIepPwmObj, | ||
1395 | Bool recfgFlag | ||
1396 | ) | ||
1397 | { | ||
1398 | IepPwmFwRegs *pIepPwmFwRegs = pIcssgIepPwmObj->pIepPwmFwRegs; | ||
1399 | volatile Uint32 *pIepPwmDcCount; | ||
1400 | Uint16 recfgDcCount; | ||
1401 | Uint8 dPwmIdx, pwmIdx; | ||
1402 | |||
1403 | if (recfgFlag == TRUE) { | ||
1404 | /* Get Duty Cycle reconfiguration */ | ||
1405 | recfgDcCount = (pIepPwmFwRegs->IEP_PWM_RECFG & IEP_PWM_RECFG_RECFG_IEP_PWM_DC_COUNT_MASK) >> IEP_PWM_RECFG_RECFG_IEP_PWM_DC_COUNT_SHIFT; | ||
1406 | } | ||
1407 | else { | ||
1408 | /* Set Duty Cycle reconfiguration reconfiguration to full mask */ | ||
1409 | recfgDcCount = IEP_PWM_RECFG_RECFG_IEP_PWM_DC_COUNT_MASK >> IEP_PWM_RECFG_RECFG_IEP_PWM_DC_COUNT_SHIFT; | ||
1410 | } | ||
1411 | |||
1412 | /* Compute LHS/RHS Duty Cycle counts */ | ||
1413 | pIepPwmDcCount = &pIepPwmFwRegs->IEP_PWM0_DC_COUNT; /* Init pointer to IEP PWM Duty Cycle Count */ | ||
1414 | for (dPwmIdx = 0; dPwmIdx < IEP_MAX_NUM_DIFF_PWM; dPwmIdx++) | ||
1415 | { | ||
1416 | pwmIdx = dPwmIdx << 1; | ||
1417 | if ((pIcssgIepPwmObj->iepPwmMode >> dPwmIdx) & 0x1) { | ||
1418 | /* Differential PWM */ | ||
1419 | |||
1420 | /* Check if reconfiguration bit set. | ||
1421 | For Differential PWM, only "even" reconfiguration bits checked for each PWM pair. */ | ||
1422 | if ((recfgDcCount >> pwmIdx) & 0x1) { | ||
1423 | /* LHS 2*i, POS/NEG */ | ||
1424 | pIcssgIepPwmObj->iepPwmDcCount[pwmIdx] = *pIepPwmDcCount; | ||
1425 | } | ||
1426 | } | ||
1427 | else { | ||
1428 | /* Single-Ended PWM */ | ||
1429 | |||
1430 | /* Check if reconfiguration bit set. | ||
1431 | For Single-Ended PWM, all reconfiguration bits checked. */ | ||
1432 | if ((recfgDcCount >> pwmIdx) & 0x1) { | ||
1433 | /* LHS 2*i, POS */ | ||
1434 | pIcssgIepPwmObj->iepPwmDcCount[pwmIdx] = *pIepPwmDcCount; | ||
1435 | } | ||
1436 | if ((recfgDcCount >> (pwmIdx+1)) & 0x1) { | ||
1437 | /* LHS 2*i+1, NEG */ | ||
1438 | pIcssgIepPwmObj->iepPwmDcCount[pwmIdx+1] = *(pIepPwmDcCount+1); | ||
1439 | } | ||
1440 | } | ||
1441 | |||
1442 | pIepPwmDcCount += 2; /* update pointer to IEP PWM Duty Cycle Count */ | ||
1443 | } | ||
1444 | } | ||
1445 | |||
1446 | /* Latch IEP PWM Deadband Counts */ | ||
1447 | static void latchIepPwmDbCount( | ||
1448 | IcssgIepPwmObj *pIcssgIepPwmObj, | ||
1449 | Bool recfgFlag | ||
1450 | ) | ||
1451 | { | ||
1452 | IepPwmFwRegs *pIepPwmFwRegs = pIcssgIepPwmObj->pIepPwmFwRegs; | ||
1453 | volatile Uint16 *pIepPwmDbCount; | ||
1454 | Uint8 dbCountRecfg; | ||
1455 | Uint8 dPwmIdx; | ||
1456 | |||
1457 | if (recfgFlag == TRUE) { | ||
1458 | /* Get Deadband reconfiguration register */ | ||
1459 | dbCountRecfg = (pIepPwmFwRegs->IEP_PWM_RECFG & IEP_PWM_RECFG_RECFG_IEP_PWM_DB_COUNT_MASK) >> IEP_PWM_RECFG_RECFG_IEP_PWM_DB_COUNT_SHIFT; | ||
1460 | } | ||
1461 | else { | ||
1462 | /* Set Deadband reconfiguration register to full mask */ | ||
1463 | dbCountRecfg = IEP_PWM_RECFG_RECFG_IEP_PWM_DB_COUNT_MASK >> IEP_PWM_RECFG_RECFG_IEP_PWM_DB_COUNT_SHIFT; | ||
1464 | } | ||
1465 | |||
1466 | pIepPwmDbCount = &pIepPwmFwRegs->IEP_PWM0_1_DB_COUNT; /* init pointer to IEP PWM Deadband Count */ | ||
1467 | for (dPwmIdx = 0; dPwmIdx < IEP_MAX_NUM_DIFF_PWM; dPwmIdx++) | ||
1468 | { | ||
1469 | if ( (dbCountRecfg >> dPwmIdx) & 0x1 ) { | ||
1470 | /* Latch updated PWM Deadband Count IEP PWM object */ | ||
1471 | pIcssgIepPwmObj->iepPwmDbCount[dPwmIdx] = *pIepPwmDbCount; | ||
1472 | } | ||
1473 | pIepPwmDbCount++; | ||
1474 | } | ||
1475 | } | ||
1476 | |||
1477 | /* Calculate IEP PWM Single-Ended and Differential Enable */ | ||
1478 | static void calcIepPwmSnglDiffEn( | ||
1479 | IcssgIepPwmObj *pIcssgIepPwmObj, | ||
1480 | Uint16 *pIepPwmSnglEn, | ||
1481 | Uint8 *pIepPwmDiffEn | ||
1482 | ) | ||
1483 | { | ||
1484 | IepPwmFwRegs *pIepPwmFwRegs = pIcssgIepPwmObj->pIepPwmFwRegs; | ||
1485 | Uint16 iepPwmSnglEn; | ||
1486 | Uint8 iepPwmDiffEn; | ||
1487 | Uint8 dPwmIdx, pwmIdx; | ||
1488 | |||
1489 | iepPwmSnglEn = 0; | ||
1490 | iepPwmDiffEn = 0; | ||
1491 | for (dPwmIdx = 0; dPwmIdx < IEP_MAX_NUM_DIFF_PWM; dPwmIdx++) | ||
1492 | { | ||
1493 | pwmIdx = dPwmIdx << 1; | ||
1494 | if ((pIcssgIepPwmObj->iepPwmMode >> dPwmIdx) & 0x1) { | ||
1495 | /* Differential PWM */ | ||
1496 | if ((pIepPwmFwRegs->IEP_PWM_EN >> pwmIdx) & 0x1) { | ||
1497 | /* Differential PWM enabled */ | ||
1498 | iepPwmDiffEn |= 1 << dPwmIdx; | ||
1499 | } | ||
1500 | } | ||
1501 | else { | ||
1502 | /* Single-Ended PWM */ | ||
1503 | if ((pIepPwmFwRegs->IEP_PWM_EN >> pwmIdx) & 0x1) { | ||
1504 | /* Single-Ended PWM enabled */ | ||
1505 | iepPwmSnglEn |= 1 << pwmIdx; | ||
1506 | } | ||
1507 | if ((pIepPwmFwRegs->IEP_PWM_EN >> (pwmIdx+1)) & 0x1) { | ||
1508 | /* Single-Ended PWM enabled */ | ||
1509 | iepPwmSnglEn |= 1 << (pwmIdx+1); | ||
1510 | } | ||
1511 | } | ||
1512 | } | ||
1513 | |||
1514 | *pIepPwmSnglEn = iepPwmSnglEn; | ||
1515 | *pIepPwmDiffEn = iepPwmDiffEn; | ||
1516 | } | ||
1517 | |||
1518 | /* Latch IEP PWM Single-Ended and Differential Enable */ | ||
1519 | static void latchIepPwmSnglDiffEn( | ||
1520 | IcssgIepPwmObj *pIcssgIepPwmObj, | ||
1521 | Uint16 iepPwmSnglEn, | ||
1522 | Uint8 iepPwmDiffEn | ||
1523 | ) | ||
1524 | { | ||
1525 | pIcssgIepPwmObj->iepPwmSnglEn = iepPwmSnglEn; | ||
1526 | pIcssgIepPwmObj->iepPwmDiffEn = iepPwmDiffEn; | ||
1527 | } | ||
1528 | |||
1529 | /* Calculate & Latch IEP PWM LHS/RHS Duty Cycle Counts */ | ||
1530 | static Int32 calcAndLatchIepPwmDcLhsRhsCount( | ||
1531 | IcssgIepPwmObj *pIcssgIepPwmObj, | ||
1532 | Bool recfgFlag | ||
1533 | ) | ||
1534 | { | ||
1535 | IepPwmFwRegs *pIepPwmFwRegs = pIcssgIepPwmObj->pIepPwmFwRegs; | ||
1536 | Uint16 recfgDcCount; | ||
1537 | Uint32 pwmPeriodCount; | ||
1538 | volatile Uint32 *pIepPwmDcCount; | ||
1539 | Uint8 dPwmIdx, pwmIdx; | ||
1540 | Uint32 dcCount, temp; | ||
1541 | Int32 status = IEP_STS_NERR; | ||
1542 | |||
1543 | |||
1544 | if (recfgFlag == TRUE) { | ||
1545 | /* Get Duty Cycle reconfiguration */ | ||
1546 | recfgDcCount = (pIepPwmFwRegs->IEP_PWM_RECFG & IEP_PWM_RECFG_RECFG_IEP_PWM_DC_COUNT_MASK) >> IEP_PWM_RECFG_RECFG_IEP_PWM_DC_COUNT_SHIFT; | ||
1547 | } | ||
1548 | else { | ||
1549 | /* Set Duty Cycle reconfiguration to full mask */ | ||
1550 | recfgDcCount = IEP_PWM_RECFG_RECFG_IEP_PWM_DC_COUNT_MASK >> IEP_PWM_RECFG_RECFG_IEP_PWM_DC_COUNT_SHIFT; | ||
1551 | } | ||
1552 | |||
1553 | /* Calculate PWM period. | ||
1554 | PWM period is 2 IEP CMP0 periods. */ | ||
1555 | pwmPeriodCount = pIcssgIepPwmObj->iepPwmPeriodCount << 1; | ||
1556 | |||
1557 | /* Compute LHS/RHS Duty Cycle counts */ | ||
1558 | pIepPwmDcCount = &pIepPwmFwRegs->IEP_PWM0_DC_COUNT; /* Init pointer to IEP PWM Duty Cycle Count */ | ||
1559 | for (dPwmIdx = 0; dPwmIdx < IEP_MAX_NUM_DIFF_PWM; dPwmIdx++) | ||
1560 | { | ||
1561 | pwmIdx = dPwmIdx << 1; | ||
1562 | if ((pIcssgIepPwmObj->iepPwmMode >> dPwmIdx) & 0x1) { | ||
1563 | /* Differential PWM */ | ||
1564 | |||
1565 | /* Check if reconfiguration bit set. | ||
1566 | For Differential PWM, only "even" reconfiguration bits checked for each PWM pair. */ | ||
1567 | if ((recfgDcCount >> pwmIdx) & 0x1) { | ||
1568 | dcCount = *pIepPwmDcCount; | ||
1569 | if ((dcCount > 0) && (dcCount < pwmPeriodCount)) { | ||
1570 | /* Calculate and latch DC count LHS/RHS */ | ||
1571 | temp = COUNT_TO_CLK(dcCount)/2; | ||
1572 | temp = CLK_TO_COUNT(temp); | ||
1573 | pIcssgIepPwmObj->iepPwmDcCountLhs[pwmIdx] = temp; /* LHS 2*i, POS/NEG */ | ||
1574 | pIcssgIepPwmObj->iepPwmDcCountRhs[pwmIdx] = temp; /* LHS 2*i, POS/NEG */ | ||
1575 | if ((COUNT_TO_CLK(dcCount) & 0x1) == 1) { | ||
1576 | pIcssgIepPwmObj->iepPwmDcCountRhs[pwmIdx] += DEF_COUNT_INC_PER_CLK; /* RHS 2*i, POS/NEG */ | ||
1577 | } | ||
1578 | } | ||
1579 | else if ((dcCount == 0) || (dcCount == pwmPeriodCount)) { | ||
1580 | /* No LHS/RHS in case DC count 0 or 100 */ | ||
1581 | ; | ||
1582 | } | ||
1583 | else { | ||
1584 | /* error, invalid DC count */ | ||
1585 | status = IPE_STS_ERR_INV_DC_COUNT; | ||
1586 | } | ||
1587 | } | ||
1588 | } | ||
1589 | else { | ||
1590 | /* Single-Ended PWM */ | ||
1591 | |||
1592 | /* Check if reconfiguration bit set. | ||
1593 | For Single-Ended PWM, all reconfiguration bits checked. */ | ||
1594 | if ((recfgDcCount >> pwmIdx) & 0x1) { | ||
1595 | dcCount = *pIepPwmDcCount; | ||
1596 | if ((dcCount > 0) && (dcCount < pwmPeriodCount)) { | ||
1597 | temp = COUNT_TO_CLK(dcCount)/2; | ||
1598 | temp = CLK_TO_COUNT(temp); | ||
1599 | pIcssgIepPwmObj->iepPwmDcCountLhs[pwmIdx] = temp; /* LHS 2*i, POS */ | ||
1600 | pIcssgIepPwmObj->iepPwmDcCountRhs[pwmIdx] = temp; /* RHS 2*i, POS */ | ||
1601 | if ((COUNT_TO_CLK(dcCount) & 0x1) == 1) { | ||
1602 | pIcssgIepPwmObj->iepPwmDcCountRhs[pwmIdx] += DEF_COUNT_INC_PER_CLK; /* RHS 2*i, POS */ | ||
1603 | } | ||
1604 | } | ||
1605 | else if ((dcCount == 0) || (dcCount == pwmPeriodCount)) { | ||
1606 | /* No LHS/RHS in case DC count 0 or 100 */ | ||
1607 | ; | ||
1608 | } | ||
1609 | else { | ||
1610 | /* error, invalid DC count */ | ||
1611 | status = IPE_STS_ERR_INV_DC_COUNT; | ||
1612 | } | ||
1613 | } | ||
1614 | if ((recfgDcCount >> (pwmIdx+1)) & 0x1) { | ||
1615 | dcCount = *(pIepPwmDcCount+1); | ||
1616 | if ((dcCount > 0) && (dcCount < pwmPeriodCount)) { | ||
1617 | temp = COUNT_TO_CLK(dcCount)/2; | ||
1618 | temp = CLK_TO_COUNT(temp); | ||
1619 | pIcssgIepPwmObj->iepPwmDcCountLhs[pwmIdx+1] = temp; /* LHS 2*i+1, NEG */ | ||
1620 | pIcssgIepPwmObj->iepPwmDcCountRhs[pwmIdx+1] = temp; /* RHS 2*i+1, NEG */ | ||
1621 | if ((COUNT_TO_CLK(dcCount) & 0x1) == 1) { | ||
1622 | pIcssgIepPwmObj->iepPwmDcCountRhs[pwmIdx+1] += DEF_COUNT_INC_PER_CLK; /* RHS 2*i+1, NEG */ | ||
1623 | } | ||
1624 | } | ||
1625 | else if ((dcCount == 0) || (dcCount == pwmPeriodCount)) { | ||
1626 | /* No LHS/RHS in case DC count 0 or 100 */ | ||
1627 | ; | ||
1628 | } | ||
1629 | else { | ||
1630 | /* error, invalid DC count */ | ||
1631 | status = IPE_STS_ERR_INV_DC_COUNT; | ||
1632 | } | ||
1633 | } | ||
1634 | } | ||
1635 | |||
1636 | pIepPwmDcCount += 2; | ||
1637 | } | ||
1638 | |||
1639 | return status; | ||
1640 | } | ||
1641 | |||
1642 | /* Initialize IEP PWM CMPx Shadow Registers */ | ||
1643 | static Int32 initIepPwmCmpxShReg( | ||
1644 | IcssgIepPwmObj *pIcssgIepPwmObj | ||
1645 | ) | ||
1646 | { | ||
1647 | Uint32 *pIepPwmDcCount; | ||
1648 | Uint32 *pIepPwmDcCountLhs; | ||
1649 | IepPwmRhsAction *pIepPwmRhsAction; | ||
1650 | Bool *pIepPwmRhsRecfgFlag; | ||
1651 | Uint32 iepPwmPeriodCount, pwmPeriodCount; | ||
1652 | Uint16 *pIepPwmSnglUpdEn; | ||
1653 | Uint8 *pIepPwmDiffUpdEn; | ||
1654 | volatile uint32_t **pIepCmpSrAddr; | ||
1655 | IepPwmLhsAction actionLhs; | ||
1656 | IepPwmRhsAction actionRhs; | ||
1657 | Uint8 dPwmIdx, pwmIdx; | ||
1658 | Bool pwmEn; | ||
1659 | |||
1660 | /* Get latched IEP PWM DC count array */ | ||
1661 | pIepPwmDcCount = &pIcssgIepPwmObj->iepPwmDcCount[0]; | ||
1662 | /* Get latched IEP PWM DC LHS count array */ | ||
1663 | pIepPwmDcCountLhs = &pIcssgIepPwmObj->iepPwmDcCountLhs[0]; | ||
1664 | /* Get RHS action array */ | ||
1665 | pIepPwmRhsAction = &pIcssgIepPwmObj->iepPwmRhsAction[0]; | ||
1666 | /* Get pointer to RHS reconfiguration flag */ | ||
1667 | pIepPwmRhsRecfgFlag = &pIcssgIepPwmObj->iepPwmRhsRecfgFlag; | ||
1668 | /* Get Single-Ended & Differential PWM Update Enable */ | ||
1669 | pIepPwmSnglUpdEn = &pIcssgIepPwmObj->iepPwmSnglUpdEn; | ||
1670 | pIepPwmDiffUpdEn = &pIcssgIepPwmObj->iepPwmDiffUpdEn; | ||
1671 | /* Get IEP CMP Shadow Registers array */ | ||
1672 | pIepCmpSrAddr = &pIcssgIepPwmObj->iepCmpSrAddr[0]; | ||
1673 | |||
1674 | /* Get IEP CMP0 period */ | ||
1675 | iepPwmPeriodCount = pIcssgIepPwmObj->iepPwmPeriodCount; | ||
1676 | /* Calculate PWM period. | ||
1677 | PWM period is 2 IEP CMP0 periods. */ | ||
1678 | pwmPeriodCount = iepPwmPeriodCount << 1; | ||
1679 | |||
1680 | /* Initialize flag to disable execution of RHS Reconfiguration */ | ||
1681 | *pIepPwmRhsRecfgFlag = FALSE; | ||
1682 | |||
1683 | for (dPwmIdx = 0; dPwmIdx < IEP_MAX_NUM_DIFF_PWM; dPwmIdx++) | ||
1684 | { | ||
1685 | if ((pIcssgIepPwmObj->iepPwmMode >> dPwmIdx) & 0x1) { | ||
1686 | /* Process Differential PWM */ | ||
1687 | |||
1688 | /* Get PWM enable */ | ||
1689 | pwmEn = (Bool)((pIcssgIepPwmObj->iepPwmDiffEn >> dPwmIdx) & 0x1); | ||
1690 | |||
1691 | pwmIdx = dPwmIdx << 1; /* multiply by 2 for differential PWM */ | ||
1692 | |||
1693 | /* Determine Initial LHS/RHS actions */ | ||
1694 | getInitLhsAction(FALSE, pwmEn, pIepPwmDcCount[pwmIdx], pwmPeriodCount, | ||
1695 | &actionLhs, &actionRhs); | ||
1696 | |||
1697 | /* Execute LHS action */ | ||
1698 | execInitLhsActionDiff(actionLhs, | ||
1699 | iepPwmPeriodCount, | ||
1700 | pIepPwmDcCountLhs[pwmIdx], | ||
1701 | pIepCmpSrAddr, | ||
1702 | pIepPwmDiffUpdEn, | ||
1703 | dPwmIdx); | ||
1704 | |||
1705 | /* Stash RHS action */ | ||
1706 | stashRhsAction(actionRhs, pIepPwmRhsRecfgFlag, &pIepPwmRhsAction[pwmIdx]); | ||
1707 | } | ||
1708 | else { | ||
1709 | /* Process Single-Ended PWMs */ | ||
1710 | |||
1711 | for (pwmIdx = dPwmIdx<<1; pwmIdx < ((dPwmIdx<<1) + NUM_PWM_PER_DIFF_PWM); pwmIdx++) | ||
1712 | { | ||
1713 | /* Get PWM enable */ | ||
1714 | pwmEn = (Bool)((pIcssgIepPwmObj->iepPwmSnglEn >> pwmIdx) & 0x1); | ||
1715 | |||
1716 | /* Determine Initial LHS/RHS actions */ | ||
1717 | getInitLhsAction(FALSE, pwmEn, pIepPwmDcCount[pwmIdx], pwmPeriodCount, | ||
1718 | &actionLhs, &actionRhs); | ||
1719 | |||
1720 | /* Execute LHS action */ | ||
1721 | execInitLhsActionSngl(actionLhs, | ||
1722 | iepPwmPeriodCount, | ||
1723 | pIepPwmDcCountLhs[pwmIdx], | ||
1724 | pIepCmpSrAddr, | ||
1725 | pIepPwmSnglUpdEn, | ||
1726 | pwmIdx); | ||
1727 | |||
1728 | /* Stash RHS action */ | ||
1729 | stashRhsAction(actionRhs, pIepPwmRhsRecfgFlag, &pIepPwmRhsAction[pwmIdx]); | ||
1730 | } | ||
1731 | } | ||
1732 | } | ||
1733 | |||
1734 | /* Process "sacrificial PWMs". | ||
1735 | Previously applied settings are overwritten for these PWMs. */ | ||
1736 | /* Determine Initial LHS/RHS actions */ | ||
1737 | |||
1738 | pwmIdx = SACR_PWM_IDX; /* "sacrificial" PWM index */ | ||
1739 | /* Get PWM enable */ | ||
1740 | pwmEn = (Bool)((pIcssgIepPwmObj->iepPwmSnglEn >> pwmIdx) & 0x1); | ||
1741 | getInitLhsAction(TRUE, pwmEn, pIepPwmDcCount[pwmIdx], pwmPeriodCount, | ||
1742 | &actionLhs, &actionRhs); | ||
1743 | /* Execute LHS action */ | ||
1744 | execInitLhsActionSngl(actionLhs, | ||
1745 | iepPwmPeriodCount, | ||
1746 | pIepPwmDcCountLhs[pwmIdx], | ||
1747 | pIepCmpSrAddr, | ||
1748 | pIepPwmSnglUpdEn, | ||
1749 | pwmIdx); | ||
1750 | /* Stash RHS action */ | ||
1751 | stashRhsAction(actionRhs, pIepPwmRhsRecfgFlag, &pIepPwmRhsAction[pwmIdx]); | ||
1752 | |||
1753 | pwmIdx = SNGL_PWM_PER_SET + SACR_PWM_IDX; /* "sacrificial" PWM index */ | ||
1754 | /* Get PWM enable */ | ||
1755 | pwmEn = (Bool)((pIcssgIepPwmObj->iepPwmSnglEn >> pwmIdx) & 0x1); | ||
1756 | getInitLhsAction(TRUE, pwmEn, pIepPwmDcCount[pwmIdx], pwmPeriodCount, | ||
1757 | &actionLhs, &actionRhs); | ||
1758 | /* Execute LHS action */ | ||
1759 | execInitLhsActionSngl(actionLhs, | ||
1760 | iepPwmPeriodCount, | ||
1761 | pIepPwmDcCountLhs[pwmIdx], | ||
1762 | pIepCmpSrAddr, | ||
1763 | pIepPwmSnglUpdEn, | ||
1764 | pwmIdx); | ||
1765 | /* Stash RHS action */ | ||
1766 | stashRhsAction(actionRhs, pIepPwmRhsRecfgFlag, &pIepPwmRhsAction[pwmIdx]); | ||
1767 | |||
1768 | return IEP_STS_NERR; | ||
1769 | } | ||
1770 | |||
1771 | /* Determine initial LHS/RHS actions */ | ||
1772 | static Int32 getInitLhsAction( | ||
1773 | Bool initToActPwm, | ||
1774 | Bool pwmEn, | ||
1775 | Uint32 iepPwmDcCount, | ||
1776 | Uint32 pwmPeriodCount, | ||
1777 | IepPwmLhsAction *pActionLhs, | ||
1778 | IepPwmRhsAction *pActionRhs | ||
1779 | ) | ||
1780 | { | ||
1781 | if (initToActPwm == FALSE) { | ||
1782 | /* Determine LHS/RHS actions for non "sacrificial" PWMs */ | ||
1783 | |||
1784 | if (pwmEn == TRUE) { | ||
1785 | if ((iepPwmDcCount > 0) && | ||
1786 | (iepPwmDcCount < pwmPeriodCount)) { | ||
1787 | /* DC = x, x!=0, x!=100 */ | ||
1788 | *pActionLhs = LHS_ACTION_Set_CmpSr_DcLhsX_And_EnableSrUpdate; | ||
1789 | *pActionRhs = RHS_ACTION_None; | ||
1790 | } | ||
1791 | else if (iepPwmDcCount == 0) { | ||
1792 | /* DC count is 0 */ | ||
1793 | *pActionLhs = LHS_ACTION_None; | ||
1794 | *pActionRhs = RHS_ACTION_None; | ||
1795 | } | ||
1796 | else if (iepPwmDcCount == pwmPeriodCount) { | ||
1797 | /* DC count is 100 */ | ||
1798 | *pActionLhs = LHS_ACTION_Set_CmpSr_EarlyInPrd_And_EnableSrUpdate; | ||
1799 | *pActionRhs = RHS_ACTION_Set_CmpSr_GtPrd_And_DisableSrUpdate; | ||
1800 | } | ||
1801 | else { | ||
1802 | /* Error, invalid DC count */ | ||
1803 | |||
1804 | /* PWM disabled in case of invalid DC count */ | ||
1805 | *pActionLhs = LHS_ACTION_None; | ||
1806 | *pActionRhs = RHS_ACTION_None; | ||
1807 | /* Indicate error to caller */ | ||
1808 | return IPE_STS_ERR_INV_DC_COUNT; | ||
1809 | } | ||
1810 | } | ||
1811 | else { | ||
1812 | /* PWM disabled, no action required */ | ||
1813 | *pActionLhs = LHS_ACTION_None; | ||
1814 | *pActionRhs = RHS_ACTION_None; | ||
1815 | } | ||
1816 | } | ||
1817 | else { | ||
1818 | /* Determine LHS/RHS actions for "sacrificial" PWMs */ | ||
1819 | |||
1820 | if (pwmEn == TRUE) { | ||
1821 | if ((iepPwmDcCount > 0) && | ||
1822 | (iepPwmDcCount < pwmPeriodCount)) { | ||
1823 | /* DC = x, x!=0, x!=100 */ | ||
1824 | *pActionLhs = LHS_ACTION_Set_CmpSr_DcLhsX_And_EnableSrUpdate; | ||
1825 | *pActionRhs = RHS_ACTION_None; | ||
1826 | } | ||
1827 | else if (iepPwmDcCount == 0) { | ||
1828 | /* DC count is 0 */ | ||
1829 | *pActionLhs = LHS_ACTION_Set_CmpSr_GtPrd_And_DisableSrUpdate; | ||
1830 | *pActionRhs = RHS_ACTION_None; | ||
1831 | } | ||
1832 | else if (iepPwmDcCount == pwmPeriodCount) { | ||
1833 | /* DC count is 100 */ | ||
1834 | *pActionLhs = LHS_ACTION_None; | ||
1835 | *pActionRhs = RHS_ACTION_Set_CmpSr_GtPrd_And_DisableSrUpdate; | ||
1836 | } | ||
1837 | else { | ||
1838 | /* Error, invalid DC count */ | ||
1839 | |||
1840 | /* PWM disabled in case of invalid DC count */ | ||
1841 | *pActionLhs = LHS_ACTION_Set_CmpSr_GtPrd_And_DisableSrUpdate; | ||
1842 | *pActionRhs = RHS_ACTION_None; | ||
1843 | /* Indicate error to caller */ | ||
1844 | return IPE_STS_ERR_INV_DC_COUNT; | ||
1845 | } | ||
1846 | } | ||
1847 | else { | ||
1848 | /* PWM disabled */ | ||
1849 | *pActionLhs = LHS_ACTION_Set_CmpSr_GtPrd_And_DisableSrUpdate; | ||
1850 | *pActionRhs = RHS_ACTION_None; | ||
1851 | } | ||
1852 | } | ||
1853 | |||
1854 | return IEP_STS_NERR; | ||
1855 | } | ||
1856 | |||
1857 | /* Initial update IEP PWM CMPx Shadow Register, Single-Ended Mode */ | ||
1858 | static void execInitLhsActionSngl( | ||
1859 | IepPwmLhsAction actionLhs, | ||
1860 | Uint32 iepPwmPeriodCount, | ||
1861 | Uint32 iepPwmDcCountLhs, | ||
1862 | volatile uint32_t **pIepCmpSrAddr, | ||
1863 | Uint16 *pIepPwmSnglUpdEn, | ||
1864 | Uint8 pwmIdx | ||
1865 | ) | ||
1866 | { | ||
1867 | volatile uint32_t *pCmpSr; | ||
1868 | |||
1869 | pCmpSr = pIepCmpSrAddr[pwmIdx]; | ||
1870 | |||
1871 | switch (actionLhs) | ||
1872 | { | ||
1873 | case LHS_ACTION_Set_CmpSr_DcLhsX_And_EnableSrUpdate: | ||
1874 | *pCmpSr = iepPwmPeriodCount - iepPwmDcCountLhs; /* Write LHS value to CMP Shadow Register */ | ||
1875 | *pIepPwmSnglUpdEn |= 1<<pwmIdx; /* Enable CMP SR update */ | ||
1876 | break; | ||
1877 | |||
1878 | case LHS_ACTION_Set_CmpSr_EarlyInPrd_And_EnableSrUpdate: | ||
1879 | *pCmpSr = CMP_SR_EARLY_VAL; /* Write LHS value to CMP Shadow Register */ | ||
1880 | *pIepPwmSnglUpdEn |= 1<<pwmIdx; /* Enable CMP SR update */ | ||
1881 | break; | ||
1882 | |||
1883 | case LHS_ACTION_Set_CmpSr_GtPrd_And_DisableSrUpdate: | ||
1884 | *pCmpSr = iepPwmPeriodCount; /* Write LHS value to CMP Shadow Register */ | ||
1885 | *pIepPwmSnglUpdEn &= ~(1<<pwmIdx); /* Enable CMP SR update */ | ||
1886 | break; | ||
1887 | |||
1888 | case LHS_ACTION_None: | ||
1889 | case LHS_ACTION_Set_CmpSr_DcLhsY: | ||
1890 | case LHS_ACTION_Set_CmpSr_DcLhsY_And_EnableSrUpdate: | ||
1891 | default: | ||
1892 | break; | ||
1893 | } | ||
1894 | } | ||
1895 | |||
1896 | /* Initial update IEP PWM CMPx Shadow Registers, Differential Mode */ | ||
1897 | static void execInitLhsActionDiff( | ||
1898 | IepPwmLhsAction actionLhs, | ||
1899 | Uint32 iepPwmPeriodCount, | ||
1900 | Uint32 iepPwmDcCountLhs, | ||
1901 | volatile uint32_t **pIepCmpSrAddr, | ||
1902 | Uint8 *pIepPwmDiffUpdEn, | ||
1903 | Uint8 dPwmIdx | ||
1904 | ) | ||
1905 | { | ||
1906 | volatile uint32_t *pCmpSrPos, *pCmpSrNeg; | ||
1907 | Uint8 pwmIdx; | ||
1908 | Uint32 temp; | ||
1909 | |||
1910 | pwmIdx = dPwmIdx << 1; /* multiply by 2 for differential PWM */ | ||
1911 | pCmpSrPos = pIepCmpSrAddr[pwmIdx]; | ||
1912 | pCmpSrNeg = pIepCmpSrAddr[pwmIdx+1]; | ||
1913 | |||
1914 | switch (actionLhs) | ||
1915 | { | ||
1916 | case LHS_ACTION_Set_CmpSr_DcLhsX_And_EnableSrUpdate: | ||
1917 | temp = iepPwmPeriodCount - iepPwmDcCountLhs; /* Compute LHS SR value */ | ||
1918 | *pCmpSrPos = temp; /* Write LHS value to CMP Shadow Register, POS */ | ||
1919 | *pCmpSrNeg = temp; /* Write LHS value to CMP Shadow Register, NEG */ | ||
1920 | *pIepPwmDiffUpdEn |= 1<<dPwmIdx; /* Enable CMP SR update */ | ||
1921 | break; | ||
1922 | |||
1923 | case LHS_ACTION_Set_CmpSr_EarlyInPrd_And_EnableSrUpdate: | ||
1924 | *pCmpSrPos = CMP_SR_EARLY_VAL; /* Write LHS value to CMP Shadow Register, POS */ | ||
1925 | *pCmpSrNeg = CMP_SR_EARLY_VAL; /* Write LHS value to CMP Shadow Register, NEG */ | ||
1926 | *pIepPwmDiffUpdEn |= 1<<dPwmIdx; /* Enable CMP SR update */ | ||
1927 | break; | ||
1928 | |||
1929 | case LHS_ACTION_Set_CmpSr_GtPrd_And_DisableSrUpdate: | ||
1930 | /* Write same LHS value to both CMP Shadow Registers in differential pair */ | ||
1931 | *pCmpSrPos = iepPwmPeriodCount; /* Write LHS value to CMP Shadow Register, POS */ | ||
1932 | *pCmpSrNeg = iepPwmPeriodCount; /* Write LHS value to CMP Shadow Register, NEG */ | ||
1933 | /* Disable CMP SR update */ | ||
1934 | *pIepPwmDiffUpdEn &= ~(1<<dPwmIdx); /* Disable CMP SR update */ | ||
1935 | break; | ||
1936 | |||
1937 | case LHS_ACTION_None: | ||
1938 | case LHS_ACTION_Set_CmpSr_DcLhsY: | ||
1939 | case LHS_ACTION_Set_CmpSr_DcLhsY_And_EnableSrUpdate: | ||
1940 | default: | ||
1941 | break; | ||
1942 | } | ||
1943 | } | ||
1944 | |||
1945 | /* Update IEP PWM CMPx Shadow Registers. | ||
1946 | PWM Enable and DC Count reconfiguration handled jointly. */ | ||
1947 | static Int32 updateIepPwmCmpxShRegPwmEnDc( | ||
1948 | IcssgIepPwmObj *pIcssgIepPwmObj | ||
1949 | ) | ||
1950 | { | ||
1951 | IepPwmFwRegs *pIepPwmFwRegs = pIcssgIepPwmObj->pIepPwmFwRegs; | ||
1952 | Uint16 recfgDcCount; | ||
1953 | volatile uint32_t *pIepPwmDcCountNew; | ||
1954 | Uint32 *pIepPwmDcCountOld, *pIepPwmDcCountLhsOld, *pIepPwmDcCountRhsOld; | ||
1955 | IepPwmRhsAction *pIepPwmRhsAction; | ||
1956 | Bool *pIepPwmRhsRecfgFlag; | ||
1957 | Uint16 *pIepPwmSnglUpdEn; | ||
1958 | Uint8 *pIepPwmDiffUpdEn; | ||
1959 | volatile uint32_t **pIepCmpSrAddr; | ||
1960 | Uint32 iepPwmPeriodCount, pwmPeriodCount; | ||
1961 | Uint8 pwmIdx, dPwmIdx; | ||
1962 | const IepPwmActionTableEntry *pTable; | ||
1963 | Uint8 rowIdx; | ||
1964 | Uint32 iepPwmDcCountLhsNew, iepPwmDcCountRhsNew; | ||
1965 | Uint16 iepPwmSnglEn; | ||
1966 | Uint8 iepPwmDiffEn; | ||
1967 | Int32 status = IEP_STS_NERR; | ||
1968 | |||
1969 | /* Get Duty Cycle reconfiguration */ | ||
1970 | recfgDcCount = (pIepPwmFwRegs->IEP_PWM_RECFG & IEP_PWM_RECFG_RECFG_IEP_PWM_DC_COUNT_MASK) >> IEP_PWM_RECFG_RECFG_IEP_PWM_DC_COUNT_SHIFT; | ||
1971 | /* Get input (new) IEP PWM DC count array */ | ||
1972 | pIepPwmDcCountNew = &pIepPwmFwRegs->IEP_PWM0_DC_COUNT; | ||
1973 | /* Get latched (old) IEP PWM DC count array */ | ||
1974 | pIepPwmDcCountOld = &pIcssgIepPwmObj->iepPwmDcCount[0]; | ||
1975 | /* Get latched (old) IEP PWM DC LHS/RHS count arrays */ | ||
1976 | pIepPwmDcCountLhsOld = &pIcssgIepPwmObj->iepPwmDcCountLhs[0]; | ||
1977 | pIepPwmDcCountRhsOld = &pIcssgIepPwmObj->iepPwmDcCountRhs[0]; | ||
1978 | /* Get RHS action array */ | ||
1979 | pIepPwmRhsAction = &pIcssgIepPwmObj->iepPwmRhsAction[0]; | ||
1980 | /* Get pointer to RHS reconfiguration flag */ | ||
1981 | pIepPwmRhsRecfgFlag = &pIcssgIepPwmObj->iepPwmRhsRecfgFlag; | ||
1982 | /* Get Single-Ended & Differential PWM Update Enable */ | ||
1983 | pIepPwmSnglUpdEn = &pIcssgIepPwmObj->iepPwmSnglUpdEn; | ||
1984 | pIepPwmDiffUpdEn = &pIcssgIepPwmObj->iepPwmDiffUpdEn; | ||
1985 | /* Get IEP CMP Shadow Registers array */ | ||
1986 | pIepCmpSrAddr = &pIcssgIepPwmObj->iepCmpSrAddr[0]; | ||
1987 | |||
1988 | /* Get IEP CMP0 period */ | ||
1989 | iepPwmPeriodCount = pIcssgIepPwmObj->iepPwmPeriodCount; | ||
1990 | /* Calculate PWM period. | ||
1991 | PWM period is 2 IEP CMP0 periods. */ | ||
1992 | pwmPeriodCount = pIcssgIepPwmObj->iepPwmPeriodCount << 1; | ||
1993 | |||
1994 | /* Init flag to disable execution of RHS Reconfiguration */ | ||
1995 | *pIepPwmRhsRecfgFlag = FALSE; | ||
1996 | |||
1997 | if ((pIepPwmFwRegs->IEP_PWM_RECFG & IEP_PWM_RECFG_RECFG_IEP_PWM_EN_MASK) == 0) { | ||
1998 | /* No change to PWM Enable */ | ||
1999 | |||
2000 | for (dPwmIdx = 0; dPwmIdx < IEP_MAX_NUM_DIFF_PWM; dPwmIdx++) | ||
2001 | { | ||
2002 | if ((pIcssgIepPwmObj->iepPwmMode >> dPwmIdx) & 0x1) { | ||
2003 | /* Process Differential PWM */ | ||
2004 | |||
2005 | /* Select Action Table */ | ||
2006 | if ((pIcssgIepPwmObj->iepPwmDiffEn >> dPwmIdx) & 0x1) { | ||
2007 | /* No Enable Reconfiguration, PWM enabled */ | ||
2008 | pTable = gActT2_EnRecfgNo_EnOldEnable; | ||
2009 | } | ||
2010 | else { | ||
2011 | /* No Enable Reconfiguration, PWM disabled */ | ||
2012 | pTable = gActT1_EnRecfgNo_EnOldDisable; | ||
2013 | } | ||
2014 | |||
2015 | pwmIdx = dPwmIdx << 1; /* multiply by 2 for differential PWM */ | ||
2016 | |||
2017 | /* Determine Action Table Row */ | ||
2018 | status = getActionTableRowDiff(recfgDcCount, dPwmIdx, | ||
2019 | pIepPwmDcCountOld[pwmIdx], pIepPwmDcCountNew[pwmIdx], | ||
2020 | pwmPeriodCount, &rowIdx); | ||
2021 | if (status != IEP_STS_NERR) { | ||
2022 | return status; | ||
2023 | } | ||
2024 | |||
2025 | /* Calculate new LHS/RHS */ | ||
2026 | calcDcLatchAction(pTable[rowIdx].latchAction, | ||
2027 | pIepPwmDcCountNew[pwmIdx], | ||
2028 | &iepPwmDcCountLhsNew, | ||
2029 | &iepPwmDcCountRhsNew); | ||
2030 | |||
2031 | /* Execute LHS action */ | ||
2032 | execLhsActionDiff(pTable[rowIdx].lhsAction, | ||
2033 | pIepPwmDcCountLhsOld[pwmIdx], iepPwmDcCountLhsNew, | ||
2034 | pIepCmpSrAddr, | ||
2035 | pIepPwmDiffUpdEn, | ||
2036 | dPwmIdx, | ||
2037 | iepPwmPeriodCount); | ||
2038 | |||
2039 | /* Stash RHS action */ | ||
2040 | stashRhsAction(pTable[rowIdx].rhsAction, pIepPwmRhsRecfgFlag, &pIepPwmRhsAction[pwmIdx]); | ||
2041 | |||
2042 | /* Execute DC latch */ | ||
2043 | execDcLatchAction(pTable[rowIdx].latchAction, | ||
2044 | &pIepPwmDcCountOld[pwmIdx], &pIepPwmDcCountLhsOld[pwmIdx], &pIepPwmDcCountRhsOld[pwmIdx], | ||
2045 | pIepPwmDcCountNew[pwmIdx], iepPwmDcCountLhsNew, iepPwmDcCountRhsNew); | ||
2046 | } | ||
2047 | else { | ||
2048 | /* Process Single-Ended PWMs */ | ||
2049 | |||
2050 | for (pwmIdx = dPwmIdx<<1; pwmIdx < ((dPwmIdx<<1) + NUM_PWM_PER_DIFF_PWM); pwmIdx++) | ||
2051 | { | ||
2052 | /* Select Action Table */ | ||
2053 | if ((pIcssgIepPwmObj->iepPwmSnglEn >> pwmIdx) & 0x1) { | ||
2054 | /* No Enable Reconfiguration, PWM enabled */ | ||
2055 | pTable = gActT2_EnRecfgNo_EnOldEnable; | ||
2056 | } | ||
2057 | else { | ||
2058 | /* No Enable Reconfiguration, PWM disabled */ | ||
2059 | pTable = gActT1_EnRecfgNo_EnOldDisable; | ||
2060 | } | ||
2061 | |||
2062 | /* Determine Action Table Row */ | ||
2063 | status = getActionTableRowSngl(recfgDcCount, pwmIdx, | ||
2064 | pIepPwmDcCountOld[pwmIdx], pIepPwmDcCountNew[pwmIdx], | ||
2065 | pwmPeriodCount, &rowIdx); | ||
2066 | if (status != IEP_STS_NERR) { | ||
2067 | return status; | ||
2068 | } | ||
2069 | |||
2070 | /* Calculate new LHS/RHS */ | ||
2071 | calcDcLatchAction(pTable[rowIdx].latchAction, | ||
2072 | pIepPwmDcCountNew[pwmIdx], | ||
2073 | &iepPwmDcCountLhsNew, | ||
2074 | &iepPwmDcCountRhsNew); | ||
2075 | |||
2076 | /* Execute LHS action */ | ||
2077 | execLhsActionSngl(pTable[rowIdx].lhsAction, | ||
2078 | pIepPwmDcCountLhsOld[pwmIdx], iepPwmDcCountLhsNew, | ||
2079 | pIepCmpSrAddr, | ||
2080 | pIepPwmSnglUpdEn, | ||
2081 | pwmIdx, | ||
2082 | iepPwmPeriodCount); | ||
2083 | |||
2084 | /* Stash RHS action */ | ||
2085 | stashRhsAction(pTable[rowIdx].rhsAction, pIepPwmRhsRecfgFlag, &pIepPwmRhsAction[pwmIdx]); | ||
2086 | |||
2087 | /* Execute DC latch */ | ||
2088 | execDcLatchAction(pTable[rowIdx].latchAction, | ||
2089 | &pIepPwmDcCountOld[pwmIdx], &pIepPwmDcCountLhsOld[pwmIdx], &pIepPwmDcCountRhsOld[pwmIdx], | ||
2090 | pIepPwmDcCountNew[pwmIdx], iepPwmDcCountLhsNew, iepPwmDcCountRhsNew); | ||
2091 | } | ||
2092 | } | ||
2093 | } | ||
2094 | } | ||
2095 | else { | ||
2096 | /* Change to PWM Enable */ | ||
2097 | |||
2098 | /* Calculate Single-Ended and Differential PWM Enable */ | ||
2099 | calcIepPwmSnglDiffEn(pIcssgIepPwmObj, &iepPwmSnglEn, &iepPwmDiffEn); | ||
2100 | |||
2101 | for (dPwmIdx = 0; dPwmIdx < IEP_MAX_NUM_DIFF_PWM; dPwmIdx++) | ||
2102 | { | ||
2103 | if ((pIcssgIepPwmObj->iepPwmMode >> dPwmIdx) & 0x1) { | ||
2104 | /* Process Differential PWM */ | ||
2105 | |||
2106 | /* Select Action Table */ | ||
2107 | if (!((pIcssgIepPwmObj->iepPwmDiffEn >> dPwmIdx) & 0x1) && | ||
2108 | ((iepPwmDiffEn >> dPwmIdx) & 0x1)) { | ||
2109 | /* Enable Reconfiguration, PWM enabled */ | ||
2110 | pTable = gActT3_EnRecfgYes_EnNewEnable; | ||
2111 | } | ||
2112 | else if (((pIcssgIepPwmObj->iepPwmDiffEn >> dPwmIdx) & 0x1) && | ||
2113 | !((iepPwmDiffEn >> dPwmIdx) & 0x1)) { | ||
2114 | /* Enable Reconfiguration, PWM disabled */ | ||
2115 | pTable = gActT4_EnRecfgYes_EnNewDisable; | ||
2116 | } | ||
2117 | else if (!((pIcssgIepPwmObj->iepPwmDiffEn >> dPwmIdx) & 0x1) && | ||
2118 | !((iepPwmDiffEn >> dPwmIdx) & 0x1)) { | ||
2119 | /* No Enable Reconfiguration, PWM disabled */ | ||
2120 | pTable = gActT1_EnRecfgNo_EnOldDisable; | ||
2121 | } | ||
2122 | else { | ||
2123 | /* No Enable Reconfiguration, PWM enabled */ | ||
2124 | pTable = gActT2_EnRecfgNo_EnOldEnable; | ||
2125 | } | ||
2126 | |||
2127 | pwmIdx = dPwmIdx << 1; | ||
2128 | |||
2129 | /* Determine Action Table Row */ | ||
2130 | status = getActionTableRowDiff(recfgDcCount, dPwmIdx, | ||
2131 | pIepPwmDcCountLhsOld[pwmIdx], pIepPwmDcCountNew[pwmIdx], | ||
2132 | pwmPeriodCount, &rowIdx); | ||
2133 | if (status != IEP_STS_NERR) { | ||
2134 | return status; | ||
2135 | } | ||
2136 | |||
2137 | /* Calculate new LHS/RHS */ | ||
2138 | calcDcLatchAction(pTable[rowIdx].latchAction, | ||
2139 | pIepPwmDcCountNew[pwmIdx], | ||
2140 | &iepPwmDcCountLhsNew, | ||
2141 | &iepPwmDcCountRhsNew); | ||
2142 | |||
2143 | /* Execute LHS action */ | ||
2144 | execLhsActionDiff(pTable[rowIdx].lhsAction, | ||
2145 | pIepPwmDcCountLhsOld[pwmIdx], iepPwmDcCountLhsNew, | ||
2146 | pIepCmpSrAddr, | ||
2147 | pIepPwmDiffUpdEn, | ||
2148 | dPwmIdx, | ||
2149 | iepPwmPeriodCount); | ||
2150 | |||
2151 | /* Stash RHS action */ | ||
2152 | stashRhsAction(pTable[rowIdx].rhsAction, pIepPwmRhsRecfgFlag, &pIepPwmRhsAction[pwmIdx]); | ||
2153 | |||
2154 | /* Execute DC latch */ | ||
2155 | execDcLatchAction(pTable[rowIdx].latchAction, | ||
2156 | &pIepPwmDcCountOld[pwmIdx], &pIepPwmDcCountLhsOld[pwmIdx], &pIepPwmDcCountRhsOld[pwmIdx], | ||
2157 | pIepPwmDcCountNew[pwmIdx], iepPwmDcCountLhsNew, iepPwmDcCountRhsNew); | ||
2158 | |||
2159 | } | ||
2160 | else { | ||
2161 | /* Process Single-Ended PWMs */ | ||
2162 | |||
2163 | for (pwmIdx = dPwmIdx<<1; pwmIdx < ((dPwmIdx<<1) + NUM_PWM_PER_DIFF_PWM); pwmIdx++) | ||
2164 | { | ||
2165 | /* Select Action Table */ | ||
2166 | if (!((pIcssgIepPwmObj->iepPwmSnglEn >> pwmIdx) & 0x1) && | ||
2167 | ((iepPwmSnglEn >> pwmIdx) & 0x1)) { | ||
2168 | /* Enable Reconfiguration, PWM enabled */ | ||
2169 | pTable = gActT3_EnRecfgYes_EnNewEnable; | ||
2170 | } | ||
2171 | else if (((pIcssgIepPwmObj->iepPwmSnglEn >> pwmIdx) & 0x1) && | ||
2172 | !((iepPwmSnglEn >> pwmIdx) & 0x1)) { | ||
2173 | /* Enable Reconfiguration, PWM disabled */ | ||
2174 | pTable = gActT4_EnRecfgYes_EnNewDisable; | ||
2175 | } | ||
2176 | else if (!((pIcssgIepPwmObj->iepPwmSnglEn >> pwmIdx) & 0x1) && | ||
2177 | (!(iepPwmSnglEn >> pwmIdx) & 0x1)) { | ||
2178 | /* No Enable Reconfiguration, PWM disabled */ | ||
2179 | pTable = gActT1_EnRecfgNo_EnOldDisable; | ||
2180 | } | ||
2181 | else { | ||
2182 | /* No Enable Reconfiguration, PWM enabled */ | ||
2183 | pTable = gActT2_EnRecfgNo_EnOldEnable; | ||
2184 | } | ||
2185 | |||
2186 | /* Determine Action Table Row */ | ||
2187 | status = getActionTableRowSngl(recfgDcCount, pwmIdx, | ||
2188 | pIepPwmDcCountOld[pwmIdx], pIepPwmDcCountNew[pwmIdx], | ||
2189 | pwmPeriodCount, &rowIdx); | ||
2190 | if (status != IEP_STS_NERR) { | ||
2191 | return status; | ||
2192 | } | ||
2193 | |||
2194 | /* Calculate new LHS/RHS */ | ||
2195 | calcDcLatchAction(pTable[rowIdx].latchAction, | ||
2196 | pIepPwmDcCountNew[pwmIdx], | ||
2197 | &iepPwmDcCountLhsNew, | ||
2198 | &iepPwmDcCountRhsNew); | ||
2199 | |||
2200 | /* Execute LHS action */ | ||
2201 | execLhsActionSngl(pTable[rowIdx].lhsAction, | ||
2202 | pIepPwmDcCountLhsOld[pwmIdx], iepPwmDcCountLhsNew, | ||
2203 | pIepCmpSrAddr, | ||
2204 | pIepPwmSnglUpdEn, | ||
2205 | pwmIdx, | ||
2206 | iepPwmPeriodCount); | ||
2207 | |||
2208 | /* Stash RHS action */ | ||
2209 | stashRhsAction(pTable[rowIdx].rhsAction, pIepPwmRhsRecfgFlag, &pIepPwmRhsAction[pwmIdx]); | ||
2210 | |||
2211 | /* Execute DC latch */ | ||
2212 | execDcLatchAction(pTable[rowIdx].latchAction, | ||
2213 | &pIepPwmDcCountOld[pwmIdx], &pIepPwmDcCountLhsOld[pwmIdx], &pIepPwmDcCountRhsOld[pwmIdx], | ||
2214 | pIepPwmDcCountNew[pwmIdx], iepPwmDcCountLhsNew, iepPwmDcCountRhsNew); | ||
2215 | } | ||
2216 | } | ||
2217 | } | ||
2218 | |||
2219 | /* Latch Single-Ended and Differential PWM Enable */ | ||
2220 | latchIepPwmSnglDiffEn(pIcssgIepPwmObj, iepPwmSnglEn, iepPwmDiffEn); | ||
2221 | } | ||
2222 | |||
2223 | return status; | ||
2224 | } | ||
2225 | |||
2226 | /* Get Action Table row, Single-Ended PWM */ | ||
2227 | static Int32 getActionTableRowSngl( | ||
2228 | Uint16 recfgDcCount, | ||
2229 | Uint8 pwmIdx, | ||
2230 | Uint32 iepPwmDcCountOld, | ||
2231 | Uint32 iepPwmDcCountNew, | ||
2232 | Uint32 pwmPeriodCount, | ||
2233 | Uint8 *pRowIdx | ||
2234 | ) | ||
2235 | { | ||
2236 | Int32 status = IEP_STS_NERR; | ||
2237 | |||
2238 | if ((recfgDcCount >> pwmIdx) & 0x1) { | ||
2239 | /* Possible change to PWM DC count */ | ||
2240 | if ((iepPwmDcCountOld > 0) && (iepPwmDcCountOld < pwmPeriodCount)) { | ||
2241 | if (iepPwmDcCountNew == iepPwmDcCountOld) { | ||
2242 | /* new DC count is x */ | ||
2243 | *pRowIdx = AT_Row01_DcOldX_DcNewX; | ||
2244 | } | ||
2245 | else if ((iepPwmDcCountNew > 0) && (iepPwmDcCountNew < pwmPeriodCount)) { | ||
2246 | /* new DC count is y, x!=y */ | ||
2247 | *pRowIdx = AT_Row02_DcOldX_DcNewY; | ||
2248 | } | ||
2249 | else if (iepPwmDcCountNew == 0) { | ||
2250 | /* new DC count is 0 */ | ||
2251 | *pRowIdx = AT_Row03_DcOldX_DcNew0; | ||
2252 | } | ||
2253 | else if (iepPwmDcCountNew == pwmPeriodCount) { | ||
2254 | /* new DC count is 100 */ | ||
2255 | *pRowIdx = AT_Row04_DcOldX_DcNew100; | ||
2256 | } | ||
2257 | else { | ||
2258 | /* error, invalid DC count */ | ||
2259 | status = IPE_STS_ERR_INV_DC_COUNT; | ||
2260 | } | ||
2261 | } | ||
2262 | else if (iepPwmDcCountOld == 0) { /* old DC count is 0 */ | ||
2263 | if ((iepPwmDcCountNew > 0) && (iepPwmDcCountNew < pwmPeriodCount)) { | ||
2264 | /* new DC count !=0, !=100 */ | ||
2265 | *pRowIdx = AT_Row05_DcOld0_DcNewY; | ||
2266 | } | ||
2267 | else if (iepPwmDcCountNew == 0) { | ||
2268 | /* new DC count is 0 */ | ||
2269 | *pRowIdx = AT_Row06_DcOld0_DcNew0; | ||
2270 | } | ||
2271 | else if (iepPwmDcCountNew == pwmPeriodCount) { | ||
2272 | /* new DC count is 100 */ | ||
2273 | *pRowIdx = AT_Row10_DcOld100_DcNew100; | ||
2274 | } | ||
2275 | else { | ||
2276 | /* error, invalid DC count */ | ||
2277 | status = IPE_STS_ERR_INV_DC_COUNT; | ||
2278 | } | ||
2279 | } | ||
2280 | else if (iepPwmDcCountOld == pwmPeriodCount) { /* old DC count is 100 */ | ||
2281 | if ((iepPwmDcCountNew > 0) && (iepPwmDcCountNew < pwmPeriodCount)) { | ||
2282 | /* new DC count !=0, !=100 */ | ||
2283 | *pRowIdx = AT_Row08_DcOld100_DcNewY; | ||
2284 | } | ||
2285 | else if (iepPwmDcCountNew == 0) { | ||
2286 | /* new DC count is 0 */ | ||
2287 | *pRowIdx = AT_Row09_DcOld100_DcNew0; | ||
2288 | } | ||
2289 | else if (iepPwmDcCountNew == pwmPeriodCount) { | ||
2290 | /* new DC count is 100 */ | ||
2291 | *pRowIdx = AT_Row10_DcOld100_DcNew100; | ||
2292 | } | ||
2293 | else { | ||
2294 | /* error, invalid DC count */ | ||
2295 | status = IPE_STS_ERR_INV_DC_COUNT; | ||
2296 | } | ||
2297 | } | ||
2298 | else { | ||
2299 | /* error, invalid DC count */ | ||
2300 | status = IPE_STS_ERR_INV_DC_COUNT; | ||
2301 | } | ||
2302 | } | ||
2303 | else { | ||
2304 | /* No change to PWM DC count */ | ||
2305 | if ((iepPwmDcCountOld > 0) && (iepPwmDcCountOld < pwmPeriodCount)) { | ||
2306 | /* latched DC count !=0, !=100 */ | ||
2307 | *pRowIdx = AT_Row01_DcOldX_DcNewX; | ||
2308 | } | ||
2309 | else if (iepPwmDcCountOld == 0) { | ||
2310 | /* old DC count is 0 */ | ||
2311 | *pRowIdx = AT_Row06_DcOld0_DcNew0; | ||
2312 | } | ||
2313 | else if (iepPwmDcCountOld == pwmPeriodCount) { | ||
2314 | /* old DC count is 100 */ | ||
2315 | *pRowIdx = AT_Row10_DcOld100_DcNew100; | ||
2316 | } | ||
2317 | else { | ||
2318 | /* error, invalid DC count */ | ||
2319 | status = IPE_STS_ERR_INV_DC_COUNT; | ||
2320 | } | ||
2321 | } | ||
2322 | |||
2323 | return status; | ||
2324 | } | ||
2325 | |||
2326 | /* Get Action Table row, Differential PWM */ | ||
2327 | static Int32 getActionTableRowDiff( | ||
2328 | Uint16 recfgDcCount, | ||
2329 | Uint8 dPwmIdx, | ||
2330 | Uint32 iepPwmDcCountOld, | ||
2331 | Uint32 iepPwmDcCountNew, | ||
2332 | Uint32 pwmPeriodCount, | ||
2333 | Uint8 *pRowIdx | ||
2334 | ) | ||
2335 | { | ||
2336 | Int32 status = IEP_STS_NERR; | ||
2337 | Uint8 pwmIdx; | ||
2338 | |||
2339 | pwmIdx = dPwmIdx << 1; /* multiply by 2 for differential PWM */ | ||
2340 | |||
2341 | if ((recfgDcCount >> pwmIdx) & 0x1) { | ||
2342 | /* Possible change to PWM DC count */ | ||
2343 | if ((iepPwmDcCountOld > 0) && (iepPwmDcCountOld < pwmPeriodCount)) { | ||
2344 | if (iepPwmDcCountNew == iepPwmDcCountOld) { | ||
2345 | /* new DC count is x */ | ||
2346 | *pRowIdx = AT_Row01_DcOldX_DcNewX; | ||
2347 | } | ||
2348 | else if ((iepPwmDcCountNew > 0) && (iepPwmDcCountNew < pwmPeriodCount)) { | ||
2349 | /* new DC count is y, x!=y */ | ||
2350 | *pRowIdx = AT_Row02_DcOldX_DcNewY; | ||
2351 | } | ||
2352 | else if (iepPwmDcCountNew == 0) { | ||
2353 | /* new DC count is 0 */ | ||
2354 | *pRowIdx = AT_Row03_DcOldX_DcNew0; | ||
2355 | } | ||
2356 | else if (iepPwmDcCountNew == pwmPeriodCount) { | ||
2357 | /* new DC count is 100 */ | ||
2358 | *pRowIdx = AT_Row04_DcOldX_DcNew100; | ||
2359 | } | ||
2360 | else { | ||
2361 | /* error, invalid DC count */ | ||
2362 | status = IPE_STS_ERR_INV_DC_COUNT; | ||
2363 | } | ||
2364 | } | ||
2365 | else if (iepPwmDcCountOld == 0) { /* old DC count is 0 */ | ||
2366 | if ((iepPwmDcCountNew > 0) && (iepPwmDcCountNew < pwmPeriodCount)) { | ||
2367 | /* new DC count !=0, !=100 */ | ||
2368 | *pRowIdx = AT_Row05_DcOld0_DcNewY; | ||
2369 | } | ||
2370 | else if (iepPwmDcCountNew == 0) { | ||
2371 | /* new DC count is 0 */ | ||
2372 | *pRowIdx = AT_Row06_DcOld0_DcNew0; | ||
2373 | } | ||
2374 | else if (iepPwmDcCountNew == pwmPeriodCount) { | ||
2375 | /* new DC count is 100 */ | ||
2376 | *pRowIdx = AT_Row10_DcOld100_DcNew100; | ||
2377 | } | ||
2378 | else { | ||
2379 | /* error, invalid DC count */ | ||
2380 | status = IPE_STS_ERR_INV_DC_COUNT; | ||
2381 | } | ||
2382 | } | ||
2383 | else if (iepPwmDcCountOld == pwmPeriodCount) { /* old DC count is 100 */ | ||
2384 | if ((iepPwmDcCountNew > 0) && (iepPwmDcCountNew < pwmPeriodCount)) { | ||
2385 | /* new DC count !=0, !=100 */ | ||
2386 | *pRowIdx = AT_Row08_DcOld100_DcNewY; | ||
2387 | } | ||
2388 | else if (iepPwmDcCountNew == 0) { | ||
2389 | /* new DC count is 0 */ | ||
2390 | *pRowIdx = AT_Row09_DcOld100_DcNew0; | ||
2391 | } | ||
2392 | else if (iepPwmDcCountNew == pwmPeriodCount) { | ||
2393 | /* new DC count is 100 */ | ||
2394 | *pRowIdx = AT_Row10_DcOld100_DcNew100; | ||
2395 | } | ||
2396 | else { | ||
2397 | /* error, invalid DC count */ | ||
2398 | status = IPE_STS_ERR_INV_DC_COUNT; | ||
2399 | } | ||
2400 | } | ||
2401 | else { | ||
2402 | /* error, invalid DC count */ | ||
2403 | status = IPE_STS_ERR_INV_DC_COUNT; | ||
2404 | } | ||
2405 | } | ||
2406 | else { | ||
2407 | /* No change to PWM DC count */ | ||
2408 | if ((iepPwmDcCountOld > 0) && (iepPwmDcCountOld < pwmPeriodCount)) { | ||
2409 | /* latched DC count !=0, !=100 */ | ||
2410 | *pRowIdx = AT_Row01_DcOldX_DcNewX; | ||
2411 | } | ||
2412 | else if (iepPwmDcCountOld == 0) { | ||
2413 | /* old DC count is 0 */ | ||
2414 | *pRowIdx = AT_Row06_DcOld0_DcNew0; | ||
2415 | } | ||
2416 | else if (iepPwmDcCountOld == pwmPeriodCount) { | ||
2417 | /* old DC count is 100 */ | ||
2418 | *pRowIdx = AT_Row10_DcOld100_DcNew100; | ||
2419 | } | ||
2420 | } | ||
2421 | |||
2422 | return status; | ||
2423 | } | ||
2424 | |||
2425 | /* Calculate IEP PWM LHS/RHS Duty Cycle Counts */ | ||
2426 | static void calcDcLatchAction( | ||
2427 | IepLatchAction actionLatch, | ||
2428 | Uint32 iepPwmDcCountNew, | ||
2429 | Uint32 *pIepPwmDcCountLhsNew, | ||
2430 | Uint32 *pIepPwmDcCountRhsNew | ||
2431 | ) | ||
2432 | { | ||
2433 | Uint32 dcCountLhs, dcCountRhs; | ||
2434 | |||
2435 | switch (actionLatch) | ||
2436 | { | ||
2437 | /* New DC count is 0 or 100. | ||
2438 | Don't calculate LHS/RHS. */ | ||
2439 | case LATCH_ACTION_Latch_0: | ||
2440 | case LATCH_ACTION_Latch_100: | ||
2441 | break; | ||
2442 | /* New DC count !=0, !=100. | ||
2443 | Calculate LHS/RHS. */ | ||
2444 | case LATCH_ACTION_Latch_New: | ||
2445 | calcDcLhsRhs(iepPwmDcCountNew, &dcCountLhs, &dcCountRhs); | ||
2446 | *pIepPwmDcCountLhsNew = dcCountLhs; | ||
2447 | *pIepPwmDcCountRhsNew = dcCountRhs; | ||
2448 | break; | ||
2449 | case LATCH_ACTION_None: | ||
2450 | default: | ||
2451 | break; | ||
2452 | } | ||
2453 | } | ||
2454 | |||
2455 | /* Calculate DC LHS/RHS for DC */ | ||
2456 | static void calcDcLhsRhs( | ||
2457 | Uint32 dcCount, | ||
2458 | Uint32 *pDcCountLhs, | ||
2459 | Uint32 *pDcCountRhs | ||
2460 | ) | ||
2461 | { | ||
2462 | Uint32 dcCountLhs, dcCountRhs; | ||
2463 | |||
2464 | dcCountLhs = COUNT_TO_CLK(dcCount)/2; | ||
2465 | dcCountLhs = CLK_TO_COUNT(dcCountLhs); | ||
2466 | dcCountRhs = dcCountLhs; | ||
2467 | if ((COUNT_TO_CLK(dcCount) & 0x1) == 1) { /* DC count is odd, distribute extra clocks to RHS */ | ||
2468 | dcCountRhs += DEF_COUNT_INC_PER_CLK; | ||
2469 | } | ||
2470 | |||
2471 | *pDcCountLhs = dcCountLhs; | ||
2472 | *pDcCountRhs = dcCountRhs; | ||
2473 | } | ||
2474 | |||
2475 | /* Execute LHS action, Single-Ended PWM */ | ||
2476 | static void execLhsActionSngl( | ||
2477 | IepPwmLhsAction lhsAction, | ||
2478 | Uint32 iepPwmDcCountLhsOld, | ||
2479 | Uint32 iepPwmDcCountLhsNew, | ||
2480 | volatile uint32_t **pIepCmpSrAddr, | ||
2481 | Uint16 *pIepPwmSnglUpdEn, | ||
2482 | Uint8 pwmIdx, | ||
2483 | Uint32 iepPwmPeriodCount | ||
2484 | ) | ||
2485 | { | ||
2486 | volatile uint32_t *pCmpSr; | ||
2487 | |||
2488 | pCmpSr = pIepCmpSrAddr[pwmIdx]; | ||
2489 | |||
2490 | switch (lhsAction) | ||
2491 | { | ||
2492 | case LHS_ACTION_Set_CmpSr_DcLhsY: | ||
2493 | *pCmpSr = iepPwmPeriodCount - iepPwmDcCountLhsNew; /* Write LHS value to CMP Shadow Register */ | ||
2494 | break; | ||
2495 | |||
2496 | case LHS_ACTION_Set_CmpSr_DcLhsX_And_EnableSrUpdate: | ||
2497 | *pCmpSr = iepPwmPeriodCount - iepPwmDcCountLhsOld; /* Write LHS value to CMP Shadow Register */ | ||
2498 | *pIepPwmSnglUpdEn |= 1<<pwmIdx; /* Enable CMP SR update */ | ||
2499 | |||
2500 | break; | ||
2501 | case LHS_ACTION_Set_CmpSr_DcLhsY_And_EnableSrUpdate: | ||
2502 | *pCmpSr = iepPwmPeriodCount - iepPwmDcCountLhsNew; /* Write LHS value to CMP Shadow Register */ | ||
2503 | *pIepPwmSnglUpdEn |= 1<<pwmIdx; /* Enable CMP SR update */ | ||
2504 | break; | ||
2505 | |||
2506 | case LHS_ACTION_Set_CmpSr_EarlyInPrd_And_EnableSrUpdate: | ||
2507 | *pCmpSr = CMP_SR_EARLY_VAL; /* Write LHS value to CMP Shadow Register */ | ||
2508 | *pIepPwmSnglUpdEn |= 1<<pwmIdx; /* Enable CMP SR update */ | ||
2509 | break; | ||
2510 | |||
2511 | case LHS_ACTION_Set_CmpSr_GtPrd_And_DisableSrUpdate: | ||
2512 | *pCmpSr = iepPwmPeriodCount; /* Write LHS value to CMP Shadow Register */ | ||
2513 | *pIepPwmSnglUpdEn &= ~(1<<pwmIdx); /* Enable CMP SR update */ | ||
2514 | break; | ||
2515 | |||
2516 | case LHS_ACTION_None: | ||
2517 | default: | ||
2518 | break; | ||
2519 | } | ||
2520 | } | ||
2521 | |||
2522 | /* Execute LHS action, Differential PWM */ | ||
2523 | static void execLhsActionDiff( | ||
2524 | IepPwmLhsAction lhsAction, | ||
2525 | Uint32 iepPwmDcCountLhsOld, | ||
2526 | Uint32 iepPwmDcCountLhsNew, | ||
2527 | volatile uint32_t **pIepCmpSrAddr, | ||
2528 | Uint8 *pIepPwmDiffUpdEn, | ||
2529 | Uint8 dPwmIdx, | ||
2530 | Uint32 iepPwmPeriodCount | ||
2531 | ) | ||
2532 | { | ||
2533 | volatile uint32_t *pCmpSrPos, *pCmpSrNeg; | ||
2534 | Uint8 pwmIdx; | ||
2535 | Uint32 temp; | ||
2536 | |||
2537 | pwmIdx = dPwmIdx << 1; /* multiply by 2 for differential PWM */ | ||
2538 | pCmpSrPos = pIepCmpSrAddr[pwmIdx]; | ||
2539 | pCmpSrNeg = pIepCmpSrAddr[pwmIdx+1]; | ||
2540 | |||
2541 | switch (lhsAction) | ||
2542 | { | ||
2543 | case LHS_ACTION_Set_CmpSr_DcLhsY: | ||
2544 | /* Write same LHS value to both CMP Shadow Registers in differential pair */ | ||
2545 | temp = iepPwmPeriodCount - iepPwmDcCountLhsNew; | ||
2546 | *pCmpSrPos = temp; | ||
2547 | *pCmpSrNeg = temp; | ||
2548 | break; | ||
2549 | |||
2550 | case LHS_ACTION_Set_CmpSr_DcLhsX_And_EnableSrUpdate: | ||
2551 | /* Write same LHS value to both CMP Shadow Registers in differential pair */ | ||
2552 | temp = iepPwmPeriodCount - iepPwmDcCountLhsOld; | ||
2553 | *pCmpSrPos = temp; | ||
2554 | *pCmpSrNeg = temp; | ||
2555 | /* Enable CMP SR update */ | ||
2556 | *pIepPwmDiffUpdEn |= 1<<dPwmIdx; | ||
2557 | break; | ||
2558 | |||
2559 | case LHS_ACTION_Set_CmpSr_DcLhsY_And_EnableSrUpdate: | ||
2560 | /* Write same LHS value to both CMP Shadow Registers in differential pair */ | ||
2561 | temp = iepPwmPeriodCount - iepPwmDcCountLhsNew; | ||
2562 | *pCmpSrPos = temp; | ||
2563 | *pCmpSrNeg = temp; | ||
2564 | /* Enable CMP SR update */ | ||
2565 | *pIepPwmDiffUpdEn |= 1<<dPwmIdx; | ||
2566 | break; | ||
2567 | |||
2568 | case LHS_ACTION_Set_CmpSr_EarlyInPrd_And_EnableSrUpdate: | ||
2569 | /* Write same LHS value to both CMP Shadow Registers in differential pair */ | ||
2570 | *pCmpSrPos = CMP_SR_EARLY_VAL; | ||
2571 | *pCmpSrNeg = CMP_SR_EARLY_VAL; | ||
2572 | /* Enable CMP SR update */ | ||
2573 | *pIepPwmDiffUpdEn |= 1<<dPwmIdx; | ||
2574 | break; | ||
2575 | |||
2576 | case LHS_ACTION_Set_CmpSr_GtPrd_And_DisableSrUpdate: | ||
2577 | /* Write same LHS value to both CMP Shadow Registers in differential pair */ | ||
2578 | *pCmpSrPos = iepPwmPeriodCount; | ||
2579 | *pCmpSrNeg = iepPwmPeriodCount; | ||
2580 | /* Disable CMP SR update */ | ||
2581 | *pIepPwmDiffUpdEn &= ~(1<<dPwmIdx); | ||
2582 | break; | ||
2583 | |||
2584 | case LHS_ACTION_None: | ||
2585 | default: | ||
2586 | break; | ||
2587 | } | ||
2588 | } | ||
2589 | |||
2590 | /* Stash RHS action */ | ||
2591 | static void stashRhsAction( | ||
2592 | IepPwmRhsAction actionRhs, | ||
2593 | Bool *pIepPwmRhsRecfgFlag, | ||
2594 | IepPwmRhsAction *pIepPwmRhsAction | ||
2595 | ) | ||
2596 | { | ||
2597 | if (actionRhs != RHS_ACTION_None) { | ||
2598 | *pIepPwmRhsRecfgFlag = TRUE; | ||
2599 | } | ||
2600 | |||
2601 | *pIepPwmRhsAction = actionRhs; | ||
2602 | } | ||
2603 | |||
2604 | /* Execute (LHS) DC latch action */ | ||
2605 | static void execDcLatchAction( | ||
2606 | IepLatchAction actionLatch, | ||
2607 | Uint32 *pIepPwmDcCountOld, | ||
2608 | Uint32 *pIepPwmDcCountLhsOld, | ||
2609 | Uint32 *pIepPwmDcCountRhsOld, | ||
2610 | Uint32 iepPwmDcCountNew, | ||
2611 | Uint32 iepPwmDcCountLhsNew, | ||
2612 | Uint32 iepPwmDcCountRhsNew | ||
2613 | ) | ||
2614 | { | ||
2615 | switch (actionLatch) | ||
2616 | { | ||
2617 | /* New DC count is 0 or 100. | ||
2618 | Latch new DC, don't calculate & latch corresponding LHS/RHS. */ | ||
2619 | case LATCH_ACTION_Latch_0: | ||
2620 | case LATCH_ACTION_Latch_100: | ||
2621 | *pIepPwmDcCountOld = iepPwmDcCountNew; | ||
2622 | break; | ||
2623 | /* New DC count !=0, !=100. | ||
2624 | Latch new DC latch corresponding LHS/RHS DC. */ | ||
2625 | case LATCH_ACTION_Latch_New: | ||
2626 | *pIepPwmDcCountOld = iepPwmDcCountNew; | ||
2627 | *pIepPwmDcCountLhsOld = iepPwmDcCountLhsNew; | ||
2628 | *pIepPwmDcCountRhsOld = iepPwmDcCountRhsNew; | ||
2629 | break; | ||
2630 | case LATCH_ACTION_None: | ||
2631 | default: | ||
2632 | break; | ||
2633 | } | ||
2634 | } | ||
2635 | |||
2636 | /* Execute stashed RHS actions */ | ||
2637 | static void execRhsActionStash( | ||
2638 | IcssgIepPwmObj *pIcssgIepPwmObj | ||
2639 | ) | ||
2640 | { | ||
2641 | Uint32 *pIepPwmDcCountRhs; | ||
2642 | Uint16 *pIepPwmDbCount; | ||
2643 | Uint16 *pIepPwmSnglUpdEn; | ||
2644 | Uint8 *pIepPwmDiffUpdEn; | ||
2645 | volatile uint32_t **pIepCmpSrAddr; | ||
2646 | Uint32 iepPwmPeriodCount; | ||
2647 | IepPwmRhsAction *pIepPwmRhsAction; | ||
2648 | Uint32 dcRhsY; | ||
2649 | volatile uint32_t *pCmpSr; | ||
2650 | Uint8 pwmIdx, dPwmIdx; | ||
2651 | |||
2652 | /* Get latched IEP PWM DC RHS count array */ | ||
2653 | pIepPwmDcCountRhs = &pIcssgIepPwmObj->iepPwmDcCountRhs[0]; | ||
2654 | /* Get Deadband count array */ | ||
2655 | pIepPwmDbCount = &pIcssgIepPwmObj->iepPwmDbCount[0]; | ||
2656 | /* Get Single-Ended & Differential PWM Update Enable */ | ||
2657 | pIepPwmSnglUpdEn = &pIcssgIepPwmObj->iepPwmSnglUpdEn; | ||
2658 | pIepPwmDiffUpdEn = &pIcssgIepPwmObj->iepPwmDiffUpdEn; | ||
2659 | /* Get IEP CMP Shadow Registers array */ | ||
2660 | pIepCmpSrAddr = &pIcssgIepPwmObj->iepCmpSrAddr[0]; | ||
2661 | /* Get period */ | ||
2662 | iepPwmPeriodCount = pIcssgIepPwmObj->iepPwmPeriodCount; | ||
2663 | /* Get RHS action array */ | ||
2664 | pIepPwmRhsAction = &pIcssgIepPwmObj->iepPwmRhsAction[0]; | ||
2665 | |||
2666 | if (pIcssgIepPwmObj->iepPwmRhsRecfgFlag == TRUE) { | ||
2667 | for (dPwmIdx = 0; dPwmIdx < IEP_MAX_NUM_DIFF_PWM; dPwmIdx++) | ||
2668 | { | ||
2669 | if ((pIcssgIepPwmObj->iepPwmMode >> dPwmIdx) & 0x1) { | ||
2670 | /* Process Differential PWM */ | ||
2671 | |||
2672 | pwmIdx = dPwmIdx << 1; | ||
2673 | switch(pIepPwmRhsAction[pwmIdx]) | ||
2674 | { | ||
2675 | case RHS_ACTION_Set_CmpSr_DcRhsY_And_EnableSrUpdate: | ||
2676 | dcRhsY = pIepPwmDcCountRhs[pwmIdx]; | ||
2677 | |||
2678 | pCmpSr = pIepCmpSrAddr[pwmIdx]; | ||
2679 | *pCmpSr = dcRhsY; /* Write RHS value to CMP Shadow Register */ | ||
2680 | pwmIdx++; | ||
2681 | pCmpSr = pIepCmpSrAddr[pwmIdx]; | ||
2682 | *pCmpSr = dcRhsY + pIepPwmDbCount[dPwmIdx]; /* Write RHS value to CMP Shadow Register */ | ||
2683 | |||
2684 | *pIepPwmDiffUpdEn |= 1<<dPwmIdx; /* Enable CMP SR update */ | ||
2685 | break; | ||
2686 | |||
2687 | case RHS_ACTION_Set_CmpSr_GtPrd_And_DisableSrUpdate: | ||
2688 | dcRhsY = pIepPwmDcCountRhs[pwmIdx]; | ||
2689 | |||
2690 | /* Write same LHS value to both CMP Shadow Registers in differential pair */ | ||
2691 | pCmpSr = pIepCmpSrAddr[pwmIdx]; | ||
2692 | *pCmpSr = iepPwmPeriodCount; /* Write value greater than Period to Shadow Register */ | ||
2693 | pwmIdx++; | ||
2694 | pCmpSr = pIepCmpSrAddr[pwmIdx]; | ||
2695 | *pCmpSr = iepPwmPeriodCount; /* Write value greater than Period to Shadow Register */ | ||
2696 | |||
2697 | /* Enable CMP SR update */ | ||
2698 | *pIepPwmDiffUpdEn &= ~(1<<dPwmIdx); /* Disable CMP SR update */ | ||
2699 | break; | ||
2700 | |||
2701 | case RHS_ACTION_None: | ||
2702 | default: | ||
2703 | break; | ||
2704 | } | ||
2705 | pIepPwmRhsAction[pwmIdx] = RHS_ACTION_None; | ||
2706 | } | ||
2707 | else { | ||
2708 | /* Process Single-Ended PWMs */ | ||
2709 | |||
2710 | for (pwmIdx = dPwmIdx<<1; pwmIdx < ((dPwmIdx<<1) + NUM_PWM_PER_DIFF_PWM); pwmIdx++) | ||
2711 | { | ||
2712 | switch (pIepPwmRhsAction[pwmIdx]) | ||
2713 | { | ||
2714 | case RHS_ACTION_Set_CmpSr_DcRhsY_And_EnableSrUpdate: | ||
2715 | dcRhsY = pIepPwmDcCountRhs[pwmIdx]; | ||
2716 | pCmpSr = pIepCmpSrAddr[pwmIdx]; | ||
2717 | *pCmpSr = dcRhsY; /* Write RHS value to CMP Shadow Register */ | ||
2718 | *pIepPwmSnglUpdEn |= 1<<pwmIdx; /* Enable CMP SR update */ | ||
2719 | break; | ||
2720 | case RHS_ACTION_Set_CmpSr_GtPrd_And_DisableSrUpdate: | ||
2721 | pCmpSr = pIepCmpSrAddr[pwmIdx]; | ||
2722 | *pCmpSr = iepPwmPeriodCount; /* Write value greater than Period to CMP Shadow Register */ | ||
2723 | *pIepPwmSnglUpdEn &= ~(1<<pwmIdx); /* Disable CMP SR update */ | ||
2724 | break; | ||
2725 | case RHS_ACTION_None: | ||
2726 | default: | ||
2727 | break; | ||
2728 | } | ||
2729 | pIepPwmRhsAction[pwmIdx] = RHS_ACTION_None; | ||
2730 | } | ||
2731 | } | ||
2732 | } | ||
2733 | } | ||
2734 | } | ||
2735 | |||
2736 | /* Update IEP PWM CMPx Shadow Registers for DB reconfiguration. */ | ||
2737 | static Int32 updateIepPwmCmpxShRegDb( | ||
2738 | IcssgIepPwmObj *pIcssgIepPwmObj | ||
2739 | ) | ||
2740 | { | ||
2741 | IepPwmFwRegs *pIepPwmFwRegs = pIcssgIepPwmObj->pIepPwmFwRegs; | ||
2742 | Uint32 *pIepPwmDcCount; | ||
2743 | volatile Uint16 *pIepPwmDbCount; | ||
2744 | volatile uint32_t *pShadowReg; | ||
2745 | Uint8 pwmIdx, dPwmIdx; | ||
2746 | |||
2747 | pIepPwmDcCount = &pIcssgIepPwmObj->iepPwmDcCountLhs[0]; /* init pointer to PWM Duty Cycle Count */ | ||
2748 | pIepPwmDbCount = &pIepPwmFwRegs->IEP_PWM0_1_DB_COUNT; /* init pointer to PWM Deadband Count */ | ||
2749 | for (dPwmIdx = 0; dPwmIdx < IEP_MAX_NUM_DIFF_PWM; dPwmIdx++) | ||
2750 | { | ||
2751 | if (((pIcssgIepPwmObj->iepPwmDiffUpdEn >> dPwmIdx) & 0x1) == 1) { /* check PWM update enabled */ | ||
2752 | /* Write CMP SR for POS PWM */ | ||
2753 | pwmIdx = dPwmIdx << 1; | ||
2754 | pShadowReg = pIcssgIepPwmObj->iepCmpSrAddr[pwmIdx]; /* set pointer to CMP Shadow Register */ | ||
2755 | *pShadowReg = pIcssgIepPwmObj->iepPwmPeriodCount - *pIepPwmDcCount; | ||
2756 | /* Write CMP SR for NEG PWM. | ||
2757 | Increment CMP SR pointer by 2 since CMP registers are 64 bit. */ | ||
2758 | pwmIdx++; | ||
2759 | pShadowReg = pIcssgIepPwmObj->iepCmpSrAddr[pwmIdx]; /* set pointer to CMP Shadow Register */ | ||
2760 | *pShadowReg = pIcssgIepPwmObj->iepPwmPeriodCount - *pIepPwmDcCount - *pIepPwmDbCount; | ||
2761 | } | ||
2762 | pIepPwmDcCount += 2; /* differential pair use same Duty Cycle Count */ | ||
2763 | pIepPwmDbCount++; | ||
2764 | } | ||
2765 | |||
2766 | /* Latch IEP PWM Deadband Count */ | ||
2767 | latchIepPwmDbCount(pIcssgIepPwmObj, TRUE); | ||
2768 | |||
2769 | return IEP_STS_NERR; | ||
2770 | } | ||