This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

CCS/TMS320F28335: context saved when enter interrupt,disassembly code

Part Number: TMS320F28335


Tool/software: Code Composer Studio

Hello all,

     I am debugging my code in the tms320f28335 platform, in my code, there are 8 tasks, their execting periods are 62.5us,125us,250us,625us,1ms,10ms,330ms and 1second respectively.The 62.5us task priority is highest and 1second task priorty is lowest.

    In my code, I declare 8 Uint32 variables(counts) for every task, when one task is executed,the  respective variable(count) will be add one.After some minutes or hours, these varibles(counts) are not correct. The times of some tasks exetuted are larger than they should be executed. The attached is the data that I calaculed and sampled,count3 she be 31209,but MCU run this task 31211 times.

I study assembly code and find some CPU registers (such as DP) are not pushed into stack when enter interrupt. Can I configure CCS to push all of cpu register into stack when enter interrupt.The following is part of my code.

interrupt void epwm_timer_isr(void)
{
mainCnt++;
EPwm1Regs.ETCLR.bit.INT = 1;
#if(1 == _SAMPLE_)
EPwm2Regs.ETCLR.bit.INT = 1;
#endif
//Acknowledge this interrupt to receive more interrupts from group 3
IER |= M_INT3;
PieCtrlRegs.PIEACK.all |= PIEACK_GROUP3;
rtTaskTimerUpdate();
EINT;
//62.5us task
scheduleRt();
}

disassembly code

epwm_timer_isr():
008d3d: 761B ASP
008d3e: FFF0 PUSH RB
008d3f: 0005 PUSH AR1H:AR0H
008d40: ABBD MOVL *SP++, XT
008d41: A8BD MOVL *SP++, XAR4
008d42: A0BD MOVL *SP++, XAR5
008d43: C2BD MOVL *SP++, XAR6
008d44: C3BD MOVL *SP++, XAR7
008d45: E20000BD MOV32 *SP++, STF
008d47: E20300BD MOV32 *SP++, R0H
008d49: E20301BD MOV32 *SP++, R1H
008d4b: E20302BD MOV32 *SP++, R2H
008d4d: E20303BD MOV32 *SP++, R3H
008d4f: E6300600 SETFLG RNDF32=1,RNDF64=1
008d51: FF69 SPM #0
008d52: 2942 CLRC OVM|PAGE0
008d53: 5616 CLRC AMODE
202 mainCnt++;
008d54: 0201 MOVB ACC, #1
008d55: 761F0320 MOVW DP, #0x320
008d57: 56010020 ADDL @0x20, ACC

void scheduleRt(void)
{
////////////125us task////////////
if(rtTaskTimer[0].flag)
{
DINT;
rtTaskTimer[0].flag = 0;
if(taskStatus.task0Busy)
{
taskStatus.task0Reen = 1;
}
else
{
taskStatus.task0Busy = 1;
}
EINT;
{
spdCount++;

//task1

}
DINT;
taskStatus.task0Busy = 0;
EINT;
}
//////////250us task//////////
if(rtTaskTimer[1].flag)
{
if(taskStatus.task0Busy)
{
return;
}
DINT;
rtTaskTimer[1].flag = 0;
if(taskStatus.task1Busy)
{
taskStatus.task1Reen = 1;
}
else
{
taskStatus.task1Busy = 1;
}
EINT;
{
posCount++;

//task2

}
DINT;
taskStatus.task1Busy = 0;
EINT;
}
//////////////////625us task///////////////////
if(rtTaskTimer[2].flag)
{
if(taskStatus.task1Busy)
{
return;
}
DINT;
rtTaskTimer[2].flag = 0;
if(taskStatus.task2Busy)
{
taskStatus.task2Reen = 1;
}
else
{
taskStatus.task2Busy = 1;
}
EINT;
{
count0++;

//task3

}
DINT;
taskStatus.task2Busy = 0;
EINT;
}
/////////////////////1ms task/////////////////////
if(rtTaskTimer[3].flag)
{
if(taskStatus.task2Busy)
{
return;
}
DINT;
rtTaskTimer[3].flag = 0;
if(taskStatus.task3Busy)
{
taskStatus.task3Reen = 1;
}
else
{
taskStatus.task3Busy = 1;
}
EINT;
{
count1++;

//task4

}
DINT;
taskStatus.task3Busy = 0;
EINT;
}
//////////////////10mstask//////////////////////
if(rtTaskTimer[4].flag)
{
if(taskStatus.task3Busy)
{
return;
}
DINT;
rtTaskTimer[4].flag = 0;
if(taskStatus.task4Busy)
{
taskStatus.task4Reen = 1;
}
else
{
taskStatus.task4Busy = 1;
}
EINT;
{
count2++;

//task5
}
DINT;
taskStatus.task4Busy = 0;
EINT;
}
//////////////////330msask///////////////////
if(rtTaskTimer[5].flag)
{
if(taskStatus.task4Busy)
{
return;
}
DINT;
rtTaskTimer[5].flag = 0;
if(taskStatus.task5Busy)
{
taskStatus.task5Reen = 1;
}
else
{
taskStatus.task5Busy = 1;
}
EINT;
{
count3++;

//task6
}
DINT;
taskStatus.task5Busy = 0;
EINT;
}
/////////////////1stask //////////////////
if(rtTaskTimer[6].flag)
{
if(taskStatus.task5Busy)
{
return;
}
DINT;
rtTaskTimer[6].flag = 0;
if(taskStatus.task6Busy)
{
taskStatus.task6Reen = 1;
}
else
{
taskStatus.task6Busy = 1;
}
EINT;
{

count4++;

//task7

}
DINT;
taskStatus.task6Busy = 0;
EINT;
}
}

