//-------------------------------------------------------------- // schreibt einen Block von 32bit Werten ins externe SDRAM // ab einer Adresse // ptrBuffer : Pointer auf den Start vom Block der geschrieben wird // startAdr : Start Adresse vom Ram ab der geschrieben wird // lenBuffer : anzahl der Daten die geschrieben werden sollen //-------------------------------------------------------------- void UB_SDRAM_WriteBuffer32b(uint32_t* ptrBuffer, uint32_t startAdr, uint32_t lenBuffer) { FMC_SDRAMWriteProtectionConfig(FMC_Bank2_SDRAM, DISABLE); // Wait until controller ready while (FMC_GetFlagStatus(FMC_Bank2_SDRAM, FMC_FLAG_Busy) != RESET); // Write all data while (lenBuffer-- != 0) { // Transfer data to the memory *(uint32_t *)(SDRAM_START_ADR + startAdr) = *ptrBuffer++; startAdr += 4; } }
//-------------------------------------------------------------- // schreibt einen Block von 32bit Werten ins externe SDRAM // ab einer Adresse // ptrBuffer : Pointer auf den Start vom Block der geschrieben wird // startAdr : Start Adresse vom Ram ab der geschrieben wird // lenBuffer : anzahl der Daten die geschrieben werden sollen //-------------------------------------------------------------- void UB_SDRAM_WriteBuffer32b(uint32_t* ptrBuffer, uint32_t startAdr, uint32_t lenBuffer) { volatile uint32_t write_pointer = (uint32_t)startAdr; FMC_SDRAMWriteProtectionConfig(FMC_Bank2_SDRAM, DISABLE); // warten bis Controller bereit while(FMC_GetFlagStatus(FMC_Bank2_SDRAM, FMC_FLAG_Busy) != RESET); // alle Daten schreiben for (; lenBuffer != 0; lenBuffer--) { // Transfer data to the memory *(uint32_t *) (SDRAM_START_ADR + write_pointer) = *ptrBuffer++; write_pointer += 4; } }
/** * @brief Writes a Entire-word buffer to the SDRAM memory. * @param pBuffer: pointer to buffer. * @param uwWriteAddress: SDRAM memory internal address from which the data will be * written. * @param uwBufferSize: number of words to write. * @retval None. */ void SDRAM_WriteBuffer(uint32_t* pBuffer, uint32_t uwWriteAddress, uint32_t uwBufferSize) { __IO uint32_t write_pointer = (uint32_t)uwWriteAddress; /* Disable write protection */ FMC_SDRAMWriteProtectionConfig(FMC_Bank1_SDRAM, DISABLE); /* Wait until the SDRAM controller is ready */ while (FMC_GetFlagStatus(FMC_Bank1_SDRAM, FMC_FLAG_Busy) != RESET) { } /* While there is data to write */ for (; uwBufferSize != 0; uwBufferSize--) { /* Transfer data to the memory */ *(uint32_t *)(SDRAM_BANK_ADDR + write_pointer) = *pBuffer++; /* Increment the address*/ write_pointer += 4; } }
/** * @brief 以“字”为单位向sdram写入数据 * @param pBuffer: 指向数据的指针 * @param uwWriteAddress: 要写入的SDRAM内部地址 * @param uwBufferSize: 要写入数据大小 * @retval None. */ void SDRAM_WriteBuffer(uint32_t* pBuffer, uint32_t uwWriteAddress, uint32_t uwBufferSize) { __IO uint32_t write_pointer = (uint32_t)uwWriteAddress; /* 禁止写保护 */ FMC_SDRAMWriteProtectionConfig(FMC_Bank2_SDRAM, DISABLE); /* 检查SDRAM标志,等待至SDRAM空闲 */ while(FMC_GetFlagStatus(FMC_Bank2_SDRAM, FMC_FLAG_Busy) != RESET) { } /* 循环写入数据 */ for (; uwBufferSize != 0; uwBufferSize--) { /* 发送数据到SDRAM */ *(uint32_t *) (SDRAM_BANK_ADDR + write_pointer) = *pBuffer++; /* 地址自增*/ write_pointer += 4; } }
/** * @brief Executes the SDRAM memory initialization sequence. * @param None. * @retval None. */ void SdRamInitSeq( void ) { FMC_SDRAMCommandTypeDef SdRamCmdCfg; uint32_t tmpr = 0; /* Step 3 --------------------------------------------------------------------*/ /* Configure a clock configuration enable command */ SdRamCmdCfg.FMC_CommandMode = FMC_Command_Mode_CLK_Enabled; SdRamCmdCfg.FMC_CommandTarget = FMC_Command_Target_bank2; SdRamCmdCfg.FMC_AutoRefreshNumber = 1; SdRamCmdCfg.FMC_ModeRegisterDefinition = 0; /* Wait until the SDRAM controller is ready */ while( FMC_GetFlagStatus( FMC_Bank2_SDRAM, FMC_FLAG_Busy ) != RESET ) { } /* Send the command */ FMC_SDRAMCmdConfig( &SdRamCmdCfg ); /* Step 4 --------------------------------------------------------------------*/ /* Insert 100 ms delay */ __Delay( 10 ); /* Step 5 --------------------------------------------------------------------*/ /* Configure a PALL (precharge all) command */ SdRamCmdCfg.FMC_CommandMode = FMC_Command_Mode_PALL; SdRamCmdCfg.FMC_CommandTarget = FMC_Command_Target_bank2; SdRamCmdCfg.FMC_AutoRefreshNumber = 1; SdRamCmdCfg.FMC_ModeRegisterDefinition = 0; /* Wait until the SDRAM controller is ready */ while( FMC_GetFlagStatus( FMC_Bank2_SDRAM, FMC_FLAG_Busy ) != RESET ) { } /* Send the command */ FMC_SDRAMCmdConfig( &SdRamCmdCfg ); /* Step 6 --------------------------------------------------------------------*/ /* Configure a Auto-Refresh command */ SdRamCmdCfg.FMC_CommandMode = FMC_Command_Mode_AutoRefresh; SdRamCmdCfg.FMC_CommandTarget = FMC_Command_Target_bank2; SdRamCmdCfg.FMC_AutoRefreshNumber = 4; SdRamCmdCfg.FMC_ModeRegisterDefinition = 0; /* Wait until the SDRAM controller is ready */ while( FMC_GetFlagStatus( FMC_Bank2_SDRAM, FMC_FLAG_Busy ) != RESET ) { } /* Send the first command */ FMC_SDRAMCmdConfig( &SdRamCmdCfg ); /* Wait until the SDRAM controller is ready */ while( FMC_GetFlagStatus( FMC_Bank2_SDRAM, FMC_FLAG_Busy ) != RESET ) { } /* Send the second command */ FMC_SDRAMCmdConfig( &SdRamCmdCfg ); /* Step 7 --------------------------------------------------------------------*/ /* Program the external memory mode register */ tmpr = (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; /* Configure a load Mode register command*/ SdRamCmdCfg.FMC_CommandMode = FMC_Command_Mode_LoadMode; SdRamCmdCfg.FMC_CommandTarget = FMC_Command_Target_bank2; SdRamCmdCfg.FMC_AutoRefreshNumber = 1; SdRamCmdCfg.FMC_ModeRegisterDefinition = tmpr; /* Wait until the SDRAM controller is ready */ while( FMC_GetFlagStatus( FMC_Bank2_SDRAM, FMC_FLAG_Busy ) != RESET ) { } /* Send the command */ FMC_SDRAMCmdConfig( &SdRamCmdCfg ); /* Step 8 --------------------------------------------------------------------*/ /* Set the refresh rate counter */ /* (15.62 us x Freq) - 20 */ /* Set the device refresh counter */ FMC_SetRefreshCount( 1386 ); /* Wait until the SDRAM controller is ready */ while( FMC_GetFlagStatus( FMC_Bank2_SDRAM, FMC_FLAG_Busy ) != RESET ) { } /* Disable write protection */ FMC_SDRAMWriteProtectionConfig( FMC_Bank2_SDRAM, DISABLE ); /* Wait until the SDRAM controller is ready */ while( FMC_GetFlagStatus( FMC_Bank2_SDRAM, FMC_FLAG_Busy ) != RESET ) { } }
/** * @brief Executes the SDRAM memory initialization sequence. * @param None. * @retval None. */ void SDRAM_InitSequence(void) { FMC_SDRAMCommandTypeDef FMC_SDRAMCommandStructure; uint32_t tmpr = 0; /* Step 3 --------------------------------------------------------------------*/ /* Configure a clock configuration enable command */ FMC_SDRAMCommandStructure.FMC_CommandMode = FMC_Command_Mode_CLK_Enabled; FMC_SDRAMCommandStructure.FMC_CommandTarget = FMC_Command_Target_bank1; FMC_SDRAMCommandStructure.FMC_AutoRefreshNumber = 1; FMC_SDRAMCommandStructure.FMC_ModeRegisterDefinition = 0; /* Wait until the SDRAM controller is ready */ while (FMC_GetFlagStatus(FMC_Bank1_SDRAM, FMC_FLAG_Busy) != RESET) { } /* Send the command */ FMC_SDRAMCmdConfig(&FMC_SDRAMCommandStructure); //In the ST example, this is 100ms, but the 429 RM says 100us is typical, and //the ISSI datasheet confirms this. 1ms seems plenty, and is much shorter than //refresh interval, meaning we won't risk losing contents if the SDRAM is in self-refresh //mode /* Step 4 --------------------------------------------------------------------*/ /* Insert 1 ms delay */ chThdSleepMilliseconds(1); /* Step 5 --------------------------------------------------------------------*/ /* Configure a PALL (precharge all) command */ FMC_SDRAMCommandStructure.FMC_CommandMode = FMC_Command_Mode_PALL; FMC_SDRAMCommandStructure.FMC_CommandTarget = FMC_Command_Target_bank1; FMC_SDRAMCommandStructure.FMC_AutoRefreshNumber = 1; FMC_SDRAMCommandStructure.FMC_ModeRegisterDefinition = 0; /* Wait until the SDRAM controller is ready */ while (FMC_GetFlagStatus(FMC_Bank1_SDRAM, FMC_FLAG_Busy) != RESET) { } /* Send the command */ FMC_SDRAMCmdConfig(&FMC_SDRAMCommandStructure); /* Step 6 --------------------------------------------------------------------*/ /* Configure a Auto-Refresh command */ FMC_SDRAMCommandStructure.FMC_CommandMode = FMC_Command_Mode_AutoRefresh; FMC_SDRAMCommandStructure.FMC_CommandTarget = FMC_Command_Target_bank1; FMC_SDRAMCommandStructure.FMC_AutoRefreshNumber = 4; FMC_SDRAMCommandStructure.FMC_ModeRegisterDefinition = 0; /* Wait until the SDRAM controller is ready */ while (FMC_GetFlagStatus(FMC_Bank1_SDRAM, FMC_FLAG_Busy) != RESET) { } /* Send the first command */ FMC_SDRAMCmdConfig(&FMC_SDRAMCommandStructure); /* Wait until the SDRAM controller is ready */ while (FMC_GetFlagStatus(FMC_Bank1_SDRAM, FMC_FLAG_Busy) != RESET) { } /* Send the second command */ FMC_SDRAMCmdConfig(&FMC_SDRAMCommandStructure); /* Step 7 --------------------------------------------------------------------*/ /* Program the external memory mode register */ tmpr = (uint32_t)SDRAM_MODEREG_BURST_LENGTH_2 | SDRAM_MODEREG_BURST_TYPE_SEQUENTIAL | SDRAM_MODEREG_CAS_LATENCY_2 | SDRAM_MODEREG_OPERATING_MODE_STANDARD | SDRAM_MODEREG_WRITEBURST_MODE_SINGLE; /* Configure a load Mode register command*/ FMC_SDRAMCommandStructure.FMC_CommandMode = FMC_Command_Mode_LoadMode; FMC_SDRAMCommandStructure.FMC_CommandTarget = FMC_Command_Target_bank1; FMC_SDRAMCommandStructure.FMC_AutoRefreshNumber = 1; FMC_SDRAMCommandStructure.FMC_ModeRegisterDefinition = tmpr; /* Wait until the SDRAM controller is ready */ while (FMC_GetFlagStatus(FMC_Bank1_SDRAM, FMC_FLAG_Busy) != RESET) { } /* Send the command */ FMC_SDRAMCmdConfig(&FMC_SDRAMCommandStructure); /* Step 8 --------------------------------------------------------------------*/ /* Set the refresh rate counter */ /* (7.81 us x Freq) - 20 */ /* Set the device refresh counter */ FMC_SetRefreshCount(683); /* Wait until the SDRAM controller is ready */ while (FMC_GetFlagStatus(FMC_Bank1_SDRAM, FMC_FLAG_Busy) != RESET) { } FMC_SDRAMWriteProtectionConfig(FMC_Bank1_SDRAM, DISABLE); }