cancel
Showing results for 
Search instead for 
Did you mean: 

SPI DMA FIFO Error on SDRAM

ys1
Associate II
Posted on December 20, 2016 at 19:20

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

}
3 REPLIES 3
Posted on December 21, 2016 at 01:23

And can you write into the SDRAM or read from it directly?

JW

ys1
Associate II
Posted on December 21, 2016 at 01:49

Yes , The SDRAM  is working fine. 

I referred to the example code at 'FMC/FMC_SDRAM' on

CubeMx(STM32Cube_FW_F7_V1.5.0).

 

I can read and write on the IAR IDE.

Thanks,

YC

Posted on January 05, 2017 at 02:42

I solved the problem as below.

But I don't know if this is the right thing to do.

void DMA2_Stream4_IRQHandler(void)

{

   hspi5.hdmatx->Instance->FCR &= ~DMA_IT_FE;

   HAL_DMA_IRQHandler(hspi5.hdmatx);

}

Please advise for me

Thanks,

YC