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: Data reception by SPI in PWM interrupt

Part Number: TMS320F28335

Tool/software: Code Composer Studio

Hi,

I have two TMS320C2000 Experimenter Kits with 28335, and let's call them A and B. Synchronized 7kHz PWM interrupt are applied on both board by using EPWMSYNCO I/O, and it works well.

After A board enters PWM interrupt, it will send 16bit data by SPI (baud rate: 9.375MHz) after finishing some calculation. FYI, the time taking for the calculation before SPI transmission is about 30us.

For B board, it waits for the SPI data reception right after entering the PWM interrupt.

With 16 bit data transmission and synchronized 7kHz PWM interrupt, I believe the time for B board to receive the data from SPI in the PWM interrupt should be more than enough.

However, I find that B board takes the whole time of the interrupt to wait for the data. Here is the timing measured from the scope.

The data received by B board is also not complete. Some data points are missing.

The SPI setup is the following:

1) A board: 

void spi_init()
{
     SpiaRegs.SPICCR.bit.SPISWRESET = 0; // Clear this bit before changing SPI configuration
     SpiaRegs.SPICCR.all = 0x000F;                // Reset on, write:rising edge; read: falling edge
                                                                         // no loop back, 16-bit char bits
                                                                         // 0000 1111

     SpiaRegs.SPICTL.all = 0x0006;                 // Enable master mode, normal phase (no delay half cycle),
                                                                         // enable talk, and SPI int disabled.
                                                                         // 0000 0110

     SpiaRegs.SPIBRR = 0x0000;                     // LSPCLK/4, 37.5 MHz/4 = 9.375 MHz
     SpiaRegs.SPICCR.all = 0x008F;                // Relinquish SPI from Reset, 1100 1111
     SpiaRegs.SPIPRI.bit.FREE = 1;                 // Set so breakpoints don't disturb xmission
}

void spi_xmit(Uint16 a)
{
     volatile Uint16 dummy_x = 0;

     GpioDataRegs.GPACLEAR.bit.GPIO19 = 1;
     SpiaRegs.SPITXBUF=a;

     while(SpiaRegs.SPISTS.bit.INT_FLAG == 0) { }
     dummy_x = SpiaRegs.SPIRXBUF;
     GpioDataRegs.GPASET.bit.GPIO19 = 1;
}

2) B board:

void spi_init()
{
     SpiaRegs.SPICCR.bit.SPISWRESET = 0; // Clear this bit before changing SPI configuration
     SpiaRegs.SPICCR.all = 0x000F;               // Reset on, write:rising edge; read: falling edge
                                                                        // no loop back, 16-bit char bits
                                                                        // 0000 1111

     SpiaRegs.SPICTL.all = 0x0002;               // Enable slave mode, normal phase (no delay half cycle),
                                                                       // enable talk, and SPI int disabled.
                                                                       // 0000 0010

     SpiaRegs.SPIBRR = 0x0000;                  // LSPCLK/4, 37.5 MHz/4 = 9.375 MHz
     SpiaRegs.SPICCR.all = 0x008F;             // Relinquish SPI from Reset, 1100 1111
     SpiaRegs.SPIPRI.bit.FREE = 1;              // Set so breakpoints don't disturb xmission
}

void spi_receive()
{
     while(SpiaRegs.SPISTS.bit.INT_FLAG == 0) { }
     Drive_data = SpiaRegs.SPIRXBUF;

}

Due to the application in my research, PWM interrupt is necessary, therefore the interrupt from SPI data reception is not considered here.

Does anyone have an idea for solving this issue? I appreciate any help from you.

Thanks. :)

Hung-Yen

  • Hung-yen,

    Please clarify for me: On the falling edge of the yellow signal, board A will transmit the SPI data, and Board B captures the data on the green signal?

    Can you share an annotated scope plot of the following signals?
    Yellow: same
    Green - set to 0 before you call spi_receive() and set to 1 immediately after exiting spi_receive().
    pink: same
    Blue: SPISIMO or SPICLK. either one works.
    Trigger on Rising edge of (EPWMSYNCO)
    Time scale to see just one period

    Once Board B sees the full data word expected (16 bits), it will trigger the INT_FLAG and you should be able to read SPIRXBUF.

    Your concern is that board B is not getting the data when it should?
    is your data correct? I want to make sure that the SPI is not out of sync and is getting the correct data, even though it is late.


    Thanks,
    Mark
  • Mark,

    Here is the plot you request:

    The data is transmitted from board A through SPI after the calculations are done. Both the calculations and SPI xmit are done within the PWM interrupt.

    My concern is that board B cannot get the complete data from board A. Here is the data recorded in board A and board B individually.

    The data I sent from board A is the 80Hz sine wave with 22 dc offset, and each data point is calculated and transmitted in every interrupt by board A.

    I use an array in each DSP to record the data in every interrupt, and output them to Matlab to get this plot.

    Please note that they are not in phase since I start and stop recording the data in each DSP manually.

    The received data are within the range of the sine wave transmitted from board A, and is quite distorted.

    I hope these information help for the clarification. Thank you for your time.

    Hung-Yen

  • An update about this issue:
    The sine wave can be received correctly by board B, so no distortion anymore. The issue causing this seems to be the connection of SPISTE pin.
    However, the SPI_receive() still takes the whole interrupt time to get the data (see the 1st figure in my reply above), and this is obviously not desirable.
    I hope that anyone can have an idea to help me solve this issue. Thanks!

    Hung-Yen
  • A further update:
    After the issue of SPISTE was solved, I try to put spi_receive() in while loop outside the PWM interrupt instead of inside the interrupt. Now everything works well.

    Hung-Yen
  • I am glad to hear that you go it working. Yes it appears that since you are in a polling loop of the SPI, it will block any other activity while waiting for the next reception. decoupling the received data will generally be a best practice for this type of situation.

    -Mark