2015-09-30 04:50 AM
Hi I am trying to read and write data to the SDRAM. I have used the HAL drivers available on the STM website (
STM32Cube_FW_F7_V1.0.0\Projects\STM32756G_EVAL\Examples\FMC\FMC_SDRAM
). I can successufully write the data but I am not able to read the data if I try reading it later. These are the functions I use for writing and reading the data:void write_Landmark()
{uint32_t address = uwIndex_lm; SDRAM_Write32(LANDMARK_START_ADR+address,lm_head->landmark_index);
printf(''%i \t'',SDRAM_Read32(LANDMARK_START_ADR+address+0)); // I get the data I write here fine
address = address +4;
SDRAM_WriteFloat(LANDMARK_START_ADR+address,lm_head->pos_x);
address = address +4;
SDRAM_WriteFloat(LANDMARK_START_ADR+address,lm_head->pos_y);
address = address +4;
SDRAM_WriteFloat(LANDMARK_START_ADR+address,lm_head->pos_theta);
address = address +4;
SDRAM_Write32(LANDMARK_START_ADR+address,lm_head->jump_point);
address = address +4; SDRAM_Write32(LANDMARK_START_ADR+address,lm_head->landmark_detected);
address = address +4; SDRAM_Write32(LANDMARK_START_ADR+address,lm_head->landmark_corrected);
address = address +4;
SDRAM_WriteFloat(LANDMARK_START_ADR+address,lm_head->hall_angle);
address = address +4;
SDRAM_WriteFloat(LANDMARK_START_ADR+address,lm_head->hall_distance);
address = address +4;
SDRAM_Write32(LANDMARK_START_ADR+address,lm_head->on_curve);
address = address +4;
uwIndex_lm = address;
}
void read_Landmark()
{ for(int i = 0 ; i < uwIndex_lm; i=i+40) { printf(''%i \t'',SDRAM_Read32(LANDMARK_START_ADR+i+0)); // I reprint the data and I get '65535' as output which is the default value, not what I wrote printf(''%f \t'',SDRAM_ReadFloat(LANDMARK_START_ADR+i+4)); printf(''%f \t'',SDRAM_ReadFloat(LANDMARK_START_ADR+i+8)); printf(''%f \t'',SDRAM_ReadFloat(LANDMARK_START_ADR+i+12)); printf(''%i \t'',SDRAM_Read32(LANDMARK_START_ADR+i+16)); printf(''%i \t'',SDRAM_Read32(LANDMARK_START_ADR+i+20)); printf(''%i \t'',SDRAM_Read32(LANDMARK_START_ADR+i+24)); printf(''%f \t'',SDRAM_ReadFloat(LANDMARK_START_ADR+i+28)); printf(''%f \t'',SDRAM_ReadFloat(LANDMARK_START_ADR+i+32)); printf(''%i \t'',SDRAM_Read32(LANDMARK_START_ADR+i+36)); printf(''\n\r''); } } I usd the exact code in the library for configurationn of SDRAM. Just for some more clarity: #define SDRAM_Write32(address, value) (*(__IO uint32_t *) (SDRAM_START_ADR + (address)) = (value)) #define SDRAM_START_ADR ((uint32_t)0xC0000000) #define LANDMARK_START_ADR ((uint32_t)0x0800) I would be very grateful for any help.Thank you!2015-09-30 10:19 AM
And you're using an EVAL, DISCO, or custom board?
You should probably use your debugger to probe the controller settings, and then double check the pins, controller, and settings sent to the SDRAM. Does the read back work if done immediately? Can you see it in the debugger via a memory window?2015-09-30 11:52 AM
>
I can successufully write the data but I am not able to read the data if I try reading it later.Try it with writing and retrieving a legible string rather than numbers. Incorrect SDRAM refresh setting? If so, you should see gradually degradation of the readout from ''almost good'' through ''barely readable'' to ''garbage'' when inserting delay between
a few ms to a few s. Otherwise, you might be fooled by the data cache, and the SDRAM is not working at all. JW2015-10-01 03:28 AM
2015-10-01 03:55 AM
Hi Jan,
You might be right, I will check this out. I don't think the refresh settings are wrong, but here's the code I used for refresh settings:static void SDRAM_Config(void)
{ /*##-1- Configure the SDRAM device #########################################*/ /* SDRAM device configuration */ hsdram.Instance = FMC_SDRAM_DEVICE; 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_BANK1; hsdram.Init.ColumnBitsNumber = FMC_SDRAM_COLUMN_BITS_NUM_9; 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_0; /* Initialize the SDRAM controller */ if(HAL_SDRAM_Init(&hsdram, &SDRAM_Timing) != HAL_OK) { printf(''SDRAM Init error \r\n''); /* Initialization Error */ LED1_ON(); } /* Program the SDRAM external device */ BSP_SDRAM_Initialization_Sequence(&hsdram, &command); }2015-10-01 04:10 AM
The second example you gave says:
> #elif defined(SDRAM_USE_STM32F7_DISCOVERY)
i.e. it's for the DISCOVERY board.
So, if you say you have the EVAL board, it may not apply to that one - compare the scematics in the respective UMs for those two boards.
JW
2015-10-01 06:44 AM
Hey Jan,
Yea true so I checked and probably SDRAM isn't working at all. I confirmed the the pin configurations using the CubeMX program for my board. There were some configuration changes in the code generated from CubeMX.static void SDRAM_Config(void)
{ /*##-1- Configure the SDRAM device #########################################*/ /* SDRAM device configuration */ hsdram.Instance = FMC_SDRAM_DEVICE; SDRAM_Timing.LoadToActiveDelay = 16; SDRAM_Timing.ExitSelfRefreshDelay = 16; SDRAM_Timing.SelfRefreshTime = 16; SDRAM_Timing.RowCycleDelay = 16; SDRAM_Timing.WriteRecoveryTime = 16; SDRAM_Timing.RPDelay = 16; SDRAM_Timing.RCDDelay = 16; hsdram.Init.SDBank = FMC_SDRAM_BANK2; hsdram.Init.ColumnBitsNumber = FMC_SDRAM_COLUMN_BITS_NUM_8; hsdram.Init.RowBitsNumber = FMC_SDRAM_ROW_BITS_NUM_11; hsdram.Init.MemoryDataWidth = FMC_SDRAM_MEM_BUS_WIDTH_16; hsdram.Init.InternalBankNumber = FMC_SDRAM_INTERN_BANKS_NUM_4; hsdram.Init.CASLatency = FMC_SDRAM_CAS_LATENCY_1; hsdram.Init.WriteProtection = FMC_SDRAM_WRITE_PROTECTION_DISABLE; hsdram.Init.SDClockPeriod = FMC_SDRAM_CLOCK_DISABLE; hsdram.Init.ReadBurst = FMC_SDRAM_RBURST_ENABLE ; hsdram.Init.ReadPipeDelay = FMC_SDRAM_RPIPE_DELAY_0; /* Initialize the SDRAM controller */ if(HAL_SDRAM_Init(&hsdram, &SDRAM_Timing) != HAL_OK) { printf(''SDRAM Init error \r\n''); /* Initialization Error */ LED1_ON(); } /* Program the SDRAM external device */ //BSP_SDRAM_Initialization_Sequence(&hsdram, &command);
} static void BSP_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_BANK1; Command->AutoRefreshNumber = 1; Command->ModeRegisterDefinition = 0; /* Send the command */ HAL_SDRAM_SendCommand(hsdram, Command, 0x1000); /* 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(hsdram, Command, 0x1000); /* Step 4 : 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; /* Send the command */ HAL_SDRAM_SendCommand(hsdram, Command, 0x1000); /* 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(hsdram, Command, 0x1000); /* Step 6: Set the refresh rate counter */ /* (15.62 us x Freq) - 20 */ /* Set the device refresh counter */ hsdram->Instance->SDRTR |= ((uint32_t)((1292)<< 1)); } So, when I used the new generated code I just get a hard fault and the application crashes after encountering the read command. If you know, could you pleaes explain to me when shoud one use 'BSP_SDRAM_Initialization_Sequence(&hsdram, &command)
' function?