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.

TMS320F28076: cla interrutp spi slvae can't interrupt

Part Number: TMS320F28076

Tool/software:

i use spi slave program cla task3 for spi a rx interrupt

board.c:

void SPI_init()
{

//mySPI0 initialization
SPI_disableModule(mySPI0_BASE);
SPI_setConfig(mySPI0_BASE, DEVICE_LSPCLK_FREQ, SPI_PROT_POL0PHA0,
SPI_MODE_MASTER, 700000, 8);
SPI_enableFIFO(mySPI0_BASE);
SPI_disableLoopback(mySPI0_BASE);
SPI_setEmulationMode(mySPI0_BASE, SPI_EMULATION_FREE_RUN);
SPI_enableModule(mySPI0_BASE);

//mySPI1 initialization
SPI_disableModule(mySPI1_BASE);
SPI_setConfig(mySPI1_BASE, DEVICE_LSPCLK_FREQ, SPI_PROT_POL0PHA0,
SPI_MODE_SLAVE, 500000, 16);
SPI_enableFIFO(mySPI1_BASE);
SPI_setFIFOInterruptLevel(mySPI1_BASE, SPI_FIFO_TXEMPTY, SPI_FIFO_RX4);
SPI_clearInterruptStatus(mySPI1_BASE, SPI_INT_RXFF);
SPI_enableInterrupt(mySPI1_BASE, SPI_INT_RXFF);
SPI_disableLoopback(mySPI1_BASE);
SPI_setEmulationMode(mySPI1_BASE, SPI_EMULATION_STOP_MIDWAY);
SPI_enableModule(mySPI1_BASE);
}

initcla

void initcla(void)

{

....

....

CLA_mapTaskVector(CLA1_BASE, CLA_MVECT_1, (uint16_t)&Cla1Task1);
CLA_mapTaskVector(CLA1_BASE, CLA_MVECT_8, (uint16_t)&Cla1Task8);
CLA_setTriggerSource(CLA_TASK_1, CLA_TRIGGER_EPWM6INT);
CLA_setTriggerSource(CLA_TASK_8, CLA_TRIGGER_SOFTWARE);
//add spi rx Cla1Task3
CLA_mapTaskVector(CLA1_BASE, CLA_MVECT_1, (uint16_t)&Cla1Task3);
CLA_setTriggerSource(CLA_TASK_1, CLA_TRIGGER_SPIRXAINT);

//CLA_TASKFLAG_3 jaures CLA_TRIGGER_SPIRXAINT
CLA_enableTasks(CLA1_BASE, (CLA_TASKFLAG_1 |CLA_TASKFLAG_3 | CLA_TASKFLAG_8));

CLA_enableIACK(CLA1_BASE);
//
// Force task 8, the one time initialization task
//
CLA_forceTasks(CLA1_BASE, CLA_TASKFLAG_8);

}

than cla task3

#define mySPI1_BASE SPIA_BASE

int16_t ispi,SpirxFifonum;
uint16_t rxfifoarray[4];
uint16_t txfifoarray[4];

__attribute__((interrupt)) void Cla1Task3 ( void )
{

if(SpirxFifonum>0)
{

SpirxFifonum=SPI_getRxFIFOStatus(mySPI1_BASE);
//__mdebugstop();
rxfifoarray[0]=SPI_readDataNonBlocking(mySPI1_BASE);
txfifoarray[0] =(txfifoarray[0]+4);
SPI_writeDataNonBlocking(mySPI1_BASE , txfifoarray[0]);

rxfifoarray[1]=SPI_readDataNonBlocking(mySPI1_BASE);
txfifoarray[1] =(txfifoarray[1]+4);
SPI_writeDataNonBlocking(mySPI1_BASE , txfifoarray[1]);

rxfifoarray[2]=SPI_readDataNonBlocking(mySPI1_BASE);
txfifoarray[2] =(txfifoarray[2]+4);
SPI_writeDataNonBlocking(mySPI1_BASE , txfifoarray[2]);

rxfifoarray[3]=SPI_readDataNonBlocking(mySPI1_BASE);
txfifoarray[3] =(txfifoarray[3]+4);
SPI_writeDataNonBlocking(mySPI1_BASE , txfifoarray[3]);

}

SPI_clearInterruptStatus(mySPI1_BASE, SPI_INT_RXFF);
}

my problem was the spi isr only interrupt one time.

