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