2023-04-10 03:50 AM
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.
Solved! Go to Solution.
2023-04-10 06:41 AM
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;
}
2023-04-10 06:41 AM
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;
}