#include "../../../gfx.h" #undef Red #undef Green #undef Blue #include "stm32f746g_discovery_sdram.h" #include "stm32f7xx_hal_rcc.h" #include "stm32f7xx_hal_dma.h" #include "stm32f7xx_hal_gpio.h" #include "stm32f7xx_hal_sdram.h" #if GFX_USE_OS_CHIBIOS #define HAL_GPIO_Init(port, ptr) palSetGroupMode(port, (ptr)->Pin, 0, (ptr)->Mode|((ptr)->Speed<<3)|((ptr)->Pull<<5)|((ptr)->Alternate<<7)) #endif #define SDRAM_MEMORY_WIDTH FMC_SDRAM_MEM_BUS_WIDTH_16 #define SDCLOCK_PERIOD FMC_SDRAM_CLOCK_PERIOD_2 #define REFRESH_COUNT ((uint32_t)0x0603) /* SDRAM refresh counter (100Mhz SD clock) */ #define SDRAM_TIMEOUT ((uint32_t)0xFFFF) /* DMA definitions for SDRAM DMA transfer */ #define __DMAx_CLK_ENABLE __HAL_RCC_DMA2_CLK_ENABLE #define SDRAM_DMAx_CHANNEL DMA_CHANNEL_0 #define SDRAM_DMAx_STREAM DMA2_Stream0 #define SDRAM_DMAx_IRQn DMA2_Stream0_IRQn /* FMC SDRAM Mode definition register defines */ #define SDRAM_MODEREG_BURST_LENGTH_1 ((uint16_t)0x0000) #define SDRAM_MODEREG_BURST_LENGTH_2 ((uint16_t)0x0001) #define SDRAM_MODEREG_BURST_LENGTH_4 ((uint16_t)0x0002) #define SDRAM_MODEREG_BURST_LENGTH_8 ((uint16_t)0x0004) #define SDRAM_MODEREG_BURST_TYPE_SEQUENTIAL ((uint16_t)0x0000) #define SDRAM_MODEREG_BURST_TYPE_INTERLEAVED ((uint16_t)0x0008) #define SDRAM_MODEREG_CAS_LATENCY_2 ((uint16_t)0x0020) #define SDRAM_MODEREG_CAS_LATENCY_3 ((uint16_t)0x0030) #define SDRAM_MODEREG_OPERATING_MODE_STANDARD ((uint16_t)0x0000) #define SDRAM_MODEREG_WRITEBURST_MODE_PROGRAMMED ((uint16_t)0x0000) #define SDRAM_MODEREG_WRITEBURST_MODE_SINGLE ((uint16_t)0x0200) static void BSP_SDRAM_Initialization_sequence(SDRAM_HandleTypeDef *hsdram, uint32_t RefreshCount); static void BSP_SDRAM_MspInit(SDRAM_HandleTypeDef *hsdram); static void _HAL_SDRAM_Init(SDRAM_HandleTypeDef *hsdram, FMC_SDRAM_TimingTypeDef *Timing); static HAL_StatusTypeDef _FMC_SDRAM_Init(FMC_SDRAM_TypeDef *Device, FMC_SDRAM_InitTypeDef *Init); static HAL_StatusTypeDef _FMC_SDRAM_Timing_Init(FMC_SDRAM_TypeDef *Device, FMC_SDRAM_TimingTypeDef *Timing, uint32_t Bank); static HAL_StatusTypeDef _FMC_SDRAM_SendCommand(FMC_SDRAM_TypeDef *Device, FMC_SDRAM_CommandTypeDef *Command, uint32_t Timeout); static HAL_StatusTypeDef _FMC_SDRAM_ProgramRefreshRate(FMC_SDRAM_TypeDef *Device, uint32_t RefreshRate); static void _HAL_SDRAM_Init(SDRAM_HandleTypeDef *hsdram, FMC_SDRAM_TimingTypeDef *Timing) { /* Check the SDRAM handle parameter */ if(hsdram == NULL) return; if(hsdram->State == HAL_SDRAM_STATE_RESET) { /* Allocate lock resource and initialize it */ hsdram->Lock = HAL_UNLOCKED; } /* Initialize the SDRAM controller state */ hsdram->State = HAL_SDRAM_STATE_BUSY; /* Initialize SDRAM control Interface */ _FMC_SDRAM_Init(hsdram->Instance, &(hsdram->Init)); /* Initialize SDRAM timing Interface */ _FMC_SDRAM_Timing_Init(hsdram->Instance, Timing, hsdram->Init.SDBank); /* Update the SDRAM controller state */ hsdram->State = HAL_SDRAM_STATE_READY; } static HAL_StatusTypeDef _FMC_SDRAM_Init(FMC_SDRAM_TypeDef *Device, FMC_SDRAM_InitTypeDef *Init) { uint32_t tmpr1 = 0; uint32_t tmpr2 = 0; /* Set SDRAM bank configuration parameters */ if (Init->SDBank != FMC_SDRAM_BANK2) { tmpr1 = Device->SDCR[FMC_SDRAM_BANK1]; /* Clear NC, NR, MWID, NB, CAS, WP, SDCLK, RBURST, and RPIPE bits */ tmpr1 &= ((uint32_t)~(FMC_SDCR1_NC | FMC_SDCR1_NR | FMC_SDCR1_MWID | \ FMC_SDCR1_NB | FMC_SDCR1_CAS | FMC_SDCR1_WP | \ FMC_SDCR1_SDCLK | FMC_SDCR1_RBURST | FMC_SDCR1_RPIPE)); tmpr1 |= (uint32_t)(Init->ColumnBitsNumber |\ Init->RowBitsNumber |\ Init->MemoryDataWidth |\ Init->InternalBankNumber |\ Init->CASLatency |\ Init->WriteProtection |\ Init->SDClockPeriod |\ Init->ReadBurst |\ Init->ReadPipeDelay ); Device->SDCR[FMC_SDRAM_BANK1] = tmpr1; } else /* FMC_Bank2_SDRAM */ { tmpr1 = Device->SDCR[FMC_SDRAM_BANK1]; /* Clear NC, NR, MWID, NB, CAS, WP, SDCLK, RBURST, and RPIPE bits */ tmpr1 &= ((uint32_t)~(FMC_SDCR1_NC | FMC_SDCR1_NR | FMC_SDCR1_MWID | \ FMC_SDCR1_NB | FMC_SDCR1_CAS | FMC_SDCR1_WP | \ FMC_SDCR1_SDCLK | FMC_SDCR1_RBURST | FMC_SDCR1_RPIPE)); tmpr1 |= (uint32_t)(Init->SDClockPeriod |\ Init->ReadBurst |\ Init->ReadPipeDelay); tmpr2 = Device->SDCR[FMC_SDRAM_BANK2]; /* Clear NC, NR, MWID, NB, CAS, WP, SDCLK, RBURST, and RPIPE bits */ tmpr2 &= ((uint32_t)~(FMC_SDCR1_NC | FMC_SDCR1_NR | FMC_SDCR1_MWID | \ FMC_SDCR1_NB | FMC_SDCR1_CAS | FMC_SDCR1_WP | \ FMC_SDCR1_SDCLK | FMC_SDCR1_RBURST | FMC_SDCR1_RPIPE)); tmpr2 |= (uint32_t)(Init->ColumnBitsNumber |\ Init->RowBitsNumber |\ Init->MemoryDataWidth |\ Init->InternalBankNumber |\ Init->CASLatency |\ Init->WriteProtection); Device->SDCR[FMC_SDRAM_BANK1] = tmpr1; Device->SDCR[FMC_SDRAM_BANK2] = tmpr2; } return HAL_OK; } static HAL_StatusTypeDef _FMC_SDRAM_Timing_Init(FMC_SDRAM_TypeDef *Device, FMC_SDRAM_TimingTypeDef *Timing, uint32_t Bank) { uint32_t tmpr1 = 0; uint32_t tmpr2 = 0; /* Set SDRAM device timing parameters */ if (Bank != FMC_SDRAM_BANK2) { tmpr1 = Device->SDTR[FMC_SDRAM_BANK1]; /* Clear TMRD, TXSR, TRAS, TRC, TWR, TRP and TRCD bits */ tmpr1 &= ((uint32_t)~(FMC_SDTR1_TMRD | FMC_SDTR1_TXSR | FMC_SDTR1_TRAS | \ FMC_SDTR1_TRC | FMC_SDTR1_TWR | FMC_SDTR1_TRP | \ FMC_SDTR1_TRCD)); tmpr1 |= (uint32_t)(((Timing->LoadToActiveDelay)-1) |\ (((Timing->ExitSelfRefreshDelay)-1) << 4) |\ (((Timing->SelfRefreshTime)-1) << 8) |\ (((Timing->RowCycleDelay)-1) << 12) |\ (((Timing->WriteRecoveryTime)-1) <<16) |\ (((Timing->RPDelay)-1) << 20) |\ (((Timing->RCDDelay)-1) << 24)); Device->SDTR[FMC_SDRAM_BANK1] = tmpr1; } else /* FMC_Bank2_SDRAM */ { tmpr1 = Device->SDTR[FMC_SDRAM_BANK2]; /* Clear TMRD, TXSR, TRAS, TRC, TWR, TRP and TRCD bits */ tmpr1 &= ((uint32_t)~(FMC_SDTR1_TMRD | FMC_SDTR1_TXSR | FMC_SDTR1_TRAS | \ FMC_SDTR1_TRC | FMC_SDTR1_TWR | FMC_SDTR1_TRP | \ FMC_SDTR1_TRCD)); tmpr1 |= (uint32_t)(((Timing->LoadToActiveDelay)-1) |\ (((Timing->ExitSelfRefreshDelay)-1) << 4) |\ (((Timing->SelfRefreshTime)-1) << 8) |\ (((Timing->WriteRecoveryTime)-1) <<16) |\ (((Timing->RCDDelay)-1) << 24)); tmpr2 = Device->SDTR[FMC_SDRAM_BANK1]; /* Clear TMRD, TXSR, TRAS, TRC, TWR, TRP and TRCD bits */ tmpr2 &= ((uint32_t)~(FMC_SDTR1_TMRD | FMC_SDTR1_TXSR | FMC_SDTR1_TRAS | \ FMC_SDTR1_TRC | FMC_SDTR1_TWR | FMC_SDTR1_TRP | \ FMC_SDTR1_TRCD)); tmpr2 |= (uint32_t)((((Timing->RowCycleDelay)-1) << 12) |\ (((Timing->RPDelay)-1) << 20)); Device->SDTR[FMC_SDRAM_BANK2] = tmpr1; Device->SDTR[FMC_SDRAM_BANK1] = tmpr2; } return HAL_OK; } /** * @brief Initializes the SDRAM device. * @retval SDRAM status */ void BSP_SDRAM_Init(void) { SDRAM_HandleTypeDef sdramHandle; FMC_SDRAM_TimingTypeDef Timing; /* SDRAM device configuration */ sdramHandle.Instance = FMC_SDRAM_DEVICE; /* Timing configuration for 100Mhz as SD clock frequency (System clock is up to 200Mhz) */ Timing.LoadToActiveDelay = 2; Timing.ExitSelfRefreshDelay = 7; Timing.SelfRefreshTime = 4; Timing.RowCycleDelay = 7; Timing.WriteRecoveryTime = 2; Timing.RPDelay = 2; Timing.RCDDelay = 2; sdramHandle.Init.SDBank = FMC_SDRAM_BANK1; sdramHandle.Init.ColumnBitsNumber = FMC_SDRAM_COLUMN_BITS_NUM_8; sdramHandle.Init.RowBitsNumber = FMC_SDRAM_ROW_BITS_NUM_12; sdramHandle.Init.MemoryDataWidth = SDRAM_MEMORY_WIDTH; sdramHandle.Init.InternalBankNumber = FMC_SDRAM_INTERN_BANKS_NUM_4; sdramHandle.Init.CASLatency = FMC_SDRAM_CAS_LATENCY_2; sdramHandle.Init.WriteProtection = FMC_SDRAM_WRITE_PROTECTION_DISABLE; sdramHandle.Init.SDClockPeriod = SDCLOCK_PERIOD; sdramHandle.Init.ReadBurst = FMC_SDRAM_RBURST_ENABLE; sdramHandle.Init.ReadPipeDelay = FMC_SDRAM_RPIPE_DELAY_0; /* SDRAM controller initialization */ BSP_SDRAM_MspInit(&sdramHandle); _HAL_SDRAM_Init(&sdramHandle, &Timing); /* SDRAM initialization sequence */ BSP_SDRAM_Initialization_sequence(&sdramHandle, REFRESH_COUNT); } static HAL_StatusTypeDef _HAL_SDRAM_SendCommand(SDRAM_HandleTypeDef *hsdram, FMC_SDRAM_CommandTypeDef *Command, uint32_t Timeout) { /* Check the SDRAM controller state */ if(hsdram->State == HAL_SDRAM_STATE_BUSY) { return HAL_BUSY; } /* Update the SDRAM state */ hsdram->State = HAL_SDRAM_STATE_BUSY; /* Send SDRAM command */ _FMC_SDRAM_SendCommand(hsdram->Instance, Command, Timeout); /* Update the SDRAM controller state state */ if(Command->CommandMode == FMC_SDRAM_CMD_PALL) { hsdram->State = HAL_SDRAM_STATE_PRECHARGED; } else { hsdram->State = HAL_SDRAM_STATE_READY; } return HAL_OK; } static HAL_StatusTypeDef _FMC_SDRAM_SendCommand(FMC_SDRAM_TypeDef *Device, FMC_SDRAM_CommandTypeDef *Command, uint32_t Timeout) { __IO uint32_t tmpr = 0; systemticks_t tickstart = 0; /* Set command register */ tmpr = (uint32_t)((Command->CommandMode) |\ (Command->CommandTarget) |\ (((Command->AutoRefreshNumber)-1) << 5) |\ ((Command->ModeRegisterDefinition) << 9) ); Device->SDCMR = tmpr; /* Get tick */ tickstart = gfxSystemTicks(); /* wait until command is send */ while(HAL_IS_BIT_SET(Device->SDSR, FMC_SDSR_BUSY)) { /* Check for the Timeout */ if(Timeout != HAL_MAX_DELAY) { if((Timeout == 0)||((gfxSystemTicks() - tickstart ) > Timeout)) { return HAL_TIMEOUT; } } return HAL_ERROR; } return HAL_OK; } static HAL_StatusTypeDef _HAL_SDRAM_ProgramRefreshRate(SDRAM_HandleTypeDef *hsdram, uint32_t RefreshRate) { /* Check the SDRAM controller state */ if(hsdram->State == HAL_SDRAM_STATE_BUSY) { return HAL_BUSY; } /* Update the SDRAM state */ hsdram->State = HAL_SDRAM_STATE_BUSY; /* Program the refresh rate */ _FMC_SDRAM_ProgramRefreshRate(hsdram->Instance ,RefreshRate); /* Update the SDRAM state */ hsdram->State = HAL_SDRAM_STATE_READY; return HAL_OK; } static HAL_StatusTypeDef _FMC_SDRAM_ProgramRefreshRate(FMC_SDRAM_TypeDef *Device, uint32_t RefreshRate) { /* Set the refresh rate in command register */ Device->SDRTR |= (RefreshRate<<1); return HAL_OK; } static HAL_StatusTypeDef _HAL_DMA_Init(DMA_HandleTypeDef *hdma) { uint32_t tmp = 0; /* Check the DMA peripheral state */ if(hdma == NULL) { return HAL_ERROR; } /* Change DMA peripheral state */ hdma->State = HAL_DMA_STATE_BUSY; /* Get the CR register value */ tmp = hdma->Instance->CR; /* Clear CHSEL, MBURST, PBURST, PL, MSIZE, PSIZE, MINC, PINC, CIRC, DIR, CT and DBM bits */ tmp &= ((uint32_t)~(DMA_SxCR_CHSEL | DMA_SxCR_MBURST | DMA_SxCR_PBURST | \ DMA_SxCR_PL | DMA_SxCR_MSIZE | DMA_SxCR_PSIZE | \ DMA_SxCR_MINC | DMA_SxCR_PINC | DMA_SxCR_CIRC | \ DMA_SxCR_DIR | DMA_SxCR_CT | DMA_SxCR_DBM)); /* Prepare the DMA Stream configuration */ tmp |= hdma->Init.Channel | hdma->Init.Direction | hdma->Init.PeriphInc | hdma->Init.MemInc | hdma->Init.PeriphDataAlignment | hdma->Init.MemDataAlignment | hdma->Init.Mode | hdma->Init.Priority; /* the Memory burst and peripheral burst are not used when the FIFO is disabled */ if(hdma->Init.FIFOMode == DMA_FIFOMODE_ENABLE) { /* Get memory burst and peripheral burst */ tmp |= hdma->Init.MemBurst | hdma->Init.PeriphBurst; } /* Write to DMA Stream CR register */ hdma->Instance->CR = tmp; /* Get the FCR register value */ tmp = hdma->Instance->FCR; /* Clear Direct mode and FIFO threshold bits */ tmp &= (uint32_t)~(DMA_SxFCR_DMDIS | DMA_SxFCR_FTH); /* Prepare the DMA Stream FIFO configuration */ tmp |= hdma->Init.FIFOMode; /* the FIFO threshold is not used when the FIFO mode is disabled */ if(hdma->Init.FIFOMode == DMA_FIFOMODE_ENABLE) { /* Get the FIFO threshold */ tmp |= hdma->Init.FIFOThreshold; } /* Write to DMA Stream FCR */ hdma->Instance->FCR = tmp; /* Initialize the error code */ hdma->ErrorCode = HAL_DMA_ERROR_NONE; /* Initialize the DMA state */ hdma->State = HAL_DMA_STATE_READY; return HAL_OK; } /** * @brief DeInitializes the DMA peripheral * @param hdma: pointer to a DMA_HandleTypeDef structure that contains * the configuration information for the specified DMA Stream. * @retval HAL status */ static HAL_StatusTypeDef _HAL_DMA_DeInit(DMA_HandleTypeDef *hdma) { /* Check the DMA peripheral state */ if(hdma == NULL) { return HAL_ERROR; } /* Check the DMA peripheral state */ if(hdma->State == HAL_DMA_STATE_BUSY) { return HAL_ERROR; } /* Disable the selected DMA Streamx */ __HAL_DMA_DISABLE(hdma); /* Reset DMA Streamx control register */ hdma->Instance->CR = 0; /* Reset DMA Streamx number of data to transfer register */ hdma->Instance->NDTR = 0; /* Reset DMA Streamx peripheral address register */ hdma->Instance->PAR = 0; /* Reset DMA Streamx memory 0 address register */ hdma->Instance->M0AR = 0; /* Reset DMA Streamx memory 1 address register */ hdma->Instance->M1AR = 0; /* Reset DMA Streamx FIFO control register */ hdma->Instance->FCR = (uint32_t)0x00000021; /* Clear all flags */ __HAL_DMA_CLEAR_FLAG(hdma, __HAL_DMA_GET_DME_FLAG_INDEX(hdma)); __HAL_DMA_CLEAR_FLAG(hdma, __HAL_DMA_GET_TC_FLAG_INDEX(hdma)); __HAL_DMA_CLEAR_FLAG(hdma, __HAL_DMA_GET_TE_FLAG_INDEX(hdma)); __HAL_DMA_CLEAR_FLAG(hdma, __HAL_DMA_GET_FE_FLAG_INDEX(hdma)); __HAL_DMA_CLEAR_FLAG(hdma, __HAL_DMA_GET_HT_FLAG_INDEX(hdma)); /* Initialize the error code */ hdma->ErrorCode = HAL_DMA_ERROR_NONE; /* Initialize the DMA state */ hdma->State = HAL_DMA_STATE_RESET; /* Release Lock */ __HAL_UNLOCK(hdma); return HAL_OK; } /** * @brief Programs the SDRAM device. * @param RefreshCount: SDRAM refresh counter value * @retval None */ static void BSP_SDRAM_Initialization_sequence(SDRAM_HandleTypeDef *hsdram, uint32_t RefreshCount) { FMC_SDRAM_CommandTypeDef Command; /* Step 1: Configure a clock configuration enable command */ Command.CommandMode = FMC_SDRAM_CMD_CLK_ENABLE; Command.CommandTarget = FMC_SDRAM_CMD_TARGET_BANK1; Command.AutoRefreshNumber = 1; Command.ModeRegisterDefinition = 0; /* Send the command */ _HAL_SDRAM_SendCommand(hsdram, &Command, SDRAM_TIMEOUT); /* Step 2: Insert 100 us minimum delay */ /* Inserted delay is equal to 1 ms due to systick time base unit (ms) */ gfxSleepMilliseconds(1); /* Step 3: Configure a PALL (precharge all) command */ Command.CommandMode = FMC_SDRAM_CMD_PALL; Command.CommandTarget = FMC_SDRAM_CMD_TARGET_BANK1; Command.AutoRefreshNumber = 1; Command.ModeRegisterDefinition = 0; /* Send the command */ _HAL_SDRAM_SendCommand(hsdram, &Command, SDRAM_TIMEOUT); /* Step 4: Configure an Auto Refresh command */ Command.CommandMode = FMC_SDRAM_CMD_AUTOREFRESH_MODE; Command.CommandTarget = FMC_SDRAM_CMD_TARGET_BANK1; Command.AutoRefreshNumber = 8; Command.ModeRegisterDefinition = 0; /* Send the command */ _HAL_SDRAM_SendCommand(hsdram, &Command, SDRAM_TIMEOUT); /* Step 5: Program the external memory mode register */ Command.CommandMode = FMC_SDRAM_CMD_LOAD_MODE; Command.CommandTarget = FMC_SDRAM_CMD_TARGET_BANK1; Command.AutoRefreshNumber = 1; Command.ModeRegisterDefinition = (uint32_t)SDRAM_MODEREG_BURST_LENGTH_1 |\ SDRAM_MODEREG_BURST_TYPE_SEQUENTIAL |\ SDRAM_MODEREG_CAS_LATENCY_2 |\ SDRAM_MODEREG_OPERATING_MODE_STANDARD |\ SDRAM_MODEREG_WRITEBURST_MODE_SINGLE;; /* Send the command */ _HAL_SDRAM_SendCommand(hsdram, &Command, SDRAM_TIMEOUT); /* Step 6: Set the refresh rate counter */ /* Set the device refresh rate */ _HAL_SDRAM_ProgramRefreshRate(hsdram, RefreshCount); } /** * @brief Initializes SDRAM MSP. * @param hsdram: SDRAM handle * @param Params * @retval None */ static void BSP_SDRAM_MspInit(SDRAM_HandleTypeDef *hsdram) { static DMA_HandleTypeDef dma_handle; GPIO_InitTypeDef gpio_init_structure; /* Enable FMC clock */ __HAL_RCC_FMC_CLK_ENABLE(); /* Enable chosen DMAx clock */ __DMAx_CLK_ENABLE(); /* Enable GPIOs clock */ __HAL_RCC_GPIOC_CLK_ENABLE(); __HAL_RCC_GPIOD_CLK_ENABLE(); __HAL_RCC_GPIOE_CLK_ENABLE(); __HAL_RCC_GPIOF_CLK_ENABLE(); __HAL_RCC_GPIOG_CLK_ENABLE(); __HAL_RCC_GPIOH_CLK_ENABLE(); /* Common GPIO configuration - some are already setup by ChibiOS Init */ gpio_init_structure.Mode = GPIO_MODE_AF_PP; gpio_init_structure.Pull = GPIO_PULLUP; gpio_init_structure.Speed = GPIO_SPEED_FAST; gpio_init_structure.Alternate = GPIO_AF12_FMC; /* GPIOC configuration */ gpio_init_structure.Pin = GPIO_PIN_3; HAL_GPIO_Init(GPIOC, &gpio_init_structure); /* GPIOD configuration */ gpio_init_structure.Pin = GPIO_PIN_0 | GPIO_PIN_1 | GPIO_PIN_3 | GPIO_PIN_8 | GPIO_PIN_9 | GPIO_PIN_10 | GPIO_PIN_14 | GPIO_PIN_15; HAL_GPIO_Init(GPIOD, &gpio_init_structure); /* GPIOE configuration */ gpio_init_structure.Pin = GPIO_PIN_0 | GPIO_PIN_1 | GPIO_PIN_7| GPIO_PIN_8 | GPIO_PIN_9 |\ GPIO_PIN_10 | GPIO_PIN_11 | GPIO_PIN_12 | GPIO_PIN_13 | GPIO_PIN_14 |\ GPIO_PIN_15; HAL_GPIO_Init(GPIOE, &gpio_init_structure); /* GPIOF configuration */ gpio_init_structure.Pin = GPIO_PIN_0 | GPIO_PIN_1 | GPIO_PIN_2| GPIO_PIN_3 | GPIO_PIN_4 |\ GPIO_PIN_5 | GPIO_PIN_11 | GPIO_PIN_12 | GPIO_PIN_13 | GPIO_PIN_14 |\ GPIO_PIN_15; HAL_GPIO_Init(GPIOF, &gpio_init_structure); /* GPIOG configuration */ gpio_init_structure.Pin = GPIO_PIN_0 | GPIO_PIN_1 | GPIO_PIN_4| GPIO_PIN_5 | GPIO_PIN_8 |\ GPIO_PIN_15; HAL_GPIO_Init(GPIOG, &gpio_init_structure); /* GPIOH configuration */ gpio_init_structure.Pin = GPIO_PIN_3 | GPIO_PIN_5; HAL_GPIO_Init(GPIOH, &gpio_init_structure); /* Configure common DMA parameters */ dma_handle.Init.Channel = SDRAM_DMAx_CHANNEL; dma_handle.Init.Direction = DMA_MEMORY_TO_MEMORY; dma_handle.Init.PeriphInc = DMA_PINC_ENABLE; dma_handle.Init.MemInc = DMA_MINC_ENABLE; dma_handle.Init.PeriphDataAlignment = DMA_PDATAALIGN_WORD; dma_handle.Init.MemDataAlignment = DMA_MDATAALIGN_WORD; dma_handle.Init.Mode = DMA_NORMAL; dma_handle.Init.Priority = DMA_PRIORITY_HIGH; dma_handle.Init.FIFOMode = DMA_FIFOMODE_DISABLE; dma_handle.Init.FIFOThreshold = DMA_FIFO_THRESHOLD_FULL; dma_handle.Init.MemBurst = DMA_MBURST_SINGLE; dma_handle.Init.PeriphBurst = DMA_PBURST_SINGLE; dma_handle.Instance = SDRAM_DMAx_STREAM; /* Associate the DMA handle */ __HAL_LINKDMA(hsdram, hdma, dma_handle); /* Deinitialize the stream for new transfer */ _HAL_DMA_DeInit(&dma_handle); /* Configure the DMA stream */ _HAL_DMA_Init(&dma_handle); /* NVIC configuration for DMA transfer complete interrupt */ NVIC_SetPriority(SDRAM_DMAx_IRQn, NVIC_EncodePriority(NVIC_GetPriorityGrouping(), 5, 0)); /* Enable interrupt */ NVIC_EnableIRQ(SDRAM_DMAx_IRQn); }