Unable to use eCAP4 to eCAP6 on TMS320F28377S

10 views (last 30 days)
My Hardware / Software setup:
  1. MATLAB 2016b
  2. Launchpad 28377S (C2000)
I am trying to use the C2000 support package in MATLAB 2016b to call an interrupt on each of the six eCAPs.
I have set up 3 interrupts successfully using eCAP1 to eCAP3. As I input a signal using a function generator, the interrupt fires and does what is expected.
However, when I add a fourth eCAP (whether eCAP4, eCAP5, or eCAP6), I get a problem when I apply the same signal with a function generator to the GPIO assigned to these ECAPs. It causes my Simulink coder application's main loop to crash (the main app is toggling a GPIO to flicker an LED, and it quits flickering).
I am wondering if there are any known bugs with using the eCAP4, eCAP5, or eCAP6 blocks on the TMS320F28377S processor.
My Hardware Interrupt setup follows:
CPU Interrupt Numbers: [3 4 4 4 4 4 4]
PIE Interrupt Numbers: [2 1 2 3 4 5 6]
Simulink Task Priorities: [25 10 11 12 13 14 15]
Preemption Flags: [0 0 0 0 0 0 0]
My eCAP settings follow:
void init_CAP_GPIO()
9 {
10 EALLOW;
11 InputXbarRegs.INPUT7SELECT = 10; /* Set eCAP1 source to GPIO10 */
12 InputXbarRegs.INPUT8SELECT = 11; /* Set eCAP2 source to GPIO11 */
13 InputXbarRegs.INPUT9SELECT = 18; /* Set eCAP3 source to GPIO18 */
14 InputXbarRegs.INPUT10SELECT = 19; /* Set eCAP4 source to GPIO19 */
15 EDIS;
16 }
17
18 void init_CAP1()
19 {
20 EALLOW;
21 CpuSysRegs.PCLKCR3.bit.ECAP1 = 1;
22 EDIS;
23 ECap1Regs.ECEINT.all = 0x0000; /* Disable all capture interrupts*/
24 ECap1Regs.ECCLR.all = 0xFFFF; /* Clear all CAP interrupt flags*/
25 ECap1Regs.ECCTL1.bit.CAPLDEN = 0; /* Disable CAP1-CAP4 register loads*/
26 ECap1Regs.ECCTL2.bit.TSCTRSTOP = 0; /* Make sure the counter is stopped*/
27 ECap1Regs.CTRPHS = 0U; /* Counter Phase Control*/
28 ECap1Regs.ECCTL2.bit.SYNCO_SEL = 1; /* Select CTR=PRD event */
29 ECap1Regs.ECCTL2.bit.CAP_APWM = 0; /* Capture mode*/
30 ECap1Regs.ECCTL2.bit.CONT_ONESHT = 0;/* One-shot*/
31 ECap1Regs.ECCTL1.bit.PRESCALE = 0U; /*Event prescaler*/
32 ECap1Regs.ECCTL2.bit.STOP_WRAP = 1; /* Stop at 4 events*/
33 ECap1Regs.ECCTL1.bit.CAP1POL = 0; /* Select rising or falling edge*/
34 ECap1Regs.ECCTL1.bit.CTRRST1 = 0; /* Difference operation */
35 ECap1Regs.ECCTL1.bit.CAP2POL = 0; /* Select rising or falling edge*/
36 ECap1Regs.ECCTL1.bit.CTRRST2 = 0; /* Difference operation */
37 ECap1Regs.ECEINT.bit.CEVT1 = 1;
38 ECap1Regs.ECEINT.bit.CEVT2 = 1;
39 ECap1Regs.ECCLR.all = 0x0FF; /* Clear pending interrupts*/
40 ECap1Regs.ECCTL2.bit.REARM = 1; /* arm one-shot*/
41 ECap1Regs.ECCTL2.bit.TSCTRSTOP = 1; /* Start Counter*/
42 ECap1Regs.ECCTL1.bit.CAPLDEN = 1; /* Enable CAP1-CAP4 register loads*/
43 }
44
45 void init_CAP2()
46 {
47 EALLOW;
48 CpuSysRegs.PCLKCR3.bit.ECAP2 = 1;
49 EDIS;
50 ECap2Regs.ECEINT.all = 0x0000; /* Disable all capture interrupts*/
51 ECap2Regs.ECCLR.all = 0xFFFF; /* Clear all CAP interrupt flags*/
52 ECap2Regs.ECCTL1.bit.CAPLDEN = 0; /* Disable CAP1-CAP4 register loads*/
53 ECap2Regs.ECCTL2.bit.TSCTRSTOP = 0; /* Make sure the counter is stopped*/
54 ECap2Regs.CTRPHS = 0U; /* Counter Phase Control*/
55 ECap2Regs.ECCTL2.bit.SYNCO_SEL = 1; /* Select CTR=PRD event */
56 ECap2Regs.ECCTL2.bit.CAP_APWM = 0; /* Capture mode*/
57 ECap2Regs.ECCTL2.bit.CONT_ONESHT = 0;/* One-shot*/
58 ECap2Regs.ECCTL1.bit.PRESCALE = 0U; /*Event prescaler*/
59 ECap2Regs.ECCTL2.bit.STOP_WRAP = 1; /* Stop at 4 events*/
60 ECap2Regs.ECCTL1.bit.CAP1POL = 0; /* Select rising or falling edge*/
61 ECap2Regs.ECCTL1.bit.CTRRST1 = 0; /* Difference operation */
62 ECap2Regs.ECCTL1.bit.CAP2POL = 0; /* Select rising or falling edge*/
63 ECap2Regs.ECCTL1.bit.CTRRST2 = 0; /* Difference operation */
64 ECap2Regs.ECEINT.bit.CEVT1 = 1;
65 ECap2Regs.ECEINT.bit.CEVT2 = 1;
66 ECap2Regs.ECCLR.all = 0x0FF; /* Clear pending interrupts*/
67 ECap2Regs.ECCTL2.bit.REARM = 1; /* arm one-shot*/
68 ECap2Regs.ECCTL2.bit.TSCTRSTOP = 1; /* Start Counter*/
69 ECap2Regs.ECCTL1.bit.CAPLDEN = 1; /* Enable CAP1-CAP4 register loads*/
70 }
71
72 void init_CAP3()
73 {
74 EALLOW;
75 CpuSysRegs.PCLKCR3.bit.ECAP3 = 1;
76 EDIS;
77 ECap3Regs.ECEINT.all = 0x0000; /* Disable all capture interrupts*/
78 ECap3Regs.ECCLR.all = 0xFFFF; /* Clear all CAP interrupt flags*/
79 ECap3Regs.ECCTL1.bit.CAPLDEN = 0; /* Disable CAP1-CAP4 register loads*/
80 ECap3Regs.ECCTL2.bit.TSCTRSTOP = 0; /* Make sure the counter is stopped*/
81 ECap3Regs.CTRPHS = 0U; /* Counter Phase Control*/
82 ECap3Regs.ECCTL2.bit.SYNCO_SEL = 1; /* Select CTR=PRD event */
83 ECap3Regs.ECCTL2.bit.CAP_APWM = 0; /* Capture mode*/
84 ECap3Regs.ECCTL2.bit.CONT_ONESHT = 0;/* One-shot*/
85 ECap3Regs.ECCTL1.bit.PRESCALE = 0U; /*Event prescaler*/
86 ECap3Regs.ECCTL2.bit.STOP_WRAP = 1; /* Stop at 4 events*/
87 ECap3Regs.ECCTL1.bit.CAP1POL = 0; /* Select rising or falling edge*/
88 ECap3Regs.ECCTL1.bit.CTRRST1 = 0; /* Difference operation */
89 ECap3Regs.ECCTL1.bit.CAP2POL = 0; /* Select rising or falling edge*/
90 ECap3Regs.ECCTL1.bit.CTRRST2 = 0; /* Difference operation */
91 ECap3Regs.ECEINT.bit.CEVT1 = 1;
92 ECap3Regs.ECEINT.bit.CEVT2 = 1;
93 ECap3Regs.ECCLR.all = 0x0FF; /* Clear pending interrupts*/
94 ECap3Regs.ECCTL2.bit.REARM = 1; /* arm one-shot*/
95 ECap3Regs.ECCTL2.bit.TSCTRSTOP = 1; /* Start Counter*/
96 ECap3Regs.ECCTL1.bit.CAPLDEN = 1; /* Enable CAP1-CAP4 register loads*/
97 }
98
99 void init_CAP4()
100 {
101 EALLOW;
102 CpuSysRegs.PCLKCR3.bit.ECAP4 = 1;
103 EDIS;
104 ECap4Regs.ECEINT.all = 0x0000; /* Disable all capture interrupts*/
105 ECap4Regs.ECCLR.all = 0xFFFF; /* Clear all CAP interrupt flags*/
106 ECap4Regs.ECCTL1.bit.CAPLDEN = 0; /* Disable CAP1-CAP4 register loads*/
107 ECap4Regs.ECCTL2.bit.TSCTRSTOP = 0; /* Make sure the counter is stopped*/
108 ECap4Regs.CTRPHS = 0U; /* Counter Phase Control*/
109 ECap4Regs.ECCTL2.bit.SYNCO_SEL = 1; /* Select CTR=PRD event */
110 ECap4Regs.ECCTL2.bit.CAP_APWM = 0; /* Capture mode*/
111 ECap4Regs.ECCTL2.bit.CONT_ONESHT = 0;/* One-shot*/
112 ECap4Regs.ECCTL1.bit.PRESCALE = 0U; /*Event prescaler*/
113 ECap4Regs.ECCTL2.bit.STOP_WRAP = 1; /* Stop at 4 events*/
114 ECap4Regs.ECCTL1.bit.CAP1POL = 0; /* Select rising or falling edge*/
115 ECap4Regs.ECCTL1.bit.CTRRST1 = 0; /* Difference operation */
116 ECap4Regs.ECCTL1.bit.CAP2POL = 0; /* Select rising or falling edge*/
117 ECap4Regs.ECCTL1.bit.CTRRST2 = 0; /* Difference operation */
118 ECap4Regs.ECEINT.bit.CEVT1 = 1;
119 ECap4Regs.ECEINT.bit.CEVT2 = 1;
120 ECap4Regs.ECCLR.all = 0x0FF; /* Clear pending interrupts*/
121 ECap4Regs.ECCTL2.bit.REARM = 1; /* arm one-shot*/
122 ECap4Regs.ECCTL2.bit.TSCTRSTOP = 1; /* Start Counter*/
123 ECap4Regs.ECCTL1.bit.CAPLDEN = 1; /* Enable CAP1-CAP4 register loads*/
124 }
125

