title: STM32F - SPI with DMA "ErrorCallback" and frames shifted
body: <p>I am communicating 2 uC (an arduino display as MASTER and STM32F429 as slave).Its communication consists of 10 bytes in full duplex through SPI using DMA, every 150ms.</p>
  
  <p>During some minutes the communication goes very good, both uC are sending their 10 bytes properly. During this time, I have noted that "HAL_SPI_ErrorCallback" function is called becasue I have added a counter within and it is increased little by little, but the comminication still goes well.</p>
  
  <p>My first question is: Is it normal that sometimes ErrorCallback function is called randomly? due to noise or whatever the communication has an instantaneous error... I guess..</p>
  
  <p><a href="https://i.stack.imgur.com/7wHAR.jpg" rel="nofollow noreferrer">Here are a capture of the MISO signal in green, CLK in whie and CS in yellow</a></p>
  
  <p>On the other hand, after a while (randomly 10 min, 1h ...) the communication is corrupted just in the MISO signal , the STM32 sends the 10 bytes frame but instead of sending Byte0 Byte1 Byte2 Byte3 Byte4 Byte5 Byte6 Byte7 Byte8 Byte9 Byte10, (LSB first)</p>
  
  <p>it sends:</p>
  
  <p>Byte10 Byte0 Byte1 Byte2 Byte3 Byte4 Byte5 Byte6 Byte7 Byte8 Byte9, IT IS MOVED TO RIGTH 1 byte!?!?</p>
  
  <p>Attached you can see the capture "Working.jpg" with byte0 = 0x02 and the rest of the bytes = 0. In the other capture "NOT_working.jpg" is a capture with the problem. Both uC were working properly for a while and suddenly the STM32 uC started to send this frame all the time (the communication frame is byte = 0x02 and the rest of the bytes = 0 in order to see easily this error).</p>
  
  <p><a href="https://i.stack.imgur.com/CnLHq.jpg" rel="nofollow noreferrer">Working.jpg - which is MISO signal sending the frame properly</a></p>
  
  <p><a href="https://i.stack.imgur.com/Ox3ZM.jpg" rel="nofollow noreferrer">NOT_working.jpg - which is MISO signal sending the frame incorrectly</a></p>
  
  <p>I have tried the communication in:
  "Init.Mode = DMA_NORMAL" and "DMA_CIRCULAR", and both configuration have the same behaviour.
  I have creaged the 2 variables in order to find out the problem:</p>
  
  <pre><code>    DMA_counter_RX = __HAL_DMA_GET_COUNTER(&amp;hdma_spi6_rx);
      DMA_counter_TX = __HAL_DMA_GET_COUNTER(&amp;hdma_spi6_tx); 
  </code></pre>
  
  <p>And the the comunications goes well, DMA_counter_RX = 10 BUT DMA_counter_TX = 9. This values are normal. But as soon as the shift error occurs, both DMA counters are = 10.</p>
  
  <p>Also this problem always happens in debug mode when I click on "suspend" (pause) and "resume"(play) as soon as I click on "resume"  and the processor continues with the program, the MISO signal is shifted forever.</p>
  
  <p>Additionally I am using TIM1, TIM5, TIM2, TIM3 and TIM4 for other things like PWM and interruptions but not related to SPI...</p>
  
  <p>I have tried to solve this problem modifying all the NVIC priorities for all interruptions and so on but the problem get worst.</p>
  
  <p>I am using System Workbench for STM32  latest version.</p>
  
  <p>Any help is appreciate! Thanks in advance and best regards.</p>
  
  <p>Alejandro</p>
  
  <p>Sorry for long question... :(</p>
  
  <p>Bellow you can see my configuration for SPI and DMA if it can help you:</p>
  
  <pre><code>void MX_DMA_Init(void)
  {
    __HAL_RCC_DMA2_CLK_ENABLE();
  
  
  
    HAL_NVIC_SetPriority(DMA2_Stream5_IRQn, 2, 0);
    HAL_NVIC_EnableIRQ(DMA2_Stream5_IRQn);
    HAL_NVIC_SetPriority(DMA2_Stream6_IRQn, 2, 0);
    HAL_NVIC_EnableIRQ(DMA2_Stream6_IRQn);
  
  }
  
  void MX_SPI6_Init(void)
  {
  
    hspi6.Instance = SPI6;
    hspi6.Init.Mode = SPI_MODE_SLAVE;
    hspi6.Init.Direction = SPI_DIRECTION_2LINES;
    hspi6.Init.DataSize = SPI_DATASIZE_8BIT;
    hspi6.Init.CLKPolarity = SPI_POLARITY_LOW;
    hspi6.Init.CLKPhase = SPI_PHASE_1EDGE;
    hspi6.Init.NSS = SPI_NSS_HARD_INPUT;
    hspi6.Init.FirstBit = SPI_FIRSTBIT_MSB;
    hspi6.Init.TIMode = SPI_TIMODE_DISABLE;
    hspi6.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE;
    hspi6.Init.CRCPolynomial = 10;
    if (HAL_SPI_Init(&amp;hspi6) != HAL_OK)
    {
      Error_Handler();
    }
  
  }
  
  void HAL_SPI_MspInit(SPI_HandleTypeDef* hspi)
  {
  
        GPIO_InitTypeDef GPIO_InitStruct;
        if(hspi-&gt;Instance==SPI6)
        {
          __HAL_RCC_SPI6_CLK_ENABLE();
  
  
  
          /**SPI6 GPIO Configuration
          PG8     ------&gt; SPI6_NSS
          PG12     ------&gt; SPI6_MISO
          PG13     ------&gt; SPI6_SCK
          PG14     ------&gt; SPI6_MOSI
          */
          GPIO_InitStruct.Pin = GPIO_PIN_8|GPIO_PIN_12|GPIO_PIN_13|GPIO_PIN_14;
          GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
          GPIO_InitStruct.Pull = GPIO_NOPULL;
          GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_MEDIUM;
          GPIO_InitStruct.Alternate = GPIO_AF5_SPI6;
          HAL_GPIO_Init(GPIOG, &amp;GPIO_InitStruct);
  
  
  
          hdma_spi6_rx.Instance = DMA2_Stream6;
          hdma_spi6_rx.Init.Channel = DMA_CHANNEL_1;
          hdma_spi6_rx.Init.Direction = DMA_PERIPH_TO_MEMORY;
          hdma_spi6_rx.Init.PeriphInc = DMA_PINC_DISABLE;
          hdma_spi6_rx.Init.MemInc = DMA_MINC_ENABLE;
          hdma_spi6_rx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;
          hdma_spi6_rx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;
          hdma_spi6_rx.Init.Mode = DMA_NORMAL;
          hdma_spi6_rx.Init.Priority = DMA_PRIORITY_MEDIUM;
          hdma_spi6_rx.Init.FIFOMode = DMA_FIFOMODE_DISABLE;
          if (HAL_DMA_Init(&amp;hdma_spi6_rx) != HAL_OK)
          {
            Error_Handler();
          }
  
  
  
          __HAL_LINKDMA(hspi,hdmarx,hdma_spi6_rx);
  
  
  
          hdma_spi6_tx.Instance = DMA2_Stream5;
          hdma_spi6_tx.Init.Channel = DMA_CHANNEL_1;
          hdma_spi6_tx.Init.Direction = DMA_MEMORY_TO_PERIPH;
          hdma_spi6_tx.Init.PeriphInc = DMA_PINC_DISABLE;
          hdma_spi6_tx.Init.MemInc = DMA_MINC_ENABLE;
          hdma_spi6_tx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;
          hdma_spi6_tx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;
          hdma_spi6_tx.Init.Mode = DMA_NORMAL;
          hdma_spi6_tx.Init.Priority = DMA_PRIORITY_MEDIUM;
          hdma_spi6_tx.Init.FIFOMode = DMA_FIFOMODE_DISABLE;
          if (HAL_DMA_Init(&amp;hdma_spi6_tx) != HAL_OK)
          {
            Error_Handler();
          }
  
  
  
          __HAL_LINKDMA(hspi,hdmatx,hdma_spi6_tx);
  
  
  
          /* Peripheral interrupt init */
          HAL_NVIC_SetPriority(SPI6_IRQn, 2, 0);
          HAL_NVIC_EnableIRQ(SPI6_IRQn);
        }
  }
  </code></pre>
  
  <p>During initialization code, I configure SPI6 and DMA as it is described before, just after that I enable communication using:</p>
  
  <pre><code>HAL_SPI_TransmitReceive_DMA(&amp;hspi6, (uint8_t*)HMI_slave_TX_data, (uint8_t*)HMI_slave_RX_data, 10);
  </code></pre>
  
  <p>Also it were added the following 2 functions related to SPI communication:</p>
  
  <pre><code>void HAL_SPI_TxRxCpltCallback(SPI_HandleTypeDef *hspi)
  {
      if(hspi -&gt; Instance == SPI6)
      {
          HAL_SPI_TransmitReceive_DMA(&amp;hspi6, (uint8_t*)HMI_slave_TX_data, (uint8_t*)HMI_slave_RX_data, 10);
      }
  }
  
  
  
  
  
  void HAL_SPI_ErrorCallback(SPI_HandleTypeDef *hspi)
  {
      if(hspi -&gt; Instance == SPI6)
      {
  
          HAL_SPI_TransmitReceive_DMA(&amp;hspi6, (uint8_t*)HMI_slave_TX_data, (uint8_t*)HMI_slave_RX_data,10);
      }
  }
  </code></pre>
  
  <p>STM cube mx automatically created:</p>
  
  <pre><code>void DMA2_Stream5_IRQHandler(void)
  {
    /* USER CODE BEGIN DMA2_Stream5_IRQn 0 */
  
  
  
    /* USER CODE END DMA2_Stream5_IRQn 0 */
    HAL_DMA_IRQHandler(&amp;hdma_spi6_tx);
    /* USER CODE BEGIN DMA2_Stream5_IRQn 1 */
  
  
  
    /* USER CODE END DMA2_Stream5_IRQn 1 */
  }
  
  
  
  /**
  * @brief This function handles DMA2 stream6 global interrupt.
  */
  void DMA2_Stream6_IRQHandler(void)
  {
    /* USER CODE BEGIN DMA2_Stream6_IRQn 0 */
  
  
  
    /* USER CODE END DMA2_Stream6_IRQn 0 */
    HAL_DMA_IRQHandler(&amp;hdma_spi6_rx);
    /* USER CODE BEGIN DMA2_Stream6_IRQn 1 */
  
  
  
    /* USER CODE END DMA2_Stream6_IRQn 1 */
  }
  
  
  
  void SPI6_IRQHandler(void)
  {
    /* USER CODE BEGIN SPI6_IRQn 0 */
  
  
  
    /* USER CODE END SPI6_IRQn 0 */
    HAL_SPI_IRQHandler(&amp;hspi6);
    /* USER CODE BEGIN SPI6_IRQn 1 */
  
  
  
    /* USER CODE END SPI6_IRQn 1 */
  }
  </code></pre>
  
  <p>------------------------------EDITED----------------------------
  I add 2 captures of the SPI register </p>
  
  <p><a href="https://i.stack.imgur.com/SRDq8.png" rel="nofollow noreferrer">SPI registers WORKING</a></p>
  
  <h2><a href="https://i.stack.imgur.com/SH6ji.png" rel="nofollow noreferrer">SPI registers ERROR</a></h2>