Skip to main content
RFlod.1
Associate
April 11, 2022
Solved

Reading 8 bit arrays from external SDRAM in STM32H7 gives corrupt data

  • April 11, 2022
  • 4 replies
  • 1818 views

We are using STM32H745I-DISCO which has a 16 MByte SDRAM. We can read and write 32 and 16 bit values but when we try to read 8 byte arrays we get corrupt data and do not understand how to fix it.

// -------------------------------- TEST CODE 
// t1 struct is placed in external memory (code works when put in RAM_D2 but no external ram
 
void SDRAM_Test8()
{
	int result = 1, i;
	uint32_t adressStart = 0;
 
	for(adressStart; adressStart < (8*1024*1024-(BUFFER_SIZE8*4)); adressStart += BUFFER_SIZE8)
	{
	
	/* Fill the buffer to write */
	Fill_Buffer8(t1.aTxBuffer8, BUFFER_SIZE8, 0x00);
 
 
 
	/* Fill the Read buffer */
	memset(t1.aRxBuffer8,0,BUFFER_SIZE8);
 
	for (i = 0; i < BUFFER_SIZE8; i++)
	{
		*(__IO uint8_t*) (SDRAM_BANK_ADDR + i + adressStart) = t1.aTxBuffer8[i];
	}
 
 
 
	for (i = 0; i < BUFFER_SIZE8; i++)
	{
		t1.aRxBuffer8[i] = *(__IO uint8_t*) (SDRAM_BANK_ADDR + i + adressStart);
	}
 
	for (i = 0; i < BUFFER_SIZE8; i++)
	{
		if (t1.aRxBuffer8[i] != t1.aTxBuffer8[i])
		{
		result = 0;
		break;
		}
	}
}
 
 
 
 
void MPU_Config(void)
{
 MPU_Region_InitTypeDef MPU_InitStruct;
 
 /* Disable the MPU */
 HAL_MPU_Disable();
 
 /* Configure the MPU as Strongly ordered for not defined regions */
 MPU_InitStruct.Enable = MPU_REGION_ENABLE;
 MPU_InitStruct.BaseAddress = 0x00;
 MPU_InitStruct.Size = MPU_REGION_SIZE_4GB;
 MPU_InitStruct.AccessPermission = MPU_REGION_NO_ACCESS;
 MPU_InitStruct.IsBufferable = MPU_ACCESS_NOT_BUFFERABLE;
 MPU_InitStruct.IsCacheable = MPU_ACCESS_NOT_CACHEABLE;
 MPU_InitStruct.IsShareable = MPU_ACCESS_SHAREABLE;
 MPU_InitStruct.Number = MPU_REGION_NUMBER0;
 MPU_InitStruct.TypeExtField = MPU_TEX_LEVEL0;
 MPU_InitStruct.SubRegionDisable = 0x87;
 MPU_InitStruct.DisableExec = MPU_INSTRUCTION_ACCESS_DISABLE;
 
 HAL_MPU_ConfigRegion(&MPU_InitStruct);
 
 /* Configure the MPU attributes as WT for SDRAM */
 MPU_InitStruct.Enable = MPU_REGION_ENABLE;
 MPU_InitStruct.BaseAddress = SDRAM_BANK_ADDR;
 MPU_InitStruct.Size = MPU_REGION_SIZE_16MB;
 MPU_InitStruct.AccessPermission = MPU_REGION_FULL_ACCESS;
 MPU_InitStruct.IsBufferable = MPU_ACCESS_NOT_BUFFERABLE;
 MPU_InitStruct.IsCacheable = MPU_ACCESS_NOT_CACHEABLE;
 MPU_InitStruct.IsShareable = MPU_ACCESS_NOT_SHAREABLE;
 MPU_InitStruct.Number = MPU_REGION_NUMBER1;
 MPU_InitStruct.TypeExtField = MPU_TEX_LEVEL0;
 MPU_InitStruct.SubRegionDisable = 0x00;
 MPU_InitStruct.DisableExec = MPU_INSTRUCTION_ACCESS_ENABLE;
 
 HAL_MPU_ConfigRegion(&MPU_InitStruct);
 
 /* Enable the MPU */
 HAL_MPU_Enable(MPU_PRIVILEGED_DEFAULT);
 
 /* Enable the CPU Cache */
 CPU_CACHE_Enable();
 
}
 
 
 
void SDRAM_Init()
{
	 /*##-1- Configure the SDRAM device #########################################*/
	 /* SDRAM device configuration */
	 hsdram.Instance = FMC_SDRAM_DEVICE;
 
	 /* Timing configuration */
	 SDRAM_Timing.LoadToActiveDelay = 2;
	 SDRAM_Timing.ExitSelfRefreshDelay = 7;
	 SDRAM_Timing.SelfRefreshTime = 4;
	 SDRAM_Timing.RowCycleDelay = 7;
	 SDRAM_Timing.WriteRecoveryTime = 2;
	 SDRAM_Timing.RPDelay = 2;
	 SDRAM_Timing.RCDDelay = 2;
 
	 hsdram.Init.SDBank = FMC_SDRAM_BANK2;
	 hsdram.Init.ColumnBitsNumber = FMC_SDRAM_COLUMN_BITS_NUM_8;
	 hsdram.Init.RowBitsNumber = FMC_SDRAM_ROW_BITS_NUM_12;
	 hsdram.Init.MemoryDataWidth = SDRAM_MEMORY_WIDTH;
	 hsdram.Init.InternalBankNumber = FMC_SDRAM_INTERN_BANKS_NUM_4;
	 hsdram.Init.CASLatency = FMC_SDRAM_CAS_LATENCY_3;
	 hsdram.Init.WriteProtection = FMC_SDRAM_WRITE_PROTECTION_DISABLE;
	 hsdram.Init.SDClockPeriod = SDCLOCK_PERIOD;
	 hsdram.Init.ReadBurst = FMC_SDRAM_RBURST_ENABLE;
	 hsdram.Init.ReadPipeDelay = FMC_SDRAM_RPIPE_DELAY_2;
 
	 /* Initialize the SDRAM controller */
	 if(HAL_SDRAM_Init(&hsdram, &SDRAM_Timing) != HAL_OK)
	 {
	 /* Initialization Error */
	 Error_Handler();
	 }
 
	 /* Program the SDRAM external device */
	 SDRAM_Initialization_Sequence(&hsdram, &command);
	 printf("Initiating SDRAM \r\n");
 
	 /*##-2- SDRAM memory read/write access #####################################*/
}
 
 
 
/**
 * @brief Perform the SDRAM exernal memory inialization sequence
 * @param hsdram: SDRAM handle
 * @param Command: Pointer to SDRAM command structure
 * @retval None
 */
static void SDRAM_Initialization_Sequence(SDRAM_HandleTypeDef *hsdram, FMC_SDRAM_CommandTypeDef *Command)
{
 __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_BANK2;;
 Command->AutoRefreshNumber = 1;
 Command->ModeRegisterDefinition = 0;
 
 /* Send the command */
 HAL_SDRAM_SendCommand(hsdram, 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_BANK2;
 Command->AutoRefreshNumber = 1;
 Command->ModeRegisterDefinition = 0;
 
 /* Send the command */
 HAL_SDRAM_SendCommand(hsdram, Command, SDRAM_TIMEOUT);
 
 /* Step 4 : Configure a Auto-Refresh command */
 Command->CommandMode = FMC_SDRAM_CMD_AUTOREFRESH_MODE;
 Command->CommandTarget = FMC_SDRAM_CMD_TARGET_BANK2;
 Command->AutoRefreshNumber = 8;
 Command->ModeRegisterDefinition = 0;
 
 /* Send the command */
 HAL_SDRAM_SendCommand(hsdram, 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_BANK2;
 Command->AutoRefreshNumber = 1;
 Command->ModeRegisterDefinition = tmpmrd;
 
 /* Send the command */
 HAL_SDRAM_SendCommand(hsdram, Command, SDRAM_TIMEOUT);
 
 /* Step 6: Set the refresh rate counter */
 /* Set the device refresh rate */
 HAL_SDRAM_ProgramRefreshRate(hsdram, REFRESH_COUNT);
 
}
 
 
 
 

This topic has been closed for replies.
Best answer by RFlod.1

Solved. CubeMX did not initiate SDRAM_NBL1 and SDRAM_NBL0

4 replies

RFlod.1
RFlod.1AuthorBest answer
Associate
April 12, 2022

Solved. CubeMX did not initiate SDRAM_NBL1 and SDRAM_NBL0

Amel NASRI
ST Technical Moderator
April 14, 2022

Thanks @Community member​ for sharing the solution you found.

@Sara BEN HADJ YAHYA​ can you please have a look & take required corrective action.

-Amel

To give better visibility on the answered topics, please click on "Best Answer" on the reply which solved your issue or answered your question.
Sara BEN HADJ YAHYA
ST Technical Moderator
April 15, 2022

Hello @Community member​ ,

Thanks for your feedback,

Could you please share your ioc file and specify where you added the fix so that we can reproduce and see if we can address a change?

Thanks,

Sara.

In order to give better visibility on the answered topics, please click on 'Best answer' on the reply which solved your issue or answered your question.
RFlod.1
RFlod.1Author
Associate
April 19, 2022

We hade initiation of PE0 and PE1 in the code below:

static void HAL_FMC_MspInit(void){
 /* USER CODE BEGIN FMC_MspInit 0 */
 
 /* USER CODE END FMC_MspInit 0 */
 GPIO_InitTypeDef GPIO_InitStruct ={0};
 if (FMC_Initialized) {
 return;
 }
 FMC_Initialized = 1;
 RCC_PeriphCLKInitTypeDef PeriphClkInitStruct = {0};
 
 /** Initializes the peripherals clock
 */
 PeriphClkInitStruct.PeriphClockSelection = RCC_PERIPHCLK_FMC;
 PeriphClkInitStruct.FmcClockSelection = RCC_FMCCLKSOURCE_D1HCLK;
 if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInitStruct) != HAL_OK)
 {
 Error_Handler();
 }
 
 /* Peripheral clock enable */
 __HAL_RCC_FMC_CLK_ENABLE();
 
 __HAL_RCC_GPIOD_CLK_ENABLE();
 __HAL_RCC_GPIOE_CLK_ENABLE();
 __HAL_RCC_GPIOG_CLK_ENABLE();
 __HAL_RCC_GPIOF_CLK_ENABLE();
 __HAL_RCC_GPIOH_CLK_ENABLE();
 
 /** FMC GPIO Configuration
 PG15 ------> FMC_SDNCAS
 PD0 ------> FMC_D2
 PD1 ------> FMC_D3
 PG8 ------> FMC_SDCLK
 PF2 ------> FMC_A2
 PF1 ------> FMC_A1
 PF0 ------> FMC_A0
 PG5 ------> FMC_BA1
 PF3 ------> FMC_A3
 PG4 ------> FMC_BA0
 PF5 ------> FMC_A5
 PF4 ------> FMC_A4
 PE10 ------> FMC_D7
 PH5 ------> FMC_SDNWE
 PF13 ------> FMC_A7
 PF14 ------> FMC_A8
 PE9 ------> FMC_D6
 PE11 ------> FMC_D8
 PD15 ------> FMC_D1
 PD14 ------> FMC_D0
 PF12 ------> FMC_A6
 PF15 ------> FMC_A9
 PE12 ------> FMC_D9
 PE15 ------> FMC_D12
 PF11 ------> FMC_SDNRAS
 PG0 ------> FMC_A10
 PE8 ------> FMC_D5
 PE13 ------> FMC_D10
 PH6 ------> FMC_SDNE1
 PD10 ------> FMC_D15
 PD9 ------> FMC_D14
 PG1 ------> FMC_A11
 PE7 ------> FMC_D4
 PE14 ------> FMC_D11
 PH7 ------> FMC_SDCKE1
 PD8 ------> FMC_D13
 */
 GPIO_InitStruct.Pin = GPIO_PIN_15|GPIO_PIN_8|GPIO_PIN_5|GPIO_PIN_4
 |GPIO_PIN_0|GPIO_PIN_1;
 GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
 GPIO_InitStruct.Pull = GPIO_NOPULL;
 GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
 GPIO_InitStruct.Alternate = GPIO_AF12_FMC;
 HAL_GPIO_Init(GPIOG, &GPIO_InitStruct);
 
 GPIO_InitStruct.Pin = GPIO_PIN_0|GPIO_PIN_1|GPIO_PIN_15|GPIO_PIN_14
 |GPIO_PIN_10|GPIO_PIN_9|GPIO_PIN_8;
 GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
 GPIO_InitStruct.Pull = GPIO_NOPULL;
 GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
 GPIO_InitStruct.Alternate = GPIO_AF12_FMC;
 HAL_GPIO_Init(GPIOD, &GPIO_InitStruct);
 
 GPIO_InitStruct.Pin = GPIO_PIN_2|GPIO_PIN_1|GPIO_PIN_0|GPIO_PIN_3
 |GPIO_PIN_5|GPIO_PIN_4|GPIO_PIN_13|GPIO_PIN_14
 |GPIO_PIN_12|GPIO_PIN_15|GPIO_PIN_11;
 GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
 GPIO_InitStruct.Pull = GPIO_NOPULL;
 GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
 GPIO_InitStruct.Alternate = GPIO_AF12_FMC;
 HAL_GPIO_Init(GPIOF, &GPIO_InitStruct);
 
 GPIO_InitStruct.Pin = GPIO_PIN_0| GPIO_PIN_1|GPIO_PIN_10|GPIO_PIN_9|GPIO_PIN_11|GPIO_PIN_12
 |GPIO_PIN_15|GPIO_PIN_8|GPIO_PIN_13|GPIO_PIN_7
 |GPIO_PIN_14;
 GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
 GPIO_InitStruct.Pull = GPIO_NOPULL;
 GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
 GPIO_InitStruct.Alternate = GPIO_AF12_FMC;
 HAL_GPIO_Init(GPIOE, &GPIO_InitStruct);
 
 GPIO_InitStruct.Pin = GPIO_PIN_5|GPIO_PIN_6|GPIO_PIN_7;
 GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
 GPIO_InitStruct.Pull = GPIO_NOPULL;
 GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
 GPIO_InitStruct.Alternate = GPIO_AF12_FMC;
 HAL_GPIO_Init(GPIOH, &GPIO_InitStruct);
 
 /* USER CODE BEGIN FMC_MspInit 1 */
 
 /* USER CODE END FMC_MspInit 1 */
}