cancel
Showing results for 
Search instead for 
Did you mean: 

Sector erase OSPI on STM32L4P5G Discovery Board timeout

JSchu.5
Associate II

Hi everybody,

I'm trying to delete a single sector of my STM32L4P5G Discovery Board MX25UM51245G OctoSPI Flash memory but I always end up in a timeout. Reading memory by function BSP_OSPI_NOR_Read() is working as expected. I'm using the bord support code of the STM32L45R Evaluation Board. The timeout occurs within OSPI_NOR_WriteEnable() function call caused by the command HAL_OSPI_Receive(). My board is running at 120MHz. I will add the files as attachment and post the relevant functions here. Be aware I adapted the OSPI_NOR_MspInit() to match the other hardware. I used the app note AN5050 to bring the flash to memory mapped mode what is working as expected. But for flash manipulation I require the indirect mode. Does anyone have an idea why I end up in a timeout?

uint8_t BSP_OSPI_NOR_Erase_Sector(uint32_t Sector)
{
  OSPI_RegularCmdTypeDef sCommand;
 
  if (Sector >= (uint32_t)(MX25LM51245G_FLASH_SIZE/MX25LM51245G_SECTOR_SIZE))
  {
    return OSPI_NOR_ERROR;
  }
 
  /* Initialize the erase command */
  sCommand.OperationType         = HAL_OSPI_OPTYPE_COMMON_CFG;
  sCommand.FlashId               = HAL_OSPI_FLASH_ID_1;
  sCommand.Instruction           = OCTAL_SECTOR_ERASE_CMD;
  sCommand.InstructionMode       = HAL_OSPI_INSTRUCTION_8_LINES;
  sCommand.InstructionSize       = HAL_OSPI_INSTRUCTION_16_BITS;
  sCommand.Address               = (Sector * MX25LM51245G_SECTOR_SIZE);
  sCommand.AddressMode           = HAL_OSPI_ADDRESS_8_LINES;
  sCommand.AddressSize           = HAL_OSPI_ADDRESS_32_BITS;
  sCommand.AlternateBytesMode    = HAL_OSPI_ALTERNATE_BYTES_NONE;
  sCommand.DataMode              = HAL_OSPI_DATA_NONE;
  sCommand.DummyCycles           = 0;
  sCommand.DQSMode               = HAL_OSPI_DQS_DISABLE;
  sCommand.SIOOMode              = HAL_OSPI_SIOO_INST_EVERY_CMD;
 
#if defined BSP_OSPI_NOR_DDR_MODE_DEACTIVATED
  sCommand.InstructionDtrMode    = HAL_OSPI_INSTRUCTION_DTR_DISABLE;
  sCommand.AddressDtrMode        = HAL_OSPI_ADDRESS_DTR_DISABLE;
#else
  sCommand.InstructionDtrMode    = HAL_OSPI_INSTRUCTION_DTR_ENABLE;
  sCommand.AddressDtrMode        = HAL_OSPI_ADDRESS_DTR_ENABLE;
#endif
 
  /* Enable write operations */
  if (OSPI_NOR_WriteEnable(&OSPINORHandle) != OSPI_NOR_OK)
  {
    return OSPI_NOR_ERROR;
  }
 
  /* Send the command */
  if (HAL_OSPI_Command(&OSPINORHandle, &sCommand, HAL_OSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
  {
    return OSPI_NOR_ERROR;
  }
 
  return OSPI_NOR_OK;
}

And the write enable function

static uint8_t OSPI_NOR_WriteEnable(OSPI_HandleTypeDef *hospi)
{
  OSPI_RegularCmdTypeDef  sCommand;
  OSPI_AutoPollingTypeDef sConfig;
  uint8_t reg[2];
 
  /* Enable write operations */
  sCommand.OperationType         = HAL_OSPI_OPTYPE_COMMON_CFG;
  sCommand.FlashId               = HAL_OSPI_FLASH_ID_1;
  sCommand.Instruction           = OCTAL_WRITE_ENABLE_CMD;
  sCommand.InstructionMode       = HAL_OSPI_INSTRUCTION_8_LINES;
  sCommand.InstructionSize       = HAL_OSPI_INSTRUCTION_16_BITS;
  sCommand.AddressMode           = HAL_OSPI_ADDRESS_NONE;
  sCommand.AlternateBytesMode    = HAL_OSPI_ALTERNATE_BYTES_NONE;
  sCommand.DataMode              = HAL_OSPI_DATA_NONE;
  sCommand.DummyCycles           = 0;
  sCommand.DQSMode               = HAL_OSPI_DQS_DISABLE;
  sCommand.SIOOMode              = HAL_OSPI_SIOO_INST_EVERY_CMD;
 
#if defined BSP_OSPI_NOR_DDR_MODE_DEACTIVATED
  sCommand.InstructionDtrMode    = HAL_OSPI_INSTRUCTION_DTR_DISABLE;
#else
  sCommand.InstructionDtrMode    = HAL_OSPI_INSTRUCTION_DTR_ENABLE;
#endif
 
  if (HAL_OSPI_Command(&OSPINORHandle, &sCommand, HAL_OSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
  {
    return OSPI_NOR_ERROR;
  }
 
  /* Configure automatic polling mode to wait for write enabling */
  sConfig.Match           = MX25LM51245G_SR_WEL;
  sConfig.Mask            = MX25LM51245G_SR_WEL;
  sConfig.MatchMode       = HAL_OSPI_MATCH_MODE_AND;
  sConfig.Interval        = 0x10;
  sConfig.AutomaticStop   = HAL_OSPI_AUTOMATIC_STOP_ENABLE;
 
  sCommand.Instruction    = OCTAL_READ_STATUS_REG_CMD;
  sCommand.Address        = 0x0;
  sCommand.AddressMode    = HAL_OSPI_ADDRESS_8_LINES;
  sCommand.AddressSize    = HAL_OSPI_ADDRESS_32_BITS;
  sCommand.DataMode       = HAL_OSPI_DATA_8_LINES;
  sCommand.NbData         = 2;
 
#if defined BSP_OSPI_NOR_DDR_MODE_DEACTIVATED
  sCommand.AddressDtrMode = HAL_OSPI_ADDRESS_DTR_DISABLE;
  sCommand.DataDtrMode    = HAL_OSPI_DATA_DTR_DISABLE;
  sCommand.DQSMode        = HAL_OSPI_DQS_DISABLE;
  sCommand.DummyCycles    = DUMMY_CYCLES_READ_OCTAL;
#else
  sCommand.AddressDtrMode = HAL_OSPI_ADDRESS_DTR_ENABLE;
  sCommand.DataDtrMode    = HAL_OSPI_DATA_DTR_ENABLE;
  sCommand.DQSMode        = HAL_OSPI_DQS_ENABLE;
  sCommand.DummyCycles    = 4;
#endif
  DEBUG_FPRINT_LINE(LOG_LEVEL_DEBUG, "Poll");
  do
  {
    HAL_Delay(1); /* sConfig.Interval(0x10) / Clock(55 MHz) = 0.29 ms */
 
    if (HAL_OSPI_Command(&OSPINORHandle, &sCommand, HAL_OSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
    {
        DEBUG_FPRINT_LINE(LOG_LEVEL_DEBUG, "HAL_OSPI_Command error");
      return OSPI_NOR_ERROR;
    }
 
    if (HAL_OSPI_Receive(&OSPINORHandle, reg, HAL_OSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
    {
        DEBUG_FPRINT_LINE(LOG_LEVEL_DEBUG, "HAL_OSPI_Receive Timeout");
      return OSPI_NOR_ERROR;
    }
  }while((reg[0] & sConfig.Mask ) != sConfig.Match);
 
  return OSPI_NOR_OK;
}

1 ACCEPTED SOLUTION

Accepted Solutions
JSchu.5
Associate II

Thank you for your response. The example code for this discovery board is working as expected. I did not know this project is existing. Thanks for the hint.

View solution in original post

4 REPLIES 4

You need to wait for the erase to complete, probably less so for the WriteEnable

I would clear the sCommand structure, and probably the flag status register.

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
JSchu.5
Associate II

Thank you for your reponse. I know that I have to wait for the earase to terminate but I do not run into the wait instruction because of the previous timeout. What do you mean by clear the sCommand structure? Reset to 0? Where?

OSPI_RegularCmdTypeDef sCommand = {0};

Uninitialized fields will otherwise have whatever random junk is on the stack when the function is called. This can have a lot of random and undefined behaviour if the HAL assumes it is a bit pattern. Can save hours chasing ghosts. Enabling asserts can also catch so parameter issues.

The Micron parts would use the flag status register, looks like this is Macronix, sorry.

Some reason not to use the 4P5's BSP directly?

STM32Cube_FW_L4_V1.16.0\Drivers\BSP\STM32L4P5G-Discovery\stm32l4p5g_discovery_ospi_nor.c

Not sure why you'd see "HAL_OSPI_Receive Timeout", it does that on the first pass?

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
JSchu.5
Associate II

Thank you for your response. The example code for this discovery board is working as expected. I did not know this project is existing. Thanks for the hint.