AnsweredAssumed Answered

Not all data sent out SPI using DMA

Question asked by Dan Kendall on May 6, 2016
Latest reply on May 12, 2016 by Dan Kendall



I am using an Emcraft Vybrid SOM and am trying to transmit SPI data using DMA.  This is occurring on the M4 and I have the SPI configured using MQX, but use the following source for the actual transmit.  What I see on the SPI signals is that some of the data is sent, but not all of it, but it is the same data everytime.  I am sending a 48 byte buffer of incrementing values (0, 1, 2, 3, 4, 5, etc.).  What I am seeing makes me think that the DMA is sending data to the SPI transmit register as fast as it can, and is not being throttled by the SPI TFFF DMA request.  I am viewing the transmit data on a logic analyzer.  The SPI TCR is of size 13, and the TXFR FIFO registers show the data that was actually transmitted.  I am not using the receive of the SPI.




#define SIZE8  0

#define SIZE16 1

#define SIZE32 2

#define SIZE64 3


//Test using DMA 0 Channel 20, MUX 1

CCM_CCGR0 |= CCM_CCGR0_CG5(3); //DMA Channel Mux1



_int_install_kernel_isr(NVIC_DSPI2, SPI2_ISR);

_bsp_int_init(NVIC_DSPI2, 3, 0, TRUE);


SPI2_RSER |= 0x03000000; //Enable DMA request for TFFF (transmit buffer fill flash)

SPI2_MCR = 0x803F1002;

SPI2_TCR = 0;

DMAMUX1_CHCFG9 = 0; //Clear source


DMA0_TCD20_SADDR = 0; //Source Address For Transfer

DMA0_TCD20_ATTR = DMA_ATTR_SMOD(0) | DMA_ATTR_SSIZE(SIZE8) //Modulo and access size for source

  | DMA_ATTR_DMOD(0) | DMA_ATTR_DSIZE(SIZE8);//and destination

DMA0_TCD20_SOFF = 1; //source address offset in bytes after each access

DMA0_TCD20_SLAST = 0; //source address adjustment on major loop completion - used to reset TCD

DMA0_TCD20_DADDR = (volatile void*)(&SPI2_PUSHR); //Destination Address For Transfer

DMA0_TCD20_CITER_ELINKNO = 1; //current major count

DMA0_TCD20_DOFF = 0; //destination address offset in bytes after each access

DMA0_TCD20_DLASTSGA = 0; //destination address adjustment on major loop completion - used to reset TCD

DMA0_TCD20_BITER_ELINKNO = 1; //total major iteration count

DMA0_SERQ = 20;





//Setup the structure (data pointer and data size)

rw.BUFFER_LENGTH = writeData->dataSize;

rw.WRITE_BUFFER = (char_ptr)writeData->data;



_DCACHE_FLUSH(); //Cleans up data in external memory


DMAMUX1_CHCFG9 = 0; //Source = Clear

DMA0_TCD20_SADDR = (uint32_t)(rw.WRITE_BUFFER); //Source Address For Transfer

DMA0_TCD20_NBYTES_MLNO = DMA_NBYTES_MLNO_NBYTES(rw.BUFFER_LENGTH); //total number of bytes in minor loop


DMA0_TCD20_CSR = 0x08; //set all bits to zero

DMA0_TCD20_CSR |= 1;





0x00, 0x01, 0x02, 0x03, 0x04, 0x07, 0x0C, 0x12, 0x18, 0x1E, 0x24, 0x29, 0x2F


Thanks for any help,


Dan K.