please help me check miss which code?

  • Hi Juares,

    Are you trying to use SPI interrupts (on CPU) at all? Or ONLY CLA tasks for SPI communication? 

    I see that you set the CLA trigger for Task1 to be the CLA_TRIGGER_SPIRXAINT. If you are wanting to use Task 3 for SPI1, did you mean to put Task3 here instead of Task1?

    Best Regards,

    Allison

  • this spi interrupt run in mcu is correct ,no problem.

    but i want to move to cla do the spi isr

    i modify 

    void initcla(void)
    {

    ....

    ....
    CLA_mapTaskVector(CLA1_BASE, CLA_MVECT_1, (uint16_t)&Cla1Task1);
    //add spi rx Cla1Task3
    CLA_mapTaskVector(CLA1_BASE, CLA_MVECT_3, (uint16_t)&Cla1Task3);
    CLA_mapTaskVector(CLA1_BASE, CLA_MVECT_8, (uint16_t)&Cla1Task8);
    CLA_setTriggerSource(CLA_TASK_1, CLA_TRIGGER_EPWM6INT);
    //add spi rx Cla1Task3
    CLA_setTriggerSource(CLA_TASK_3, CLA_TRIGGER_SPIRXAINT);
    CLA_setTriggerSource(CLA_TASK_8, CLA_TRIGGER_SOFTWARE);
    #pragma diag_warning=770

    //
    // Enable Tasks 1 ,3 and 8
    //CLA_TASKFLAG_3 jaures CLA_TRIGGER_SPIRXAINT
    CLA_enableTasks(CLA1_BASE, (CLA_TASKFLAG_1 |CLA_TASKFLAG_3 | CLA_TASKFLAG_8));

    CLA_enableIACK(CLA1_BASE);
    //
    // Force task 8, the one time initialization task
    //
    CLA_forceTasks(CLA1_BASE, CLA_TASKFLAG_8);
    }

    task 1 for dsp digital power compensator

    task 3 for spi interrutp 

    task 8 for var init

    but the task 3 only triggter one time?

    may program tx data keep 0x0004?

    why ?

  • Hi Jaures,

    I believe I see the issue. You do need to clear the interrupt source at the end of the task to receive further task triggers, however you cannot call SPI_clearInterruptStatus() from a .cla file since it is defined in the spi.c file, and therefore is compiled only for the c28x. Can you try putting the below line at the end of the CLA task instead which will clear the flag directly?

    HWREGH(base + SPI_O_FFRX) |= SPI_FFRX_RXFFINTCLR;

    The reason you don't see an issue with calling some of the other driverlib functions from your CLA task (like SPI_readDataNonBlocking() and SPI_writeDataNonBlocking()) is that these are defined in the spi.h file, meaning that they are inline functions and the contents will replace the function call in the .cla file at compile time. You can generally only call driverlib functions defined in a .h file from a .cla file.

    Let me know if this fixes the issue.

    Best Regards,

    Delaney

  • modify task 3 running normal

    but why first time rx fifo (SpirxFifonum)=16?

    the SpirxFifoCNT =1;

    needs add 

    if(SpirxFifonum>4)
    {
    HWREGH(SPIA_BASE + SPI_O_FFRX) |= SPI_FFRX_RXFFOVFCLR;
    HWREGH(SPIA_BASE + SPI_O_STS) |= SPI_STS_OVERRUN_FLAG;
    SpirxFifoCNT=SpirxFifoCNT+0x01U;
    }

    why trigger SPI_FFRX_RXFFOVFCLR or SPI_STS_OVERRUN_FLAG?

    #define mySPI1_BASE SPIA_BASE

    void SPI_init()
    {
    //mySPI1 initialization
    SPI_disableModule(mySPI1_BASE);
    SPI_setConfig(mySPI1_BASE, DEVICE_LSPCLK_FREQ, SPI_PROT_POL0PHA0,
    SPI_MODE_SLAVE, 500000, 16);
    SPI_enableFIFO(mySPI1_BASE);
    SPI_setFIFOInterruptLevel(mySPI1_BASE, SPI_FIFO_TXEMPTY, SPI_FIFO_RX4);
    SPI_clearInterruptStatus(mySPI1_BASE, SPI_INT_RXFF);
    SPI_enableInterrupt(mySPI1_BASE, SPI_INT_RXFF);
    SPI_disableLoopback(mySPI1_BASE);
    SPI_setEmulationMode(mySPI1_BASE, SPI_EMULATION_STOP_MIDWAY);
    SPI_enableModule(mySPI1_BASE);
    }

    __attribute__((interrupt)) void Cla1Task3 ( void )
    {

    //SpirxFifonum=((HWREGH(SPIA_BASE + SPI_O_FFRX) & SPI_FFRX_RXFFST_M) >>SPI_FFRX_RXFFST_S);
    SpirxFifonum=((SPI_RxFIFOLevel)((HWREGH(SPIA_BASE + SPI_O_FFRX) & SPI_FFRX_RXFFST_M) >>SPI_FFRX_RXFFST_S));
    if(SpirxFifonum>4)
    {
    HWREGH(SPIA_BASE + SPI_O_FFRX) |= SPI_FFRX_RXFFOVFCLR;
    HWREGH(SPIA_BASE + SPI_O_STS) |= SPI_STS_OVERRUN_FLAG;
    SpirxFifoCNT=SpirxFifoCNT+0x01U;
    }
    else{}

    if(SpirxFifonum>0)
    {
    for(ispi=0;ispi<SpirxFifonum;ispi++)
    {
    //rxfifoarray[ispi]=SPI_readDataNonBlocking(mySPI1_BASE);
    rxfifoarray[ispi]=(HWREGH(SPIA_BASE + SPI_O_RXBUF));
    //static inline void
    //__mdebugstop();
    txfifoarray[ispi] =(txfifoarray[ispi]+4);
    // SPI_writeDataNonBlocking(mySPI1_BASE , txfifoarray[ispi]);
    HWREGH(SPIA_BASE + SPI_O_TXBUF) =txfifoarray[ispi];
    }
    }
    //SPI_clearInterruptStatus(mySPI1_BASE, SPI_INT_RXFF);
    HWREGH(SPIA_BASE + SPI_O_FFRX) |= SPI_FFRX_RXFFINTCLR;

    }

  • Hi Jaures,

    Glad to hear you got the CLA task working. I will let Allison comment on your SPI configurations and the behavior you're seeing.

    Best Regards,

    Delaney

  • modify task 3 running normal

    but why first time rx fifo (SpirxFifonum)=16?

    the SpirxFifoCNT =1;

    needs add 

    if(SpirxFifonum>4)
    {
    HWREGH(SPIA_BASE + SPI_O_FFRX) |= SPI_FFRX_RXFFOVFCLR;
    HWREGH(SPIA_BASE + SPI_O_STS) |= SPI_STS_OVERRUN_FLAG;
    SpirxFifoCNT=SpirxFifoCNT+0x01U;
    }

    why trigger SPI_FFRX_RXFFOVFCLR or SPI_STS_OVERRUN_FLAG?

    #define mySPI1_BASE SPIA_BASE

    void SPI_init()
    {
    //mySPI1 initialization
    SPI_disableModule(mySPI1_BASE);
    SPI_setConfig(mySPI1_BASE, DEVICE_LSPCLK_FREQ, SPI_PROT_POL0PHA0,
    SPI_MODE_SLAVE, 500000, 16);
    SPI_enableFIFO(mySPI1_BASE);
    SPI_setFIFOInterruptLevel(mySPI1_BASE, SPI_FIFO_TXEMPTY, SPI_FIFO_RX4);
    SPI_clearInterruptStatus(mySPI1_BASE, SPI_INT_RXFF);
    SPI_enableInterrupt(mySPI1_BASE, SPI_INT_RXFF);
    SPI_disableLoopback(mySPI1_BASE);
    SPI_setEmulationMode(mySPI1_BASE, SPI_EMULATION_STOP_MIDWAY);
    SPI_enableModule(mySPI1_BASE);
    }

    __attribute__((interrupt)) void Cla1Task3 ( void )
    {

    //SpirxFifonum=((HWREGH(SPIA_BASE + SPI_O_FFRX) & SPI_FFRX_RXFFST_M) >>SPI_FFRX_RXFFST_S);
    SpirxFifonum=((SPI_RxFIFOLevel)((HWREGH(SPIA_BASE + SPI_O_FFRX) & SPI_FFRX_RXFFST_M) >>SPI_FFRX_RXFFST_S));
    if(SpirxFifonum>4)
    {
    HWREGH(SPIA_BASE + SPI_O_FFRX) |= SPI_FFRX_RXFFOVFCLR;
    HWREGH(SPIA_BASE + SPI_O_STS) |= SPI_STS_OVERRUN_FLAG;
    SpirxFifoCNT=SpirxFifoCNT+0x01U;
    }
    else{}

    if(SpirxFifonum>0)
    {
    for(ispi=0;ispi<SpirxFifonum;ispi++)
    {
    //rxfifoarray[ispi]=SPI_readDataNonBlocking(mySPI1_BASE);
    rxfifoarray[ispi]=(HWREGH(SPIA_BASE + SPI_O_RXBUF));
    //static inline void
    //__mdebugstop();
    txfifoarray[ispi] =(txfifoarray[ispi]+4);
    // SPI_writeDataNonBlocking(mySPI1_BASE , txfifoarray[ispi]);
    HWREGH(SPIA_BASE + SPI_O_TXBUF) =txfifoarray[ispi];
    }
    }
    //SPI_clearInterruptStatus(mySPI1_BASE, SPI_INT_RXFF);
    HWREGH(SPIA_BASE + SPI_O_FFRX) |= SPI_FFRX_RXFFINTCLR;

    }

  • Hi Juares,

    When you ask the following:

    why first time rx fifo (SpirxFifonum)=16
    • Are you seeing the RXFIFO Status = 16 (meaning all 16 levels of the RX FIFO are full)?   
    • You are setting the RX FIFO Interrupt level to 4, meaning you should trigger an interrupt (in this case, a CLA task3) when the RXFIFO has at least 4 levels full of data ready to be read. 

    Apologies, but it is a bit difficult for me to follow what the exact problem is - could you please help break down the issue you are seeing?

    1. Please first clarify: What are you trying to do?
      1. How much data are you expecting to receive and transmit?
      2. At what point are you trying to read from the RXFIFO (are you wanting to read every time the RXFIFO contains at least 4 data)?
      3. Where are you moving the RXFIFO data to? Is the issue only related to how you are storing the received data? And not the receival itself?
    2. What symptom are you seeing of the issue?
      1. Is the issue only with RX? Or is there an issue with SPI TX as well?
      2. Are any error flags being set?
      3. Are the CLA tasks occurring correctly/as expected?
      4. Are you scoping the SPI lines to ensure the expected signals (data, chip select, clock) are being seen?

    Is there a specific reason you are using a mix of driverlib code and HWREGH code rather than only driverlib?

    Best Regards,

    Allison

    • Are you seeing the RXFIFO Status = 16 (meaning all 16 levels of the RX FIFO are full)?
      • yes   
    • You are setting the RX FIFO Interrupt level to 4, meaning you should trigger an interrupt (in this case, a CLA task3) when the RXFIFO has at least 4 levels full of data ready to be read. 
      • yes

    Please first clarify: What are you trying to do?
    a.How much data are you expecting to receive and transmit?
    4word pre 10ms mcu1 master sent to mcu2 slave test
    b.At what point are you trying to read from the RXFIFO (are you wanting to read every time the RXFIFO contains at least 4 data)?
    yes per 10ms mcu1 sent to mcu2
    c.Where are you moving the RXFIFO data to? Is the issue only related to how you are storing the received data? And not the receival itself?
    the 4 word data for task 1 digital power use,but only test for new,
    but the data no any change ,for test now

    What symptom are you seeing of the issue?
    a.Is the issue only with RX? Or is there an issue with SPI TX as well?
    tx form mcu1 spi master to doing mcu1 lib,not doing at cla ,and no problem
    b.Are any error flags being set?
    spi rx fifo full,over run flag for one times(SPI_FFRX_RXFFOVFCLR or SPI_STS_OVERRUN_FLAG)
    c.Are the CLA tasks occurring correctly/as expected?
    not detail test,i thank no problem
    d.Are you scoping the SPI lines to ensure the expected signals (data, chip select, clock) are being seen?
    yes attached picture

    Is there a specific reason you are using a mix of driverlib code and HWREGH code rather than only driverlib?
    use sys.cfg the gen board.c ;void SPI_init() mcu to do inital no at cla,only task 3 at cla

  • Hi Juares,

    Thank you for your responses.

    Can you please try stepping through your code in CCS using the "Step Over" and "Step Into" buttons while monitoring the SPI status using the "Registers" viewing window with "Continuous Refresh" on? The SPI RX status should start at 0 when you first initialize the SPI module, and error flags should be clear. By stepping through the code, I'd like to identify when exactly (what point in the code) the status changes, and see if it happens when you'd expect. 

    The RX FIFO status should not overflow if the CLA is triggered correctly (when the RX FIFO reaches 4 levels full) to go read whatever data is in the FIFO to clear it.

    If I am reading the channels correctly on the scope capture, it looks like the signals are all looking good, so I suspect there could be some software or configuration issue here.

    Best Regards,

    Allison

  • i busy now,i will try it