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/TMS320F28027: can't use three XINT

Part Number: TMS320F28027
Other Parts Discussed in Thread: CONTROLSUITE

Tool/software: Code Composer Studio

I want to use three external interrupt(XINT1,XINT2,XINT3) at the HVPSFB project.
So , I write flollowing code.


////////////////////////////////////main////////////////////////////////////////////

EALLOW;
PieVectTable.XINT1 = & XINT1_ISR;
GpioIntRegs.GPIOXINT1SEL.bit.GPIOSEL = 0x10;       // trigger select is  GPIO16
EDIS;
PieCtrlRegs.PIEIER1.bit.INTx4 = 1;
XIntruptRegs.XINT1CR.bit.POLARITY = 0x3;
XIntruptRegs.XINT1CR.bit.ENABLE = 0x1;

EALLOW;
PieVectTable.XINT2 = & XINT2_ISR;
GpioIntRegs.GPIOXINT2SEL.bit.GPIOSEL = 0x13;       // trigger select is  GPIO19
EDIS;
PieCtrlRegs.PIEIER1.bit.INTx5 = 1;
XIntruptRegs.XINT2CR.bit.POLARITY = 0x3;
XIntruptRegs.XINT2CR.bit.ENABLE = 0x1;

IER |= M_INT1;


EALLOW;
PieVectTable.XINT3 = & XINT3_ISR;
GpioIntRegs.GPIOXINT3SEL.bit.GPIOSEL = 0x12;       // trigger select is  GPIO18
EDIS;
PieCtrlRegs.PIEIER12.bit.INTx1 = 1;
XIntruptRegs.XINT3CR.bit.POLARITY = 0x1;
XIntruptRegs.XINT3CR.bit.ENABLE = 0x1;

IER |= M_INT12;

////////////////////////////////////////////////////////////////////////////////


////////////////////////////////  ISR////////////////////////////////////////
interrupt void XINT1_ISR(void)
{
XINT1_flag = 1;
PieCtrlRegs.PIEACK.all = PIEACK_GROUP1;
return;
}

interrupt void XINT2_ISR(void)
{
XINT2_flag = 1;
PieCtrlRegs.PIEACK.all = PIEACK_GROUP1;
return;
}

interrupt void XINT3_ISR(void)
{
XINT3_flag = 1;
PieCtrlRegs.PIEACK.all = PIEACK_GROUP12;
return;
}

///////////////////////////////////////////////////////////////////////////////////////

///////////////////DevInit////////////////////////////////
//  GPIO-16 - PIN FUNCTION = (Unused)
 GpioCtrlRegs.GPAMUX2.bit.GPIO16 = 0; // 0=GPIO,  1=SPISIMO-A,  2=CANTX-B,  3=TZ5
 GpioCtrlRegs.GPADIR.bit.GPIO16 = 0;  // 1=OUTput,  0=INput
 GpioDataRegs.GPACLEAR.bit.GPIO16 = 1; // uncomment if --> Set Low initially
// GpioDataRegs.GPASET.bit.GPIO16 = 1;  // uncomment if --> Set High initially

//  GPIO-18 - PIN FUNCTION = (Unused)
 GpioCtrlRegs.GPAMUX2.bit.GPIO18 = 0; // 0=GPIO,  1=SPICLK-A,  2=SCITX-B,  3=Resv
 GpioCtrlRegs.GPADIR.bit.GPIO18 = 0;  // 1=OUTput,  0=INput
 GpioDataRegs.GPACLEAR.bit.GPIO18 = 1; // uncomment if --> Set Low initially
// GpioDataRegs.GPASET.bit.GPIO18 = 1;  // uncomment if --> Set High initially

//  GPIO-19 - PIN FUNCTION = (Unused)
 GpioCtrlRegs.GPAMUX2.bit.GPIO19 = 0; // 0=GPIO,  1=SPISTE-A,  2=SCIRX-B,  3=Resv
 GpioCtrlRegs.GPADIR.bit.GPIO19 = 0;  // 1=OUTput,  0=INput
 GpioDataRegs.GPACLEAR.bit.GPIO19 = 1; // uncomment if --> Set Low initially
// GpioDataRegs.GPASET.bit.GPIO19 = 1;  // uncomment if --> Set High initially


When I use any two XINT(for example use XINT1, XINT3 and comment out XINT2),
these XINT operate correct.
But when I use three XINT,these XINT operation are strange
Three XINT_flag change the value from about -30000 to 30000.
XINT_flag don't change except interrupt,and these must be 0 or 1.

Why XINT operate strange?

  • So XINTn_flag is supposed to be either 0 or 1, but it is getting corrupted to some other value? Am I understanding correctly? All of the XINTn_flags are affected?

    I don't see anything wrong with your XINT code. Maybe there's something outside of this that's corrupting the RAM where the variables are located. Can you look for signs of stack overflow?

    Whitney

  • Yes,you are correct.

    When use three XINT,all XINT_flag's value is switching from about -30000 to 30000 at randam .

    And all XINT_flag's value are different.

    Sorry,what is stack overflow and how can this be indicated for you?

    In HVPSFB project,

    There are two default interrupt(DPL-ISR , ISR__temp).

    Add XINT1~3, there are five interrupt now.

    When remove 1 out of these 5 interrupt, It operate correctly.

    Is there upper limit amount in the amount of interrupt?

  • There isn't necessarily a hard limit to the number of interrupts--it's just up to you to look at how often they're occurring and how long they're each taking to run to make sure you aren't missing timing requirements, experiencing overflows, starving lower priority "tasks", etc...

    In your application, you allocate an amount of memory to serve as a stack (you should see a .stack section in your .cmd file and --stack_size option in your compiler settings to configure where it's stored and how big it is). If you aren't familiar with the concept, you can check out the compiler user's guide for more details: http://www.ti.com/lit/pdf/SPRU514

    If the stack grows beyond the allocated size, it's called stack overflow. Since it's growing beyond its expected location, it could start overwriting other memory--like where your flag variables are stored. An easy way to check for stack overflow when debugging is to open the Memory Browser in CCS and fill the stack with a known pattern and run the application and see how much of the pattern gets overwritten.

    Whitney

  • I  fill 0001 in stack(0x00000400~0x00000780) and start operating.
    When the amount of interrupts are 4,
    the stack data change from 0x00000400 to 0x00000428.
    Another data don't change.

    But when the amount of interrupts are 5,
    not only all stack data change but also another data change.

    At default,I think stack memory is 0x000400 ~ 0x00780 by the following code in CMD file.
    (I can't understand not 0x00800 but 0x00780)

    PAGE1:
     RAMM1 :origin=0x000400,length=0x00400
    .stack :>RAMM1, PAGE=1

    If RAMM length is longer,is this problem settled?

  • Yeah, that looks like stack overflow. Try making your stack bigger in your compiler options (you'll probably need to move .stack to a bigger RAM block too in your cmd file). It is a little concerning that the difference in stack usage would be so dramatic though with just 1 extra interrupt enabled. Do you have a lot of local variables? A lot of nested function calls? Printfs?

    It is okay if your stack doesn't take up the entire RAM block. That just means that space can be used by the linker for other stuff.

    Whitney
  • To expand stack space,I made memory map below.

    Left line is default map.

    I will change to right line map. 

    To change memory map,I change the code below.

    (In F28027_FLASH_HVPSFB.CMD)

    RAMM1       : origin = 0x000400, length = 0x000550

    (In DPS2802x_Headers_nonBIOS.cmd)

       DEV_EMU     :     origin = 0x000977, length = 0x000105   
      SYS_PWR_CTL : origin = 0x000A7D, length = 0x000003   

    After changing the code,I check memory browser.

    The stack space expand.

    「DevEmuRegs」and 「SYSPWR_CTRL_BORCFG」 change.

    But,「DEVEMU_DEVICECNF」,「DEVEMU_CLASSID」,「DEVEMU_REVID」 don't change.

    How change these?

    And Is this way OK?

  • Most of those sections in DPS2802x_Headers_nonBIOS.cmd are memory mapped registers and can't be changed. Your stack can only go in RAM. Maybe try using the "Memory Allocation" view in CCS to help you find a place for it.

    Whitney

  • I understand that memorys in DPS2802x_Headers_nonBIOS.cmd can't be changed and
    stack can only go in RAM.

    So, stack can in
    0x000000~0x000800
    0x008000~0x009000
    0x3F8000~0x3F9000
    Is it right?


    I tried to move RAMM1 to 0x3F8000~0x3F9000.
    Then debug stop because of ISR_ILLEGAL.
     Can 0x3F8000~0x3F9000 use?


    And,I adjust progRAM and dataRAM refer to Memory Allocation.
    I set progRAM to 0x008000~0x008250.
    progRAM usage rate is 94%.
    I set dataRAM to 0x008250~0x009000 and stack size set to 0xb00.
    dataRAM usage rate is 98%.
    But, stack overflow occur despite the stack size is three times bigger.
    Do Increase of 1 interrupt use so many stack?

    And are there other way to operate?

  • 0x3F8000-0x3F900 is the same as the section at 0x8000--you see it says "dual mapped" so that won't work.

    Like I said, that is a suspiciously large jump in stack size for for just one additional interrupt. Maybe there's something else going on like a buffer overflowing or a pointer getting corrupted and that's overwriting the stack. Can you try placing breakpoints to figure out when in the code things start going wrong?

    Whitney
  • I find the place causing overflow by placing breakpoint.
    The place is Task A1 inside "if ( (*ePWM[1]).TZFLG.bit.OST == 1 )".

     Because of my experiment environment,
     the operation enter "if ( (*ePWM[1]).TZFLG.bit.OST == 1 )".
     If it's improved so as not to enter there,
     overflow don't occur.

    In detail,
    When I set breakpoint to first "asm (" NOP")" and debug start, the code stop at breakpoint and don't overflow.
    But When I set breakpoint to second"asm (" NOP")" and debug start, the code don't stop and stack overflow.

    If the code restart  after debugging set breakpoint to first "asm (" NOP")" , and stopped.
    The code don't stop and stack overflow.

    If the code advance to "DINT" by using stepinto after debugging set breakpoint to first "asm (" NOP")" , and stopped.
    the code stop at breakpoint and don't overflow.


     
    I don't understand why and how improve.
     When I add three XINT, I don't change Task A1 code.
     To operate correctly ,Is there something which should be added?

  • I'm guess when you're adding/removing the XINTs you're just enabling/disabling them and not making any other changes to the code--like removing the ISRs or anything?

    How are you triggering the XINTs? How often? Does the code fail the first time they are triggered or can you run for a little while before things start going wrong?

    Whitney
  • I don't change enabling/disabling,but remove the code.
    But I return it to the beginning finally.
    Removed place are
    ・first declaration 「interrupt void ISR_Temp(void);」
    ・following code in A1 task
    DINT; // Disable Global interrupt
    EALLOW;
    PieVectTable.EPWM1_INT = &ISR_Temp; // Temporary Interrupt to service pending interrupts

    EPwm1Regs.ETSEL.bit.INTEN = 0; //Disable interrupt at the peripheral level

    EINT; // Enable Global interrupt INTM
    asm (" NOP");
    asm (" NOP");
    asm (" NOP");
    asm (" NOP");
    asm (" NOP"); // Wait 5 cycles for any pending interrupts to be serviced
    DINT; // Disable Global interrupt

    PieVectTable.EPWM1_INT = &DPL_ISR; // Interrupt re-mapped

    // EDIS;

    PieCtrlRegs.PIEIER3.bit.INTx1 = 0; // PIE level Disable, Grp3 / Int1

    PieCtrlRegs.PIEIFR3.bit.INTx1 = 0; // Clear IFR register

    // Acknowledge this interrupt to receive more interrupts from group 3
    PieCtrlRegs.PIEACK.all = PIEACK_GROUP3;

    EINT;



    The cord which is being added is as I mention first.


    XINTs are triggerd by the voltage supplied from DC power supply.
    In other words, it's manual.
    But stack overflow occuer when interrupt don't occur.

    By my first code,
    the operation enter "if ( (*ePWM[1]).TZFLG.bit.OST == 1 )" in A1 task from the beginning.
    And occur overflow at "NOP" as I mentioned last time.

    I change the code so as not to enter there from the beginning.
    Then, if make ePWM1 OST,operate correctly.
  • I don't think that if statement is actually causing the problem--that code is pretty harmless, being just a read of a register. Maybe you're getting an interrupt around the same time you reach that code and it's the interrupt that's causing the issue? I know you said you aren't triggering the XINTs, but could one of your other two interrupts have code that could cause an issue?

    Also, do you mind sharing your .map file? If you don't mind, it might be helpful to see two .map files--one when the code is working (2 XINTs) and one from when the code isn't working (3 XINTs).

    Thanks,

    Whitney

  • As I mentioned,

    my 3 XINTs are triggered by other 3 DC power supplys.

    So 3 XINTs are all manual.

    Of course, I don't trigger all XINTs.

    I attach a file.

    In the file,

    there are two map file.

    One is 2XINT,the other is 3XINT.

    And I want to resolve as soon as possible,

    there is all file about this project.XINT_problem.zip

  • I think I have an answer. In your ISR_Temp() function you add an IRET instead of letting it run to the compiler generated one. You're skipping a NASP which means under certain circumstances your SP is going to be incorrect, leading to an invalid return address.

    I removed the asm(" IRET") and I didn't see the memory being overwritten anymore--the ISR returns properly after executing the NASP. It's still not clear to me what role XINT3 is playing in this though. I don't seem to hit the ISR_Temp() at all when it's in the code. This should at least help you move forward with your debug though.

    Here's more info on the context save and restore if you're interested: processors.wiki.ti.com/.../C28x_Context_Save_and_Restore

    Whitney

  • thank you for your answer.
    I remove "asm(" IRET") " and success.

    Isn't it a problem to remove this?
    This code is wirrten default in controlSUITE.
  • I think it must be a bug in the code from controlSUITE then. Like I said, it can leave the stack pointer incorrectly aligned, leading to a bad context restore.

    Whitney