Author Topic: STM32H7 SDRAM  (Read 5909 times)

0 Members and 1 Guest are viewing this topic.

Offline MitaliusTopic starter

  • Contributor
  • Posts: 12
  • Country: ru
STM32H7 SDRAM
« on: January 09, 2019, 09:04:15 am »
I use custom SDRAM on my board (AS4C8M32SA-6BIN : https://www.alliancememory.com/wp-content/uploads/pdf/dram/Alliance%20Memory_256M%20SDRAM_AS4C8M32SA-6_7BIN(BCN)%20A%20die_rev%201.0%20November%202016.pdf)

But I get HardFault when I try to write to the address 0xD0000000

I don't understand what did wrong



Here's my code I removed all the unnecessary for clarity
I get an error when I put WriteRecoveryTime equal to 2, so I set it to 4. I don't know why this happens
Code: [Select]
// AS4C8M32SA-6BIN
#define SDRAM_MODEREG_BURST_LENGTH_1             ((uint16_t)0x0000)
#define SDRAM_MODEREG_BURST_LENGTH_2             ((uint16_t)0x0001)
#define SDRAM_MODEREG_BURST_LENGTH_4             ((uint16_t)0x0002)
#define SDRAM_MODEREG_BURST_LENGTH_8             ((uint16_t)0x0003)
#define SDRAM_MODEREG_BURST_TYPE_SEQUENTIAL      ((uint16_t)0x0000)
#define SDRAM_MODEREG_BURST_TYPE_INTERLEAVED     ((uint16_t)0x0008)
#define SDRAM_MODEREG_CAS_LATENCY_2              ((uint16_t)0x0020)
#define SDRAM_MODEREG_CAS_LATENCY_3              ((uint16_t)0x0030)
#define SDRAM_MODEREG_OPERATING_MODE_STANDARD    ((uint16_t)0x0000)
#define SDRAM_MODEREG_WRITEBURST_MODE_PROGRAMMED ((uint16_t)0x0000)
#define SDRAM_MODEREG_WRITEBURST_MODE_SINGLE     ((uint16_t)0x0200)

#define SDRAM_REFRESH_COUNT                    ((uint32_t)4096)


void SdramInitSequence() {
FMC_SDRAM_CommandTypeDef command;

command.CommandMode            = FMC_SDRAM_CMD_CLK_ENABLE;
command.CommandTarget          = FMC_SDRAM_CMD_TARGET_BANK1;
command.AutoRefreshNumber      = 1;
command.ModeRegisterDefinition = 0;
HAL_SDRAM_SendCommand(&hsdram1, &command, 0xFFFF);

HAL_Delay(1);

command.CommandMode            = FMC_SDRAM_CMD_PALL;
command.CommandTarget          = FMC_SDRAM_CMD_TARGET_BANK1;
command.AutoRefreshNumber      = 1;
command.ModeRegisterDefinition = 0;
HAL_SDRAM_SendCommand(&hsdram1, &command, 0xFFFF);

command.CommandMode            = FMC_SDRAM_CMD_AUTOREFRESH_MODE;
command.CommandTarget          = FMC_SDRAM_CMD_TARGET_BANK1;
command.AutoRefreshNumber      = 8;
command.ModeRegisterDefinition = 0;
HAL_SDRAM_SendCommand(&hsdram1, &command, 0xFFFF);

command.CommandMode            = FMC_SDRAM_CMD_LOAD_MODE;
command.CommandTarget          = FMC_SDRAM_CMD_TARGET_BANK1;
command.AutoRefreshNumber      = 1;
command.ModeRegisterDefinition = 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;
HAL_SDRAM_SendCommand(&hsdram1, &command, 0xFFFF);

HAL_SDRAM_ProgramRefreshRate(&hsdram1, SDRAM_REFRESH_COUNT);
}



int main(void) {
MPU_Config();
SCB_EnableICache();
SCB_EnableDCache();
 
HAL_Init();
SystemClock_Config();
MX_GPIO_Init();
MX_FMC_Init();
 
 
SdramInitSequence();
 
 
// HardFault
*(__IO uint32_t*)(0xD0000000) = 0xAFAFAFAF;
 
while(1);
}





/* FMC initialization function */
static void MX_FMC_Init(void) {
  FMC_SDRAM_TimingTypeDef SdramTiming;

  /* Perform the SDRAM1 memory initialization sequence */
  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_12;
  hsdram1.Init.MemoryDataWidth = FMC_SDRAM_MEM_BUS_WIDTH_32;
  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_ENABLE;
  hsdram1.Init.ReadPipeDelay = FMC_SDRAM_RPIPE_DELAY_0;

  // 166MHz: 1 clk = 6ns
  /* SdramTiming */
  SdramTiming.LoadToActiveDelay = 2; // tMRD
  SdramTiming.ExitSelfRefreshDelay = 10; // tXSR
  SdramTiming.SelfRefreshTime = 6; // tRAS
  SdramTiming.RowCycleDelay = 10; // tRC
  SdramTiming.WriteRecoveryTime = 4; // tWR (????)
  SdramTiming.RPDelay = 3; // tRP
  SdramTiming.RCDDelay = 3; // tRCD

  if(HAL_SDRAM_Init(&hsdram1, &SdramTiming) != HAL_OK){
    _Error_Handler(__FILE__, __LINE__);
  }
}





void MPU_Config(void) {
  MPU_Region_InitTypeDef MPU_InitStruct;

  /* Disables the MPU */
  HAL_MPU_Disable();

  /* Initializes and configures the Region and the memory to be protected */
  MPU_InitStruct.Enable = MPU_REGION_ENABLE;
  MPU_InitStruct.Number = MPU_REGION_NUMBER0;
  MPU_InitStruct.BaseAddress = 0xD0000000;
  MPU_InitStruct.Size = MPU_REGION_SIZE_32MB;
  MPU_InitStruct.SubRegionDisable = 0x0;
  MPU_InitStruct.TypeExtField = MPU_TEX_LEVEL0;
  MPU_InitStruct.AccessPermission = MPU_REGION_FULL_ACCESS;
  MPU_InitStruct.DisableExec = MPU_INSTRUCTION_ACCESS_ENABLE;
  MPU_InitStruct.IsShareable = MPU_ACCESS_NOT_SHAREABLE;
  MPU_InitStruct.IsCacheable = MPU_ACCESS_CACHEABLE;
  MPU_InitStruct.IsBufferable = MPU_ACCESS_NOT_BUFFERABLE;

  HAL_MPU_ConfigRegion(&MPU_InitStruct);

  /* Enables the MPU */
  HAL_MPU_Enable(MPU_PRIVILEGED_DEFAULT);
}

 

Offline lucazader

  • Regular Contributor
  • *
  • Posts: 221
  • Country: au
Re: STM32H7 SDRAM
« Reply #1 on: January 09, 2019, 09:52:05 am »
I am using a similar ram chip (AS4C4M16SA-6BIN ) with an STM32F7.

Below is the MX_FMC_Init function that is working for me.
Code: [Select]
void MX_FMC_Init(void)
{
    FMC_SDRAM_TimingTypeDef SdramTiming;

    /** Perform the SDRAM1 memory initialization sequence
     */
    hsdram1.Instance = FMC_SDRAM_DEVICE;
    /* hsdram1.Init */
    hsdram1.Init.SDBank = FMC_SDRAM_BANK1;
    hsdram1.Init.ColumnBitsNumber = FMC_SDRAM_COLUMN_BITS_NUM_8;
    hsdram1.Init.RowBitsNumber = FMC_SDRAM_ROW_BITS_NUM_12;
    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_2;
    hsdram1.Init.WriteProtection = FMC_SDRAM_WRITE_PROTECTION_DISABLE;
    hsdram1.Init.SDClockPeriod = FMC_SDRAM_CLOCK_PERIOD_3;
    hsdram1.Init.ReadBurst = FMC_SDRAM_RBURST_ENABLE;
    hsdram1.Init.ReadPipeDelay = FMC_SDRAM_RPIPE_DELAY_0;
    /* SdramTiming */
    SdramTiming.LoadToActiveDelay = 2;
    SdramTiming.ExitSelfRefreshDelay = 6;
    SdramTiming.SelfRefreshTime = 4;
    SdramTiming.RowCycleDelay = 6;
    SdramTiming.WriteRecoveryTime = 2;
    SdramTiming.RPDelay = 2;
    SdramTiming.RCDDelay = 2;

    if (HAL_SDRAM_Init(&hsdram1, &SdramTiming) != HAL_OK)
    {
        _Error_Handler(__FILE__, __LINE__);
    }
}

Hope this helps you..?
 
The following users thanked this post: Mitalius

Offline MitaliusTopic starter

  • Contributor
  • Posts: 12
  • Country: ru
Re: STM32H7 SDRAM
« Reply #2 on: January 29, 2019, 01:22:42 pm »
Sorry, I was working on another project and could not answer.

Unfortunately, I still get HardFault
Could you show your SdramInitSequence?






 

Offline lucazader

  • Regular Contributor
  • *
  • Posts: 221
  • Country: au
Re: STM32H7 SDRAM
« Reply #3 on: January 29, 2019, 06:09:59 pm »
Hope this helps.
Code: [Select]
#define SDRAM_TIMEOUT ((uint32_t)0xFFFF)

#define REFRESH_COUNT ((uint32_t)0x0569)
void SDRAM_Initialization_sequence(void)
{
    __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 5: Program the external memory mode register */
    tmpmrd = (uint32_t)SDRAM_MODEREG_BURST_LENGTH_1 | SDRAM_MODEREG_BURST_TYPE_SEQUENTIAL
        | SDRAM_MODEREG_CAS_LATENCY_2 | 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 4: Configure the 1st 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(&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 4: Configure the 2nd 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(&hsdram1, &Command, SDRAM_TIMEOUT);

    /* Step 6: Set the refresh rate counter */
    /* Set the device refresh rate */
    HAL_SDRAM_ProgramRefreshRate(&hsdram1, REFRESH_COUNT);
}
 
The following users thanked this post: Mitalius

Offline MitaliusTopic starter

  • Contributor
  • Posts: 12
  • Country: ru
Re: STM32H7 SDRAM
« Reply #4 on: February 06, 2019, 02:41:37 pm »
I did it, thanks
 

Offline Yansi

  • Super Contributor
  • ***
  • Posts: 3893
  • Country: 00
  • STM32, STM8, AVR, 8051
Re: STM32H7 SDRAM
« Reply #5 on: February 07, 2019, 05:51:29 am »
So did this help? What or where was the mistake?
 

Offline igame2000

  • Newbie
  • Posts: 1
  • Country: sg
Re: STM32H7 SDRAM
« Reply #6 on: November 26, 2021, 05:47:07 am »
Confirmed. This trick really works for me.
« Last Edit: November 26, 2021, 07:44:18 am by igame2000 »
 


Share me

Digg  Facebook  SlashDot  Delicious  Technorati  Twitter  Google  Yahoo
Smf