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.

LAUNCHXL-F28379D: F28379D SPI and DMA

Part Number: LAUNCHXL-F28379D


Hello everybody

Well, I am sending data from SPI master to slave using DMA (F28379D launch pad). Data is received right
with configuring FIFO level to be  8  words or lower and Burst to be 7. 

when i changed the FIFO level to 16 ,15.......9 and Burst to 15, 14,......8, the received data becomes non arranged as it was at sending end and some data is missed.

pls, any suggestions?

best regards 

  • Hi Hosam,

    I will try to reproduce the issue at my end and get back to you.

    Regards,
    Veena
  • Thank you so much veena I will stay tuned.

  • Hi Hosam,

    Just wanted to confirm, are you configuring the burst size as 16-FIFOLVL for transmitting?

    Regards,
    Veena
  • Hi Veena
    I have used 2 configurations. The 1st one is Burst size = FIFOLVL -1 and this works for 8 FIFO words or lower as stated in my post. The 2ed case was Burst size = (16 – TXFFIL) – 1 (ref manual: 2137) and this is not working.

    Regards,

    Hosam

  • Hi Hosam,

    It depends whether it is Tx or Rx side.

    For transmitting data, The DMA burst size should be equal to 16-TXFFIL. For Receiving data, DMA burst size has to be RXFFIL.
    Note that the actual register content will Burst size - 1. If you are using driverlib API DMA_configBurst, the API takes care of decrementing the value by 1.

    Regards,
    Veena
  • Hello Veena
    For sorry, the same problem remains.

    looking forward hearing from you.

    thanks 

  • Hi Hosam,

    Could you share the code you are using?

    Regards,
    Veena
  • Hi Veena 
    Here is the code that adapted from TI examples.


    //
    #include "F28x_Project.h"

    //
    // Defines
    //
    #define TXBURST (16-TXFIFO_LVL)-1 // burst size should be less than 8
    #define TRANSFER 3 // [(MEM_BUFFER_SIZE/FIFO_LVL)-1]
    #define TXFIFO_LVL 15 // FIFO Interrupt Level

    #define RXBURST RXFIFO_LVL-1 // burst size should be less than 8
    #define RXFIFO_LVL 15 // FIFO Interrupt Level
    //
    // Globals
    //
    #pragma DATA_SECTION(sdata, "ramgs0"); // map the TX data to memory
    #pragma DATA_SECTION(rdata, "ramgs1"); // map the RX data to memory
    Uint16 sdata[128]; // Send data buffer
    Uint16 rdata[128]; // Receive data buffer

    volatile Uint16 *DMADest;
    volatile Uint16 *DMASource;

    void dma_init(void);
    void spi_fifo_init(void);

    //
    // Main
    //
    void main(void)
    {
    Uint16 i;

    InitSysCtrl();
    InitSpiaGpio();

    DINT;
    IER = 0x0000;
    IFR = 0x0000;
    InitPieCtrl();
    InitPieVectTable();
    //
    // Step 4. Initialize the Device Peripherals:
    //
    dma_init(); // Set up DMA for SPI configuration

    EALLOW;
    CpuSysRegs.SECMSEL.bit.PF2SEL = 1; // Ensure DMA is connected to Peripheral Frame 2 bridge (EALLOW protected)
    EDIS;
    spi_fifo_init(); // Initialize the SPI only
    //
    // Initialize the data buffers
    //
    for(i=0; i<128; i++)
    {
    sdata[i] = i;
    rdata[i]= 0;
    }

    StartDMACH6();
    StartDMACH5();

    while(1)

    {

    }
    }

    //
    // spi_fifo_init - Initialize SPIA FIFO
    //
    void spi_fifo_init()
    {
    // SPIA FIFO regesters conf
    SpibRegs.SPIFFTX.bit.TXFFIL = TXFIFO_LVL;
    SpibRegs.SPIFFRX.bit.RXFFIL = RXFIFO_LVL; // Set RX FIFO level
    SpiaRegs.SPIFFTX.bit.TXFFIL = TXFIFO_LVL; // Set TX FIFO level
    SpiaRegs.SPIFFRX.bit.RXFFIL = RXFIFO_LVL;
    SpiaRegs.SPIFFTX.bit.SPIFFENA = 1;
    SpiaRegs.SPIFFTX.bit.TXFFINTCLR = 1;
    SpiaRegs.SPIFFRX.bit.RXFFINTCLR = 1;
    SpiaRegs.SPIFFRX.bit.RXFFOVFCLR = 1;
    SpiaRegs.SPIFFTX.bit.TXFIFO = 1;
    SpiaRegs.SPIFFRX.bit.RXFIFORESET = 1;
    SpiaRegs.SPIFFTX.bit.SPIRST = 1;
    // SPIB FIFO regesters conf
    SpibRegs.SPIFFTX.bit.SPIFFENA = 1;
    SpibRegs.SPIFFTX.bit.TXFFINTCLR = 1;
    SpibRegs.SPIFFRX.bit.RXFFINTCLR = 1;
    SpibRegs.SPIFFRX.bit.RXFFOVFCLR = 1;
    SpibRegs.SPIFFTX.bit.TXFIFO = 1;
    SpibRegs.SPIFFRX.bit.RXFIFORESET = 1;
    SpibRegs.SPIFFTX.bit.SPIRST = 1;

    //
    // Initialize core SPIA registers
    //
    InitSpi();

    // Initialize core SPIB registers
    SpibRegs.SPICCR.bit.SPISWRESET = 0;
    SpibRegs.SPICCR.bit.CLKPOLARITY = 0;
    SpibRegs.SPICCR.bit.SPICHAR = (16-1);
    SpibRegs.SPICCR.bit.SPILBK = 1;

    SpibRegs.SPICTL.bit.MASTER_SLAVE = 0;
    SpibRegs.SPICTL.bit.TALK = 1;
    SpibRegs.SPICTL.bit.CLK_PHASE = 0;
    SpibRegs.SPICTL.bit.SPIINTENA = 0;

    // Set the baud rate
    SpibRegs.SPIBRR.bit.SPI_BIT_RATE = 0x0f;//SPI_BRR;

    // Set FREE bit
    // Halting on a breakpoint will not halt the SPI
    SpibRegs.SPIPRI.bit.FREE = 1;

    // Release the SPI from reset
    SpibRegs.SPICCR.bit.SPISWRESET = 1;
    }

    //
    // dma_init - DMA setup for both TX and RX channels.
    //
    void dma_init()
    {
    //
    // Initialize DMA
    //
    DMAInitialize();

    DMASource = (volatile Uint16 *)sdata;
    DMADest = (volatile Uint16 *)rdata;

    //
    // configure DMACH5 for TX
    //
    DMACH5AddrConfig(&SpiaRegs.SPITXBUF,DMASource);
    DMACH5BurstConfig(TXBURST,1,0); // Burst size, src step, dest step
    DMACH5TransferConfig(TRANSFER,1,0); // transfer size, src step, dest step
    DMACH5ModeConfig(DMA_SPIATX,PERINT_ENABLE,ONESHOT_DISABLE,CONT_ENABLE,
    SYNC_DISABLE,SYNC_SRC,OVRFLOW_DISABLE,SIXTEEN_BIT,
    CHINT_END,CHINT_DISABLE);

    //
    // configure DMA CH2 for RX
    //
    DMACH6AddrConfig(DMADest,&SpibRegs.SPIRXBUF);
    DMACH6BurstConfig(RXBURST,0,1);
    DMACH6TransferConfig(TRANSFER,0,1);
    DMACH6ModeConfig(DMA_SPIBRX,PERINT_ENABLE,ONESHOT_DISABLE,CONT_ENABLE,
    SYNC_DISABLE,SYNC_SRC,OVRFLOW_DISABLE,SIXTEEN_BIT,
    CHINT_END,CHINT_DISABLE);
    }
    //
    // End of file
    //

    regards

  • Hi,

    I updated your code a little bit to make it run on my environment. I changed the TX and RX FIFO levels to 12 and I am able to see the data being received correctly.

    Can you re-check the SPI/DMA configuration you are using

    Attaching the code I used

    //
    #include "F28x_Project.h"
    
    //
    // Defines
    //
    #define TXFIFO_LVL          12 // FIFO Interrupt Level
    #define TXBURST             (16-TXFIFO_LVL)-1 // burst size should be less than 8
    #define TXTRANSFER          (384/(16-TXFIFO_LVL)) - 1 // [(MEM_BUFFER_SIZE/FIFO_LVL)-1]
    
    #define RXFIFO_LVL          12 // FIFO Interrupt Level
    #define RXBURST             RXFIFO_LVL-1 // burst size should be less than 8
    #define RXTRANSFER          (384/RXFIFO_LVL) - 1 // [(MEM_BUFFER_SIZE/FIFO_LVL)-1]
    
    //
    // Globals
    //
    #pragma DATA_SECTION(sdata, "ramgs0"); // map the TX data to memory
    #pragma DATA_SECTION(rdata, "ramgs1"); // map the RX data to memory
    Uint16 sdata[384]; // Send data buffer
    Uint16 rdata[384]; // Receive data buffer
    
    volatile Uint16 *DMADest;
    volatile Uint16 *DMASource;
    
    void dma_init(void);
    void spi_fifo_init(void);
    
    //
    // Main
    //
    void main(void)
    {
        Uint16 i;
    
        InitSysCtrl();
        InitSpiaGpio();
        InitSpibGpio();
    
        DINT;
        IER = 0x0000;
        IFR = 0x0000;
        InitPieCtrl();
        InitPieVectTable();
        //
        // Step 4. Initialize the Device Peripherals:
        //
        dma_init(); // Set up DMA for SPI configuration
    
        EALLOW;
        CpuSysRegs.SECMSEL.bit.PF2SEL = 1; // Ensure DMA is connected to Peripheral Frame 2 bridge (EALLOW protected)
        EDIS;
        spi_fifo_init(); // Initialize the SPI only
        //
        // Initialize the data buffers
        //
        for(i=0; i<384; i++)
        {
            sdata[i] = i;
            rdata[i]= 0;
        }
    
        StartDMACH6();
        StartDMACH5();
    
        while(1)
    
        {
    
        }
    }
    
    //
    // spi_fifo_init - Initialize SPIA FIFO
    //
    void spi_fifo_init()
    {
        // SPIA FIFO regesters conf
        SpibRegs.SPIFFTX.bit.TXFFIL = TXFIFO_LVL;
        SpibRegs.SPIFFRX.bit.RXFFIL = RXFIFO_LVL; // Set RX FIFO level
        SpiaRegs.SPIFFTX.bit.TXFFIL = TXFIFO_LVL; // Set TX FIFO level
        SpiaRegs.SPIFFRX.bit.RXFFIL = RXFIFO_LVL;
        SpiaRegs.SPIFFTX.bit.SPIFFENA = 1;
        SpiaRegs.SPIFFTX.bit.TXFFINTCLR = 1;
        SpiaRegs.SPIFFRX.bit.RXFFINTCLR = 1;
        SpiaRegs.SPIFFRX.bit.RXFFOVFCLR = 1;
        SpiaRegs.SPIFFTX.bit.TXFIFO = 1;
        SpiaRegs.SPIFFRX.bit.RXFIFORESET = 1;
        SpiaRegs.SPIFFTX.bit.SPIRST = 1;
        // SPIB FIFO regesters conf
        SpibRegs.SPIFFTX.bit.SPIFFENA = 1;
        SpibRegs.SPIFFTX.bit.TXFFINTCLR = 1;
        SpibRegs.SPIFFRX.bit.RXFFINTCLR = 1;
        SpibRegs.SPIFFRX.bit.RXFFOVFCLR = 1;
        SpibRegs.SPIFFTX.bit.TXFIFO = 1;
        SpibRegs.SPIFFRX.bit.RXFIFORESET = 1;
        SpibRegs.SPIFFTX.bit.SPIRST = 1;
    
        //
        // Initialize core SPIA registers
        //
        SpiaRegs.SPICCR.bit.SPISWRESET = 0;
        SpiaRegs.SPICCR.bit.CLKPOLARITY = 0;
        SpiaRegs.SPICCR.bit.SPICHAR = (16-1);
     //   SpiaRegs.SPICCR.bit.SPILBK = 1;
    
        SpiaRegs.SPICTL.bit.MASTER_SLAVE = 1;
        SpiaRegs.SPICTL.bit.TALK = 1;
        SpiaRegs.SPICTL.bit.CLK_PHASE = 0;
        SpiaRegs.SPICTL.bit.SPIINTENA = 0;
        // Set the baud rate
        SpiaRegs.SPIBRR.bit.SPI_BIT_RATE = 0x0f;//SPI_BRR;
    
        // Set FREE bit
        // Halting on a breakpoint will not halt the SPI
        SpiaRegs.SPIPRI.bit.FREE = 1;
    
        // Release the SPI from reset
        SpiaRegs.SPICCR.bit.SPISWRESET = 1;
    
        // Initialize core SPIB registers
        SpibRegs.SPICCR.bit.SPISWRESET = 0;
        SpibRegs.SPICCR.bit.CLKPOLARITY = 0;
        SpibRegs.SPICCR.bit.SPICHAR = (16-1);
      //  SpibRegs.SPICCR.bit.SPILBK = 1;
    
        SpibRegs.SPICTL.bit.MASTER_SLAVE = 0;
        SpibRegs.SPICTL.bit.TALK = 1;
        SpibRegs.SPICTL.bit.CLK_PHASE = 0;
        SpibRegs.SPICTL.bit.SPIINTENA = 0;
    
        // Set the baud rate
        SpibRegs.SPIBRR.bit.SPI_BIT_RATE = 0x0f;//SPI_BRR;
    
        // Set FREE bit
        // Halting on a breakpoint will not halt the SPI
        SpibRegs.SPIPRI.bit.FREE = 1;
    
        // Release the SPI from reset
        SpibRegs.SPICCR.bit.SPISWRESET = 1;
    }
    
    //
    // dma_init - DMA setup for both TX and RX channels.
    //
    void dma_init()
    {
        //
        // Initialize DMA
        //
        DMAInitialize();
    
        DMASource = (volatile Uint16 *)sdata;
        DMADest = (volatile Uint16 *)rdata;
    
        //
        // configure DMACH5 for TX
        //
        DMACH5AddrConfig(&SpiaRegs.SPITXBUF,DMASource);
        DMACH5BurstConfig(TXBURST,1,0); // Burst size, src step, dest step
        DMACH5TransferConfig(TXTRANSFER,1,0); // transfer size, src step, dest step
        DMACH5ModeConfig(DMA_SPIATX,PERINT_ENABLE,ONESHOT_DISABLE,CONT_ENABLE,
        SYNC_DISABLE,SYNC_SRC,OVRFLOW_DISABLE,SIXTEEN_BIT,
        CHINT_END,CHINT_DISABLE);
    
        //
        // configure DMA CH2 for RX
        //
        DMACH6AddrConfig(DMADest,&SpibRegs.SPIRXBUF);
        DMACH6BurstConfig(RXBURST,0,1);
        DMACH6TransferConfig(RXTRANSFER,0,1);
        DMACH6ModeConfig(DMA_SPIBRX,PERINT_ENABLE,ONESHOT_DISABLE,CONT_ENABLE,
        SYNC_DISABLE,SYNC_SRC,OVRFLOW_DISABLE,SIXTEEN_BIT,
        CHINT_END,CHINT_DISABLE);
    }
    //
    // End of file
    //
    

    Regards,

    Veena

  • Hi,

    To add, the TX Transfer size to be configured must be (Number of words)/(16 - TXFIFO_LVL) - 1 instead of (Number of words)/(TXFIFO_LVL) - 1

    This is because the burst size is 16- TXFIFO_LVL and not TXFIFO_LVL

    Regards,
    Veena

  • Hi Veena 
    Thank you for your effort, Yes your code works on 12 and 8 TX, RX FIFO levels but it is not work on 10,11,13,14 FIFO level. For each change in FIFO level i changed the number of words to be integer. I became more confused.

    Regards

  • HI Hosam,

    I changed the FIFO levels to 10 and 11 and I still see the data being received correctly. Note that I changed the total data size to be multiple of FIFOLVL and 16-FIFOLVL. For example, if I set TX & RX FIFOLVL is 10, TX burst size is 6 and RX burst size is 10 and the transfer happens in a chunks of 6 words and 10 words. i adjusted the total buffer to be a multiple of both 6 and 10.

    Regards,
    Veena
  • Hi Hosam,

    Were you able to resolve your issue?

    Regards,
    Veena
  • Hi Veena,
    For sorry the same issue is still. However, I am not convinced by making a special configuration for each fifo level even the result of this equation [(MEM_BUFFER_SIZE/FIFO_LVL)-1] is not integer. Sure TX/RX burst must be right but am talking about the previous equation result. As a result of the above two lines, the code should work for any number of fifo (1-16) without problem unless hardware fault or another hidden configuration.

    thanks
    Hosam
  • Hi Hosam,

    I understand your point. I was able to reproduce the issue you are talking. I will discuss this with the design engineers and get back to you.
    One recommendation I would like to convey is, I feel it is better if we keep the burst sizes same on both Tx and Rx sides. So on the TX side, you send B amount of data at once and at the Rx side you receive B amount of data. That , I feel, is a cleaner approach (I am not sure whether this is documented in the TRM. I will check with design team if this is the recommended approach).

    I updated the above code to have TXFIFOLVL as 11 and RXFIFOLVL as 5. So TX DMA transfers 5 data at once, RX SPI receives this 5 data and DMA again transfers this 5 data to RAM.
    When I updated the code to set both TX and RX FIFOLVLs as 11, I found that the received data was out for order. i am not sure why this behavior

    Regards,
    Veena
  • Hi Hosam,

    You were using DMA continuous mode which means, even after the transfer is complete it will reinitialize the DMA to transfer the data again from the start. Did you intend to have this option enabled? If you want to send the buffer once, I recommend you to disable the continuous mode.
    If you are viewing the rxData through the memory browser/expressions window, you will find it out of order because the DMA transfer is still happening in the background while the debugger is fetching the rxData contents on the memory browser. The JTAG reads the rxData contents one by one at a clock which is much slower than the DMA clock. You can disable this by configuring the FREE bit in DEBUGCTRL register in DMA. By configuring a value of 0, DMA transfer will be frozen when you halt the debugger.

    Hope this helps.

    Regards,
    Veena
  • Thank u so much Veena for your effort,
    Now i got the point but when disabling continues mode for DMA and make it free to run, the data out of order but it is OK. Thanks to ur effort I gotcha. 

    Many thanks