592 lines
20 KiB
C
592 lines
20 KiB
C
#include "gfx.h"
|
|
#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"
|
|
|
|
#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;
|
|
#if !GFX_USE_OS_CHIBIOS
|
|
GPIO_InitTypeDef gpio_init_structure;
|
|
#endif
|
|
|
|
/* 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 */
|
|
#if !GFX_USE_OS_CHIBIOS
|
|
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);
|
|
#endif
|
|
|
|
/* 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);
|
|
}
|