123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266 |
- /*
- * Copyright (c) 2006-2018, RT-Thread Development Team
- *
- * SPDX-License-Identifier: Apache-2.0
- *
- * Change Logs:
- * Date Author Notes
- * 2018-12-04 zylx The first version for STM32F4xx
- */
- #include <rtthread.h>
- #include <rtdevice.h>
- #include <board.h>
- #ifdef BSP_USING_SDRAM
- #include <sdram_port.h>
- #define DRV_DEBUG
- #define LOG_TAG "drv.sdram"
- #include <drv_log.h>
- static SDRAM_HandleTypeDef hsdram1;
- static FMC_SDRAM_CommandTypeDef command;
- #ifdef RT_USING_MEMHEAP_AS_HEAP
- static struct rt_memheap system_heap;
- #endif
- /**
- * @brief Perform the SDRAM exernal memory inialization sequence
- * @param hsdram: SDRAM handle
- * @param Command: Pointer to SDRAM command structure
- * @retval None
- */
- static void SDRAM_Initialization_Sequence(SDRAM_HandleTypeDef *hsdram, FMC_SDRAM_CommandTypeDef *Command)
- {
- __IO uint32_t tmpmrd = 0;
- uint32_t target_bank = 0;
- #if SDRAM_TARGET_BANK == 1
- target_bank = FMC_SDRAM_CMD_TARGET_BANK1;
- #else
- target_bank = FMC_SDRAM_CMD_TARGET_BANK2;
- #endif
- /* Configure a clock configuration enable command */
- Command->CommandMode = FMC_SDRAM_CMD_CLK_ENABLE;
- Command->CommandTarget = target_bank;
- Command->AutoRefreshNumber = 1;
- Command->ModeRegisterDefinition = 0;
- /* Send the command */
- HAL_SDRAM_SendCommand(hsdram, Command, 0x1000);
- /* Insert 100 ms delay */
- /* interrupt is not enable, just to delay some time. */
- for (tmpmrd = 0; tmpmrd < 0xffffff; tmpmrd ++)
- ;
- /* Configure a PALL (precharge all) command */
- Command->CommandMode = FMC_SDRAM_CMD_PALL;
- Command->CommandTarget = target_bank;
- Command->AutoRefreshNumber = 1;
- Command->ModeRegisterDefinition = 0;
- /* Send the command */
- HAL_SDRAM_SendCommand(hsdram, Command, 0x1000);
- /* Configure a Auto-Refresh command */
- Command->CommandMode = FMC_SDRAM_CMD_AUTOREFRESH_MODE;
- Command->CommandTarget = target_bank;
- Command->AutoRefreshNumber = 8;
- Command->ModeRegisterDefinition = 0;
- /* Send the command */
- HAL_SDRAM_SendCommand(hsdram, Command, 0x1000);
- /* Program the external memory mode register */
- #if SDRAM_DATA_WIDTH == 8
- tmpmrd = (uint32_t)SDRAM_MODEREG_BURST_LENGTH_1 |
- #elif SDRAM_DATA_WIDTH == 16
- tmpmrd = (uint32_t)SDRAM_MODEREG_BURST_LENGTH_2 |
- #else
- tmpmrd = (uint32_t)SDRAM_MODEREG_BURST_LENGTH_4 |
- #endif
- SDRAM_MODEREG_BURST_TYPE_SEQUENTIAL |
- #if SDRAM_CAS_LATENCY == 3
- SDRAM_MODEREG_CAS_LATENCY_3 |
- #else
- SDRAM_MODEREG_CAS_LATENCY_2 |
- #endif
- SDRAM_MODEREG_OPERATING_MODE_STANDARD |
- SDRAM_MODEREG_WRITEBURST_MODE_SINGLE;
- Command->CommandMode = FMC_SDRAM_CMD_LOAD_MODE;
- Command->CommandTarget = target_bank;
- Command->AutoRefreshNumber = 1;
- Command->ModeRegisterDefinition = tmpmrd;
- /* Send the command */
- HAL_SDRAM_SendCommand(hsdram, Command, 0x1000);
- /* Set the device refresh counter */
- HAL_SDRAM_ProgramRefreshRate(hsdram, SDRAM_REFRESH_COUNT);
- }
- static int SDRAM_Init(void)
- {
- int result = RT_EOK;
- FMC_SDRAM_TimingTypeDef SDRAM_Timing;
- /* SDRAM device configuration */
- hsdram1.Instance = FMC_SDRAM_DEVICE;
- SDRAM_Timing.LoadToActiveDelay = LOADTOACTIVEDELAY;
- SDRAM_Timing.ExitSelfRefreshDelay = EXITSELFREFRESHDELAY;
- SDRAM_Timing.SelfRefreshTime = SELFREFRESHTIME;
- SDRAM_Timing.RowCycleDelay = ROWCYCLEDELAY;
- SDRAM_Timing.WriteRecoveryTime = WRITERECOVERYTIME;
- SDRAM_Timing.RPDelay = RPDELAY;
- SDRAM_Timing.RCDDelay = RCDDELAY;
- #if SDRAM_TARGET_BANK == 1
- hsdram1.Init.SDBank = FMC_SDRAM_BANK1;
- #else
- hsdram1.Init.SDBank = FMC_SDRAM_BANK2;
- #endif
- #if SDRAM_COLUMN_BITS == 8
- hsdram1.Init.ColumnBitsNumber = FMC_SDRAM_COLUMN_BITS_NUM_8;
- #elif SDRAM_COLUMN_BITS == 9
- hsdram1.Init.ColumnBitsNumber = FMC_SDRAM_COLUMN_BITS_NUM_9;
- #elif SDRAM_COLUMN_BITS == 10
- hsdram1.Init.ColumnBitsNumber = FMC_SDRAM_COLUMN_BITS_NUM_10;
- #else
- hsdram1.Init.ColumnBitsNumber = FMC_SDRAM_COLUMN_BITS_NUM_11;
- #endif
- #if SDRAM_ROW_BITS == 11
- hsdram1.Init.RowBitsNumber = FMC_SDRAM_ROW_BITS_NUM_11;
- #elif SDRAM_ROW_BITS == 12
- hsdram1.Init.RowBitsNumber = FMC_SDRAM_ROW_BITS_NUM_12;
- #else
- hsdram1.Init.RowBitsNumber = FMC_SDRAM_ROW_BITS_NUM_13;
- #endif
- #if SDRAM_DATA_WIDTH == 8
- hsdram1.Init.MemoryDataWidth = FMC_SDRAM_MEM_BUS_WIDTH_8;
- #elif SDRAM_DATA_WIDTH == 16
- hsdram1.Init.MemoryDataWidth = FMC_SDRAM_MEM_BUS_WIDTH_16;
- #else
- hsdram1.Init.MemoryDataWidth = FMC_SDRAM_MEM_BUS_WIDTH_32;
- #endif
- hsdram1.Init.InternalBankNumber = FMC_SDRAM_INTERN_BANKS_NUM_4;
- #if SDRAM_CAS_LATENCY == 1
- hsdram1.Init.CASLatency = FMC_SDRAM_CAS_LATENCY_1;
- #elif SDRAM_CAS_LATENCY == 2
- hsdram1.Init.CASLatency = FMC_SDRAM_CAS_LATENCY_2;
- #else
- hsdram1.Init.CASLatency = FMC_SDRAM_CAS_LATENCY_3;
- #endif
- hsdram1.Init.WriteProtection = FMC_SDRAM_WRITE_PROTECTION_DISABLE;
- #if SDCLOCK_PERIOD == 2
- hsdram1.Init.SDClockPeriod = FMC_SDRAM_CLOCK_PERIOD_2;
- #else
- hsdram1.Init.SDClockPeriod = FMC_SDRAM_CLOCK_PERIOD_3;
- #endif
- hsdram1.Init.ReadBurst = FMC_SDRAM_RBURST_ENABLE;
- #if SDRAM_RPIPE_DELAY == 0
- hsdram1.Init.ReadPipeDelay = FMC_SDRAM_RPIPE_DELAY_0;
- #elif SDRAM_RPIPE_DELAY == 1
- hsdram1.Init.ReadPipeDelay = FMC_SDRAM_RPIPE_DELAY_1;
- #else
- hsdram1.Init.ReadPipeDelay = FMC_SDRAM_RPIPE_DELAY_2;
- #endif
- /* Initialize the SDRAM controller */
- if (HAL_SDRAM_Init(&hsdram1, &SDRAM_Timing) != HAL_OK)
- {
- LOG_E("SDRAM init failed!");
- result = -RT_ERROR;
- }
- else
- {
- /* Program the SDRAM external device */
- SDRAM_Initialization_Sequence(&hsdram1, &command);
- LOG_D("sdram init success, mapped at 0x%X, size is %d bytes, data width is %d", SDRAM_BANK_ADDR, SDRAM_SIZE, SDRAM_DATA_WIDTH);
- #ifdef RT_USING_MEMHEAP_AS_HEAP
- /* If RT_USING_MEMHEAP_AS_HEAP is enabled, SDRAM is initialized to the heap */
- rt_memheap_init(&system_heap, "sdram", (void *)SDRAM_BANK_ADDR, SDRAM_SIZE);
- #endif
- }
- return result;
- }
- INIT_BOARD_EXPORT(SDRAM_Init);
- #ifdef DRV_DEBUG
- #ifdef FINSH_USING_MSH
- int sdram_test(void)
- {
- int i = 0;
- uint32_t start_time = 0, time_cast = 0;
- #if SDRAM_DATA_WIDTH == 8
- char data_width = 1;
- uint8_t data = 0;
- #elif SDRAM_DATA_WIDTH == 16
- char data_width = 2;
- uint16_t data = 0;
- #else
- char data_width = 4;
- uint32_t data = 0;
- #endif
- /* write data */
- LOG_D("Writing the %ld bytes data, waiting....", SDRAM_SIZE);
- start_time = rt_tick_get();
- for (i = 0; i < SDRAM_SIZE / data_width; i++)
- {
- #if SDRAM_DATA_WIDTH == 8
- *(__IO uint8_t *)(SDRAM_BANK_ADDR + i * data_width) = (uint8_t)0x55;
- #elif SDRAM_DATA_WIDTH == 16
- *(__IO uint16_t *)(SDRAM_BANK_ADDR + i * data_width) = (uint16_t)0x5555;
- #else
- *(__IO uint32_t *)(SDRAM_BANK_ADDR + i * data_width) = (uint32_t)0x55555555;
- #endif
- }
- time_cast = rt_tick_get() - start_time;
- LOG_D("Write data success, total time: %d.%03dS.", time_cast / RT_TICK_PER_SECOND,
- time_cast % RT_TICK_PER_SECOND / ((RT_TICK_PER_SECOND * 1 + 999) / 1000));
- /* read data */
- LOG_D("start Reading and verifying data, waiting....");
- for (i = 0; i < SDRAM_SIZE / data_width; i++)
- {
- #if SDRAM_DATA_WIDTH == 8
- data = *(__IO uint8_t *)(SDRAM_BANK_ADDR + i * data_width);
- if (data != 0x55)
- {
- LOG_E("SDRAM test failed!");
- break;
- }
- #elif SDRAM_DATA_WIDTH == 16
- data = *(__IO uint16_t *)(SDRAM_BANK_ADDR + i * data_width);
- if (data != 0x5555)
- {
- LOG_E("SDRAM test failed!");
- break;
- }
- #else
- data = *(__IO uint32_t *)(SDRAM_BANK_ADDR + i * data_width);
- if (data != 0x55555555)
- {
- LOG_E("SDRAM test failed!");
- break;
- }
- #endif
- }
- if (i >= SDRAM_SIZE / data_width)
- {
- LOG_D("SDRAM test success!");
- }
- return RT_EOK;
- }
- MSH_CMD_EXPORT(sdram_test, sdram test)
- #endif /* FINSH_USING_MSH */
- #endif /* DRV_DEBUG */
- #endif /* BSP_USING_SDRAM */
|