Добрый день!
Пытаюсь завести SDRAM
MT48LC16M16 на моем STM32F429. Схему проверил уже несколько раз и не только я - все верно. Грешу уже только на инициализацию, уже просто не знаю куда смотреть. Тайминги уже несколько раз перепроверил. Если не затруднит, может кто посмотрит, может я просто что-то проглядел, по-причине "замыленности" глаза.
Код:CODE
/**
* @brief Executes the SDRAM memory initialization sequence.
* @param None.
* @retval None.
*/
void SDRAM_InitSequence(void)
{
FMC_SDRAMCommandTypeDef FMC_SDRAMCommandStructure;
uint32_t tmpr = 0;
uint32_t timeout = SDRAM_TIMEOUT;
// Step 3 --------------------------------------------------------------------
// Configure a clock configuration enable command
FMC_SDRAMCommandStructure.FMC_CommandMode = FMC_Command_Mode_CLK_Enabled; // 0x00000001
FMC_SDRAMCommandStructure.FMC_CommandTarget = FMC_Command_Target_bank2; // 0x00000010
FMC_SDRAMCommandStructure.FMC_AutoRefreshNumber = 1; //
FMC_SDRAMCommandStructure.FMC_ModeRegisterDefinition = 0; //
// Wait until the SDRAM controller is ready
while ( ( FMC_GetFlagStatus ( FMC_Bank2_SDRAM, FMC_FLAG_Busy ) != RESET ) && (timeout > 0) )
{
timeout--;
}
// Send the command
// SDCMR = 0x00000011 = xx 0001 0001
// MRD = 0
// NRFS = 0 - Clock Configuration Enable
// CTB1 = 1 - Command issued to SDRAM Bank 1
// CTB2 = 0 - Command not issued to SDRAM Bank 2
// MODE = 001 - Clock Configuration Enable
FMC_SDRAMCmdConfig ( &FMC_SDRAMCommandStructure );
// Step 4 --------------------------------------------------------------------
// Insert 100 ms delay
timeout = SDRAM_TIMEOUT;
while (timeout--);
//_delay_ms ( 100 );
// Step 5 --------------------------------------------------------------------
// Configure a PALL (precharge all) command
FMC_SDRAMCommandStructure.FMC_CommandMode = FMC_Command_Mode_PALL;
FMC_SDRAMCommandStructure.FMC_CommandTarget = FMC_Command_Target_bank2;
FMC_SDRAMCommandStructure.FMC_AutoRefreshNumber = 1;
FMC_SDRAMCommandStructure.FMC_ModeRegisterDefinition = 0;
// Wait until the SDRAM controller is ready
timeout = SDRAM_TIMEOUT;
while ( ( FMC_GetFlagStatus ( FMC_Bank2_SDRAM, FMC_FLAG_Busy ) != RESET ) && (timeout > 0) )
{
timeout--;
}
// Send the command
// SDCMR = 0x00000012 = xxx 0001 0010
// MRD = 0
// NRFS = 0 - Clock Configuration Enable
// CTB1 = 1 - Command issued to SDRAM Bank 1
// CTB2 = 0 - Command not issued to SDRAM Bank 2
// MODE = 010 - Clock Configuration Enable
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_bank2;
FMC_SDRAMCommandStructure.FMC_AutoRefreshNumber = 8;
FMC_SDRAMCommandStructure.FMC_ModeRegisterDefinition = 0;
// Wait until the SDRAM controller is ready
timeout = SDRAM_TIMEOUT;
while ( ( FMC_GetFlagStatus ( FMC_Bank2_SDRAM, FMC_FLAG_Busy ) != RESET ) && (timeout > 0) )
{
timeout--;
}
// Send the command
// SDCMR = 0x00000013 = xxx 0001 0011
// MRD = 0
// NRFS = 7 - 7 Auto refresh cycles
// CTB1 = 1 - Command issued to SDRAM Bank 1
// CTB2 = 0 - Command not issued to SDRAM Bank 2
// MODE = 011 - Auto-refresh command
FMC_SDRAMCmdConfig ( &FMC_SDRAMCommandStructure );
// Step 7 --------------------------------------------------------------------
// Program the external memory mode register
// 12 bits
tmpr = (uint32_t)SDRAM_MODEREG_BURST_LENGTH_1 | // 0x0000
SDRAM_MODEREG_BURST_TYPE_SEQUENTIAL | // 0x0000
SDRAM_MODEREG_CAS_LATENCY_3 | // 0x0030
SDRAM_MODEREG_OPERATING_MODE_STANDARD | // 0x0000
SDRAM_MODEREG_WRITEBURST_MODE_SINGLE; // 0x0200
// Configure a load Mode register command
FMC_SDRAMCommandStructure.FMC_CommandMode = FMC_Command_Mode_LoadMode; // 0x00000004
FMC_SDRAMCommandStructure.FMC_CommandTarget = FMC_Command_Target_bank2; // 0x00000010
FMC_SDRAMCommandStructure.FMC_AutoRefreshNumber = 1; // 0 -> NRFS
FMC_SDRAMCommandStructure.FMC_ModeRegisterDefinition = tmpr; // 0x0230 << 9
// Wait until the SDRAM controller is ready
timeout = SDRAM_TIMEOUT;
while ( ( FMC_GetFlagStatus(FMC_Bank2_SDRAM, FMC_FLAG_Busy) != RESET ) && ( timeout > 0 ) )
{
timeout--;
}
// Send the command
// MRD = 0x230
// NRFS = 0 - 0 Auto refresh cycles
// CTB1 = 1 - Command issued to SDRAM Bank 1
// CTB2 = 0 - Command not issued to SDRAM Bank 2
// MODE = 100 - Load Mode Register
FMC_SDRAMCmdConfig(&FMC_SDRAMCommandStructure);
// Step 8 --------------------------------------------------------------------
/* Set the refresh rate counter */
/* (15.62 us x Freq) - 20 */
/* Set the device refresh counter */
FMC_SetRefreshCount ( 1385 );
// Wait until the SDRAM controller is ready
timeout = SDRAM_TIMEOUT;
while ( (FMC_GetFlagStatus(FMC_Bank2_SDRAM, FMC_FLAG_Busy) != RESET) && (timeout > 0) )
{
timeout--;
}
}
void initSdram (void)
{
FMC_SDRAMInitTypeDef FMC_SDRAMInitStructure;
FMC_SDRAMTimingInitTypeDef FMC_SDRAMTimingInitStructure;
// Enable FMC clock
RCC_AHB3PeriphClockCmd ( RCC_AHB3Periph_FMC, ENABLE );
SDRAM_GPIOConfig();
// FMC Configuration ---------------------------------------------------------
// FMC SDRAM Bank configuration
// Timing configuration for 90 Mhz of SD clock frequency (180Mhz/2)
// TMRD: 2 Clock cycles
FMC_SDRAMTimingInitStructure.FMC_LoadToActiveDelay = 2;
// TXSR: min=70ns (7x11.11ns)
FMC_SDRAMTimingInitStructure.FMC_ExitSelfRefreshDelay = 7;
// TRAS: min=42ns (4x11.11ns) max=120k (ns)
FMC_SDRAMTimingInitStructure.FMC_SelfRefreshTime = 4;
// TRC: min=70 (7x11.11ns)
FMC_SDRAMTimingInitStructure.FMC_RowCycleDelay = 7;
// TWR: min=1+ 7ns (1+1x11.11ns)
FMC_SDRAMTimingInitStructure.FMC_WriteRecoveryTime = 2;
// TRP: 20ns => 2x11.11ns
FMC_SDRAMTimingInitStructure.FMC_RPDelay = 2;
// TRCD: 20ns => 2x11.11ns
FMC_SDRAMTimingInitStructure.FMC_RCDDelay = 2;
// ОТладка: SDTR = 0x01116361
// FMC SDRAM control configuration
FMC_SDRAMInitStructure.FMC_Bank = FMC_Bank2_SDRAM; // 0
// Col addressing: [8:0] - 9 bits
FMC_SDRAMInitStructure.FMC_ColumnBitsNumber = FMC_ColumnBits_Number_9b; // 0x00000001
// Row addressing: [12:0] - 13 bits
FMC_SDRAMInitStructure.FMC_RowBitsNumber = FMC_RowBits_Number_13b; // 0x00000008
FMC_SDRAMInitStructure.FMC_SDMemoryDataWidth = FMC_SDMemory_Width_16b; // 0x00000010
FMC_SDRAMInitStructure.FMC_InternalBankNumber = FMC_InternalBank_Number_4; // 0x00000040
// CL: Cas Latency = 3 clock cycles
FMC_SDRAMInitStructure.FMC_CASLatency = FMC_CAS_Latency_3; // 0x00000180
FMC_SDRAMInitStructure.FMC_WriteProtection = FMC_Write_Protection_Disable; // 0x00000000
FMC_SDRAMInitStructure.FMC_SDClockPeriod = FMC_SDClock_Period_2; // 0x00000800
FMC_SDRAMInitStructure.FMC_ReadBurst = FMC_Read_Burst_Enable; // 0x00001000
FMC_SDRAMInitStructure.FMC_ReadPipeDelay = FMC_ReadPipe_Delay_1; // 0x00002000
FMC_SDRAMInitStructure.FMC_SDRAMTimingStruct = &FMC_SDRAMTimingInitStructure;
// FMC SDRAM bank initialization
// SDCR := 0x000039D9 - xx x011 1001 1101 1001
// RPIPE = 01; - one HCLK clock cycle delay
// RBURST = 1; - single read requests are always managed as bursts
// SDCLK = 10; - SDCLK period = 2 x HCLK periods
// WP = 0; - write accesses allowed
// CAS = 11; - CAS Latency - 3 cycles
// NB = 1; - 4 internal Banks
// MWID = 01; - memory data bus width - 16 bits
// NR = 10; - number of row address bits - 13 bits
// NC = 01; - number of column address bits - 9 bits
FMC_SDRAMInit ( &FMC_SDRAMInitStructure );
SDRAM_InitSequence();
}
Проверяю работоспособность так:
CODE
#define SDRAM_ADR 0xD0000000
void sdramWriteTest(void)
{
u32 * p;
p = SDRAM_ADR;
printf("\tWriting to sdram\r\n");
for (u32 i = 0; i < 8000000; i++)
p[i] = i;
}
void sdramReadTest (void)
{
u32 * y;
y = SDRAM_ADR;
for (u32 i = 0; i < 8000000; i++)
{
if ( y[i] != i )
{
printf("\t\tsomething wrong in sdram %d - %x \r\n", i, y[i]);
break;
}
}
printf("\tSdram test end\r\n");
}
При чтении уже на втором слове обнаруживается несовпадение между записанным и считанным.