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.

My working SPI with DMA example

Other Parts Discussed in Thread: CC3200, ENERGIA

Hello,

I have finally resolved all my problems with SPI, DMA and FIFO (see e2e.ti.com/.../399482 or e2e.ti.com/.../402137) and wanted to share my working examples with you. I hope they serve as a useful starting point for anyone who wants to work with SPI and DMA in the future.

My examples are compiling fine on Linux with gcc 4.9.3 from launchpad.net/gcc-arm-embedded. All you need to change is the path for the SDK in the Makefile.
The hardware setup is similar to the SPI example in the SDK: just connect two CC3200 via cable (Pins GND, P05, P06, P07 and P08). I have set the following jumpers: J6, J7, J8. J9. J10, J11, J12, J13.

transfer_1024_byte.zip implements a simple SPI/DMA transfer that will transfer 1024 (or whatever DMA_SIZE is set to) bytes from the master to the slave and back. It then calculates the buffer's CRC checksum and (on the master) compares the send checksum to the received checksum.

transfer_64k.zip shows how to transfer a 64k buffer from the master to the slave and back again.

If you have any questions or suggestions, please just let me know.

I want to give a special thanks to Praveen, who really helped me a lot to understand SPI/DMA and fix my bugs.

Cheers,
Severin

transfer_1024_byte.zip

