2022-04-11 09:12 AM
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);
}
Solved! Go to Solution.
2022-04-12 05:50 AM
Solved. CubeMX did not initiate SDRAM_NBL1 and SDRAM_NBL0
2022-04-12 05:50 AM
Solved. CubeMX did not initiate SDRAM_NBL1 and SDRAM_NBL0
2022-04-14 07:27 AM
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.
2022-04-15 01:00 AM
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.
2022-04-19 12:09 AM
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 */
}