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