AnsweredAssumed Answered

SPI DMA FIFO Error on SDRAM

Question asked by cho.young_sang on Dec 20, 2016
Latest reply on Jan 5, 2017 by cho.young_sang

Hi,

I'm working on 3-Wire(PF7-CLK,PF9-MOSI,PF8-MISO) SPI (SPI5, slave mode, direct mode) using a STM32F769-EVAL.

My goal is to transmit data from SDRAM buffer thru SPI to SPI-Master

I'm using "HAL_SPI_Transmit_DMA" function to test the above operation.

Here is my problem to setup the SPI DMA.

If It uses the inside SRAM(0x20000xxx) to transmit buffer, It is working fine.

But if It uses the SDRAM(0xC0000000) to transmit buffer, I get DMA FIFO error.

I referred to the example code of CubeMx(STM32Cube_FW_F7_V1.5.0).

it seems like a register setting problem but i can't find what is wrong.

The DMA FIFO error interrupt occurs immediately when HAL_SPI_Transmit_DMA performed.


Code:
1) DMA2 FIFO Error
pBuf = (uint8_t *)SDRAM_BANK_ADDR; //0xC0000000 -> SDRAM
if(HAL_SPI_Transmit_DMA(&hspi5, (uint8_t*)(pBuf), aPacketSz)!= HAL_OK)

2) Working Fine

uint8_t dbuf[6144*8]; //0x20000xxx -> SRAM
pBuf = (uint8_t *) dbuf;

if(HAL_SPI_Transmit_DMA(&hspi5, (uint8_t*)(pBuf), aPacketSz)!= HAL_OK)

-------------------------------------------------------------------------------------------------------------------------------------------------------------------

 

static void SPI_Init(void)
{
   hspi5.Instance = SPI5;
   hspi5.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_32;
   hspi5.Init.Direction = SPI_DIRECTION_2LINES;
   hspi5.Init.CLKPhase = SPI_PHASE_1EDGE;
   hspi5.Init.CLKPolarity = SPI_POLARITY_LOW;
   hspi5.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE;
   hspi5.Init.CRCPolynomial = 7;
   hspi5.Init.DataSize = SPI_DATASIZE_8BIT;
   hspi5.Init.FirstBit = SPI_FIRSTBIT_MSB;
   hspi5.Init.NSS = SPI_NSS_SOFT;
   hspi5.Init.TIMode = SPI_TIMODE_DISABLE;
   hspi5.Init.Mode = SPI_MODE_SLAVE;

   if (HAL_SPI_Init(&hspi5) != HAL_OK)
   {
      Error_Handler();
   }
}

 

void HAL_SPI_MspInit(SPI_HandleTypeDef* hspi)
{

   GPIO_InitTypeDef GPIO_InitStruct;
   if(hspi->Instance==SPI5)
   {
   /* Peripheral clock enable */
   __HAL_RCC_GPIOF_CLK_ENABLE();
   __HAL_RCC_SPI5_CLK_ENABLE();
   __HAL_RCC_DMA2_CLK_ENABLE();
   /**SPI5 GPIO Configuration
   PF7 ------> SPI5_SCK
   PF9 ------> SPI5_MOSI
   PF8 ------> SPI5_MISO
   */
   GPIO_InitStruct.Pin = GPIO_PIN_7;
   GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
   GPIO_InitStruct.Pull = GPIO_PULLUP;
   GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
   GPIO_InitStruct.Alternate = GPIO_AF5_SPI5;
   HAL_GPIO_Init(GPIOF, &GPIO_InitStruct);

   GPIO_InitStruct.Pin = GPIO_PIN_9|GPIO_PIN_8;
   GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
   GPIO_InitStruct.Pull = GPIO_NOPULL;
   GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
   GPIO_InitStruct.Alternate = GPIO_AF5_SPI5;
   HAL_GPIO_Init(GPIOF, &GPIO_InitStruct);

   /* Peripheral DMA init*/

   hdma_spi5_tx.Instance = DMA2_Stream4;
   hdma_spi5_tx.Init.Channel = DMA_CHANNEL_2;
   hdma_spi5_tx.Init.FIFOMode = DMA_FIFOMODE_DISABLE;
   hdma_spi5_tx.Init.FIFOThreshold = DMA_FIFO_THRESHOLD_FULL;
   hdma_spi5_tx.Init.MemBurst = DMA_MBURST_INC4;
   hdma_spi5_tx.Init.PeriphBurst = DMA_PBURST_INC4;
   hdma_spi5_tx.Init.Direction = DMA_MEMORY_TO_PERIPH;
   hdma_spi5_tx.Init.PeriphInc = DMA_PINC_DISABLE;
   hdma_spi5_tx.Init.MemInc = DMA_MINC_ENABLE;
   hdma_spi5_tx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;
   hdma_spi5_tx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;
   hdma_spi5_tx.Init.Mode = DMA_NORMAL;
   hdma_spi5_tx.Init.Priority = DMA_PRIORITY_LOW;

   if (HAL_DMA_Init(&hdma_spi5_tx) != HAL_OK)
   {
      Error_Handler();
   }
   __HAL_LINKDMA(hspi,hdmatx,hdma_spi5_tx);

   /* Configure the DMA handler for Transmission process */

   hdma_spi5_rx.Instance = DMA2_Stream3;
   hdma_spi5_rx.Init.Channel = DMA_CHANNEL_2;
   hdma_spi5_rx.Init.FIFOMode = DMA_FIFOMODE_DISABLE;
   hdma_spi5_rx.Init.FIFOThreshold = DMA_FIFO_THRESHOLD_FULL;
   hdma_spi5_rx.Init.MemBurst = DMA_MBURST_INC4;
   hdma_spi5_rx.Init.PeriphBurst = DMA_PBURST_INC4;
   hdma_spi5_rx.Init.Direction = DMA_PERIPH_TO_MEMORY;
   hdma_spi5_rx.Init.PeriphInc = DMA_PINC_DISABLE;
   hdma_spi5_rx.Init.MemInc = DMA_MINC_ENABLE;
   hdma_spi5_rx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;
   hdma_spi5_rx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;
   hdma_spi5_rx.Init.Mode = DMA_NORMAL;
   hdma_spi5_rx.Init.Priority = DMA_PRIORITY_HIGH;
   if (HAL_DMA_Init(&hdma_spi5_rx) != HAL_OK)
   {
      Error_Handler();
   }
   __HAL_LINKDMA(hspi,hdmarx,hdma_spi5_rx);

   // tx
   /* DMA2_Stream4_IRQn interrupt configuration */
   HAL_NVIC_SetPriority(DMA2_Stream4_IRQn, 0, 1);
   HAL_NVIC_EnableIRQ(DMA2_Stream4_IRQn);

   // rx
   /* DMA2_Stream3_IRQn interrupt configuration */
   HAL_NVIC_SetPriority(DMA2_Stream3_IRQn, 0, 0);
   HAL_NVIC_EnableIRQ(DMA2_Stream3_IRQn);

   // spi
   HAL_NVIC_SetPriority(SPI5_IRQn, 0, 1);
   HAL_NVIC_EnableIRQ(SPI5_IRQn);
   }
}

 

void DMA2_Stream3_IRQHandler(void)
{
   HAL_DMA_IRQHandler(hspi5.hdmarx);

}

void DMA2_Stream4_IRQHandler(void)
{
   HAL_DMA_IRQHandler(hspi5.hdmatx);
}

void SPI5_IRQHandler(void)
{
   HAL_SPI_IRQHandler(&hspi5);
}

Outcomes