AnsweredAssumed Answered

Trouble writing External Loader for QSPI Flash for ST-Link utility

Question asked by Job Menue on Oct 4, 2017
Latest reply on Feb 20, 2018 by Roland Hoesch



I am having problems writing my own External Loader for the ST-Link utility. In a previous version of our custom board, we used the same QSPI chip as the one on the STM32F746-EVAL, the MT25QL256. In a new version of our custom board however, we use the IS25LP256D.


After reading both of the datasheets, I see that most of the commands are exactly the same. I also found out that the source code for the F7 Demo Project uses the header file for the N25Q512A, which has exactly the same hex commands as the other Micron chip used in the Evaluation board. This means that I would only have to edit and append the header file for the N25Q512. And even then, only a couple of commands are used.


I used the demo project N25Q256A_STM32L476-EVAL located in the folder of the ST-Link utility. Because the F7 Demo project uses certain BSP functions for the N25Q512 (or MT25QL256 apparently, because the source code works on this chip as well), I surmise that I can use the same BSP functions in my own External Loader and maybe only change the instruction code.


So far, I have the following Initialization code:

int Init (void)
// System init
// Clock Init
// STM32F746 BSP init


return 1;

The SystemInit is a standard function in the system_stm32f7xx.c source file. I use exactly the same SystemClock_Config as I use in my project which worked on the previous QSPI chip. (200 MHz SYSCLK, 50 MHz APB1, 100 MHz APB2)


uint8_t BSP_QSPI_Init(void)
QSPIHandle.Instance = QUADSPI;

/* Call the DeInit function to reset the driver */
if (HAL_QSPI_DeInit(&QSPIHandle) != HAL_OK)
return QSPI_ERROR;

/* System level initialization */
BSP_QSPI_MspInit(&QSPIHandle, NULL);

/* QSPI initialization */
/* QSPI freq = SYSCLK /(1 + ClockPrescaler) = 200 MHz/(1+1) = 100 Mhz */
QSPIHandle.Init.ClockPrescaler = 1;
QSPIHandle.Init.FifoThreshold = 4;
QSPIHandle.Init.FlashSize = POSITION_VAL(N25Q512A_FLASH_SIZE) - 1;
QSPIHandle.Init.ChipSelectHighTime = QSPI_CS_HIGH_TIME_6_CYCLE; /* Min 50ns for nonRead */
QSPIHandle.Init.ClockMode = QSPI_CLOCK_MODE_0;
QSPIHandle.Init.FlashID = QSPI_FLASH_ID_1;

if (HAL_QSPI_Init(&QSPIHandle) != HAL_OK)
return QSPI_ERROR;

/* QSPI memory reset */
if (QSPI_ResetMemory(&QSPIHandle) != QSPI_OK)

/* Set the QSPI memory in 4-bytes address mode */
// After this, EXTADD = 1
if (QSPI_EnterFourBytesAddressMode(&QSPIHandle) != QSPI_OK)

// Enter QE bit
if(QSPI_EnterQuadEnableBit(&QSPIHandle) != QSPI_OK)

/* Configuration of the dummy cycles on QSPI memory side */
if (QSPI_DummyCyclesCfg(&QSPIHandle) != QSPI_OK)

return QSPI_OK;

Currently, I use 8 dummy cycles, which should be enough.


Again, I use the same BSP functions as are available in the BSP for my evaluation board. These worked on the previous chip, and not a lot has changed, so I cannot for the life of me figure out what is going wrong.


Can anyone help me out?