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.
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
#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){}; } } void spi_setup() { MAP_SPIReset(GSPI_BASE); UDMAInit(); MAP_SPIConfigSetExpClk(GSPI_BASE,MAP_PRCMPeripheralClockGet(PRCM_GSPI), SPI_IF_BIT_RATE,SPI_MODE_MASTER,SPI_SUB_MODE_0, (SPI_SW_CTRL_CS | SPI_4PIN_MODE | SPI_TURBO_OFF | SPI_CS_ACTIVEHIGH | SPI_WL_8)); MAP_SPIIntRegister(GSPI_BASE,interrupt_handler); 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); MAP_SPIDmaEnable(GSPI_BASE,SPI_TX_DMA); MAP_SPIIntEnable(GSPI_BASE, SPI_INT_EOW); MAP_SPIEnable(GSPI_BASE); } 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) {} } int main() { uint32_t tx_crc = 0; uint32_t tx_crc_old = 0; uint32_t a = 364; uint32_t b = 53457; uint32_t c = 976; uint32_t d = 66; uint32_t error_counter = 0; uint32_t transfer_counter = 0; init(); // initialize buffers with some known value memset(tx_buffer,0x33,sizeof(tx_buffer)); memset(rx_buffer,0x44,sizeof(rx_buffer)); // wait for keystroke: this gives the user time to start the slave Report("Start the slave and press any key to transmit data....\n\r"); MAP_UARTCharGet(UARTA0_BASE); spi_setup(); tx_crc = fill_buffer(tx_buffer,DMA_SIZE); // One "dummy" transfer, to fill the slave's TX buffer // this gets rid of the first "wrong" transfer in which // we would only receive the slave's default buffer values spi_transfer(tx_buffer,rx_buffer); while(1) { tx_crc_old = tx_crc; change_seed(a++,b++,c++,d++); tx_crc = fill_buffer(tx_buffer,DMA_SIZE); spi_transfer(tx_buffer,rx_buffer); /* // uncomment for step-by-step transfers print_buffer(rx_buffer,DMA_SIZE,"RX"); print_buffer(tx_buffer,DMA_SIZE,"TX"); Report("Press any key to start the next transfer...\n\r"); MAP_UARTCharGet(UARTA0_BASE); */ if(crc(rx_buffer,DMA_SIZE) != tx_crc_old) { error_counter++; } transfer_counter++; if(transfer_counter == 100) { Report("Transferred 100 items, %d errors!\n\r",error_counter); error_counter = 0; transfer_counter = 0; Report("Press any key to test again\n\r"); MAP_UARTCharGet(UARTA0_BASE); } } return 0; }
#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){}; } } /* * Here we should get rid of everything, but the 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); } void spi_setup() { 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); 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); } int main() { init(); // initialize buffers with some known value memset(tx_buffer,0x55,sizeof(tx_buffer)); memset(rx_buffer,0x22,sizeof(rx_buffer)); spi_setup(); spi_transfer(tx_buffer,rx_buffer); Message("Enabled SPI Interface in Slave Mode!\n\r"); while(1) { memcpy(tx_buffer,rx_buffer,DMA_SIZE); // here we could also change the tx_buffer // e.g. tx_buffer[0] = 18; } return 0; }