cancel
Showing results for 
Search instead for 
Did you mean: 

STM32F722 reads mostly incorrect values from SDRAM

Lars Beiderbecke
Senior III
Posted on July 03, 2018 at 12:05

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 similarly

the 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); // 2HCLK

I 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.
17 REPLIES 17
Posted on July 03, 2018 at 19:42

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_NBL1

 By Bank

 PC0 ------> FMC_SDNWE

 PC2 ------> FMC_SDNE0 CS

 PC3 ------> FMC_SDCKE0

 PD0 ------> FMC_D2

 PD1 ------> FMC_D3

 PD8 ------> FMC_D13

 PD9 ------> FMC_D14

 PD10 ------> FMC_D15

 PD14 ------> FMC_D0

 PD15 ------> FMC_D1

 PE0 ------> 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_D12

 PF0 ------> 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_A9

 PG0 ------> 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);

}
Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
Posted on July 03, 2018 at 21:43

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=false
Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
Posted on July 04, 2018 at 18:39

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?

Posted on July 04, 2018 at 18:46

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.hex

18:40:28 : File : tmp/SDRAM-001.hex

18:40:28 : Size : 11648 Bytes

18: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 port

I 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.

Posted on July 04, 2018 at 19:53

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=false
Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
Posted on July 04, 2018 at 20:19

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.hex

20:09:55 : File : tmp/SDRAM-001A.hex

20:09:55 : Size : 11648 Bytes

20:09:55 : Address : 0x08000000

20:09:55 : Erasing Segment <0> Address <0x08000000> Size <11648>Bytes

20: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 bytes

20:09:55 : w ap 0 @0x20000000 0x00000004 bytes

20:09:55 : w ap 0 @0x20000004 0x00000978 bytes

20:09:55 : Erasing internal memory sector 0

20:09:55 : halt ap 0

20:09:55 : w 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 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 0x00000001

20:09:55 : erase: 0228ms

20: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 bytes

20:09:55 : w ap 0 @0x20000000 0x00000004 bytes

20:09:55 : w ap 0 @0x20000004 0x00000978 bytes

20:09:55 : w ap 0 @0x20000DA0 0x000016C0 bytes

20:09:55 : W B1 in RAM @0x20000DA0 size 0x000016C0 : 0039ms

20:09:55 : halt ap 0

20:09:55 : w ap 0 reg 0 0x00000001

...

20:09:55 : w ap 0 reg 14 0x20000001

20:09:55 : w ap 0 reg 15 0x20000005

20:09:55 : w ap 0 reg 16 0x01000000

20:09:55 : w ap 0 reg 17 0x20000D78

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 0x00000001

20:09:55 : w ap 0 reg 0 0x08000000

20:09:55 : w ap 0 reg 1 0x000016C0

20:09:55 : w ap 0 reg 2 0x20000DA0

20:09:55 : w ap 0 reg 3 0x00000002

...

20:09:55 : w ap 0 reg 14 0x20000001

20:09:55 : w ap 0 reg 15 0x20000053

20:09:55 : w ap 0 reg 16 0x01000000

20:09:55 : w ap 0 reg 17 0x20000D78

20:09:55 : w ap 0 reg 18 0x00000000

20:09:55 : run ap 0

20:09:55 : w ap 0 @0x200205A0 0x000016C0 bytes

20:09:55 : W B2 in RAM @0x200205A0 size 0x000016C0: 0060ms

20:09:55 : r ap 0 reg 0 0x00000001

20:09:55 : Wait W B1 in Flash @0x08000000 size 0x000016C0: 0001ms

20:09:55 : w ap 0 reg 0 0x080016C0

20:09:55 : w ap 0 reg 1 0x000016C0

20:09:55 : w ap 0 reg 2 0x200205A0

...

20:09:55 : w ap 0 reg 14 0x20000001

20:09:55 : w ap 0 reg 15 0x20000053

20:09:55 : w ap 0 reg 16 0x01000000

20:09:55 : w ap 0 reg 17 0x20000D78

20:09:55 : w ap 0 reg 18 0x00000000

20:09:55 : run ap 0

20:09:55 : Total W: 0148ms

20:09:55 : File download complete

20:09:55 : Time elapsed during the download operation is: 00:00:00.399

20: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 0x00000000

20:09:56 : run ap 0

20:09:56 : halt ap 0

20:09:56 : r ap 0 reg 0 0x00000001

20:09:56 : r ap 0 @0x08000000 0x00002D80 bytes

20:09:56 : Download verified successfully

20:09:56 : Address: : 0x2000000

20:09:56 : Warning: The core is locked up

20:09:56 : Start operation achieved successfully

However, 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?

Posted on July 04, 2018 at 23:08

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.

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
Posted on July 05, 2018 at 05:00

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
Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..