drv_pwm.c 18 KB

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