Добрый день, форумчане!
Мы перешли на наших платах с STM32F429 на STM32H743. Сейчас пытаюсь оживить SDRAM (MT48LC16M16A2). Ввиду того, что регистры у FMC аналогичны (за исключением двух вещей: нет статусного сигнала BUSY и необходимо после настройки включать FMC в регистре FMC_BCR1), перетянул настройку SDRAM с контроллера STM32F4. Внутреннюю частоту (120 МГц) и частоту SDRAM (60 МГц) настроил точно также как и STM32F4. Повторюсь, снял с платы F4 и поставил H7 для освоения.
Пишу по 16 бит без burst режима. Ремап не делал. Пишу по адресу 0xC0000000 (банк 1 SDRAM) и добавляю смещение.
Но вот почему-то не хочет запускаться нормально FMC.
Обнаружил осциллографом:
1. Нет сигналов BA0, BA1 и UDQM, LDQM. Хотя пишу в каждый банк.
2. Сигналы RAS и CAS не имеют сдвига друг относительно друга. но может так и должно быть не знаю.
Экспериментально обнаружил, что если писать в 0х60000000 то сигналы появляются (кроме BA0), но всё равно не записать в SDRAM данные. В примерах на HAL вижу, что настраивают они банк2 минуя банк 1. Может там что-то не так с ним.
Кто-нибудь уже разбирался с темой STM32H7 и SDRAM? Буду признателен за любую помощь!
#define SDRAM_START_ADDR ((uint32_t) 0xC0000000) // SDRAM bank1 area start address
static void fmc_SDRAM_Config(void)
{
FMC_Bank1->BTCR[0] &= ~(1 << FMC_BCR1_FMCEN_Pos);
FMC_Bank5_6->SDCR[0] = FMC_SDCR1_SDCLK_1 | FMC_SDCR1_CAS_1 | FMC_SDCR1_NB | FMC_SDCR1_MWID_0 | FMC_SDCR1_NR_1 | FMC_SDCR1_NC_0;
uint8_t TMRD, TXSR, TRAS, TRC, TWR, TRP, TRCD;
TMRD = 2;
TXSR = 5;
TRAS = 5;
TRC = 4;
TWR = 4;
TRP = 2;
TRCD = 2;
FMC_Bank5_6->SDTR[0] = (uint32_t) (((TMRD - 1) << FMC_SDTR1_TMRD_Pos) |
((TXSR - 1) << FMC_SDTR1_TXSR_Pos) |
((TRC - 1) << FMC_SDTR1_TRC_Pos) |
((TRAS - 1) << FMC_SDTR1_TRAS_Pos) |
((TRP - 1) << FMC_SDTR1_TRP_Pos) |
((TWR - 1) << FMC_SDTR1_TWR_Pos) |
((TRCD - 1) << FMC_SDTR1_TRCD_Pos));
FMC_Bank1->BTCR[0] |= (1 << FMC_BCR1_FMCEN_Pos);
}
static void fmc_SDRAM_Initialization_Sequence(void)
{
/*
STEP 1: Clock enable command
*/
FMC_Bank5_6->SDCMR = (uint32_t)((FMC_MODE_CLOCKCONFIG << FMC_SDCMR_MODE_Pos) |\
(1 << FMC_SDCMR_CTB1_Pos) |\
((1 - 1) << FMC_SDCMR_NRFS_Pos) |\
(0 << FMC_SDCMR_MRD_Pos));
/*
Delay = 1000 mks
*/
HAL_Delay(1);
/*
STEP 2: All Bank Precharge command
*/
FMC_Bank5_6->SDCMR = (uint32_t)((FMC_MODE_PALL << FMC_SDCMR_MODE_Pos) |\
(1 << FMC_SDCMR_CTB1_Pos) |\
((1 - 1) << FMC_SDCMR_NRFS_Pos) |\
(0 << FMC_SDCMR_MRD_Pos));
/*
STEP 3: Auto refresh command (NRFS = TRC in SDCR1 register)
*/
FMC_Bank5_6->SDCMR = (uint32_t)((FMC_MODE_AUTOREFRESH << FMC_SDCMR_MODE_Pos) |\
(1 << FMC_SDCMR_CTB1_Pos) |\
((8 - 1) << FMC_SDCMR_NRFS_Pos) |\
(0 << FMC_SDCMR_MRD_Pos));
/*
STEP 4: MRD register program:
Mode Register = 0b0000 0100 0100 0 (CL = 2; M9 - Single Location Access)
*/
uint32_t tmpmrd = (uint32_t)0x220;
FMC_Bank5_6->SDCMR = (uint32_t)((FMC_MODE_LOADMODEREG << FMC_SDCMR_MODE_Pos) |\
(1 << FMC_SDCMR_CTB2_Pos) |\
((1 - 1) << FMC_SDCMR_NRFS_Pos) |\
(tmpmrd << FMC_SDCMR_MRD_Pos));
/*
STEP 5: Set refresh count
*/
FMC_Bank5_6->SDRTR = (FMC_Bank5_6->SDRTR & FMC_SDRTR_REIE) | (0x000001EF << 1);
}
void fmc_SDRAM_Init(void)
{
RCC->D1CCIPR |= (RCC->D1CCIPR & RCC_D1CCIPR_FMCSEL) | RCC_D1CCIPR_FMCSEL_1; // FMC kernel clock source = per_pll2 = 120 MHz
RCC->AHB3ENR |= RCC_AHB3ENR_FMCEN; // Enable the FMC interface clock
fmc_SDRAM_GPIOConfig();
fmc_SDRAM_Config();
fmc_SDRAM_Initialization_Sequence();
}
int main(void)
{
Init_SoftwareModules();
fmc_SDRAM_Init();
uint32_t Address, Pattern;
while(1)
{
Address = SDRAM_START_ADDR;
Pattern = 0xAAAA;
MemTest_WriteReadSDRAM(Address, Pattern, dbw16Bit);
Address = SDRAM_START_ADDR + 0x4000;
Pattern = 0xAAAA;
MemTest_WriteReadSDRAM(Address, Pattern, dbw16Bit);
Address = SDRAM_START_ADDR + 0x8000;
Pattern = 0xAAAA;
MemTest_WriteReadSDRAM(Address, Pattern, dbw16Bit);
Address = SDRAM_START_ADDR + 0xC000;
Pattern = 0xAAAA;
MemTest_WriteReadSDRAM(Address, Pattern, dbw16Bit);
}
}