2024-02-13 11:31 AM
I went through the ST External QSPI Loader how to and have verified my quadspi.c/h driver is good with the Winbond W25Q64 flash part we are using. However after I create the .stldr and load it into the STM32 Programmer it will not read from the flash...get Error:data read failed. I've attached the project if someone could help me out with what could be wrong?
Solved! Go to Solution.
2024-12-11 02:34 PM
Just to wrap up the solution to this LONG thread....
Initially I was using TIM6 for the timebase (based on application using FreeRTOS that cannot use SysTick) but the NVIC priority was set to 15. I'm not sure if the priority was the problem or some timeout with the Loader_Src.c Init() function, but the ST Support solution to comment out __set_PRIMASK(0); that enabled interrupts just masked the issue and since the interrupts were no longer running the HAL_GetTick() never incremented so timeout values made no difference and I had HAL_Delay() overridden to use a loop of NOP.
By using SysTick for the Timebase and setting it's NVIC priority to 0 instead of 15 (default) I was able to use enable interrupts in Init() and use the standard HAL_Delay() and HAL_GetTick() just fine and almost everything worked just fine. However, the Chip Erase still failed....Tesla was correct that this was a timeout issue. Basically, I had a timeout value of 20000 (HAL_QSPI_TIMEOUT_DEFAULT_VALUE) I was using for most the QSPI functions. I started using a larger value for erasing the chip, but I was using this larger timeout for issuing the erase chip command when in fact the HAL_QSPI_AutoPolling() is what needed the larger timeout value since that is what is waiting for the erase to complete. Once I modified my AutoPolling function to use a larger timeout when doing a chip erase then that method started working as well. Just multiple misunderstanding of how this loader works on my part on multiple fronts.
#define CSP_QPSI_TIMEOUT_DEFAULT_VALUE 20000
#define CSP_QPSI_MASSERASE_TIMEOUT_VALUE 65000
uint8_t CSP_QSPI_Erase_Chip(void) {
QSPI_CommandTypeDef sCommand = { 0 };
if (QSPI_WriteEnable() != HAL_OK) {
return HAL_ERROR;
}
/* Erasing Sequence --------------------------------- */
sCommand.InstructionMode = QSPI_INSTRUCTION_1_LINE;
sCommand.Instruction = CHIP_ERASE_CMD;
sCommand.AddressMode = QSPI_ADDRESS_NONE;
sCommand.AlternateByteMode = QSPI_ALTERNATE_BYTES_NONE;
sCommand.DataMode = QSPI_DATA_NONE;
sCommand.DummyCycles = 0;
sCommand.DdrMode = QSPI_DDR_MODE_DISABLE;
sCommand.DdrHoldHalfCycle = QSPI_DDR_HHC_ANALOG_DELAY;
sCommand.SIOOMode = QSPI_SIOO_INST_EVERY_CMD;
if (HAL_QSPI_Command(&hqspi, &sCommand, CSP_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) {
return HAL_ERROR;
}
if (QSPI_AutoPollingMemReady(CSP_QPSI_MASSERASE_TIMEOUT_VALUE) != HAL_OK) {
return HAL_ERROR;
}
return HAL_OK;
}