transfer_64k.zip

  • Thanks for sharing Severin!

    It would be cool if you could place your source code on Github, as it will make it easier for people to find and use in the future.

    if this is not something that interests you, I'd consider placing in my Github for others to gain access to if you were find with this? I would of course reference your name in the code and README.

    Let me know your thoughts on my suggestions.

    Glenn

  • Hello Glenn,

    thank you, that is an excellent idea! I went ahead and created a github account and a repository:
    github.com/.../cc3200_dma_spi_example

    After checking with $employer, I released the code under the BSD 2-clause license: This should make it easy for everyone to use it. If you want, you can also link/copy/etc to to your repository. It might even be better, as your repositories surely have a higher visibility!

    Cheers,
    Severin
  • Hi Severin,

    Thanks that is fantastic, it will really assist others to have a bunch of open source code ready to use to develop CC3200 based products.

    And yes, I have created a Fork in my account so others will see this repository when they visit my account. This links back to you, so people know who the original creator was.

    Glenn.
  • Hello Glenn,

    Thank you! Yes, I hope it will be of help for future developers. In a way these are exactly the examples that I was looking for :-)

    For completeness' sake I extended my repository with an example of a simple SPI transfer without DMA and FIFO.

    Cheers,
    Severin
  • Thanks, I have Pulled the updates into my Forked repository.

    Glenn.
  • Thanks a lot Severin and Glenn.

    Regards,
    Siddaram
  • Thanks a lot Severin and Glenn.

    I am closing the thread, if needed please open a new thread and add a link to this one for reference

    Regards,
    Siddaram
  • Hi Severin,

    I would like to do that SPI slave only do receiving data without sending. Need I prepare tx_buffer and do function calls about TX such as SPIFIFOEnbale() and SPIDmaEnable()?

    Thx.

    --

    BR,

    Michael Wu

  • Hello Sir,
    Using your code, I have converted my program in energia for cc3200.

    I am able to transmit only 33 Bytes of data and when I transmit 100Bytes, the code freezes. I am attaching the code with the same:
    #include <Energia.h>
    #include <driverlib/udma.h>
    #include <driverlib/spi.h>
    #include <driverlib/prcm.h>
    #include "udma_if.h"
    #include "inc/hw_mcspi.h"

    #define NBYTES 33
    #define SPIhz 1000000

    volatile int spidone;

    void SPIisr() {
    uint32_t status = MAP_SPIIntStatus(GSPI_BASE,true);
    MAP_SPIIntClear(GSPI_BASE,SPI_INT_EOW);
    MAP_SPIIntClear(GSPI_BASE,status);
    spidone = 1;
    MAP_SPICSDisable(GSPI_BASE);
    }

    void SPIinit() {
    MAP_PRCMPeripheralClkEnable(PRCM_GSPI, PRCM_RUN_MODE_CLK);

    MAP_PinTypeSPI(PIN_05, PIN_MODE_7); // SCLK pin 7
    MAP_PinTypeSPI(PIN_06, PIN_MODE_7); // MISO pin 14
    MAP_PinTypeSPI(PIN_07, PIN_MODE_7); // MOSI pin 15
    MAP_PinTypeSPI(PIN_08, PIN_MODE_7); // CS pin 18

    MAP_SPIReset(GSPI_BASE);
    UDMAInit();
    MAP_SPIConfigSetExpClk(GSPI_BASE,MAP_PRCMPeripheralClockGet(PRCM_GSPI),
    SPIhz,SPI_MODE_MASTER,SPI_SUB_MODE_0,
    (SPI_SW_CTRL_CS |
    SPI_4PIN_MODE |
    SPI_TURBO_OFF |
    SPI_CS_ACTIVELOW |
    SPI_WL_8));


    MAP_SPIWordCountSet(GSPI_BASE, NBYTES);
    MAP_SPIFIFOLevelSet(GSPI_BASE, 1, 1);
    MAP_SPIFIFOEnable(GSPI_BASE, SPI_RX_FIFO);
    MAP_SPIFIFOEnable(GSPI_BASE, SPI_TX_FIFO);
    MAP_SPIDmaEnable(GSPI_BASE,SPI_RX_DMA);
    MAP_SPIDmaEnable(GSPI_BASE,SPI_TX_DMA);
    MAP_SPIIntRegister(GSPI_BASE,SPIisr);
    MAP_SPIIntEnable(GSPI_BASE, SPI_INT_EOW);
    MAP_SPIEnable(GSPI_BASE);
    Serial.println("SPI Initialization Completed");
    }

    void spi_transfer(uint8_t* tx, uint8_t* rx)
    {
    Serial.println("DMA transfer setting up");
    spidone = 0;
    SetupTransfer(UDMA_CH31_GSPI_TX,
    UDMA_MODE_BASIC,
    NBYTES,
    UDMA_SIZE_8,
    UDMA_ARB_1,
    tx,
    UDMA_SRC_INC_8,
    (void *)(GSPI_BASE + MCSPI_O_TX0),
    UDMA_DST_INC_NONE);

    SetupTransfer(UDMA_CH30_GSPI_RX,
    UDMA_MODE_BASIC,
    NBYTES,
    UDMA_SIZE_8,
    UDMA_ARB_1,
    (void *)(GSPI_BASE + MCSPI_O_RX0),
    UDMA_SRC_INC_NONE,
    rx,
    UDMA_DST_INC_8);

    // Serial.println("waiting for SPI done");
    MAP_SPICSEnable(GSPI_BASE);
    while (!spidone) {
    Serial.print(".");
    delay(1);
    }
    //

    Serial.println("DMA transfer completed");
    }

    uint8_t rxbuf[NBYTES]={0};
    uint8_t txbuf[NBYTES];
    uint8_t test[NBYTES]={1};
    uint8_t test1[NBYTES]={2};
    int i = 0;
    void setup()
    {
    Serial.begin(115200);
    SPIinit();
    for(int j=0;j<NBYTES;j++){
    test[j]=1;
    test1[j]=2;
    }

    }

    void loop()
    {

    for (int k = 0; k < NBYTES; k++) {
    txbuf[k] = i+k+10;
    Serial.println(rxbuf[k]);
    }
    spi_transfer(txbuf, rxbuf);
    delay(2000);
    // spi_transfer(test, rxbuf);
    // delay(1000);
    // spi_transfer(test1, rxbuf);
    // delay(1000);
    i++;
    }

    Please let me know how to correct it.

    Regards
    Nitish