diff --git a/src/omv/sdram.c b/src/omv/sdram.c new file mode 100644 index 000000000..63ccbb677 --- /dev/null +++ b/src/omv/sdram.c @@ -0,0 +1,174 @@ +#include +#include +#include +#include "mdefs.h" +#include "pincfg.h" +#include "systick.h" +//#include "sdram.h" + +#define SDRAM_TIMEOUT ((uint32_t)0xFFFF) +#define REFRESH_COUNT ((uint32_t)0x0569) /* SDRAM refresh counter (90Mhz SD clock) */ +#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 SDRAM_HandleTypeDef hsdram; +static FMC_SDRAM_TimingTypeDef SDRAM_Timing; +static FMC_SDRAM_CommandTypeDef command; +static void sdram_init_sequence(SDRAM_HandleTypeDef *hsdram, FMC_SDRAM_CommandTypeDef *Command); +extern void __fatal_error(const char *msg); + +bool sdram_init() +{ + /* SDRAM device configuration */ + hsdram.Instance = FMC_SDRAM_DEVICE; + /* Timing configuration for 90 Mhz of SD clock frequency (180Mhz/2) */ + /* TMRD: 2 Clock cycles */ + SDRAM_Timing.LoadToActiveDelay = 2; + /* TXSR: min=70ns (6x11.90ns) */ + SDRAM_Timing.ExitSelfRefreshDelay = 7; + /* TRAS: min=42ns (4x11.90ns) max=120k (ns) */ + SDRAM_Timing.SelfRefreshTime = 4; + /* TRC: min=63 (6x11.90ns) */ + SDRAM_Timing.RowCycleDelay = 7; + /* TWR: 2 Clock cycles */ + SDRAM_Timing.WriteRecoveryTime = 2; + /* TRP: 15ns => 2x11.90ns */ + SDRAM_Timing.RPDelay = 2; + /* TRCD: 15ns => 2x11.90ns */ + SDRAM_Timing.RCDDelay = 2; + + hsdram.Init.SDBank = FMC_SDRAM_BANK1; + hsdram.Init.RowBitsNumber = FMC_SDRAM_ROW_BITS_NUM_12; + hsdram.Init.ColumnBitsNumber = FMC_SDRAM_COLUMN_BITS_NUM_10; + hsdram.Init.MemoryDataWidth = FMC_SDRAM_MEM_BUS_WIDTH_8; + hsdram.Init.InternalBankNumber = FMC_SDRAM_INTERN_BANKS_NUM_4; + hsdram.Init.CASLatency = FMC_SDRAM_CAS_LATENCY_3; + hsdram.Init.WriteProtection = FMC_SDRAM_WRITE_PROTECTION_DISABLE; + hsdram.Init.SDClockPeriod = FMC_SDRAM_CLOCK_PERIOD_3; + hsdram.Init.ReadBurst = FMC_SDRAM_RBURST_DISABLE; + hsdram.Init.ReadPipeDelay = FMC_SDRAM_RPIPE_DELAY_1; + + /* Initialize the SDRAM controller */ + if(HAL_SDRAM_Init(&hsdram, &SDRAM_Timing) != HAL_OK) { + return false; + } + + /* Program the SDRAM external device */ + sdram_init_sequence(&hsdram, &command); + return true; +} + +static void sdram_init_sequence(SDRAM_HandleTypeDef *hsdram, FMC_SDRAM_CommandTypeDef *Command) +{ + __IO uint32_t tmpmrd =0; + /* Step 3: 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, 0x1000); + + /* Step 4: Insert 100 ms delay */ + HAL_Delay(100); + + /* Step 5: 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, 0x1000); + + /* Step 6 : Configure a Auto-Refresh command */ + Command->CommandMode = FMC_SDRAM_CMD_AUTOREFRESH_MODE; + Command->CommandTarget = FMC_SDRAM_CMD_TARGET_BANK1; + Command->AutoRefreshNumber = 4; + Command->ModeRegisterDefinition = 0; + + /* Send the command */ + HAL_SDRAM_SendCommand(hsdram, Command, 0x1000); + + /* Step 7: Program the external memory mode register */ + tmpmrd = (uint32_t)SDRAM_MODEREG_BURST_LENGTH_2 | + SDRAM_MODEREG_BURST_TYPE_SEQUENTIAL | + SDRAM_MODEREG_CAS_LATENCY_3 | + SDRAM_MODEREG_OPERATING_MODE_STANDARD | + SDRAM_MODEREG_WRITEBURST_MODE_SINGLE; + + Command->CommandMode = FMC_SDRAM_CMD_LOAD_MODE; + Command->CommandTarget = FMC_SDRAM_CMD_TARGET_BANK1; + Command->AutoRefreshNumber = 1; + Command->ModeRegisterDefinition = tmpmrd; + + /* Send the command */ + HAL_SDRAM_SendCommand(hsdram, Command, 0x1000); + + /* Step 8: Set the refresh rate counter */ + /* (15.62 us x Freq) - 20 */ + /* Set the device refresh counter */ + HAL_SDRAM_ProgramRefreshRate(hsdram, REFRESH_COUNT); +} + + +bool DISABLE_OPT sdram_test() +{ + uint8_t pattern = 0xAA; + uint8_t antipattern = 0x55; + uint32_t mem_size = (16*1024*1024); + uint8_t * const mem_base = (uint8_t*)0xC0000000; + + printf("sdram test...\n"); + /* test data bus */ + for (uint8_t i=1; i; i<<=1) { + *mem_base = i; + if (*mem_base != i) { + printf("data bus lines test failed! data (%d)\n", i); + BREAK(); + } + } + + /* test address bus */ + /* Check individual address lines */ + for (uint32_t i=1; i PD14 | FMC_A0 <-> PF0 | FMC_CLK <-> PG8 | + | FMC_D1 <-> PD15 | FMC_A1 <-> PF1 | FMC_CLKE <-> PC3 | + | FMC_D2 <-> PD0 | FMC_A2 <-> PF2 | FMC_WE <-> PC0 | + | FMC_D3 <-> PD1 | FMC_A3 <-> PF3 | FMC_CS <-> PC2 | + | FMC_D4 <-> PE7 | FMC_A4 <-> PF4 | FMC_DQM <-> PE0 | + | FMC_D5 <-> PE8 | FMC_A5 <-> PF5 | FMC_BA0 <-> PG4 | + | FMC_D6 <-> PE9 | FMC_A6 <-> PF12 | FMC_BA1 <-> PG5 | + | FMC_D7 <-> PE10 | FMC_A7 <-> PF13 | FMC_RAS <-> PF11 | + | | FMC_A8 <-> PF14 | FMC_CAS <-> PG15 | + | | FMC_A9 <-> PF15 | | + | | FMC_A10 <-> PG0 | | + | | FMC_A11 <-> PG1 | | + +-------------------+--------------------+--------------------+ */ + /* SDRAM GPIO configuration */ + GPIO_InitTypeDef GPIO_Init_Structure; + GPIO_Init_Structure.Pull = GPIO_NOPULL; + GPIO_Init_Structure.Mode = GPIO_MODE_AF_PP; + GPIO_Init_Structure.Speed = GPIO_SPEED_FAST; + GPIO_Init_Structure.Alternate = GPIO_AF12_FMC; + + /* GPIOC configuration */ + GPIO_Init_Structure.Pin = GPIO_PIN_0 | GPIO_PIN_2 | GPIO_PIN_3; + HAL_GPIO_Init(GPIOC, &GPIO_Init_Structure); + + /* GPIOD configuration */ + GPIO_Init_Structure.Pin = GPIO_PIN_0 | GPIO_PIN_1 | GPIO_PIN_14 | GPIO_PIN_15; + HAL_GPIO_Init(GPIOD, &GPIO_Init_Structure); + + /* GPIOE configuration */ + GPIO_Init_Structure.Pin = GPIO_PIN_0 | GPIO_PIN_7 | GPIO_PIN_8 | GPIO_PIN_9 | GPIO_PIN_10; + 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); +} + void HAL_MspDeInit(void) { diff --git a/src/omv/stm32f429.ld b/src/omv/stm32f429.ld index d797d8289..796e3f768 100755 --- a/src/omv/stm32f429.ld +++ b/src/omv/stm32f429.ld @@ -14,6 +14,7 @@ MEMORY FLASH_TEXT (rx) : ORIGIN = 0x08010000, LENGTH = 1984K RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 192K CCM (xrw) : ORIGIN = 0x10000000, LENGTH = 64K + SDRAM (xrw) : ORIGIN = 0xC0000000, LENGTH = 16M } /* Highest address of the user mode stack */ diff --git a/src/sthal/Makefile b/src/sthal/Makefile index fc09dcb92..8cbb62b83 100644 --- a/src/sthal/Makefile +++ b/src/sthal/Makefile @@ -22,12 +22,16 @@ stm32f4xx_hal_rcc_ex.c\ stm32f4xx_hal_rng.c\ stm32f4xx_hal_rtc.c\ stm32f4xx_hal_rtc_ex.c\ +stm32f4xx_hal_sd.c\ +stm32f4xx_hal_sdram.c\ stm32f4xx_hal_spi.c\ stm32f4xx_hal_tim.c\ stm32f4xx_hal_tim_ex.c\ stm32f4xx_hal_uart.c\ stm32f4xx_hal_usart.c\ stm32f4xx_ll_usb.c\ +stm32f4xx_ll_sdmmc.c\ +stm32f4xx_ll_fmc.c\ syscalls.c\ )