#include "corefmc.h" #include "fmc.h" #include "delay.h" //---------------------------------------------------------------------------- void InitSDRAM(void); //---------------------------------------------------------------------------- void InitCoreFmc(void) { InitSDRAM(); } //---------------------------------------------------------------------------- #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) //---------------------------------------------------------------------------- uint8_t SDRAM_SendCommand1(uint32_t CommandMode, uint32_t Bank, uint32_t RefreshNum, uint32_t RegVal) { uint32_t CommandTarget; FMC_SDRAM_CommandTypeDef Command; if(Bank == 1) CommandTarget = FMC_SDRAM_CMD_TARGET_BANK1; else if(Bank == 2) CommandTarget = FMC_SDRAM_CMD_TARGET_BANK2; else CommandTarget = FMC_SDRAM_CMD_TARGET_BANK1_2; Command.CommandMode = CommandMode; Command.CommandTarget = CommandTarget; Command.AutoRefreshNumber = RefreshNum; Command.ModeRegisterDefinition = RegVal; if (HAL_SDRAM_SendCommand(&hsdram1, &Command, 0x1000) == HAL_OK) { return 1; } return 0; } uint8_t SDRAM_SendCommand2(uint32_t CommandMode, uint32_t Bank, uint32_t RefreshNum, uint32_t RegVal) { uint32_t CommandTarget; FMC_SDRAM_CommandTypeDef Command; if(Bank == 1) CommandTarget = FMC_SDRAM_CMD_TARGET_BANK1; else if(Bank == 2) CommandTarget = FMC_SDRAM_CMD_TARGET_BANK2; else CommandTarget = FMC_SDRAM_CMD_TARGET_BANK1_2; Command.CommandMode = CommandMode; Command.CommandTarget = CommandTarget; Command.AutoRefreshNumber = RefreshNum; Command.ModeRegisterDefinition = RegVal; if (HAL_SDRAM_SendCommand(&hsdram2, &Command, 0x1000) == HAL_OK) { return 1; } return 0; } void InitSDRAM(void) { uint32_t temp; // sdram1 SDRAM_SendCommand1(FMC_SDRAM_CMD_CLK_ENABLE, 1, 1, 0); //步骤3:使能时钟信号,SDCKE0 = 1 DelayUs(500); //步骤4:至少延时200us SDRAM_SendCommand1(FMC_SDRAM_CMD_PALL, 1, 1, 0); //步骤5:发送全部预充电命令 SDRAM_SendCommand1(FMC_SDRAM_CMD_AUTOREFRESH_MODE, 1, 8, 0); //步骤6:设置自动刷新次数 temp = SDRAM_MODEREG_BURST_LENGTH_1 | //设置突发长度:1 SDRAM_MODEREG_BURST_TYPE_SEQUENTIAL | //设置突发类型:连续 SDRAM_MODEREG_CAS_LATENCY_3 | //设置CAS值:3 SDRAM_MODEREG_OPERATING_MODE_STANDARD | //设置操作模式:标准 SDRAM_MODEREG_WRITEBURST_MODE_SINGLE; //设置突发写模式:单点访问 SDRAM_SendCommand1(FMC_SDRAM_CMD_LOAD_MODE, 1, 1, temp); //步骤7:装载模式寄存器的值 // SDRAM刷新周期是64ms,行数是8192行,时钟频率是180MHz/2=90MHz // 所以 COUNT = (64ms/8192)/(1/90us)-20 = 64000*90/8192-20 = 683 HAL_SDRAM_ProgramRefreshRate(&hsdram1, 683); //步骤8:设置刷新速率 // sdram2 SDRAM_SendCommand2(FMC_SDRAM_CMD_CLK_ENABLE, 2, 1, 0); //步骤3:使能时钟信号,SDCKE0 = 1 DelayUs(500); //步骤4:至少延时200us SDRAM_SendCommand2(FMC_SDRAM_CMD_PALL, 2, 1, 0); //步骤5:发送全部预充电命令 SDRAM_SendCommand2(FMC_SDRAM_CMD_AUTOREFRESH_MODE, 2, 8, 0); //步骤6:设置自动刷新次数 temp = SDRAM_MODEREG_BURST_LENGTH_1 | //设置突发长度:1 SDRAM_MODEREG_BURST_TYPE_SEQUENTIAL | //设置突发类型:连续 SDRAM_MODEREG_CAS_LATENCY_3 | //设置CAS值:3 SDRAM_MODEREG_OPERATING_MODE_STANDARD | //设置操作模式:标准 SDRAM_MODEREG_WRITEBURST_MODE_SINGLE; //设置突发写模式:单点访问 SDRAM_SendCommand2(FMC_SDRAM_CMD_LOAD_MODE, 2, 1, temp); //步骤7:装载模式寄存器的值 HAL_SDRAM_ProgramRefreshRate(&hsdram2, 683); //步骤8:设置刷新速率 } //---------------------------------------------------------------------------- // 写入半字数据 void FmcWriteReg(u32 wAddr, u16 data) { *((u16*)(wAddr)) = data; } // 读取半字数据 u16 FmcReadReg(u32 rAddr) { return (*((vu16 *)(rAddr))); } void FmcWriteConstBuf(u32 wAddr, u16* pBuffer, u32 num) { // printf("FmcWriteConstBuf, addr=0x%x, len=%d\r\n", wAddr, num); while(num != 0) { *((u16*)(wAddr)) = *pBuffer++; num--; } } void FmcReadConstBuf(u32 rAddr, u16* pBuffer, u32 num) { while(num != 0) { *pBuffer++ = *((vu16*)(rAddr)); num--; } }