Answers (3)

DKalale
DKalale on 11 Oct 2016
So this was a tough one to find, but I think I found the problem. I noticed that in the MW_c28xx_csl.c file that there was some discrepancy between the ECAP1 - ECAP3 isr's versus the ECAP4 - ECAP6 isr's. See the following code snippet below that was NOT working:
25 interrupt void ECAP1_INT_isr(void)
26 {
27 isr_int4pie1_task_fcn();
28 PieCtrlRegs.PIEACK.all = PIEACK_GROUP4;/* Acknowledge to receive more interrupts*/
29 ECap1Regs.ECCLR.all = ECap1Regs.ECFLG.all;
30 }
31
32 interrupt void ECAP2_INT_isr(void)
33 {
34 isr_int4pie2_task_fcn();
35 PieCtrlRegs.PIEACK.all = PIEACK_GROUP4;/* Acknowledge to receive more interrupts*/
36 ECap2Regs.ECCLR.all = ECap2Regs.ECFLG.all;
37 }
38
39 interrupt void ECAP3_INT_isr(void)
40 {
41 isr_int4pie3_task_fcn();
42 PieCtrlRegs.PIEACK.all = PIEACK_GROUP4;/* Acknowledge to receive more interrupts*/
43 ECap3Regs.ECCLR.all = ECap3Regs.ECFLG.all;
44 }
45
46 interrupt void ECAP4_INT_isr(void)
47 {
48 isr_int4pie4_task_fcn();
49 EALLOW;
50 ECap4Regs.ECCLR.bit.INT = 1;
51 EDIS;
52 PieCtrlRegs.PIEACK.all = PIEACK_GROUP4;/* Acknowledge to receive more interrupts*/
53 }
54
55 interrupt void ECAP5_INT_isr(void)
56 {
57 isr_int4pie5_task_fcn();
58 EALLOW;
59 ECap5Regs.ECCLR.bit.INT = 1;
60 EDIS;
61 PieCtrlRegs.PIEACK.all = PIEACK_GROUP4;/* Acknowledge to receive more interrupts*/
62 }
63
64 interrupt void ECAP6_INT_isr(void)
65 {
66 isr_int4pie6_task_fcn();
67 EALLOW;
68 ECap6Regs.ECCLR.bit.INT = 1;
69 EDIS;
70 PieCtrlRegs.PIEACK.all = PIEACK_GROUP4;/* Acknowledge to receive more interrupts*/
71 }
Note that ECAP4 to ECAP6 are different than ECAP1 to ECAP3... It appears that not all of the ECap#Regs.ECCLR register was cleared during the isr for ECAP4 to ECAP6. This confirms why the main loop of my program was hanging. There was an interrupt that was continually triggering (actually there were 3)!
I edited the ti_c2837xS_interrupts.tlc file to fix this code generation... here are my edits
OLD:
238 !(intnum==4 && (pienum==1 || pienum==2 || pienum==3)) && /% Don't clear for eCAP %/ \
305 %%Clear eCAP flag when use INT 4.1 to 4.3
306 %if intnum==4 && (pienum>=1 && pienum<=3)
NEW:
238 !(intnum==4 && (pienum==1 || pienum==2 || pienum==3 || pienum==4 || pienum==5 || pienum==6)) && /% Don't clear for eCAP %/ \
305 %%Clear eCAP flag when use INT 4.1 to 4.6
306 %if intnum==4 && (pienum>=1 && pienum<=6)
This ends up generating the correct MW_c28xx_csl.c file as seen below:
25 interrupt void ECAP1_INT_isr(void)
26 {
27 isr_int4pie1_task_fcn();
28 PieCtrlRegs.PIEACK.all = PIEACK_GROUP4;/* Acknowledge to receive more interrupts*/
29 ECap1Regs.ECCLR.all = ECap1Regs.ECFLG.all;
30 }
31
32 interrupt void ECAP2_INT_isr(void)
33 {
34 isr_int4pie2_task_fcn();
35 PieCtrlRegs.PIEACK.all = PIEACK_GROUP4;/* Acknowledge to receive more interrupts*/
36 ECap2Regs.ECCLR.all = ECap2Regs.ECFLG.all;
37 }
38
39 interrupt void ECAP3_INT_isr(void)
40 {
41 isr_int4pie3_task_fcn();
42 PieCtrlRegs.PIEACK.all = PIEACK_GROUP4;/* Acknowledge to receive more interrupts*/
43 ECap3Regs.ECCLR.all = ECap3Regs.ECFLG.all;
44 }
45
46 interrupt void ECAP4_INT_isr(void)
47 {
48 isr_int4pie4_task_fcn();
49 PieCtrlRegs.PIEACK.all = PIEACK_GROUP4;/* Acknowledge to receive more interrupts*/
50 ECap4Regs.ECCLR.all = ECap4Regs.ECFLG.all;
51 }
52
53 interrupt void ECAP5_INT_isr(void)
54 {
55 isr_int4pie5_task_fcn();
56 PieCtrlRegs.PIEACK.all = PIEACK_GROUP4;/* Acknowledge to receive more interrupts*/
57 ECap5Regs.ECCLR.all = ECap5Regs.ECFLG.all;
58 }
59
60 interrupt void ECAP6_INT_isr(void)
61 {
62 isr_int4pie6_task_fcn();
63 PieCtrlRegs.PIEACK.all = PIEACK_GROUP4;/* Acknowledge to receive more interrupts*/
64 ECap6Regs.ECCLR.all = ECap6Regs.ECFLG.all;
65 }
I have deployed this to hardware and have confirmed that this solved my problem.

Brian McKay
Brian McKay on 11 Oct 2016
Hi,
Thanks for digging into this. I forwarded your post to the development team for their assessment - but I suspect you have found a bug and fixed it.
-Brian
  1 Comment
DKalale
DKalale on 11 Oct 2016
Hi Brian,
Now that I have had to edit the TLC file, do you know if there is a way to reference my "own" set of TLC files? ...instead of the default set in
C:\ProgramData\MATLAB\SupportPackages\R2016b\toolbox\target\supportpackages\tic2000\tlc_c
This is similar to how I can reference my own Control Suite Directory when I go through the "targetupdater" setup. I can just overwrite the TLCs on my machine, but it makes it very difficult for someone else to reproduce my code.

Sign in to comment.


Aditya Padmanabha
Aditya Padmanabha on 20 Feb 2017
Hi,
Thanks for pointing out the issue. This issue has been fixed and updated in the latest support package release.
-Aditya

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!