cancel
Showing results for 
Search instead for 
Did you mean: 

STM32F469 external QSPI loader

PaulQ
Associate III

Hello, I am trying to create an external loader for N25Q128A QSPI. I'm currently developing on STM32F469I-DISCO. My loader doesn't work once loaded into STM32 ST-LINK utility (nor in CUBE programmer). If I modify my project adding a main file with a test sequence and I modify my scatter file I can debug normally, flash get correctly initializated, red etc. Please notice my loader is based on HAL.

Perhaps something related with address relocation ? I added  --keep=dev_inf.o control to my linker and flagged "Read-Only Position Independent" and "Read-Write Position Independent" flags, but no relief until now.

Thank you for help/suggestions

12 REPLIES 12

Set logging output to most verbose.

Inspect .STLDR with FromELF.

Make sure you don't have a vector table and dependency on SysTick.

Output telemetry to a UART.​

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

List pins used by device in your implementation.​

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

HI,

stldr inspection gives me

ID Type Binding Name

114 STT_FUNC STB_GLOBAL Init

116 STT_FUNC STB_GLOBAL SectorErase

117 STT_FUNC STB_GLOBAL Read

119 STT_FUNC STB_GLOBAL Write

(stldr file is loaded by ST-LINK utility, but only working command seem "sector erase")

Pin assignment is OK, tested with STM32f469I-DISCO schematics. After all, if I add a "main" procedure to my project

int main(void)

{

uint32_t Address = 0x00000000;

uint32_t Size = 0x100;

pbuffer = &buffer[0];

Init ();

Read (Address, Size, pbuffer);

SectorErase (0x00000000, 0x00010000);

Write (Address, Size, pbuffer);

Read (Address, Size, pbuffer);

}

program works.

I don't use interrupt mode nor DMA mode fin hal_qspi driver...

I wouldn't export Read, my experience suggests it makes the tools very unhappy.

Usually they call Init(0), and that maps the QSPI to 0x90000000 and they directly read the memory in-place via JTAG and don't involve the external loader.

The docs for this are awful, and the .stldr files are different from the example sources.

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

I took away Read (Read is not visible anymore in ST-LINK Utility), and added memory mapped mode in Init(). Once again I tested my code in standalone mode:

int main(void)

{

uint32_t Address = 0x00000000;

uint32_t Size = 0x100;

pbuffer = &buffer[0];

Init (); // now, read memory with Keil IDE

SectorErase (0x00000000, 0x00010000);

Write (Address, Size, pbuffer);

}

Unfortunately loader still does not work, not even Read...

I noticed that stm32f4xx_hal_qspi uses quite convoluted way of checking/setting flags:

while((FlagStatus)(__HAL_QSPI_GET_FLAG(hqspi, Flag)) != State) // where GET_FLAG is

(READ_BIT((__HANDLE__)->Instance->SR, (__FLAG__)) != 0U)

So we have pointer to pointer to instance member, just to set/clear one bit ! OMG...

Maybe this kind of complications collides with position independent code ?

PaulQ
Associate III

Weird....

I set up very simple serial debug and found that QSPIHandle is corrupted:

Loader_Src.c:

/* Private variables ---------------------------------------------------------*/

QSPI_HandleTypeDef QSPIHandle; 

...

KeepInCompilation int Init (uint8_t configureMemoryMappedMode)

{

memset(&QSPIHandle, 0, sizeof(QSPIHandle));

...

HAL_QSPI_DeInit(&QSPIHandle);

}

stm32f4xx_hal_qspi.c:

HAL_StatusTypeDef HAL_QSPI_DeInit(QSPI_HandleTypeDef *hqspi)

{

....

 /* Initialize the QSPI state */

 hqspi->State = HAL_QSPI_STATE_RESET;

  

  // check it back.......

 if (hqspi->State == HAL_QSPI_STATE_RESET) 

sendUartChar(0x20); // should be sent on terminal

 else

sendUartChar(0x21); // <-------- I read this

So, seems like you cannot call a function passing a pointer to a structure as an argument ? I can't believe this....

Hello Clive, as I understood from another post that you are an assembler guru and you've already remapped some "standard" loaders.

As I'm getting crazy with mine, would it be possible for you to modify N25Q128A_STM32469I-DISCO.stldr and remap the QSPI pins as follow ?

/* Definition for QSPI Pins */

#define QSPI_CS_PIN        GPIO_PIN_10

#define QSPI_CS_GPIO_PORT     GPIOB

#define QSPI_CLK_PIN       GPIO_PIN_10

#define QSPI_CLK_GPIO_PORT    GPIOF

#define QSPI_D0_PIN        GPIO_PIN_9

#define QSPI_D0_GPIO_PORT     GPIOC

#define QSPI_D1_PIN        GPIO_PIN_9

#define QSPI_D1_GPIO_PORT     GPIOF

#define QSPI_D2_PIN        GPIO_PIN_2

#define QSPI_D2_GPIO_PORT     GPIOE

#define QSPI_D3_PIN        GPIO_PIN_6

#define QSPI_D3_GPIO_PORT     GPIOF

This would really save my day, actually I'm struggling since one week

Thank you

Paolo

Will see what I can do here.

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

PayPal accepted

HSE: 8 MHz

CLK:PF10:AF9

NCS:PB10:AF9

D0:PC9:AF9

D1:PF9:AF10

D2:PE2:AF9

D3:PF6:AF9

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