2019-10-17 02:06 AM
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
2019-10-17 05:07 AM
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.
2019-10-17 05:09 AM
List pins used by device in your implementation.
2019-10-17 09:47 AM
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...
2019-10-17 11:25 AM
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.
2019-10-17 11:03 PM
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 ?
2019-10-21 02:47 AM
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....
2019-10-21 09:17 AM
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
2019-10-21 11:45 AM
Will see what I can do here.
2019-10-21 05:04 PM
PayPal accepted
HSE: 8 MHz
CLK:PF10:AF9
NCS:PB10:AF9
D0:PC9:AF9
D1:PF9:AF10
D2:PE2:AF9
D3:PF6:AF9