cancel
Showing results for 
Search instead for 
Did you mean: 

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

RFlod.1
Associate II

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

1 ACCEPTED SOLUTION

Accepted Solutions
RFlod.1
Associate II

Solved. CubeMX did not initiate SDRAM_NBL1 and SDRAM_NBL0

View solution in original post

4 REPLIES 4
RFlod.1
Associate II

Solved. CubeMX did not initiate SDRAM_NBL1 and SDRAM_NBL0

Amel NASRI
ST Employee

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 Accept as Solution on the reply which solved your issue or answered your question.

Sara BEN HADJ YAHYA
ST Employee

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.

RFlod.1
Associate II

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 */
}