cancel
Showing results for 
Search instead for 
Did you mean: 

STM32F469 SPI DMA repeat TX while filling RX buffer?

PGroe.2
Associate III

Hi there

I got an IC that needs to be fed with 32bit NOP words via SPI TX (0x00000000) to get 32bit data output via RX at the same time. Communication works fine in SPI polling mode but I really want to try to do it via DMA...

My RX buffer is an array of DMA maximum possible 65535 NDTR uint16_t's. For both TX/RX SPI-DMA I use max datawidth of 16bit. (I did not yet mess with data packaging so I use 2*uint16_t per send/receive word)

0693W000008zC2SQAU.pngWhat is the best way to constantly send those NOP's to the IC without creating a txBuffer of the same size as the rxBuffer (65535) until rxBuffer is full and then stop?

Is it possible to use circular mode on TX only to repeatedly send 0x0000 while RX fills the big rxBuffer?

2 REPLIES 2
Piranha
Chief II

Just don't set MINC bit in DMA_SxCR register for Tx and the DMA will send the same integer over and over again.

PGroe.2
Associate III

Thanks, I think I got it. I changed the txBuffer array to an normal uint16_t initialized with 0 and changed TX MemoryAddress accordingly. I set both TX/RX datalenght

to maximum of 65535 and as suggested TX MemoryIncr. to none.

I enabled DMA RX TC interrupt and I stop both streams in it. Seems to work so far :):

uint16_t rxRawData[65535] = {0x0000};
 
void GET_DATA(void){
	uint16_t txbuf = 0x0000;
	
	LL_DMA_DisableStream(DMA2, LL_DMA_STREAM_3);               // TX
	while(LL_DMA_IsEnabledStream(DMA2, LL_DMA_STREAM_3));
	LL_DMA_DisableStream(DMA2, LL_DMA_STREAM_0);               // RX
	while(LL_DMA_IsEnabledStream(DMA2, LL_DMA_STREAM_0));      
 
	LL_DMA_SetPeriphAddress(DMA2, LL_DMA_STREAM_3, (uint32_t)&SPI1->DR);
	LL_DMA_SetMemoryAddress(DMA2, LL_DMA_STREAM_3, (uint32_t)&txbuf);
	LL_DMA_SetPeriphAddress(DMA2, LL_DMA_STREAM_0, (uint32_t)&SPI1->DR);
	LL_DMA_SetMemoryAddress(DMA2, LL_DMA_STREAM_0, (uint32_t)rxRawData);
 
	LL_DMA_SetMemoryIncMode(DMA2, LL_DMA_STREAM_3, LL_DMA_MEMORY_NOINCREMENT);
	
	LL_DMA_SetDataLength(DMA2, LL_DMA_STREAM_3, 65535);
	LL_DMA_SetDataLength(DMA2, LL_DMA_STREAM_0, 65535);
	LL_DMA_EnableIT_TC(DMA2, LL_DMA_STREAM_3);
	LL_DMA_DisableIT_HT(DMA2, LL_DMA_STREAM_3);
	LL_DMA_EnableIT_TE(DMA2, LL_DMA_STREAM_3);
	LL_DMA_EnableIT_TC(DMA2, LL_DMA_STREAM_0);
	LL_DMA_EnableIT_TE(DMA2, LL_DMA_STREAM_0);
 
	LL_SPI_EnableDMAReq_TX(SPI1);
	LL_SPI_EnableDMAReq_RX(SPI1);
 
	CS(1);
	LL_DMA_EnableStream(DMA2, LL_DMA_STREAM_0);
	LL_DMA_EnableStream(DMA2, LL_DMA_STREAM_3);
}
 
void SPI1RX_DMA_TC_Callback(void){
		LL_DMA_DisableStream(DMA2, LL_DMA_STREAM_0);
		LL_SPI_DisableDMAReq_RX(SPI1);
		LL_DMA_DisableStream(DMA2, LL_DMA_STREAM_3);
		LL_SPI_DisableDMAReq_TX(SPI1);
                CS(0)
}

I succesfuly receive data until rxBuffer is full :) 0693W000008zCP7QAM.png