cancel
Showing results for 
Search instead for 
Did you mean: 

STM32F722ZE SPI with DMA Reset question

MHank.1
Associate III

I have a working, basic SPI transmit working with DMA. It transmits 20 characters in loopback mode and is working as it should.

The GPIO Pins are set up correctly.

SPI Configuration;

void SPIInit()
{
	RCC->APB2ENR |= RCC_APB2ENR_SPI1EN;
	// Master 
	SPI1->CR1 |= SPI_CR1_MSTR;
	SPI1->CR2 |= SPI_CR2_DS_0 | SPI_CR2_DS_1 | SPI_CR2_DS_2;
	SPI1->CR2 |= SPI_CR2_NSSP | SPI_CR2_SSOE;
	SPI1->CR2 |= SPI_CR2_TXDMAEN;	// For DMA
	SPI1->CR1 |= SPI_CR1_SPE;
}

DMA Configuration.

void Configure()
{
	// Enable DMA2 Clock
	RCC->AHB1ENR |= RCC_AHB1ENR_DMA2EN;
 
	// Select channel 3
	DMA2_Stream3->CR |= DMA_SxCR_CHSEL_0 | DMA_SxCR_CHSEL_1;
 
	DMA2_Stream3->PAR = (uint32_t) &SPI1->DR;
	DMA2_Stream3->M0AR = (uint32_t) &src;
 
	// Set the number of bytes to transfer
	DMA2_Stream3->NDTR = 20;
 
	DMA2_Stream3->CR |= DMA_SxCR_MINC;
 
	// Configure data direction Memory-To-Peripheral
	DMA2_Stream3->CR |= DMA_SxCR_DIR_0;
 
	// Enable DMA2, this begins transfer
	DMA2_Stream3->CR |= DMA_SxCR_EN;
}

Main routine;

void main()
{
	GPIOInit();
	SPIInit();
	Configure();
 
	while(1)
	{
		while(!(DMA2->LISR & DMA_LISR_TCIF3));
		DMA2_Stream3->NDTR = 20;
		DMA2->LISR = DMA_LISR_TCIF3 | DMA_LISR_HTIF3 | DMA_LISR_FEIF3;
		DMA2_Stream3->CR |= DMA_SxCR_EN;
	}
}

Output on my Logic Analyzer shows that 20 bytes are transmitted using the code above;

But I can't reset the DMA Stream to retransmit the data. This is just a POC, not the real deal I just want to lean how to do it.

PartsBin - An Electronic Parts Organizer for Windows
1 ACCEPTED SOLUTION

Accepted Solutions
MHank.1
Associate III

Another case of RTFM..

In the while loop I was trying to reset the LISR flags directly instead of the DMA low interrupt flag clear register (DMA_LIFCR) register.

	while(1)
	{
		while(!(DMA2->LISR & DMA_LISR_TCIF3));
		DMA2_Stream3->CR &= ~DMA_SxCR_EN;
		DMA2_Stream3->NDTR = 20;
		DMA2->LIFCR = DMA_LIFCR_CTCIF3 | DMA_LIFCR_CHTIF3 | DMA_LIFCR_CFEIF3;
		DMA2_Stream3->CR |= DMA_SxCR_EN;
	}

PartsBin - An Electronic Parts Organizer for Windows

View solution in original post

1 REPLY 1
MHank.1
Associate III

Another case of RTFM..

In the while loop I was trying to reset the LISR flags directly instead of the DMA low interrupt flag clear register (DMA_LIFCR) register.

	while(1)
	{
		while(!(DMA2->LISR & DMA_LISR_TCIF3));
		DMA2_Stream3->CR &= ~DMA_SxCR_EN;
		DMA2_Stream3->NDTR = 20;
		DMA2->LIFCR = DMA_LIFCR_CTCIF3 | DMA_LIFCR_CHTIF3 | DMA_LIFCR_CFEIF3;
		DMA2_Stream3->CR |= DMA_SxCR_EN;
	}

PartsBin - An Electronic Parts Organizer for Windows