STM32F030C6T6 SPI DMA alignment problems
Hello everyone,
I am facing a problem related to my STM32F030C6T6 controller
on SPI DMA transfers and hope for your support.
I'm using SPI DMA to continuously transfer data from the master to the slave controller. The message consists of 12 bytes
each transmitted in 8 bits. At first everything works
fine: The slave receives the data, processes it and sends it
appropriate answers back. This works for some
Minutes/seconds to approx. 30 minutes smoothly.
However, a problem suddenly arises: the message that the
Master sends appears to be shifted in the slave's SPI DMA. Although
the data is available, the order is no longer correct. this leads to
caused my protocol to no longer work correctly. This mistake
Then it goes all the way through, I had already thought maybe the DMA
pointer to the memory address can be reset, but unfortunately without
Success.
I tried to solve the problem by setting the FRXTH register
for CR2 (FIFO Reception Threshold), but without success. Himself
occurs when the slave only sends back the data received from the master
the problem occurs after a certain time. It's just the SPI module
initialized and no other interrupts can interrupt the process. The clock polarity is also the same on the slave and master.
I am aldready desperate and hope that someone has an idea.
Attached you will find a Logic Analyzer file that shows what the master
sends, as well as a debug file that shows the data in the array in which the
problem occurs.
I thank you in advance for your help and support!
void spi_init(void)
{
RCC->APB2ENR |= RCC_APB2ENR_SPI1EN;
NVIC_DisableIRQ(SPI1_IRQn);
SPI1->CR1 &= ~(SPI_CR1_MSTR); //SPI Slavemode
SPI1->CR2 |= (SPI_CR2_DS_0 | SPI_CR2_DS_1 | SPI_CR2_DS_2); //8Bit Daten
SPI1->CR1 &= ~SPI_CR1_CPOL; // Clock-Polarität auf 0 (Takt bei Ruhepegel 0)
SPI1->CR1 &= ~SPI_CR1_CPHA; // Clock-Phase auf 0 (erste Flanke bei Taktbeginn)
SPI1->CR1 &= ~SPI_CR1_LSBFIRST;
SPI1->CR2 |= SPI_CR2_FRXTH;
//SPI1->CR2 |= SPI_CR2_RXNEIE;
SPI1->CR2 |= (SPI_CR2_TXDMAEN);
SPI1->CR2 |= (SPI_CR2_RXDMAEN);
SPI1->CR1 |= (SPI_CR1_SPE);
}
void DMA_SPI_Init(void)
{
RCC->AHBENR |= RCC_AHBENR_DMAEN; //Start DMA1 Clock
//////////DMA SPI RX
DMA1_Channel2->CPAR = (uint32_t)&(SPI1->DR); //PerAdress Data register
DMA1_Channel2->CMAR = (uint32_t)&dma_SPI_RX[0]; //MemAdress
DMA1_Channel2->CNDTR = (uint32_t)12; //Anzahl Daten Inkremente
//DMA1_Channel2->CCR |= DMA_CCR_PL;
DMA1_Channel2->CCR |= DMA_CCR_CIRC | DMA_CCR_MINC; //PER-MEM ; CircMode; MemInc; Per32Bit; MEM32Bit; PioMed
//DAM IRG regestrieren
DMA1_Channel2->CCR |= DMA_CCR_TCIE; //DMA Transfer Complete interrupt
DMA1_Channel2->CCR |= DMA_CCR_EN; //DMA1 Channel1 Enable //DMA1 Channel1 Enable
////////////DMA SPI TX
DMA1_Channel3->CPAR = (uint32_t)&(SPI1->DR); //PerAdress
DMA1_Channel3->CMAR = (uint32_t)&dma_SPI_TX[0]; //MemAdress
DMA1_Channel3->CNDTR = (uint32_t)12; //Anzahl Daten Inkremente
DMA1_Channel3->CCR |= DMA_CCR_DIR | DMA_CCR_MINC;
NVIC_SetPriority(DMA1_Channel2_3_IRQn,0);
NVIC_EnableIRQ(DMA1_Channel2_3_IRQn);
DMA1_Channel3->CCR |= DMA_CCR_TCIE; //DMA Transfer Complete interrupt
DMA1_Channel3->CCR |= DMA_CCR_EN; //DMA1 Channel1 Enable
}
//DMA SPI RX und TX
void DMA1_Channel2_3_IRQHandler(void)
{
//TX Interruptflag vom DMA (SPI)
if(DMA1->ISR & DMA_ISR_TCIF3)
{
DMA1->IFCR |= DMA_IFCR_CTCIF3;
}
//RX Interruptflag vom DMA (SPI)
if(DMA1->ISR & DMA_ISR_TCIF2)
{
if(spi_interface.reason_for_id_message == false)
{
SPI_Protokoll_state();
}
else
{
// Senden aus der MAIN die ID Message
DMA1_Channel3->CCR &= ~(DMA_CCR_EN);
DMA1_Channel3->CNDTR = (uint32_t)0x0C;
DMA1_Channel3->CCR |= (DMA_CCR_EN);
}
DMA1->IFCR |= DMA_IFCR_CTCIF2;
}
}
