реклама на сайте
подробности

 
 
2 страниц V   1 2 >  
Reply to this topicStart new topic
> SDRAM MT48LC16M16 + STM32F429 + FMC
yanvasiij
сообщение Oct 20 2016, 05:30
Сообщение #1


Местный
***

Группа: Свой
Сообщений: 321
Регистрация: 23-12-11
Из: Уфа
Пользователь №: 69 041



Добрый день!

Пытаюсь завести 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");
}



При чтении уже на втором слове обнаруживается несовпадение между записанным и считанным.
Go to the top of the page
 
+Quote Post
x893
сообщение Oct 20 2016, 09:12
Сообщение #2


Профессионал
*****

Группа: Свой
Сообщений: 1 333
Регистрация: 27-10-08
Из: Планета Земля
Пользователь №: 41 226



Задам простой вопрос

Если записывать и сразу читать ?
Go to the top of the page
 
+Quote Post
yanvasiij
сообщение Oct 20 2016, 09:30
Сообщение #3


Местный
***

Группа: Свой
Сообщений: 321
Регистрация: 23-12-11
Из: Уфа
Пользователь №: 69 041



Так все работает (то есть если это делать в теле одной функции). Я если честно не понимаю почему.
Go to the top of the page
 
+Quote Post
x893
сообщение Oct 20 2016, 09:50
Сообщение #4


Профессионал
*****

Группа: Свой
Сообщений: 1 333
Регистрация: 27-10-08
Из: Планета Земля
Пользователь №: 41 226



потому что адреса где то коротят.
Напишите тест и определите что коротит.
минут 10-15 найдете я думаю.
Go to the top of the page
 
+Quote Post
yanvasiij
сообщение Oct 20 2016, 11:45
Сообщение #5


Местный
***

Группа: Свой
Сообщений: 321
Регистрация: 23-12-11
Из: Уфа
Пользователь №: 69 041



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

CODE

#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


То есть значения не совпадают со второго по десятый адреса, далее все нормально. Что это может быть???
Go to the top of the page
 
+Quote Post
skripach
сообщение Oct 20 2016, 14:28
Сообщение #6


■ ■ ■ ■
*****

Группа: Свой
Сообщений: 1 100
Регистрация: 9-08-06
Пользователь №: 19 443



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


--------------------
Делай что должен и будь что будет.
Go to the top of the page
 
+Quote Post
x893
сообщение Oct 20 2016, 16:27
Сообщение #7


Профессионал
*****

Группа: Свой
Сообщений: 1 333
Регистрация: 27-10-08
Из: Планета Земля
Пользователь №: 41 226



Изменить код - так что бы понятно с первого взгляда.
Go to the top of the page
 
+Quote Post
AVI-crak
сообщение Oct 20 2016, 17:54
Сообщение #8


Частый гость
**

Группа: Участник
Сообщений: 182
Регистрация: 16-10-15
Пользователь №: 88 894



Время рефлеша "1385" - ? это для какой тактовой?
Здесь таковая не есть частота ядра, а лишь то что прилетает на сам чип памяти.
Go to the top of the page
 
+Quote Post
yanvasiij
сообщение Oct 21 2016, 04:49
Сообщение #9


Местный
***

Группа: Свой
Сообщений: 321
Регистрация: 23-12-11
Из: Уфа
Пользователь №: 69 041



Цитата(skripach @ Oct 20 2016, 19:28) *
Схему подключения памяти покажите.


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

Прикрепленное изображение


Цитата(x893 @ Oct 20 2016, 21:27) *
Изменить код - так что бы понятно с первого взгляда.


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

CODE


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



Цитата(AVI-crak @ Oct 20 2016, 22:54) *
Время рефлеша "1385" - ? это для какой тактовой?
Здесь таковая не есть частота ядра, а лишь то что прилетает на сам чип памяти.


Тактовая частота ядра 180MHz на SDRAM приходит 90 MHz. Я что-то не совсем понял, а как тогда рассчитать это значение?
Go to the top of the page
 
+Quote Post
AVI-crak
сообщение Oct 21 2016, 05:07
Сообщение #10


Частый гость
**

Группа: Участник
Сообщений: 182
Регистрация: 16-10-15
Пользователь №: 88 894



Цитата(yanvasiij @ Oct 21 2016, 11:49) *
Тактовая частота ядра 180MHz на SDRAM приходит 90 MHz. Я что-то не совсем понял, а как тогда рассчитать это значение?

Примерно так.
Refresh rate = ( 64 ms ⁄ ( 8196rows ) ) * 90000000 = 702
Кстати, в случае когда настройка sdram начинает кочевать из проекта в проект - проще один раз написать макрос вычисления этого числа, и забыть о проблеме.
Go to the top of the page
 
+Quote Post
Obam
сообщение Oct 21 2016, 07:45
Сообщение #11


Знающий
****

Группа: Участник
Сообщений: 756
Регистрация: 14-11-14
Пользователь №: 83 663



Тогда уж: Refresh rate = ( 64 ms ⁄ ( 8196rows ) ) * 90000 = 702 иначе ж…


--------------------
Пролетарий умственного труда.
Go to the top of the page
 
+Quote Post
AVI-crak
сообщение Oct 21 2016, 08:10
Сообщение #12


Частый гость
**

Группа: Участник
Сообщений: 182
Регистрация: 16-10-15
Пользователь №: 88 894



Это из доки:
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
Go to the top of the page
 
+Quote Post
Obam
сообщение Oct 21 2016, 08:33
Сообщение #13


Знающий
****

Группа: Участник
Сообщений: 756
Регистрация: 14-11-14
Пользователь №: 83 663



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

Сообщение отредактировал IgorKossak - Oct 21 2016, 09:51
Причина редактирования: бездумное цитирование


--------------------
Пролетарий умственного труда.
Go to the top of the page
 
+Quote Post
yanvasiij
сообщение Oct 21 2016, 10:06
Сообщение #14


Местный
***

Группа: Свой
Сообщений: 321
Регистрация: 23-12-11
Из: Уфа
Пользователь №: 69 041



Вообщем изменил частоту обновления на 702. Симптом остался тот же, по прежнему при чтении первые 13 слов читаются с ошибкой.
Go to the top of the page
 
+Quote Post
AVI-crak
сообщение Oct 21 2016, 12:53
Сообщение #15


Частый гость
**

Группа: Участник
Сообщений: 182
Регистрация: 16-10-15
Пользователь №: 88 894



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

И ещё один вариант - полностью убрать хал: https://electronix.ru/forum/index.php?s=&am...t&p=1453129
Go to the top of the page
 
+Quote Post
jcxz
сообщение Oct 23 2016, 21:54
Сообщение #16


Гуру
******

Группа: Свой
Сообщений: 5 228
Регистрация: 3-07-08
Из: Омск
Пользователь №: 38 713



Цитата(yanvasiij @ Oct 21 2016, 13:06) *
Вообщем изменил частоту обновления на 702. Симптом остался тот же, по прежнему при чтении первые 13 слов читаются с ошибкой.

Ваши проблемы совершенно определённо не из-за частоты обновления. Недавно тут выкладывал результаты своих экспериментов с SDRAM на LPC1788: при отключении регенерации, содержимое начинает разрушаться в реальности через 5-7 секунд только. Так что даже если бы в 10 раз ошиблись с расчётом периода - не заметили бы. Конечно это в тепличных условиях, на столе.
Go to the top of the page
 
+Quote Post

2 страниц V   1 2 >
Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 19th July 2025 - 12:08
Рейтинг@Mail.ru


Страница сгенерированна за 0.01537 секунд с 7
ELECTRONIX ©2004-2016