yanvasilij 0 20 октября, 2016 Опубликовано 20 октября, 2016 · Жалоба Добрый день! Пытаюсь завести 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"); } При чтении уже на втором слове обнаруживается несовпадение между записанным и считанным. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
x893 55 20 октября, 2016 Опубликовано 20 октября, 2016 · Жалоба Задам простой вопрос Если записывать и сразу читать ? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
yanvasilij 0 20 октября, 2016 Опубликовано 20 октября, 2016 · Жалоба Так все работает (то есть если это делать в теле одной функции). Я если честно не понимаю почему. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
x893 55 20 октября, 2016 Опубликовано 20 октября, 2016 · Жалоба потому что адреса где то коротят. Напишите тест и определите что коротит. минут 10-15 найдете я думаю. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
yanvasilij 0 20 октября, 2016 Опубликовано 20 октября, 2016 · Жалоба Начал проверять Вашу догадку, изменил код следующим образом: #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 То есть значения не совпадают со второго по десятый адреса, далее все нормально. Что это может быть??? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
skripach 6 20 октября, 2016 Опубликовано 20 октября, 2016 · Жалоба Схему подключения памяти покажите. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
x893 55 20 октября, 2016 Опубликовано 20 октября, 2016 · Жалоба Изменить код - так что бы понятно с первого взгляда. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
AVI-crak 0 20 октября, 2016 Опубликовано 20 октября, 2016 · Жалоба Время рефлеша "1385" - ? это для какой тактовой? Здесь таковая не есть частота ядра, а лишь то что прилетает на сам чип памяти. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
yanvasilij 0 21 октября, 2016 Опубликовано 21 октября, 2016 · Жалоба Схему подключения памяти покажите. На скорую руку выкинул из схемы все, что не касается SDRAM. Так много чего лишнего было, так что там нагромождено... Изменить код - так что бы понятно с первого взгляда. эээ... Ну может так понятнее: #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. Я что-то не совсем понял, а как тогда рассчитать это значение? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
AVI-crak 0 21 октября, 2016 Опубликовано 21 октября, 2016 · Жалоба Тактовая частота ядра 180MHz на SDRAM приходит 90 MHz. Я что-то не совсем понял, а как тогда рассчитать это значение? Примерно так. Refresh rate = ( 64 ms ⁄ ( 8196rows ) ) * 90000000 = 702 Кстати, в случае когда настройка sdram начинает кочевать из проекта в проект - проще один раз написать макрос вычисления этого числа, и забыть о проблеме. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Obam 38 21 октября, 2016 Опубликовано 21 октября, 2016 · Жалоба Тогда уж: Refresh rate = ( 64 ms ⁄ ( 8196rows ) ) * 90000 = 702 иначе ж… Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
AVI-crak 0 21 октября, 2016 Опубликовано 21 октября, 2016 · Жалоба Это из доки: 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 Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Obam 38 21 октября, 2016 Опубликовано 21 октября, 2016 (изменено) · Жалоба Да без претензий, когда размерности соблюдены (; - это имелось ввиду. Изменено 21 октября, 2016 пользователем IgorKossak бездумное цитирование Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
yanvasilij 0 21 октября, 2016 Опубликовано 21 октября, 2016 · Жалоба Вообщем изменил частоту обновления на 702. Симптом остался тот же, по прежнему при чтении первые 13 слов читаются с ошибкой. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
AVI-crak 0 21 октября, 2016 Опубликовано 21 октября, 2016 · Жалоба Прикольно чип на части разбит, я-то монстров рисую в натуральную величину... Кстати, а это случайно не кеш барахлит? И ещё один вариант - полностью убрать хал: https://electronix.ru/forum/index.php?s=&am...t&p=1453129 Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться