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.

SPI with DMA in slave mode needs a SPI reset after each transfer

Other Parts Discussed in Thread: CC3200

Hello,

this posting is somewhat related to my last SPI/DMA question:
e2e.ti.com/.../399482

I now have a setup that works at 4MHz and allows me to transfer an arbitrary number of 1024 byte blocks over SPI and DMA and with FIFO between two CC3200 boards. However, my setup requires me to restart the slave's SPI interface after every transfer (after every End of Word (EOW) interrupt).
The master simply requires me to setup the DMA requests again:
void spi_transfer(uint8_t* tx, uint8_t* rx)
{
    transfer_complete = 0;
    SetupTransfer(UDMA_CH30_GSPI_RX,UDMA_MODE_BASIC,DMA_SIZE,
                UDMA_SIZE_8,UDMA_ARB_1,
                (void *)(GSPI_BASE + MCSPI_O_RX0),UDMA_SRC_INC_NONE,
                rx,UDMA_DST_INC_8);

    SetupTransfer(UDMA_CH31_GSPI_TX,UDMA_MODE_BASIC,DMA_SIZE,
                UDMA_SIZE_8,UDMA_ARB_1,
                tx,UDMA_SRC_INC_8,
                (void *)(GSPI_BASE + MCSPI_O_TX0),UDMA_DST_INC_NONE);    
    SPICSEnable(GSPI_BASE);
    // wait for the transfer to complete
    while(!transfer_complete)
    {}
}

However, the slave requires me to issue a SPIReset and then configure the SPI interface again (I would expect to only need the two SetupTransfer calls):
void spi_transfer(uint8_t* tx, uint8_t* rx)
{
    MAP_SPIReset(GSPI_BASE);

    //UDMAInit();

    MAP_SPIConfigSetExpClk(GSPI_BASE,MAP_PRCMPeripheralClockGet(PRCM_GSPI),
                     SPI_IF_BIT_RATE,SPI_MODE_SLAVE,SPI_SUB_MODE_0,
                     (SPI_HW_CTRL_CS |
                     SPI_4PIN_MODE |
                     SPI_TURBO_OFF |
                     SPI_CS_ACTIVEHIGH |
                     SPI_WL_8));    
    MAP_SPIIntRegister(GSPI_BASE,interrupt_handler);

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

    SetupTransfer(UDMA_CH31_GSPI_TX,UDMA_MODE_BASIC,DMA_SIZE,
                UDMA_SIZE_8,UDMA_ARB_1,
                tx,UDMA_SRC_INC_8,
        (void *)(GSPI_BASE + MCSPI_O_TX0),UDMA_DST_INC_NONE);
    
    MAP_SPIWordCountSet( GSPI_BASE, DMA_SIZE);
    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|SPI_TX_DMA);
    MAP_SPIIntEnable( GSPI_BASE, SPI_INT_EOW);
    MAP_SPIEnable(GSPI_BASE);

}


I attached the master.c and slave.c, as well as a ZIP archive of the whole project.

Am I setting SPI up correctly? Is there any other error in my code?

Thank you for your time!

Severin

8585.master.c
Fullscreen
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#include "common.h"
uint32_t transfer_complete = 0;
static void interrupt_handler()
{
uint32_t status = MAP_SPIIntStatus(GSPI_BASE,true);
MAP_SPIIntClear(GSPI_BASE,SPI_INT_EOW);
SPICSDisable(GSPI_BASE);
transfer_complete = 1;
if(!(status & SPI_INT_EOW) )
{
Message("Error: Unexpected SPI interrupt!\n\r");
while(1){};
}
}
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

2318.slave.c
Fullscreen
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#include "common.h"
void spi_transfer(uint8_t* tx, uint8_t* rx);
static void interrupt_handler()
{
uint32_t status = MAP_SPIIntStatus(GSPI_BASE,true);
MAP_SPIIntClear(GSPI_BASE,SPI_INT_EOW);
spi_transfer(tx_buffer,rx_buffer);
if(!(status & SPI_INT_EOW))
{
Message("Error: Unexpected SPI interrupt!\n\r");
while(1){};
}
}
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

dma_spi_duplex_example.zip

  • Hi Severin,

    Please try disabling and re-enabling the channel using MAP_SPIDisable(GSPI_BASE) and MAP_SPIEnable(GSPI_BASE) respectively instead of resetting and reconfiguring the whole SPI.

    Thanks and Regards,
    Praveen
  • Praveen, you are the best, thank you! I changed the code to:
    void spi_transfer(uint8_t* tx, uint8_t* rx)
    {
    MAP_SPIDisable(GSPI_BASE);
    SetupTransfer(UDMA_CH30_GSPI_RX,UDMA_MODE_BASIC,DMA_SIZE,
    UDMA_SIZE_8,UDMA_ARB_1,
    (void *)(GSPI_BASE + MCSPI_O_RX0),UDMA_SRC_INC_NONE,
    rx,UDMA_DST_INC_8);

    SetupTransfer(UDMA_CH31_GSPI_TX,UDMA_MODE_BASIC,DMA_SIZE,
    UDMA_SIZE_8,UDMA_ARB_1,
    tx,UDMA_SRC_INC_8,
    (void *)(GSPI_BASE + MCSPI_O_TX0),UDMA_DST_INC_NONE);
    MAP_SPIEnable(GSPI_BASE);
    }

    and it works perfectly.

    Thank you and best regards,
    Severin