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 SLAVE TRANSMISSON BY DMA

Part Number: LAUNCHXL-F28379D
Other Parts Discussed in Thread: C2000WARE

Hello TI people,


Now i can transmit data from MASTER SPI to SLAVE one using DMA but i cant receive data from slave DMA to Master.
BTW, I initiated MASTER CLock by sending DUMMY data before starting slave DMA channel that i configured for transmission.

is there any special configuration for this setup?


regards

  • Hi Hosam,

    Let me clarify your query. I suppose you have 2 devices connected via SPI. At the master device, you are able to use the DMA. But at the slave device, you do not receive the DMA request when the SPI data is received.

    Is my understanding correct?

    Regards,
    Veena
  • Hi Veena 
    Thanks for your quick response. yes there is a misunderstanding. Well, Master can use DMA for transmission and slave can use it for reception but when i programmed to the opposite case it was not work. I mean making MASETR DMA for reception and slave DMA for transmission.

    Note: I sent dummy data from Master to initiate slave transmission.

    I hope that is clear

    Thanks 

  • Hi Hosam,

    I understood the issue now.
    Could you look at the SPI + DMA example available at D:\ti\c2000\C2000Ware_1_00_03_00\driverlib\f28004x\examples\spi\spi_ex3_loopback_dma.c?
    The example is for a different device, but you could refer to this example on how the DMA is configured for both TX and RX.


    Regards,
    Veena
  • Hi Veena,
    This code is acting in the same way. I mean, Master sends data via DMA and Slave receives data via DMA too and this works fine with me. The problem as i stated for configuring Master to recive data via DMA and Slave sends data via DMA.
    thanks
  • Hi Hosam,

    So, I updated the the code i had shared in the other E2E thread to enable DMA for both TX and RX in SPI A and B. And it seems to work fine

    Attaching the code.

    2818.new.c
    //
    #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 Veena
    Sure, i know this code works fine in one direction. I mean master sends  data to slave using DMA channels correctly.
    while the opposite  case is  the  slave send data to master via DMA is not working.

    Pls, pls, if u got my point, let me know.

     

    thanks

    hosam

  • Hi Hosam,

    I think I posted the wrong code there.I do not have the code right now. but it was pretty much the same except I had configured DMA for both TX and RX on SPI A and B and it worked fine.

    Another point I want to highlight here is SPI is a full duplex communication peripheral which means both master and slave transmits and receives data at the same time. A write to master TXBUF initiates the transfer and the contents of slave TXBUF are also transferred. A write to slave TXBUF will not initiate a transfer. If you do not have any data to be sent from master, you can simply write 0 to TXBUF, just to initiate the transfer.

    Regards,
    Veena
  • Hi Veena,
    Yes i have made what u stated. Always i keep in mind this point
    "'''''''''''
    Another point I want to highlight here is SPI is a full duplex communication peripheral which means both master and slave transmits and receives data at the same time. A write to master TXBUF initiates the transfer and the contents of slave TXBUF are also transferred. A write to slave TXBUF will not initiate a transfer. If you do not have any data to be sent from master, you can simply write 0 to TXBUF, just to initiate the transfer.
    "'''''

    but no progress, Pls send me your tested code while u have it thanks.

    regards
    Hosam
  • Hi,

    Find attached the code for DMA configuration for both TX and RX on SPI A and B

    new3.c
    //
    #include "F28x_Project.h"
    
    //
    // Defines
    //
    #define TXFIFO_LVL          11 // FIFO Interrupt Level
    #define TXBURST             (16-TXFIFO_LVL)-1 // burst size should be less than 8
    #define TXTRANSFER          (uint32_t)((384/(16-TXFIFO_LVL)) - 1) // [(MEM_BUFFER_SIZE/FIFO_LVL)-1]
    
    #define RXFIFO_LVL          5 // FIFO Interrupt Level
    #define RXBURST             RXFIFO_LVL-1 // burst size should be less than 8
    #define RXTRANSFER          (uint32_t)((384/RXFIFO_LVL) - 1) // [(MEM_BUFFER_SIZE/FIFO_LVL)-1]
    
    //
    // Globals
    //
    #pragma DATA_SECTION(sdataA, "ramgs0"); // map the TX data to memory
    #pragma DATA_SECTION(rdataA, "ramgs1"); // map the RX data to memory
    #pragma DATA_SECTION(sdataB, "ramgs0"); // map the TX data to memory
    #pragma DATA_SECTION(rdataB, "ramgs1"); // map the RX data to memory
    Uint16 sdataA[384]; // Send data buffer
    Uint16 rdataA[384]; // Receive data buffer
    Uint16 sdataB[384]; // Send data buffer
    Uint16 rdataB[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++)
        {
            sdataA[i] = i;
            rdataA[i] = 0;
            sdataB[i] = 100 + i;
            rdataB[i] = 0;
        }
    
        StartDMACH6();
        StartDMACH4();
        StartDMACH3();
        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 SPI A TX
        //
        DMACH5AddrConfig(&SpiaRegs.SPITXBUF,sdataA);
        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 CH6 for SPI B RX
        //
        DMACH6AddrConfig(rdataB,&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);
    
        //
        // configure DMACH3 for SPI B TX
        //
        DMACH3AddrConfig(&SpibRegs.SPITXBUF,sdataB);
        DMACH3BurstConfig(TXBURST,1,0); // Burst size, src step, dest step
        DMACH3TransferConfig(TXTRANSFER,1,0); // transfer size, src step, dest step
        DMACH3ModeConfig(DMA_SPIBTX,PERINT_ENABLE,ONESHOT_DISABLE,CONT_ENABLE,
        SYNC_DISABLE,SYNC_SRC,OVRFLOW_DISABLE,SIXTEEN_BIT,
        CHINT_END,CHINT_DISABLE);
    
        //
        // configure DMA CH4 for SPI A RX
        //
        DMACH4AddrConfig(rdataA,&SpiaRegs.SPIRXBUF);
        DMACH4BurstConfig(RXBURST,0,1);
        DMACH4TransferConfig(RXTRANSFER,0,1);
        DMACH4ModeConfig(DMA_SPIARX,PERINT_ENABLE,ONESHOT_DISABLE,CONT_ENABLE,
        SYNC_DISABLE,SYNC_SRC,OVRFLOW_DISABLE,SIXTEEN_BIT,
        CHINT_END,CHINT_DISABLE);
    }
    //
    // End of file
    //
    

    Regards,

    Veena

  • Thank u so much Veena for your effort,
    See u in another Thread.

    Many thanks