Skip to main content
MHank.1
Associate III
April 10, 2023
Solved

STM32F722ZE SPI with DMA Reset question

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.

This topic has been closed for replies.
MHank.1
MHank.1Best answer
Associate III
April 10, 2023

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 @ JaxCoder.com

1 reply

MHank.1
MHank.1AuthorBest answer
Associate III
April 10, 2023

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 @ JaxCoder.com