1 /*
2  * Copyright (c) 2006-2022, RT-Thread Development Team
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  *
6  * Change Logs:
7  * Date           Author       Notes
8  * 2022-09-24     qiyu      first version
9  */
10 
11 #include "rtdbg.h"
12 #include "drv_pwm.h"
13 #include "F2837xD_device.h"
14 #include "F28x_Project.h"     /* Device Headerfile and Examples Include File */
15 #include "drv_config.h"
16 #include "F2837xD_epwm.h"
17 /*
18  * for now, cpu rate is a fixed value, waiting to be modified to an auto-ajustable variable.
19 */
20 #ifdef BSP_USING_PWM
21 rt_err_t rt_device_pwm_register(struct rt_device_pwm *device, const char *name, const struct rt_pwm_ops *ops, const void *user_data);
22 
23 #define CPU_FREQUENCY 200e6
24 /*
25  * TODO unknown issue, according to the configuration,
26  * this division should be 2,
27  * while 2 is inconsistent with the measured result
28  */
29 #define PWM_DIVISION 2
30 #define CHANNEL_A       1
31 #define CHANNEL_B       2
32 #define UPDOWN 1
33 
34 enum
35 {
36 #ifdef BSP_USING_PWM1
37     PWM1_INDEX,
38 #endif
39 #ifdef BSP_USING_PWM2
40     PWM2_INDEX,
41 #endif
42 #ifdef BSP_USING_PWM3
43     PWM3_INDEX,
44 #endif
45 #ifdef BSP_USING_PWM4
46     PWM4_INDEX,
47 #endif
48 #ifdef BSP_USING_PWM5
49     PWM5_INDEX,
50 #endif
51 #ifdef BSP_USING_PWM6
52     PWM6_INDEX,
53 #endif
54 #ifdef BSP_USING_PWM7
55     PWM7_INDEX,
56 #endif
57 #ifdef BSP_USING_PWM8
58     PWM8_INDEX,
59 #endif
60 #ifdef BSP_USING_PWM9
61     PWM9_INDEX,
62 #endif
63 #ifdef BSP_USING_PWM10
64     PWM10_INDEX,
65 #endif
66 #ifdef BSP_USING_PWM11
67     PWM11_INDEX,
68 #endif
69 #ifdef BSP_USING_PWM12
70     PWM12_INDEX,
71 #endif
72 };
73 
74 static rt_err_t drv_pwm_control(struct rt_device_pwm *device, int cmd, void *arg);
75 
76 static struct rt_pwm_ops rt_pwm_ops =
77 {
78     drv_pwm_control
79 };
80 
81 static struct c28x_pwm c28x_pwm_obj[] =
82 {
83 #ifdef BSP_USING_PWM1
84     PWM1_CONFIG,
85 #endif
86 
87 #ifdef BSP_USING_PWM2
88     PWM2_CONFIG,
89 #endif
90 
91 #ifdef BSP_USING_PWM3
92     PWM3_CONFIG,
93 #endif
94 
95 #ifdef BSP_USING_PWM4
96     PWM4_CONFIG,
97 #endif
98 
99 #ifdef BSP_USING_PWM5
100     PWM5_CONFIG,
101 #endif
102 
103 #ifdef BSP_USING_PWM6
104     PWM6_CONFIG,
105 #endif
106 
107 #ifdef BSP_USING_PWM7
108     PWM7_CONFIG,
109 #endif
110 
111 #ifdef BSP_USING_PWM8
112     PWM8_CONFIG,
113 #endif
114 
115 };
116 
drv_pwm_set(volatile struct EPWM_REGS * epwm,struct rt_pwm_configuration * configuration)117 static rt_err_t drv_pwm_set(volatile struct EPWM_REGS *epwm,struct rt_pwm_configuration *configuration)
118 {
119     if(epwm == RT_NULL)
120     {
121         return -RT_ERROR;
122     }
123     /*
124      * TODO Unknown problem
125      * the clock division configuration of PWM module is 1
126      * however, the experiment result shows the division is 2
127      */
128 
129     /* Set the configuration of PWM according to the parameter*/
130     rt_uint32_t prd = configuration->period/(1e9/(CPU_FREQUENCY/PWM_DIVISION))/2;
131     rt_uint32_t comp = prd*configuration->pulse/configuration->period;
132     rt_uint32_t dead_time = configuration->dead_time/(1e9/(CPU_FREQUENCY/PWM_DIVISION));
133     rt_uint32_t phase = configuration->phase;
134 
135     epwm->TBPRD = prd;                       /* Set timer period*/
136     epwm->TBCTR = 0x0000;                     /* Clear counter*/
137     epwm->CMPCTL.bit.SHDWAMODE = RT_SHADOW_MODE;    /* Load registers every ZERO*/
138     epwm->CMPCTL.bit.SHDWBMODE = RT_SHADOW_MODE;
139     /* Setup compare */
140     if(configuration->channel == CHANNEL_A)
141     {
142         epwm->CMPA.bit.CMPA = comp;
143     }else
144     {
145         epwm->CMPB.bit.CMPB = comp;
146     }
147 
148     /* Set actions */
149     epwm->AQCTLA.bit.CAU = AQ_CLEAR;            /* Set PWMA on Zero*/
150     epwm->AQCTLA.bit.CAD = AQ_SET;
151     epwm->AQCTLB.bit.CBU = AQ_CLEAR;            /* Set PWMB on Zero*/
152     epwm->AQCTLB.bit.CBD = AQ_SET;
153 
154     /* Active Low PWMs - Setup Deadband */
155     /* TODO finish complementary setting */
156     epwm->DBCTL.bit.POLSEL = DB_ACTV_HIC;
157     epwm->DBRED.bit.DBRED = dead_time;
158     epwm->DBFED.bit.DBFED = dead_time;
159     epwm->DBCTL.bit.OUT_MODE = DB_FULL_ENABLE;
160     /*
161     if(configuration->complementary)
162     {
163     }
164     else
165     {
166         epwm->DBRED.bit.DBRED = 0;
167         epwm->DBFED.bit.DBFED = 0;
168         epwm->DBCTL.bit.POLSEL = DB_ACTV_HI;
169         epwm->DBCTL.bit.OUT_MODE = DB_DISABLE;
170     }
171     */
172 
173     epwm->DBCTL.bit.IN_MODE = DBA_ALL;
174     /* if disable dead time, set dead_time to 0 */
175 
176 #ifdef BSP_PWM1_CTR_MODE_UPDOWN
177     if(phase<180)
178     {
179         epwm->TBPHS.bit.TBPHS = prd * phase/180;
180         epwm->TBCTL.bit.PHSDIR = 0; /* count up */
181     }else
182     {
183         epwm->TBPHS.bit.TBPHS = prd-prd * (phase-180)/180;
184         epwm->TBCTL.bit.PHSDIR = 1; /* count up*/
185     }
186 #endif
187     if(epwm == &EPwm1Regs)
188     {
189         epwm->TBCTL.bit.PHSEN = TB_DISABLE;        /* Disable phase loading */
190         epwm->TBCTL.bit.SYNCOSEL = TB_CTR_ZERO;
191     }else
192     {
193         epwm->TBCTL.bit.PHSEN = TB_ENABLE;        /* Disable phase loading */
194         epwm->TBCTL.bit.SYNCOSEL = TB_SYNC_IN;
195     }
196     return RT_EOK;
197 }
198 
drv_pwm_get(struct EPWM_REGS * epwm,struct rt_pwm_configuration * configuration)199 static rt_err_t drv_pwm_get(struct EPWM_REGS *epwm,struct rt_pwm_configuration *configuration)
200 {
201     /* Retrieve the pwm configuration */
202     if(epwm == RT_NULL)
203     {
204         return -RT_ERROR;
205     }
206     rt_uint32_t prd = epwm->TBPRD;
207     rt_uint32_t comp = epwm->CMPA.bit.CMPA;
208     if(UPDOWN)
209     {
210         /* if in updown mode, period in configuration has to be doubled */
211         configuration->period = prd*(1e9/(CPU_FREQUENCY/PWM_DIVISION))*2;
212     }
213     else
214     {
215         configuration->period = prd*(1e9/(CPU_FREQUENCY/PWM_DIVISION));
216     }
217     configuration->pulse = comp*configuration->period/prd;
218     return RT_EOK;
219 }
220 
drv_pwm_set_period(struct EPWM_REGS * epwm,rt_uint32_t period)221 static rt_err_t drv_pwm_set_period(struct EPWM_REGS *epwm, rt_uint32_t period)
222 {
223     if(epwm == RT_NULL)
224     {
225         return -RT_ERROR;
226     }
227     rt_uint32_t prd = period/(1e9/(CPU_FREQUENCY/PWM_DIVISION))/2;
228     epwm->TBPRD = prd;                       /* Set timer period */
229     return RT_EOK;
230 }
231 
drv_pwm_set_pulse(struct EPWM_REGS * epwm,int channel,rt_uint32_t pulse)232 static rt_err_t drv_pwm_set_pulse(struct EPWM_REGS *epwm, int channel, rt_uint32_t pulse)
233 {
234     if(epwm == RT_NULL)
235     {
236         return -RT_ERROR;
237     }
238     rt_uint32_t comp = pulse/(1e9/(CPU_FREQUENCY/PWM_DIVISION));
239     if(channel == CHANNEL_A)
240     {
241         epwm->CMPA.bit.CMPA = comp;    /* set comparator value */
242     }else
243     {
244         epwm->CMPB.bit.CMPB = comp;    /* set comparator value */
245     }
246     return RT_EOK;
247 }
248 
drv_pwm_set_dead_time(struct EPWM_REGS * epwm,rt_uint32_t dead_time)249 static rt_err_t drv_pwm_set_dead_time(struct EPWM_REGS *epwm, rt_uint32_t dead_time)
250 {
251     if(epwm == RT_NULL)
252     {
253         return -RT_ERROR;
254     }
255     rt_uint32_t _dead_time = dead_time/(1e9/(CPU_FREQUENCY/PWM_DIVISION));
256     epwm->DBRED.bit.DBRED = _dead_time;  /* rising dead time */
257     epwm->DBFED.bit.DBFED = _dead_time;  /* falling dead time */
258     return RT_EOK;
259 }
260 
drv_pwm_set_phase(struct EPWM_REGS * epwm,rt_uint32_t phase)261 static rt_err_t drv_pwm_set_phase(struct EPWM_REGS *epwm, rt_uint32_t phase)
262 {
263     if(epwm == RT_NULL)
264     {
265         return -RT_ERROR;
266     }
267     if(phase<180)
268     {
269         epwm->TBPHS.bit.TBPHS = epwm->TBPRD * phase/180;
270         epwm->TBCTL.bit.PHSDIR = 0;/* count up */
271     }else
272     {
273         epwm->TBPHS.bit.TBPHS = epwm->TBPRD-epwm->TBPRD * (phase-180)/180;
274         epwm->TBCTL.bit.PHSDIR = 1;/* count up */
275     }
276 
277     return RT_EOK;
278 }
279 
drv_pwm_enable_irq(volatile struct EPWM_REGS * epwm,rt_bool_t enable)280 static rt_err_t drv_pwm_enable_irq(volatile struct EPWM_REGS *epwm,rt_bool_t enable)
281 {
282     if(epwm == RT_NULL)
283     {
284         return -RT_ERROR;
285     }
286     if(enable == RT_TRUE)
287     {
288         /* Interrupt setting */
289         epwm->ETSEL.bit.INTEN = 1;               /* Enable INT */
290     }else{
291         epwm->ETSEL.bit.INTEN = 0;               /* Enable INT */
292     }
293     return RT_EOK;
294 }
295 
drv_pwm_enable(volatile struct EPWM_REGS * epwm,rt_bool_t enable)296 static rt_err_t drv_pwm_enable(volatile struct EPWM_REGS *epwm,rt_bool_t enable)
297 {
298     /*
299     * TODO
300     * Still not sure about how to stop PWM in C2000
301     */
302     if(epwm == RT_NULL)
303     {
304         return -RT_ERROR;
305     }
306     if(enable == RT_TRUE)
307     {
308         /* clear trip zone flag */
309         EALLOW;
310         epwm->TZCLR.bit.OST = 1;
311         EDIS;
312     }
313     else
314     {
315         /* set trip zone flag */
316         EALLOW;
317         epwm->TZFRC.bit.OST = 1;
318         EDIS;
319     }
320     return RT_EOK;
321 }
322 
drv_pwm_control(struct rt_device_pwm * device,int cmd,void * arg)323 static rt_err_t drv_pwm_control(struct rt_device_pwm *device, int cmd, void *arg)
324 {
325     struct rt_pwm_configuration *configuration = (struct rt_pwm_configuration *)arg;
326     struct c28x_pwm *pwm = (struct c28x_pwm *)device->parent.user_data;
327 
328     switch (cmd)
329     {
330     case PWM_CMD_ENABLE:
331         return drv_pwm_enable((struct EPWM_REGS *)(pwm->pwm_regs), RT_TRUE);
332     case PWM_CMD_DISABLE:
333         return drv_pwm_enable((struct EPWM_REGS *)(pwm->pwm_regs), RT_FALSE);
334     case PWM_CMD_SET:
335         return drv_pwm_set((struct EPWM_REGS *)(pwm->pwm_regs), configuration);
336     case PWM_CMD_GET:
337         return drv_pwm_get((struct EPWM_REGS *)(pwm->pwm_regs), configuration);
338     case PWM_CMD_SET_PERIOD:
339         return drv_pwm_set_period((struct EPWM_REGS *)(pwm->pwm_regs), configuration->period);
340     case PWM_CMD_SET_PULSE:
341         return drv_pwm_set_pulse((struct EPWM_REGS *)(pwm->pwm_regs), configuration->channel,configuration->pulse);
342     case PWM_CMD_SET_DEAD_TIME:
343         return drv_pwm_set_dead_time((struct EPWM_REGS *)(pwm->pwm_regs), configuration->dead_time);
344     case PWM_CMD_SET_PHASE:
345         return drv_pwm_set_phase((struct EPWM_REGS *)(pwm->pwm_regs), configuration->phase);
346     case PWM_CMD_ENABLE_IRQ:
347         return drv_pwm_enable_irq((struct EPWM_REGS *)(pwm->pwm_regs), RT_TRUE);
348     case PWM_CMD_DISABLE_IRQ:
349         return drv_pwm_enable_irq((struct EPWM_REGS *)(pwm->pwm_regs), RT_FALSE);
350     default:
351         return -RT_EINVAL;
352     }
353 }
354 
pwm_isr(struct rt_device_pwm * rt_pwm)355 static void pwm_isr(struct rt_device_pwm *rt_pwm)
356 {
357     struct c28x_pwm *pwm;
358     pwm = (struct c28x_pwm *)rt_pwm->parent.user_data;
359     PieCtrlRegs.PIEACK.all = PIEACK_GROUP3;
360     pwm->pwm_regs->ETCLR.bit.INT = 1;
361 }
362 
363 #define EPWM_ISR_DEFINE(i) void EPWM##i##_Isr(){\
364     rt_interrupt_enter();   \
365     pwm_isr(&(c28x_pwm_obj[PWM##i##_INDEX].pwm_device));  \
366     rt_interrupt_leave();   \
367 }
368 
369 #ifdef BSP_PWM1_IT_ENABLE
370 EPWM_ISR_DEFINE(1)
371 void EPWM1_Isr();
372 #endif
373 #ifdef BSP_PWM2_IT_ENABLE
374 EPWM_ISR_DEFINE(2)
375 void EPWM2_Isr();
376 #endif
377 #ifdef BSP_PWM3_IT_ENABLE
378 EPWM_ISR_DEFINE(3)
379 void EPWM3_Isr();
380 #endif
381 #ifdef BSP_PWM4_IT_ENABLE
382 EPWM_ISR_DEFINE(4)
383 void EPWM4_Isr();
384 #endif
385 
386 
c28x_hw_pwm_init(struct c28x_pwm * device)387 static int c28x_hw_pwm_init(struct c28x_pwm *device)
388 {
389     IER |= M_INT3;
390     rt_err_t result = 0;
391     EALLOW;
392 #ifdef BSP_USING_PWM1
393     GpioCtrlRegs.GPAPUD.all |= 5<<(1-1)*4;      /* Disable pull-up(EPWM1A) */
394     GpioCtrlRegs.GPAMUX1.all|= 5<<(1-1)*4;      /* Configure as EPWM1A */
395     EPwm1Regs.TZCTL.bit.TZA = TZ_OFF;           /* diable A when trip zone */
396     EPwm1Regs.TZCTL.bit.TZB = TZ_OFF;           /* diable B when trip zone */
397     EPwm1Regs.TBCTL.bit.CTRMODE = BSP_PWM1_CTRMODE;
398     EPwm1Regs.TBCTL.bit.HSPCLKDIV = BSP_PWM1_HSPCLKDIV;       /* Clock ratio to SYSCLKOUT*/
399     EPwm1Regs.TBCTL.bit.CLKDIV = BSP_PWM1_CLKDIV;
400     EPwm1Regs.CMPCTL.bit.LOADAMODE = BSP_PWM1_LOADAMODE;
401     EPwm1Regs.CMPCTL.bit.LOADBMODE = BSP_PWM1_LOADAMODE;
402     #ifdef BSP_PWM1_IT_ENABLE
403         EPwm1Regs.ETSEL.bit.INTEN = 1;               /* Enable INT */
404         EPwm1Regs.ETSEL.bit.INTSEL = BSP_PWM1_INTSEL;
405         EPwm1Regs.ETPS.bit.INTPRD = BSP_PWM1_INTPRD;
406         /* Assigning ISR to PIE */
407         PieVectTable.EPWM1_INT = &EPWM1_Isr;
408         /* ENABLE Interrupt */
409     #else
410         EPwm1Regs.ETSEL.bit.INTEN = 0;               /* Disable INT */
411     #endif
412     #ifdef BSP_PWM1_ADC_TRIGGER
413         EPwm1Regs.ETSEL.bit.SOCAEN    = 1;        // Enable SOC on A group
414         EPwm1Regs.ETSEL.bit.SOCASEL  = BSP_PWM1_SOCASEL;        // Select SOC from zero
415         EPwm1Regs.ETPS.bit.SOCAPRD   = BSP_PWM1_SOCAPRD;        // Generate pulse on 1st event
416     #else
417         EPwm1Regs.ETSEL.bit.SOCAEN    = 0;        // Disable SOC on A group
418     #endif
419     #ifdef BSP_PWM1_MASTER
420         EPwm1Regs.TBCTL.bit.PHSEN = TB_DISABLE;        /* Disable phase loading */
421         EPwm1Regs.TBCTL.bit.SYNCOSEL = TB_CTR_ZERO;
422     #else
423         EPwm1Regs.TBCTL.bit.PHSEN = TB_ENABLE;        /* Disable phase loading */
424         EPwm1Regs.TBCTL.bit.SYNCOSEL = TB_SYNC_IN;
425     #endif
426 #endif
427 #ifdef BSP_USING_PWM2
428     GpioCtrlRegs.GPAPUD.all |= 5<<(2-1)*4;      /* Disable pull-up on  (EPWM2A) */
429     GpioCtrlRegs.GPAMUX1.all|= 5<<(2-1)*4;      /* Configure as EPWM2A */
430     EPwm2Regs.TZCTL.bit.TZA = TZ_OFF;           /* diable A when trip zone */
431     EPwm2Regs.TZCTL.bit.TZB = TZ_OFF;           /* diable B when trip zone */
432     EPwm2Regs.TBCTL.bit.CTRMODE = BSP_PWM2_CTRMODE;
433     EPwm2Regs.TBCTL.bit.HSPCLKDIV = BSP_PWM2_HSPCLKDIV;       /* Clock ratio to SYSCLKOUT*/
434     EPwm2Regs.TBCTL.bit.CLKDIV = BSP_PWM2_CLKDIV;
435     EPwm2Regs.CMPCTL.bit.LOADAMODE = BSP_PWM2_LOADAMODE;
436     EPwm2Regs.CMPCTL.bit.LOADBMODE = BSP_PWM2_LOADAMODE;
437     #ifdef BSP_PWM2_IT_ENABLE
438         EPwm2Regs.ETSEL.bit.INTEN = 1;               /* Enable INT */
439         EPwm2Regs.ETSEL.bit.INTSEL = BSP_PWM2_INTSEL;
440         EPwm2Regs.ETPS.bit.INTPRD = BSP_PWM2_INTPRD;
441         /* Assigning ISR to PIE */
442         PieVectTable.EPWM2_INT = &EPWM2_Isr;
443         /* ENABLE Interrupt */
444     #else
445         EPwm2Regs.ETSEL.bit.INTEN = 0;               /* Disable INT */
446     #endif
447     #ifdef BSP_PWM2_ADC_TRIGGER
448         EPwm2Regs.ETSEL.bit.SOCAEN    = 1;        // Enable SOC on A group
449         EPwm2Regs.ETSEL.bit.SOCASEL  = BSP_PWM2_SOCASEL;        // Select SOC from zero
450         EPwm2Regs.ETPS.bit.SOCAPRD   = BSP_PWM2_SOCAPRD;        // Generate pulse on 1st event
451     #else
452         EPwm2Regs.ETSEL.bit.SOCAEN    = 0;        // Disable SOC on A group
453     #endif
454     #ifdef BSP_PWM2_MASTER
455         EPwm2Regs.TBCTL.bit.PHSEN = TB_DISABLE;        /* Disable phase loading */
456         EPwm2Regs.TBCTL.bit.SYNCOSEL = TB_CTR_ZERO;
457     #else
458         EPwm2Regs.TBCTL.bit.PHSEN = TB_ENABLE;        /* Disable phase loading */
459         EPwm2Regs.TBCTL.bit.SYNCOSEL = TB_SYNC_IN;
460     #endif
461 #endif
462 #ifdef BSP_USING_PWM3
463     GpioCtrlRegs.GPAPUD.all |= 5<<(3-1)*4;      /* Disable pull-up on (EPWM3A) */
464     GpioCtrlRegs.GPAMUX1.all|= 5<<(3-1)*4;      /* Configure as EPWM3A */
465     EPwm3Regs.TZCTL.bit.TZA = TZ_OFF;           /* diable A when trip zone */
466     EPwm3Regs.TZCTL.bit.TZB = TZ_OFF;           /* diable B when trip zone */
467     EPwm3Regs.TBCTL.bit.CTRMODE = BSP_PWM3_CTRMODE;
468     EPwm3Regs.TBCTL.bit.HSPCLKDIV = BSP_PWM3_HSPCLKDIV;       /* Clock ratio to SYSCLKOUT*/
469     EPwm3Regs.TBCTL.bit.CLKDIV = BSP_PWM3_CLKDIV;
470     EPwm3Regs.CMPCTL.bit.LOADAMODE = BSP_PWM3_LOADAMODE;
471     EPwm3Regs.CMPCTL.bit.LOADBMODE = BSP_PWM3_LOADAMODE;
472     #ifdef BSP_PWM3_IT_ENABLE
473         EPwm3Regs.ETSEL.bit.INTEN = 1;               /* Enable INT */
474         EPwm3Regs.ETSEL.bit.INTSEL = BSP_PWM3_INTSEL;
475         EPwm3Regs.ETPS.bit.INTPRD = BSP_PWM3_INTPRD;
476         /* Assigning ISR to PIE */
477         PieVectTable.EPWM3_INT = &EPWM3_Isr;
478         /* ENABLE Interrupt */
479     #else
480         EPwm3Regs.ETSEL.bit.INTEN = 0;               /* Disable INT */
481     #endif
482     #ifdef BSP_PWM3_ADC_TRIGGER
483         EPwm3Regs.ETSEL.bit.SOCAEN    = 1;        // Enable SOC on A group
484         EPwm3Regs.ETSEL.bit.SOCASEL  = BSP_PWM3_SOCASEL;        // Select SOC from zero
485         EPwm3Regs.ETPS.bit.SOCAPRD   = BSP_PWM3_SOCAPRD;        // Generate pulse on 1st event
486     #else
487         EPwm3Regs.ETSEL.bit.SOCAEN    = 0;        // Disable SOC on A group
488     #endif
489     #ifdef BSP_PWM3_MASTER
490         EPwm3Regs.TBCTL.bit.PHSEN = TB_DISABLE;        /* Disable phase loading */
491         EPwm3Regs.TBCTL.bit.SYNCOSEL = TB_CTR_ZERO;
492     #else
493         EPwm3Regs.TBCTL.bit.PHSEN = TB_ENABLE;        /* Disable phase loading */
494         EPwm3Regs.TBCTL.bit.SYNCOSEL = TB_SYNC_IN;
495     #endif
496 #endif
497 #ifdef BSP_USING_PWM4
498     GpioCtrlRegs.GPAPUD.all |= 5<<(4-1)*4;      /* Disable pull-up on (EPWM4A) */
499     GpioCtrlRegs.GPAMUX1.all|= 5<<(4-1)*4;      /* Configure as EPWM4A */
500     EPwm4Regs.TZCTL.bit.TZA = TZ_OFF;           /* diable A when trip zone */
501     EPwm4Regs.TZCTL.bit.TZB = TZ_OFF;           /* diable B when trip zone */
502     EPwm4Regs.TBCTL.bit.CTRMODE = BSP_PWM4_CTRMODE;
503     EPwm4Regs.TBCTL.bit.HSPCLKDIV = BSP_PWM4_HSPCLKDIV;       /* Clock ratio to SYSCLKOUT*/
504     EPwm4Regs.TBCTL.bit.CLKDIV = BSP_PWM4_CLKDIV;
505     EPwm4Regs.CMPCTL.bit.LOADAMODE = BSP_PWM4_LOADAMODE;
506     EPwm4Regs.CMPCTL.bit.LOADBMODE = BSP_PWM4_LOADAMODE;
507     #ifdef BSP_PWM4_IT_ENABLE
508         EPwm4Regs.ETSEL.bit.INTEN = 1;               /* Enable INT */
509         EPwm4Regs.ETSEL.bit.INTSEL = BSP_PWM4_INTSEL;
510         EPwm4Regs.ETPS.bit.INTPRD = BSP_PWM4_INTPRD;
511         /* Assigning ISR to PIE */
512         PieVectTable.EPWM4_INT = &EPWM4_Isr;
513         /* ENABLE Interrupt */
514     #else
515         EPwm4Regs.ETSEL.bit.INTEN = 0;               /* Disable INT */
516     #endif
517     #ifdef BSP_PWM4_ADC_TRIGGER
518         EPwm4Regs.ETSEL.bit.SOCAEN    = 1;        // Enable SOC on A group
519         EPwm4Regs.ETSEL.bit.SOCASEL  = BSP_PWM4_SOCASEL;        // Select SOC from zero
520         EPwm4Regs.ETPS.bit.SOCAPRD   = BSP_PWM4_SOCAPRD;        // Generate pulse on 1st event
521     #else
522         EPwm4Regs.ETSEL.bit.SOCAEN    = 0;        // Disable SOC on A group
523     #endif
524     #ifdef BSP_PWM4_MASTER
525         EPwm4Regs.TBCTL.bit.PHSEN = TB_DISABLE;        /* Disable phase loading */
526         EPwm4Regs.TBCTL.bit.SYNCOSEL = TB_CTR_ZERO;
527     #else
528         EPwm4Regs.TBCTL.bit.PHSEN = TB_ENABLE;        /* Disable phase loading */
529         EPwm4Regs.TBCTL.bit.SYNCOSEL = TB_SYNC_IN;
530     #endif
531 #endif
532     EDIS;
533 
534     return result;
535 }
536 
c28x_pwm_init(void)537 int c28x_pwm_init(void)
538 {
539     int i = 0;
540     int result = RT_EOK;
541 
542     for (i = 0; i < sizeof(c28x_pwm_obj) / sizeof(c28x_pwm_obj[0]); i++)
543     {
544         /* pwm init */
545         if (c28x_hw_pwm_init(&c28x_pwm_obj[i]) != RT_EOK)
546         {
547             LOG_E("%s init failed", c28x_pwm_obj[i].name);
548             result = -RT_ERROR;
549             return result;
550         }
551         else
552         {
553             LOG_D("%s init success", c28x_pwm_obj[i].name);
554 
555             /* register pwm device */
556             if (rt_device_pwm_register(&c28x_pwm_obj[i].pwm_device, c28x_pwm_obj[i].name, &rt_pwm_ops, &c28x_pwm_obj[i]) == RT_EOK)
557             {
558                 LOG_D("%s register success", c28x_pwm_obj[i].name);
559             }
560             else
561             {
562                 LOG_E("%s register failed", c28x_pwm_obj[i].name);
563                 result = -RT_ERROR;
564             }
565         }
566     }
567     struct rt_pwm_configuration config_tmp1 =
568     {
569        .channel = CHANNEL_A,
570        .period = BSP_PWM1_INIT_PERIOD,
571        .pulse = BSP_PWM1_INIT_PULSE,
572        .dead_time = BSP_PWM1_DB,
573        .phase = 0,
574        .complementary = RT_TRUE
575     };
576     drv_pwm_set(c28x_pwm_obj[0].pwm_regs,&config_tmp1);
577 //    config_tmp1.phase = BSP_PWM2_PHASE;
578 //    drv_pwm_set(c28x_pwm_obj[1].pwm_regs,&config_tmp1);
579 //    config_tmp1.phase = BSP_PWM3_PHASE;
580 //    drv_pwm_set(c28x_pwm_obj[2].pwm_regs,&config_tmp1);
581 //    config_tmp1.phase = BSP_PWM4_PHASE;
582 //    drv_pwm_set(c28x_pwm_obj[3].pwm_regs,&config_tmp1);
583     return result;
584 
585 }
586 INIT_DEVICE_EXPORT(c28x_pwm_init);
587 #endif /* BSP_USING_PWM */
588