cancel
Showing results for 
Search instead for 
Did you mean: 

Duplicate write to external SDRAM

chwalng
Associate

Hello,

I am using STM32F469 with an external SDRAM (Alliance AS4C16M16MSA-6BIN) through FMC bus. Both STM32F469 and AS4C16M16MSA-6BIN run at 1.8V. The FMC bus is configured with 13 address pins and 16 data pins as follows:

 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_3;
 
 hsdram1.Init.WriteProtection = FMC_SDRAM_WRITE_PROTECTION_DISABLE;
 
 hsdram1.Init.SDClockPeriod = FMC_SDRAM_CLOCK_PERIOD_2;
 
 hsdram1.Init.ReadBurst = FMC_SDRAM_RBURST_DISABLE;
 
 hsdram1.Init.ReadPipeDelay = FMC_SDRAM_RPIPE_DELAY_1;
 
 
 
 /* Timing configuration for 75 MHz of SDRAM clock frequency () */
 
 
 
 SdramTiming.LoadToActiveDelay = 2;
 
 SdramTiming.ExitSelfRefreshDelay = 7;
 
 SdramTiming.SelfRefreshTime = 4;
 
 SdramTiming.RowCycleDelay = 7;
 
 SdramTiming.WriteRecoveryTime = 2;
 
 SdramTiming.RPDelay = 2;
 
 SdramTiming.RCDDelay = 2;

And SDRAM is configured as:

 __IO uint32_t tmpmrd = 0;
 
 
 
 /* Step 1: 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;
 
 
 
 /* Send the command */
 
 HAL_SDRAM_SendCommand(&hsdram1, &Command, SDRAM_TIMEOUT);
 
 
 
 /* Step 2: Insert 100 us minimum delay */
 
 /* Inserted delay is equal to 1 ms due to systick time base unit (ms) */
 
 HAL_Delay(1);
 
 
 
 /* Step 3: 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;
 
 
 
 /* Send the command */
 
 HAL_SDRAM_SendCommand(&hsdram1, &Command, SDRAM_TIMEOUT);
 
 
 
 /* Step 4: Configure an Auto Refresh command */
 
 Command.CommandMode      = FMC_SDRAM_CMD_AUTOREFRESH_MODE;
 
 Command.CommandTarget     = FMC_SDRAM_CMD_TARGET_BANK1;
 
 Command.AutoRefreshNumber   = 4;
 
 Command.ModeRegisterDefinition = 0;
 
 
 
 /* Send the command */
 
 HAL_SDRAM_SendCommand(&hsdram1, &Command, SDRAM_TIMEOUT);
 
 
 
 /* Step 5: Program the external memory mode register */
 
 tmpmrd = (uint32_t)SDRAM_MODEREG_BURST_LENGTH_1     |\
 
           SDRAM_MODEREG_BURST_TYPE_SEQUENTIAL  |\
 
           SDRAM_MODEREG_CAS_LATENCY_3      |\
 
           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;
 
 
 
 /* Send the command */
 
 HAL_SDRAM_SendCommand(&hsdram1, &Command, SDRAM_TIMEOUT);
 
 
 
 /* Step 6: Set the refresh rate counter */
 
 /* Set the device refresh rate */
 
 HAL_SDRAM_ProgramRefreshRate(&hsdram1, RefreshCount);

I am running a address bus test on the SDRAM.

datum *
 
BSP_SDRAM_MemTestAddressBus(volatile datum * baseAddress, uint32_t nBytes)
 
{
 
	uint32_t addressMask = (nBytes/sizeof(datum) - 1);
 
	uint32_t offset;
 
	uint32_t testoffset;
 
 
	datum pattern 		= (datum) 0xAAAAAAA;
 
	datum antipattern 	= (datum) 0x55555555;
 
 
 
	/*
 
	 * Write the default pattern at each of power-of-two offsets
 
	 * */
 
	for (offset = 1; (offset & addressMask) != 0; offset ++)
 
	{
		 *(__IO uint32_t*) (SDRAM_DEVICE_ADDR + 4*offset) = pattern;
	}
 
 
 
	/*
 
	 * Write the default pattern at each of power-of-two offsets
 
	 * */
 
	for (offset = 1; (offset & addressMask) != 0; offset <<= 1)
 
	{
		baseAddress[offset] = pattern;
	}
 
 
 
	/*
 
	 * Check for address bits stuck high.
 
	 * */
 
	testoffset = 2;
 
	baseAddress[testoffset] = antipattern;
 
 
 
	for (offset = 1; (offset & addressMask) != 0; offset <<= 1)
 
	{
		if (baseAddress[offset] != pattern)
 
		{
			return ((datum *) &baseAddress[offset]);
		}
	}
 
	baseAddress[testoffset] = pattern;
 
	/*
 
	 * Check for address bits stuck low or shorted.
 
	 * */
 
	for (testoffset = 1; (testoffset & addressMask) !=0; testoffset <<=1)
 
	{
		baseAddress[testoffset] = antipattern;
 
			if (baseAddress[0] != pattern)
 
			{
				return ((datum *) &baseAddress[testoffset]);
			}
 
 
 
		for (offset = 1; (offset & addressMask) != 0; offset <<=1)
 
		{
			if ((baseAddress[offset] != pattern) && (offset != testoffset))
			{
				return ((datum *) &baseAddress[testoffset]);
			}
		}
 
		baseAddress[testoffset] = pattern;
	}
 
	return (NULL);
 
 
 
}/* memTestAddressBus() */

The problem is, when one address is accessed, it always duplicates the operation to another address location. The memory reading is as follows:

0693W000007DWq3QAG.jpg 

I simply wrote 0xAAAAAAA to the location 0xC00000004 and the data in 0xC0000000C updated at the same time.

Any suggestion on this issue? Thanks in advance.

1 ACCEPTED SOLUTION

Accepted Solutions
Hugues DE CARVALHO
Associate III

FYI, here was the solution to this issue:

"We ended up by replacing a new SDRAM and resolved the problem, it seems highly likely the fault was caused by a bad soldering on the BGA SDRAM."

Hugues

View solution in original post

2 REPLIES 2

Sounds like short or bad solder joint on A1 (either memory or STM32), or A1 not configured correctly in GPIO.

Check former by measuring, latter by reading out and checking the respective GPIO registers.

JW

Hugues DE CARVALHO
Associate III

FYI, here was the solution to this issue:

"We ended up by replacing a new SDRAM and resolved the problem, it seems highly likely the fault was caused by a bad soldering on the BGA SDRAM."

Hugues