part of disassembly code

scheduleRt():
30512f: FE04 ADDB SP, #4
39 if(rtTaskTimer[0].flag)
305130: 761F0321 MOVW DP, #0x321
305132: 9218 MOV AL, @0x18
305133: 6140 SB C$L5, EQ
41 DINT;
305134: 3B10 SETC INTM
42 rtTaskTimer[0].flag = 0;
305135: 2B18 MOV @0x18, #0
43 if(taskStatus.task0Busy)
305136: 761F031A MOVW DP, #0x31a
305138: 9232 MOV AL, @0x32
305139: 6104 SB C$L1, EQ
45 taskStatus.task0Reen = 1;
30513a: 56BF0139 MOVB @0x39, #0x01, UNC
46 }
30513c: 6F03 SB C$L2, UNC
49 taskStatus.task0Busy = 1;
C$L1:
30513d: 56BF0132 MOVB @0x32, #0x01, UNC
51 EINT;
C$L2:
30513f: 2910 CLRC INTM
53 spdCount++;
305140: 0201 MOVB ACC, #1
305141: 5601002E ADDL @0x2e, ACC
54 DTS2 = 1;
305143: 761F01BF MOVW DP, #0x1bf
305145: 1A010008 OR @0x1, #0x0008
55 mtDrvSpdTrqCtrl();
305147: FF69 SPM #0
305148: 76703CEF LCR mtDrvSpdTrqCtrl
56 spdFbkRpm = _IQmpy(speed1.Speed,SPDBASERPM);
30514a: 761F0319 MOVW DP, #0x319
30514c: 8F002EE0 MOVL XAR4, #0x002ee0
30514e: 872E MOVL XT, @0x2e
30514f: 761F0314 MOVW DP, #0x314
305151: 566300A4 QMPYL ACC, XT, @XAR4
305153: 560500A4 IMPYL P, XT, @XAR4
305155: 56A7 LSL64 ACC:P, 8
305156: 9602 MOV @0x2, AL
57 if((spdFbkRpm < rangZeroSpd)&&(spdFbkRpm > -rangZeroSpd))
305157: 761F0317 MOVW DP, #0x317
305159: 9224 MOV AL, @0x24
30515a: 761F0314 MOVW DP, #0x314
30515c: 5402 CMP AL, @0x2
30515d: 6509 SB C$L3, LEQ
30515e: FF5C NEG AL
30515f: 5402 CMP AL, @0x2
305160: 6306 SB C$L3, GEQ
59 sysStatus.bits.zeroSpd = 1;
305161: 761F0313 MOVW DP, #0x313
305163: 1A220020 OR @0x22, #0x0020
60 }
305165: 6F05 SB C$L4, UNC
63 sysStatus.bits.zeroSpd = 0;
C$L3:
305166: 761F0313 MOVW DP, #0x313
305168: 1822FFDF AND @0x22, #0xffdf
65 DTS2 = 0;
C$L4:
30516a: 761F01BF MOVW DP, #0x1bf
30516c: 1801FFF7 AND @0x1, #0xfff7
67 DINT;
30516e: 3B10 SETC INTM
68 taskStatus.task0Busy = 0;
30516f: 761F031A MOVW DP, #0x31a
305171: 2B32 MOV @0x32, #0
69 EINT;
305172: 2910 CLRC INTM
72 if(rtTaskTimer[1].flag)
C$L5:
305173: 761F0321 MOVW DP, #0x321
305175: 921B MOV AL, @0x1b
305176: FFE100A4 B C$L15, EQ
74 if(taskStatus.task0Busy)
305178: 761F031A MOVW DP, #0x31a
30517a: 9232 MOV AL, @0x32
30517b: FFE003F9 B C$L57, NEQ
78 DINT;
30517d: 3B10 SETC INTM
79 rtTaskTimer[1].flag = 0;
30517e: 761F0321 MOVW DP, #0x321
305180: 2B1B MOV @0x1b, #0
80 if(taskStatus.task1Busy)
305181: 761F031A MOVW DP, #0x31a
305183: 9233 MOV AL, @0x33
305184: 6104 SB C$L6, EQ
82 taskStatus.task1Reen = 1;
305185: 56BF013A MOVB @0x3a, #0x01, UNC
83 }
305187: 6F03 SB C$L7, UNC
86 taskStatus.task1Busy = 1;
C$L6:
305188: 56BF0133 MOVB @0x33, #0x01, UNC
88 EINT;
C$L7:
30518a: 2910 CLRC INTM
90 posCount++;
30518b: 0201 MOVB ACC, #1
30518c: 5601002A ADDL @0x2a, ACC
91 DTS1 = 1;
30518e: 761F01BF MOVW DP, #0x1bf
305190: 1A010004 OR @0x1, #0x0004
92 if(600 != udcMan)
305192: 8F000258 MOVL XAR4, #0x000258
305194: 761F0314 MOVW DP, #0x314
305196: 0E05 MOVU ACC, @0x5
305197: 0FA4 CMPL ACC, @XAR4
305198: 6110 SB C$L8, EQ

  • On C2000 there is minimal a hardware context save which takes place on each interrupt (see attachment).  Certain registers are pushed onto the stack automatically, including the data page pointer DP.  The compiler will push additional registers to the stack if it uses them in the ISR.

    I do not know how this influences the timing of your tasks, but I see you are disabling the global interrupt mask at times.  Possibly interrupts are occasionally being missed?

    Regards,

    Richard

    interrupt context save.pdf

  •   Hello Richard,

       Thanks for your reply!

      In my project of motor control, I write a scheduler to run the 8 tasks. The frequency of some tasks executed are

    more than I expected.For example, in one second, task 4 should be executed 1000 times, but it be executed more than

    1000 times, sometimes it is 1003 times,sometimes it is 1005 times, the executed times is not  constant, but I am

    sure it is larger than 1000.

     In my code, I disabling the global interrupt mask at times because of the critical code, and when these critical

    code are executed,I enabled he global interrupt mask at once.These doesn,t influence on the frequency of task

    executed.

     Dear Richard, I have spent a lot of time on this issue,but I can not find the bug,please help me.I guess there is

    something wrong with the compiler.If you need the project code,I can send you by email.

     Today, I do some test,the test results are as following,

    When task 3 is entered, a gpio(channel 2) is set, and when task 3 is finished(is executed completely),the gpio(channel 2) is drived low, task 3's period is 1ms.From the first attchment,we can see task 3 is executed twice,and the blank time is 600ns,It should be 1ms just as the second attachment.

    Please take some time to review my code,Thanks!

    Best regards,

    Victor

  • Victor,

    Some questions:

     - what is channel 1 in the two oscilloscope plots you sent?

     - what is triggering task 3?  Do you have a hardware timer set up and if so, which one?

    Regards,

    Richard

  • Dear Richard,

    - what is channel 1 in the two oscilloscope plots you sent?

    I show task 3 code as follows,

    if(rtTaskTimer[3].flag)

    {

    DTS1 = 1;
    if(taskBusyStatus.word&0x0007)
    {
           return;
    }
    DINT;
    rtTaskTimer[3].flag = 0;
    if(taskBusyStatus.bit.task3Busy)
    {
           taskReenStatus.bit.task3Reen = 1;
    }
    else
    {
           taskBusyStatus.bit.task3Busy = 1;
    }
    EINT;
    DTS2 = 1;
    count1++;
    //task 3......
    //............
    //............
    DTS2 = 0;
    DINT;
    taskBusyStatus.bit.task3Busy = 0;
    EINT;
    DTS1 = 0;

    }



    channel one is sent by gpio DTS1 and channel 2 is sent by gpio DTS2.From above two pictures,Plots on first picture

    are wrong and it occurs occasionally.Plots on second picture are right.

    rtTaskTimer[3].flag is set in the task 0(its priority is highest) and cleared in task 3
    taskBusyStatus.word&0x0007 is for detecting Whether there are higher priority tasks


    - what is triggering task 3? Do you have a hardware timer set up and if so, which one?

    There is a task(its priority is highest and its executed period is 62.5us) is triggered by hardware timer.
    In fact,there are two interrupt sources for the task,EPwm1 is ET_CTR_ZERO interrupt and EPwm2 is ET_CTR_PRD interrupt,their periods are both 125us.So the task is executed on every 62.5us. 

    The configuration is as follow,
    EALLOW; // This is needed to write to EALLOW protected registers
    PieVectTable.EPWM1_INT = &epwm_timer_isr;
    PieVectTable.EPWM2_INT = &epwm_timer_isr;
    EDIS;

    void F281X_EV1_PWM_Init(PWMGEN *p)
    {
    // Enable TZ1 as one shot trip sources
    EALLOW;
    EPwm1Regs.TZSEL.bit.OSHT3 = 1;
    EPwm2Regs.TZSEL.bit.OSHT3 = 1;
    EPwm3Regs.TZSEL.bit.OSHT3 = 1;
    EPwm4Regs.TZSEL.bit.OSHT3 = 1;
    // What do we want the TZ1 to do?
    EPwm1Regs.TZCTL.bit.TZA = TZ_HIZ;
    EPwm1Regs.TZCTL.bit.TZB = TZ_HIZ;
    EPwm2Regs.TZCTL.bit.TZA = TZ_HIZ;
    EPwm2Regs.TZCTL.bit.TZB = TZ_HIZ;
    EPwm3Regs.TZCTL.bit.TZA = TZ_HIZ;
    EPwm3Regs.TZCTL.bit.TZB = TZ_HIZ;
    EPwm4Regs.TZCTL.bit.TZA = TZ_NO_CHANGE;
    EPwm4Regs.TZCTL.bit.TZB = TZ_NO_CHANGE;
    // Enable TZ interrupt
    EPwm4Regs.TZEINT.bit.OST = 1;
    SysCtrlRegs.PCLKCR0.bit.TBCLKSYNC = 0; // Stop all the TB clocks
    EDIS;
    //=====================================================================
    // Initialization Time
    //========================// EPWM Module 1 config
    EPwm1Regs.TBPRD = p->PeriodMax; // Period = 1600 TBCLK counts
    EPwm1Regs.TBPHS.half.TBPHS = 0; // Set Phase register to zero
    EPwm1Regs.TBCTL.bit.CTRMODE = TB_COUNT_UPDOWN; // Symmetrical mode
    EPwm1Regs.TBCTL.bit.HSPCLKDIV = 0; // /1
    EPwm1Regs.TBCTL.bit.PHSEN = TB_DISABLE; // Master module
    EPwm1Regs.TBCTL.bit.PRDLD = TB_SHADOW;
    EPwm1Regs.TBCTL.bit.SYNCOSEL = TB_CTR_ZERO; // Sync down-stream module
    EPwm1Regs.CMPCTL.bit.SHDWAMODE = CC_SHADOW;
    EPwm1Regs.CMPCTL.bit.SHDWBMODE = CC_SHADOW;
    EPwm1Regs.CMPCTL.bit.LOADAMODE = CC_CTR_ZERO_PRD; // load on CTR=Zero/Period
    EPwm1Regs.CMPCTL.bit.LOADBMODE = CC_CTR_ZERO_PRD; // load on CTR=Zero/Period
    EPwm1Regs.AQCTLA.bit.CAU = AQ_CLEAR; // set actions for EPWM1A
    EPwm1Regs.AQCTLA.bit.CAD = AQ_SET;
    EPwm1Regs.DBCTL.bit.OUT_MODE = DB_FULL_ENABLE; // enable Dead-band module
    EPwm1Regs.DBCTL.bit.POLSEL = DB_ACTV_HIC; // Active Hi complementary
    EPwm1Regs.DBFED = DBTIME;//350; 4.8us // FED = 50 TBCLKs
    EPwm1Regs.DBRED = DBTIME;//350; 4.8us // RED = 50 TBCLKs
    //EPWM Module 2 configuration
    EPwm2Regs.TBPRD = p->PeriodMax; // Period = 1600 TBCLK counts
    EPwm2Regs.TBPHS.half.TBPHS = 0; // Set Phase register to zero
    EPwm2Regs.TBCTL.bit.CTRMODE = TB_COUNT_UPDOWN; // Symmetrical mode
    EPwm2Regs.TBCTL.bit.HSPCLKDIV = 0; // /1
    EPwm2Regs.TBCTL.bit.PHSEN = TB_ENABLE; // Slave module
    EPwm2Regs.TBCTL.bit.PRDLD = TB_SHADOW;
    EPwm2Regs.TBCTL.bit.SYNCOSEL = TB_SYNC_IN; // sync flow-through
    EPwm2Regs.CMPCTL.bit.SHDWAMODE = CC_SHADOW;
    EPwm2Regs.CMPCTL.bit.SHDWBMODE = CC_SHADOW;
    EPwm2Regs.CMPCTL.bit.LOADAMODE = CC_CTR_ZERO_PRD; // load on CTR=Zero/Period
    EPwm2Regs.CMPCTL.bit.LOADBMODE = CC_CTR_ZERO_PRD; // load on CTR=Zero/Period
    EPwm2Regs.AQCTLA.bit.CAU = AQ_CLEAR; // set actions for EPWM2A
    EPwm2Regs.AQCTLA.bit.CAD = AQ_SET;
    EPwm2Regs.DBCTL.bit.OUT_MODE = DB_FULL_ENABLE; // enable Dead-band module
    EPwm2Regs.DBCTL.bit.POLSEL = DB_ACTV_HIC; // Active Hi complementary
    EPwm2Regs.DBFED = DBTIME;//350; //4.8us // FED = 50 TBCLKs
    EPwm2Regs.DBRED = DBTIME;//350; //4.8us // RED = 50 TBCLKs
    //EPWM Module 3 configuration
    EPwm3Regs.TBPRD = p->PeriodMax; // Period = 1600 TBCLK counts
    EPwm3Regs.TBPHS.half.TBPHS = 0; // Set Phase register to zero
    EPwm3Regs.TBCTL.bit.CTRMODE = TB_COUNT_UPDOWN; // Symmetrical mode
    EPwm3Regs.TBCTL.bit.HSPCLKDIV = 0; // /1
    EPwm3Regs.TBCTL.bit.PHSEN = TB_ENABLE; // Slave module
    EPwm3Regs.TBCTL.bit.PRDLD = TB_SHADOW;
    EPwm3Regs.TBCTL.bit.SYNCOSEL = TB_SYNC_IN; // sync flow-through
    EPwm3Regs.CMPCTL.bit.SHDWAMODE = CC_SHADOW;
    EPwm3Regs.CMPCTL.bit.SHDWBMODE = CC_SHADOW;
    EPwm3Regs.CMPCTL.bit.LOADAMODE = CC_CTR_ZERO_PRD; // load on CTR=Zero/Period
    EPwm3Regs.CMPCTL.bit.LOADBMODE = CC_CTR_ZERO_PRD; // load on CTR=Zero/Period
    EPwm3Regs.AQCTLA.bit.CAU = AQ_CLEAR; // set actions for EPWM3A
    EPwm3Regs.AQCTLA.bit.CAD = AQ_SET;
    EPwm3Regs.DBCTL.bit.OUT_MODE = DB_FULL_ENABLE; // enable Dead-band module
    EPwm3Regs.DBCTL.bit.POLSEL = DB_ACTV_HIC; // Active Hi complementary
    EPwm3Regs.DBFED = DBTIME; //4.8us // 2.4us

    //FED = 50 TBCLKs
    EPwm3Regs.DBRED = DBTIME; //350;

    //4.8us // 2.4us RED = 50 TBCLKs
    //Run Time (Note: Example execution of one run-time instant)
    EPwm1Regs.ETSEL.bit.INTSEL = ET_CTR_ZERO; // Select INT on Zero event
    EPwm1Regs.ETSEL.bit.INTEN = 1; // Enable INT
    EPwm1Regs.ETPS.bit.INTPRD = ET_1ST; // Generate INT on 1st event

    EPwm2Regs.ETSEL.bit.INTSEL = ET_CTR_PRD; // Enable INT on Period event
    EPwm2Regs.ETSEL.bit.INTEN = 1; // Enable INT
    EPwm2Regs.ETPS.bit.INTPRD = ET_1ST; // Generate INT on 1st event

    //ADC trigger
    EPwm1Regs.ETSEL.bit.SOCAEN = 1; // Enable SOCA
    EPwm1Regs.ETSEL.bit.SOCASEL = ET_CTR_ZERO; // Generate SOCA pulse on zero
    EPwm1Regs.ETPS.bit.SOCAPRD = 1; // Generate pulse on 1st

    event

    EPwm2Regs.ETSEL.bit.SOCAEN = 1; // Enable SOCA
    EPwm2Regs.ETSEL.bit.SOCASEL = ET_CTR_PRD; // Generate SOCA pulse on period
    EPwm2Regs.ETPS.bit.SOCAPRD = 1; // Generate pulse on 1st

    event

    EALLOW;
    SysCtrlRegs.PCLKCR0.bit.TBCLKSYNC = 0; // do not Start all the

    timers synced
    EDIS;
    p->mFuncLmt = 31130; // 31130 95%
    }


    and in this task,there is a function,it is executed on every 62.5us and its code is as follow


    void rtTaskTimerUpdate()
    {
           int16 i;
          for(i=0;i<RTTASK_TIMERNUM;i++)
         {
              if(rtTaskTimer[i].counter < rtTaskTimer[i].period)
              {
                  rtTaskTimer[i].counter++;
             }
            else
            {
                 rtTaskTimer[i].flag = 1;
                 rtTaskTimer[i].counter = 0;
            }
        }
     }
    when rtTaskTimer[i].flag is set,it represent the corresponding should be executed.

    task 3 is triggered by rtTaskTimer[3].flag

    Hope your detailed answer sincerely!
    Best regards,
    Victor

  • Victor,

    Thanks for clarifying. I'm assuming epwm_timer_isr() is the task you're talking about. If so, can you post the code for that please? I'd like to see how you are handling the interrupt.

    There are no obvious mistakes in the code you sent, but I'm suspicious about having one ISR from two sources. Can you try a couple of simple experiments:

    - Disable one interrupt trigger, for example EPwm2Regs.ETSEL.bit.INTEN = 0; then run it. You'r tasks should run at half the rate, but do you still see the issue?

    - Write a separate and identical ISR for ePWM2. Does the issue go away?

    Regards,

    Richard
  • Dear Richard,

    I have done these experiments,

    - Disable one interrupt trigger, for example EPwm2Regs.ETSEL.bit.INTEN = 0; then run it. Your tasks should run at half the rate, but do you still see the issue?

    The issue doesn't occur when the interrupt period is 125us.But when I  set the interrupt period as 62.5us,this issue occurs again, it represent this issue is relevant to the cpu load,when the cpu load is heavy, many tasks are interrupted,and the stack is used heavily.

    - Write a separate and identical ISR for ePWM2. Does the issue go away?

    This issue still occurs.

    Richard, I think there is someting wrong with the compiler. This scheduler was good when I run it on Tms320lf2407 many years age,at that time I wrote this scheduler in assemble language.

    But TMS320F28X‘s assemble language is too complicated, I cann't write this scheduler in assemble language in a short time and this project is a little urgent.Can you help to study the disassebly,Maybe the issue  can be found easily.  Thank  you very much.

    Moreover, Not just task 3, but sometimes several tasks have  this issue.

    attached is the demo code. 

    BR

    Victor

  • When you ran with a period of 125 us, was it from changing the actual period of the PWM or did you disable the ePWM2 interrupt as Richard suggested?

    The first scope capture you shared looks like it might be the EPWM ISR being preempted by the EPWM ISR (probably at the EINT; before the DTS2 = 1;). Do you want it to be able to do that? I see you're re-enabling group 3 at the start of the ISR, so I assume so...?

    Whitney

  • Whitney and Richard,

    -When you ran with a period of 125 us, was it from changing the actual period of the PWM or did you disable the ePWM2 interrupt as Richard suggested?

    When I ran with a period of 125us, I disabled the epwm2 interrupt, only epwm1 interrupt was working. In fact ,in my system, there are two interrupt sources, one is  EPwm1  ET_CTR_ZERO interrupt and the other is EPwm2 ET_CTR_PRD interrupt, the periods of the two interrputs are both 125us, and the two interrupt executes the same code. If the two interrupts are working together, then the period is 62.5us.

    if I disabled one of the two interrputs, then the executed period of code is 125us. in the condition above, I can not find the issue

    I have do another experiment, only EPWM1 interrupt is enabled and I change PWM switching frequency from 8Khz to 16KHz, the issue occur again.

    it represent this issue is relevant to the cpu load,when the cpu load is heavy, many tasks are interrupted,and the stack is used heavily.

    -The first scope capture you shared looks like it might be the EPWM ISR being preempted by the EPWM ISR (probably at the EINT; before the DTS2 = 1;). Do you want it to be able to do that? I see you're re-enabling group 3 at the start of the ISR, so I assume so...?

    In my code,EPWM ISR can be preempted by itself. there are 8 tasks in my system,

    and task 0(period is 62.5us) should be completed in 62.5us,

    task 1(period is 125us) should be completed in 125us and it can be preempted by task 0,

    task 2(period is 250us) should be completed in 250us and it can be preempted by task 0 and task 1

    task 3(period is 625us) should be completed in 250us and it can be preempted by task 0 ,task 1,task 2

    task 4(period is 1ms) should be completed in 250us and it can be preempted by task 0 ,task 1,task 2 ,task 3

    task 5(period is 10ms) should be completed in 250us and it can be preempted by task 0 ,task 1,task 2 ,task 3,task 4

    task 6(period is 330s) should be completed in 250us and it can be preempted by task 0 ,task 1,task 2 ,task 3,task 4 ,task 5

    task 7(period is 1s) should be completed in 1s and it can be preempted by task 0 ,task 1,task 2 ,task 3,task 4 ,task 5 and task 6

    If any task can not be  completed in the corresponding time,system would report error.

    The phenomenon is too strange and illogical.

    and demo code I have upload,please take some time to review.

    I need your help!!!

    BR

    Victor

  • Victor,

    Wondering if you have made any progress from your side?

    I have examined the source files but to be honest there is simply too much and it is too complicated for me to make headway. As far as the hardware is concerned, there is no mechanism I can think of where you would get more than the programmed number of interrupts in a given interval, so I conclude this is a software issue. On the basis that the issue disappears when the update rate is reduced, I agree with you that CPU loading is involved.

    One approach which might help is to reduce the complexity of the code to the point where you have a compact test case which reliably produces the issue. I might be able to make more headway with that, but the I regret the 65 files in your attachment are too much for me to work with.

    Regards,

    Richard
  • Richard,
    I can not find the bug.
    I will write a small demo to show this strange phenomenon.
    Can you show me your email?
    In addition, can you help me delete the demo I attached last time, Thank you!
    BRS
    Victor
  • Victor,
    OK, that's good. I have deleted the attachment in your post of 1/10.
    Please post the demo back to this forum when you are ready. Thanks.
    Regards,
    Richard
  • Victor,

    It's been a couple of weeks.  Just wondering if you'd made any progress on that test case?

    Regards,

    Richard

  • Victor,

    I'm going to go ahead and close this thread. If you're still having issues with this feel free to reply again or to open a new post. Thanks.

    Regards,

    Richard