2018-07-03 03:05 AM
I'm using a custom board with F722 running at 160 MHz and a Micron 16 x 4 x 16 SDRAM presumably at 80 MHz. The following test program, however, yields wrong, but not entirely wrong values:
#define SDRAM_BASE ((uint32_t)0x60000000)
for (int i = 0; i < 256; ++i) *(__IO uint16_t*) (SDRAM_BASE + 2*i) = (i << 8) + i; for (int i = 0; i < 256; ++i) { int x = *(__IO uint16_t*) (SDRAM_BASE + 2*i); if (x != (i << 8) + i) printf('Index %x read %x != %x', i, x, (i << 8) + i); }The output for this is
Index 0 read 20 != 0
Index 1 read 21 != 101 Index 2 read 22 != 202 Index 3 read 23 != 303 ... Index f read 2f != f0f Index 10 read 30 != 1010 Index 11 read 31 != 1111 Index 12 read 32 != 1212 Index 13 read 33 != 1313 Index 14 read 34 != 1414 ... Index 1f read 3f != 1f1f Index 20 read 20 != 2020 Index 21 read 21 != 2121 Index 22 read 22 != 2222 Index 23 read 23 != 2323 Index 24 read 24 != 2424 ... Index 2f read 2f != 2f2f Index 30 read 30 != 3030 Index 31 read 31 != 3131 Index 32 read 32 != 3232 Index 33 read 33 != 3333 ...Some bit seems stuck, and the upper byte is missing completely. I also tried disabling byte access and set NBL[1:0], which is connected to DMQH/DMQL, to HIGH, but this didn't have any effect. The result is also stable, i.e. I can reproduce it by re-running the test.
If I enlarge the range and change my code from words to bytes,
for (int i = 0; i < 8192; ++i)
*(__IO uint8_t*) (SDRAM_BASE + i) = i % 256; // read bytes similarlythe test suddenly
succeeds
. But if I spread out the test to even addresses,for (int i = 0; i < 8192; ++i) {
*(__IO uint8_t*) (SDRAM_BASE +2*i
) = i % 256;I get errors again:
Index 0 read 20 != 0
Index 1 read 21 != 1 Index 2 read 22 != 2 Index 3 read 23 != 3 ... Index f read 2f != f Index 10 read 30 != 10 Index 11 read 31 != 11 Index 12 read 32 != 12 Index 13 read 33 != 13 ...I built two boards, and both behave the same. My configuration was generated by CubeMX:
hsdram1.Instance = FMC_SDRAM_DEVICE;
/* hsdram1.Init */ hsdram1.Init.SDBank = FMC_SDRAM_BANK1; hsdram1.Init.ColumnBitsNumber = FMC_SDRAM_COLUMN_BITS_NUM_9; hsdram1.Init.RowBitsNumber = FMC_SDRAM_ROW_BITS_NUM_13; hsdram1.Init.MemoryDataWidth = FMC_SDRAM_MEM_BUS_WIDTH_16; hsdram1.Init.InternalBankNumber = FMC_SDRAM_INTERN_BANKS_NUM_4; hsdram1.Init.CASLatency = FMC_SDRAM_CAS_LATENCY_2; hsdram1.Init.WriteProtection = FMC_SDRAM_WRITE_PROTECTION_DISABLE; hsdram1.Init.SDClockPeriod = FMC_SDRAM_CLOCK_PERIOD_2; hsdram1.Init.ReadBurst = FMC_SDRAM_RBURST_ENABLE; hsdram1.Init.ReadPipeDelay = FMC_SDRAM_RPIPE_DELAY_0; /* SdramTiming */ SdramTiming.LoadToActiveDelay = 2; SdramTiming.ExitSelfRefreshDelay = 6; SdramTiming.SelfRefreshTime = 3; SdramTiming.RowCycleDelay = 5; SdramTiming.WriteRecoveryTime = 2; SdramTiming.RPDelay = 2; SdramTiming.RCDDelay = 2;I added the SDRAM config sequence from the FMC example:
__IO uint32_t tmpmrd =0;
/* Step 3: Configure a clock configuration enable command */ Command.CommandMode = FMC_SDRAM_CMD_CLK_ENABLE; Command.CommandTarget = FMC_SDRAM_CMD_TARGET_BANK1; Command.AutoRefreshNumber = 1; Command.ModeRegisterDefinition = 0; HAL_SDRAM_SendCommand(&hsdram1, &Command, SDRAM_TIMEOUT); /* Step 4: Insert 100 us minimum delay */ HAL_Delay(1); /* Step 5: Configure a PALL (precharge all) command */ Command.CommandMode = FMC_SDRAM_CMD_PALL; Command.CommandTarget = FMC_SDRAM_CMD_TARGET_BANK1; Command.AutoRefreshNumber = 1; Command.ModeRegisterDefinition = 0; HAL_SDRAM_SendCommand(&hsdram1, &Command, SDRAM_TIMEOUT); /* Step 6 : Configure a Auto-Refresh command */ Command.CommandMode = FMC_SDRAM_CMD_AUTOREFRESH_MODE; Command.CommandTarget = FMC_SDRAM_CMD_TARGET_BANK1; Command.AutoRefreshNumber = 8; Command.ModeRegisterDefinition = 0; HAL_SDRAM_SendCommand(&hsdram1, &Command, SDRAM_TIMEOUT); /* Step 7: Program the external memory mode register */ tmpmrd = (uint32_t)SDRAM_MODEREG_BURST_LENGTH_1 | SDRAM_MODEREG_BURST_TYPE_SEQUENTIAL | SDRAM_MODEREG_CAS_LATENCY_2 | SDRAM_MODEREG_OPERATING_MODE_STANDARD | SDRAM_MODEREG_WRITEBURST_MODE_SINGLE; Command.CommandMode = FMC_SDRAM_CMD_LOAD_MODE; Command.CommandTarget = FMC_SDRAM_CMD_TARGET_BANK1; Command.AutoRefreshNumber = 1; Command.ModeRegisterDefinition = tmpmrd; HAL_SDRAM_SendCommand(&hsdram1, &Command, SDRAM_TIMEOUT); /* Step 8: Set the refresh rate counter: (64 ms / 8192 x Freq) - 20 */ hsdram1.Instance->SDRTR |= ((uint32_t)605); // 2HCLKI also triedlarger timings,and CL=3, but nothing helped.
My PCB has 4 layers, the SDRAM signals are separated intothree groups:
second layer: addresses, lengths 3-9 mm
third layer: data, lengths 2-1 mm
bottom layer: control, lengths 0-6
CLK length: 0 mm
Iwould suspect either some misconfiguration or bad signal tracing, but I just don't know how to examinemy problemany further than this.
#sdram #fmc Note: this post was migrated and contained many threaded conversations, some content may be missing.2018-07-03 12:42 PM
While I'm fiddling, try this I've made sure I enable the GPIO clocks, and backed off the slew-rate, which is commonly done on the DISCO/EVAL boards due to the short traces, and to avoid ringing
static void HAL_FMC_MspInit(void){
GPIO_InitTypeDef GPIO_InitStruct;if (FMC_Initialized) {
return; } FMC_Initialized = 1; /* Peripheral clock enable */ __HAL_RCC_FMC_CLK_ENABLE();/* Enable GPIOs clock */
__HAL_RCC_GPIOC_CLK_ENABLE(); __HAL_RCC_GPIOD_CLK_ENABLE(); __HAL_RCC_GPIOE_CLK_ENABLE(); __HAL_RCC_GPIOF_CLK_ENABLE(); __HAL_RCC_GPIOG_CLK_ENABLE();/** FMC GPIO Configuration
PF0 ------> FMC_A0 PF1 ------> FMC_A1 PF2 ------> FMC_A2 PF3 ------> FMC_A3 PF4 ------> FMC_A4 PF5 ------> FMC_A5 PC0 ------> FMC_SDNWE PC2 ------> FMC_SDNE0 PC3 ------> FMC_SDCKE0 PF11 ------> FMC_SDNRAS PF12 ------> FMC_A6 PF13 ------> FMC_A7 PF14 ------> FMC_A8 PF15 ------> FMC_A9 PG0 ------> FMC_A10 PG1 ------> FMC_A11 PE7 ------> FMC_D4 PE8 ------> FMC_D5 PE9 ------> FMC_D6 PE10 ------> FMC_D7 PE11 ------> FMC_D8 PE12 ------> FMC_D9 PE13 ------> FMC_D10 PE14 ------> FMC_D11 PE15 ------> FMC_D12 PD8 ------> FMC_D13 PD9 ------> FMC_D14 PD10 ------> FMC_D15 PD14 ------> FMC_D0 PD15 ------> FMC_D1 PG2 ------> FMC_A12 PG4 ------> FMC_BA0 PG5 ------> FMC_BA1 PG8 ------> FMC_SDCLK PD0 ------> FMC_D2 PD1 ------> FMC_D3 PG15 ------> FMC_SDNCAS PE0 ------> FMC_NBL0 PE1 ------> FMC_NBL1By Bank
PC0 ------> FMC_SDNWE
PC2 ------> FMC_SDNE0 CS PC3 ------> FMC_SDCKE0PD0 ------> FMC_D2
PD1 ------> FMC_D3 PD8 ------> FMC_D13 PD9 ------> FMC_D14 PD10 ------> FMC_D15 PD14 ------> FMC_D0 PD15 ------> FMC_D1PE0 ------> FMC_NBL0 DQM0 DQML
PE1 ------> FMC_NBL1 DQM1 DQMH PE7 ------> FMC_D4 PE8 ------> FMC_D5 PE9 ------> FMC_D6 PE10 ------> FMC_D7 PE11 ------> FMC_D8 PE12 ------> FMC_D9 PE13 ------> FMC_D10 PE14 ------> FMC_D11 PE15 ------> FMC_D12PF0 ------> FMC_A0
PF1 ------> FMC_A1 PF2 ------> FMC_A2 PF3 ------> FMC_A3 PF4 ------> FMC_A4 PF5 ------> FMC_A5 PF11 ------> FMC_SDNRAS PF12 ------> FMC_A6 PF13 ------> FMC_A7 PF14 ------> FMC_A8 PF15 ------> FMC_A9PG0 ------> FMC_A10
PG1 ------> FMC_A11 PG2 ------> FMC_A12 PG4 ------> FMC_BA0 PG5 ------> FMC_BA1 PG8 ------> FMC_SDCLK PG15 ------> FMC_SDNCAS*/GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_PULLUP; // GPIO_NOPULL; GPIO_InitStruct.Speed = GPIO_SPEED_FAST; // GPIO_SPEED_FREQ_VERY_HIGH; GPIO_InitStruct.Alternate = GPIO_AF12_FMC;GPIO_InitStruct.Pin = GPIO_PIN_0|GPIO_PIN_2|GPIO_PIN_3;
HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);GPIO_InitStruct.Pin = GPIO_PIN_8|GPIO_PIN_9|GPIO_PIN_10|GPIO_PIN_14
|GPIO_PIN_15|GPIO_PIN_0|GPIO_PIN_1; HAL_GPIO_Init(GPIOD, &GPIO_InitStruct);GPIO_InitStruct.Pin = GPIO_PIN_7|GPIO_PIN_8|GPIO_PIN_9|GPIO_PIN_10
|GPIO_PIN_11|GPIO_PIN_12|GPIO_PIN_13|GPIO_PIN_14 |GPIO_PIN_15|GPIO_PIN_0|GPIO_PIN_1; HAL_GPIO_Init(GPIOE, &GPIO_InitStruct);GPIO_InitStruct.Pin = GPIO_PIN_0|GPIO_PIN_1|GPIO_PIN_2|GPIO_PIN_3
|GPIO_PIN_4|GPIO_PIN_5|GPIO_PIN_11|GPIO_PIN_12 |GPIO_PIN_13|GPIO_PIN_14|GPIO_PIN_15; HAL_GPIO_Init(GPIOF, &GPIO_InitStruct);GPIO_InitStruct.Pin = GPIO_PIN_0|GPIO_PIN_1|GPIO_PIN_2|GPIO_PIN_4
|GPIO_PIN_5|GPIO_PIN_8|GPIO_PIN_15; HAL_GPIO_Init(GPIOG, &GPIO_InitStruct);}2018-07-03 02:43 PM
Ok, this should output via USART1 at 115200 8N1 (or SWV @ 160 MHz)
Open in thread mode to see attachment
________________ Attachments : SDRAM-001.hex.zip : https://st--c.eu10.content.force.com/sfc/dist/version/download/?oid=00Db0000000YtG6&ids=0680X000006HxS4&d=%2Fa%2F0X0000000ayD%2F9MDgdWrOHVm8TYcqJCV3aJkAxnKpAvvrvCvz7WaQBhw&asPdf=false2018-07-04 11:39 AM
Thank you, I got the email notification last night and tried it right away. Now I do read 2 bytes, but they're always equal to 0xffff.
When diffing the generated version and your version, it seems the only change is activating the pull-up, correct?
2018-07-04 11:46 AM
That is awesome! Unfortunately, when I tried to flash this with CubeProgrammer, the program couldn't write to the start address:
18:40:28 : Memory Programming ...
18:40:28 : Openeing and parsing file: tmp/SDRAM-001.hex18:40:28 : File : tmp/SDRAM-001.hex18:40:28 : Size : 11648 Bytes18:40:28 : Address : 0x00200000 18:40:28 : Erasing memory corresponding to segment 0:18:40:28 : Download in Progress:18:40:28 : Error: Writing in address k0x00200000 is not supported with JTAG/SWD debug portI used this program successfully before, but maybe I used 0x00800000? I'm using a Nucleo ST-LINK v2 stub. I also tried st-flash and openocd (I'm on Linux), but both programs had issues I couldn't resolve so quickly.
2018-07-04 12:53 PM
Ok, editing the first line to map to 0x08000000 instead of 0x00200000
Was building in Keil for ITCM-FLASH, forgot ST-LINK/STM32 Programmer were fussy.
________________ Attachments : SDRAM-001A.hex.zip : https://st--c.eu10.content.force.com/sfc/dist/version/download/?oid=00Db0000000YtG6&ids=0680X000006HxRz&d=%2Fa%2F0X0000000ayE%2FkV2.ONuQwMS6THbfqITnwXKwz4KvgWZY.nL45k0JJUw&asPdf=false2018-07-04 01:19 PM
Thank you! This file I could flash without problems, I think:
20:09:55 : Memory Programming ...
20:09:55 : Openeing and parsing file: tmp/SDRAM-001A.hex20:09:55 : File : tmp/SDRAM-001A.hex20:09:55 : Size : 11648 Bytes20:09:55 : Address : 0x08000000 20:09:55 : Erasing Segment <0> Address <0x08000000> Size <11648>Bytes20:09:55 : Erasing memory corresponding to segment 0:20:09:55 : reset ap 0 20:09:55 : run ap 0 20:09:55 : halt ap 0 20:09:55 : w ap 0 reg 15 (0x20000000) 20:09:55 : w ap 0 reg 17 (0x20000500) 20:09:55 : w ap 0 reg 16 (0x01000000) 20:09:55 : w ap 0 @0x20000DA0 0x00000200 bytes20:09:55 : w ap 0 @0x20000000 0x00000004 bytes20:09:55 : w ap 0 @0x20000004 0x00000978 bytes20:09:55 : Erasing internal memory sector 020:09:55 : halt ap 0 20:09:55 : w ap 0 reg 0 0x00000001...20:09:55 : w ap 0 reg 18 0x0000000020:09:55 : run ap 0 20:09:55 : halt ap 0 20:09:55 : r ap 0 reg 0 0x00000001...20:09:55 : w ap 0 reg 18 0x00000000
20:09:55 : run ap 0 20:09:55 : halt ap 0 20:09:55 : r ap 0 reg 0 0x0000000120:09:55 : erase: 0228ms20:09:55 : Download in Progress:20:09:55 : reset ap 0 20:09:55 : run ap 0 20:09:55 : halt ap 0 20:09:55 : w ap 0 reg 15 (0x20000000) 20:09:55 : w ap 0 reg 17 (0x20000500) 20:09:55 : w ap 0 reg 16 (0x01000000) 20:09:55 : w ap 0 @0x20000DA0 0x00000200 bytes20:09:55 : w ap 0 @0x20000000 0x00000004 bytes20:09:55 : w ap 0 @0x20000004 0x00000978 bytes20:09:55 : w ap 0 @0x20000DA0 0x000016C0 bytes20:09:55 : W B1 in RAM @0x20000DA0 size 0x000016C0 : 0039ms20:09:55 : halt ap 0 20:09:55 : w ap 0 reg 0 0x00000001...20:09:55 : w ap 0 reg 14 0x2000000120:09:55 : w ap 0 reg 15 0x2000000520:09:55 : w ap 0 reg 16 0x0100000020:09:55 : w ap 0 reg 17 0x20000D7820:09:55 : w ap 0 reg 18 0x0000000020:09:55 : run ap 0 20:09:55 : halt ap 0 20:09:55 : r ap 0 reg 0 0x0000000120:09:55 : w ap 0 reg 0 0x0800000020:09:55 : w ap 0 reg 1 0x000016C020:09:55 : w ap 0 reg 2 0x20000DA020:09:55 : w ap 0 reg 3 0x00000002...20:09:55 : w ap 0 reg 14 0x2000000120:09:55 : w ap 0 reg 15 0x2000005320:09:55 : w ap 0 reg 16 0x0100000020:09:55 : w ap 0 reg 17 0x20000D7820:09:55 : w ap 0 reg 18 0x0000000020:09:55 : run ap 0 20:09:55 : w ap 0 @0x200205A0 0x000016C0 bytes20:09:55 : W B2 in RAM @0x200205A0 size 0x000016C0: 0060ms20:09:55 : r ap 0 reg 0 0x0000000120:09:55 : Wait W B1 in Flash @0x08000000 size 0x000016C0: 0001ms20:09:55 : w ap 0 reg 0 0x080016C020:09:55 : w ap 0 reg 1 0x000016C020:09:55 : w ap 0 reg 2 0x200205A0...20:09:55 : w ap 0 reg 14 0x2000000120:09:55 : w ap 0 reg 15 0x2000005320:09:55 : w ap 0 reg 16 0x0100000020:09:55 : w ap 0 reg 17 0x20000D7820:09:55 : w ap 0 reg 18 0x0000000020:09:55 : run ap 0 20:09:55 : Total W: 0148ms20:09:55 : File download complete20:09:55 : Time elapsed during the download operation is: 00:00:00.39920:09:55 : VERIFYING ...20:09:55 : reset ap 0 20:09:55 : run ap 0 20:09:55 : halt ap 0 20:09:55 : w ap 0 reg 15 (0x20000000) ...20:09:56 : w ap 0 reg 18 0x0000000020:09:56 : run ap 0 20:09:56 : halt ap 0 20:09:56 : r ap 0 reg 0 0x0000000120:09:56 : r ap 0 @0x08000000 0x00002D80 bytes20:09:56 : Download verified successfully 20:09:56 : Address: : 0x200000020:09:56 : Warning: The core is locked up20:09:56 : Start operation achieved successfullyHowever, I'm not receiving anything on USART1 with 115200 8N1 -- was there a flash error, or what am I to expect? There was also a warning. Do I need hardware flow control?
2018-07-04 02:08 PM
Should run from the HSI clock via the PLL. No flow control on the VCP/USART. But should also output via SWV.
Will look over things again later.
2018-07-04 10:00 PM
Ok, so spent some more time reviewing the code
Should output via USART1 at 115200 8N1, or SWV @ 160 MHz
LARS-CUSTOM-F722 Core=160000000, 160 MHz CPUID 411FC270 DEVID 451 REVID 1000 Cortex M7 r1p0 STM32F76xxx or F77xxx C0000000 FFFFFFF8 00000000 10110221 12000011 00000040 FPU-D Single-precision and Double-precision HCLK=160000000 APB1=40000000 APB2=80000000 PLL P:160000000 Q: 35555555 R:160000000 PLL48CLK 35555555, 56 MHz HAL_SDRAM_Init : Success FAIL: [C0000000] 44604460 != 11223344 FAIL: [C0000004] FFFFFFFF != 089119A2 FAIL: [C0000008] FFFFFFFF != 04488CD1 FAIL: [C000000C] FFFFFFFF != EF9CC548 FAIL: [C0000010] FFFFFFFF != 77CE62A4 FAIL: [C0000014] FFFFFFFF != 3BE73152 FAIL: [C0000018] FFFFFFFF != 1DF398A9 FAIL: [C000001C] FFFFFFFF != E3414F74 FAIL: [C0000020] FFFFFFFF != 71A0A7BA FAIL: [C0000024] FFFFFFFF != 38D053DD FAIL: [C0000028] FFFFFFFF != F1D0AACE FAIL: [C000002C] FFFFFFFF != 78E85567 Infinite Loop... ________________ Attachments : SDRAM-002.hex.zip : https://st--c.eu10.content.force.com/sfc/dist/version/download/?oid=00Db0000000YtG6&ids=0680X000006HxRV&d=%2Fa%2F0X0000000ay8%2FBlDe3hxL_X2.g8ITjV4WaVo.qt9bO.Z0THGISYukOBk&asPdf=false