cancel
Showing results for 
Search instead for 
Did you mean: 

STM32F030C6T6 SPI DMA alignment problems

MaJo1
Associate

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;
  }
}

 

 

 

2 REPLIES 2
Uwe Bonnes
Principal II

Is the shift for bits or bytes? How are master and slave connected? Flying wires or on a board? Did you care for ringing by using a slow as possible slew rate ? Can you frame the messages with NSS?

Hello Uwe,

the shift is for bytes as you can see in the Debugger.png. Normal order should be 0x01, 0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00, 0x00,  0x00, 0xE0, 0x17 but after few minutes the order changed. The master and Slave are connected with flying wires. The wires lengths are perhaps 10 cm long. The baud rate was first at 1.2 MHz then I set it to 400 khz and I think the error occurs faster at 1.2 MHz. I use the NSS hardware pin. I've already set the NSS pin high when I'm not sending anything and only set it low during transmission, but that didn't help either. As I said, the transmission runs well for a few minutes, and then the error occurs and persists. The only solution then is to reset the controller. Is my SPI and DMA configuration correct? I don't know how to find the error; I've been searching for a long time. My slave is on a board. To test the slave, I used a development board as the master.  The messages I send from the master to the slave come at roughly 1.5 ms intervals.