Sector erase OSPI on STM32L4P5G Discovery Board timeout
- September 23, 2022
- 3 replies
- 2160 views
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;
}