AnsweredAssumed Answered

STM32F769 SPI missing data

Question asked by Jonathan Roberts on May 4, 2017
Latest reply on Jun 20, 2017 by waclawek.jan

Hi,

 

I am occasionally loosing a byte on SPI reads from an external ADC and would appreciate any suggestions about how to investigate further.

 

Summary: I have a FreeRTOS based application running on the STM32F769I Eval board. Periodically the application reads data from an external ADC (AD7606) connected via SPI. Data reads from the ADC are using DMA. Very occasionally (~one cluster in every 250000 transfers) I lose a byte in the middle of a number of successive transfers.  The missing data is visible on the bus an external SPI Analyser. The SPI Error interrupt never triggers.

 

Details:

  • The application is developed using the OpenSTM32 tools and CubeMX 4.19
  • The AD7606 is sampled at 1000Hz, driven by a hardware timer.
  • SPI & DMA Configuration
    • STM32 is the master
    • AD7606 is connected via SPI1
    • SPI Clock is 7.5MHz
    • Each SPI transfer is 16 bytes long.
    • The DMA transfer is from the SPI FIFO to external SDRAM.
    • SPI Configuration is:

      hspi1.Instance = SPI1;
      hspi1.Init.Mode = SPI_MODE_MASTER;
      hspi1.Init.Direction = SPI_DIRECTION_2LINES_RXONLY;
      hspi1.Init.DataSize = SPI_DATASIZE_8BIT;
      hspi1.Init.CLKPolarity = SPI_POLARITY_LOW;
      hspi1.Init.CLKPhase = SPI_PHASE_1EDGE;
      hspi1.Init.NSS = SPI_NSS_SOFT;
      hspi1.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_8;
      hspi1.Init.FirstBit = SPI_FIRSTBIT_MSB;
      hspi1.Init.TIMode = SPI_TIMODE_DISABLE;
      hspi1.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE;
      hspi1.Init.CRCPolynomial = 7;
      hspi1.Init.CRCLength = SPI_CRC_LENGTH_DATASIZE;
      hspi1.Init.NSSPMode = SPI_NSS_PULSE_DISABLE;

    • The DMA & GPIO Configuration is:

       

      /**SPI1 GPIO Configuration
      PB4 ------> SPI1_MISO
      PB3 ------> SPI1_SCK
      */
      GPIO_InitStruct.Pin = GPIO_PIN_4|GPIO_PIN_3;
      GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
      GPIO_InitStruct.Pull = GPIO_NOPULL;
      GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
      GPIO_InitStruct.Alternate = GPIO_AF5_SPI1;
      HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
      /* Peripheral DMA init*/

       

      hdma_spi1_rx.Instance = DMA2_Stream0;
      hdma_spi1_rx.Init.Channel = DMA_CHANNEL_3;
      hdma_spi1_rx.Init.Direction = DMA_PERIPH_TO_MEMORY;
      hdma_spi1_rx.Init.PeriphInc = DMA_PINC_DISABLE;
      hdma_spi1_rx.Init.MemInc = DMA_MINC_ENABLE;
      hdma_spi1_rx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;
      hdma_spi1_rx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;
      hdma_spi1_rx.Init.Mode = DMA_NORMAL;
      hdma_spi1_rx.Init.Priority = DMA_PRIORITY_VERY_HIGH;
      hdma_spi1_rx.Init.FIFOMode = DMA_FIFOMODE_DISABLE;
      if (HAL_DMA_Init(&hdma_spi1_rx) != HAL_OK)
      {
      Error_Handler();
      }
      __HAL_LINKDMA(spiHandle,hdmarx,hdma_spi1_rx);

 

  • The missing data is always an entire byte for example:
    On Bus:   0x24 0x06 0x24 0x0F 0x24 0x23 0x24 0x12 0x24 0x14 0x23 0xFA 0x24 0x06 0x24 0x10
    Received: 0x24 0x06 0x24 0x0F 0x23 0x24 0x12 0x24 0x14 0x23 0xFA 0x24 0x06 0x24 0x10 0x24
  • As mentioned in the summary, despite the HAL layer enabling SPI error interrupts, an error is never triggered.

 

Thanks in advance for any suggestions.

 

Jonathan

Outcomes