Перейти к содержанию
    

Добрый день!

 

Пытаюсь завести SDRAM MT48LC16M16 на моем STM32F429. Схему проверил уже несколько раз и не только я - все верно. Грешу уже только на инициализацию, уже просто не знаю куда смотреть. Тайминги уже несколько раз перепроверил. Если не затруднит, может кто посмотрит, может я просто что-то проглядел, по-причине "замыленности" глаза.

 

Код:

 

/**
 * @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();
}

 

Проверяю работоспособность так:

 

#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");
}

 

При чтении уже на втором слове обнаруживается несовпадение между записанным и считанным.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Так все работает (то есть если это делать в теле одной функции). Я если честно не понимаю почему.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

потому что адреса где то коротят.

Напишите тест и определите что коротит.

минут 10-15 найдете я думаю.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Начал проверять Вашу догадку, изменил код следующим образом:

 

#define SDRAM_ADR 0xD0000000
#define TEST_LEN 0x800000

void testSdram (void)
{
u32 * p;
p = SDRAM_ADR;
printf("\tWriting to sdram\r\n");
for (u32 i = 0; i < TEST_LEN; i++)
	p[i] = i;
}

void testEnding (void)
{
u32 * y;
y = SDRAM_ADR;
for (u32 i = 0; i < TEST_LEN; i++)
{
	if ( y[i] != i )
	{
	   	printf("\t\twrong value on adr %d - %x \r\n", i, y[i]);
	}
}
printf("\tSdram test end\r\n");
}

 

То есть теперь тест не оставливается на первом несовпадении. В результате вижу следующее:

 

    Writing to sdram

    Startint reading...
        wrong value on adr 2 - 61745309 
        wrong value on adr 3 - 20676e6f 
        wrong value on adr 4 - 756c6176 
        wrong value on adr 5 - 6e6f2065 
        wrong value on adr 6 - 72646120 
        wrong value on adr 7 - 2d203620 
        wrong value on adr 8 - 32643220 
        wrong value on adr 9 - 32323334 
        wrong value on adr 10 - a0d2034 
    Sdram test end

 

То есть значения не совпадают со второго по десятый адреса, далее все нормально. Что это может быть???

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Время рефлеша "1385" - ? это для какой тактовой?

Здесь таковая не есть частота ядра, а лишь то что прилетает на сам чип памяти.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Схему подключения памяти покажите.

 

На скорую руку выкинул из схемы все, что не касается SDRAM. Так много чего лишнего было, так что там нагромождено...

 

post-69041-1477023900_thumb.png

 

Изменить код - так что бы понятно с первого взгляда.

 

эээ... Ну может так понятнее:

 


#define SDRAM_ADR 0xD0000000
#define TEST_LEN 0x800000

void writeToSdram (void)
{
u32 * p;
p = SDRAM_ADR; /**< Присваиваю указателю адрес начала SDRAM */
printf("\tWriting to sdram\r\n", exampleStr); 
/** Пишу по этому указателю пишу четырехбайтными словами 0x800000 раз (то есть забиваю все 32 мегабайта) */
for (u32 i = 0; i < TEST_LEN; i++)
	p[i] = i; /**< Пишу значение счетчика итераций */
}

void readFromSdram (void)
{
u32 * y;
y = SDRAM_ADR; /**< Присваиваю указателю адрес начала SDRAM */
for (u32 i = 0; i < TEST_LEN; i++)
{
	/** Сравниваю значение в SDRAM со счетчиком итераций, так как при записи я записывал это самый счетчик.
	 * Если значение не совпадает, значит по этому адресу не то значение, которое я записываю.
	 * Данные об этих несовпадениях я вывожу в консоль */
	if ( y[i] != i )
	   	printf("\t\twrong value on adr %d - %x \r\n", i, y[i]);
}
printf("\tSdram test end\r\n");
}

int main (void)
{
initSdram(); /**< эта моя инииализация SDRAM, которую я показал в первом посте */

writeToSdram(); /**< Записываю в SDRAM */
readFromSdram(); /**< Читаю из SDRAM и сравниваю */

while (1)
{};
}

 

Время рефлеша "1385" - ? это для какой тактовой?

Здесь таковая не есть частота ядра, а лишь то что прилетает на сам чип памяти.

 

Тактовая частота ядра 180MHz на SDRAM приходит 90 MHz. Я что-то не совсем понял, а как тогда рассчитать это значение?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Тактовая частота ядра 180MHz на SDRAM приходит 90 MHz. Я что-то не совсем понял, а как тогда рассчитать это значение?

Примерно так.

Refresh rate = ( 64 ms ⁄ ( 8196rows ) ) * 90000000 = 702

Кстати, в случае когда настройка sdram начинает кочевать из проекта в проект - проще один раз написать макрос вычисления этого числа, и забыть о проблеме.

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Это из доки:

This register sets the refresh rate in number of SDCLK clock cycles between the refresh

cycles by configuring the Refresh Timer Count value.

 

Example

 

where 64 ms is the SDRAM refresh period.

 

Refresh rate = ( COUNT + 1 ) × SDRAM clock frequency

 

COUNT = ( SDRAM refresh period ⁄ Number of rows ) – 20

 

Refresh rate = 64 ms ⁄ ( 8196rows ) = 7,81μ s

 

7,81μ s × 60MHz = 468,6

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Да без претензий, когда размерности соблюдены (; - это имелось ввиду.

Изменено пользователем IgorKossak
бездумное цитирование

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Вообщем изменил частоту обновления на 702. Симптом остался тот же, по прежнему при чтении первые 13 слов читаются с ошибкой.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Прикольно чип на части разбит, я-то монстров рисую в натуральную величину...

Кстати, а это случайно не кеш барахлит?

 

И ещё один вариант - полностью убрать хал: https://electronix.ru/forum/index.php?s=&am...t&p=1453129

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...