cancel
Showing results for 
Search instead for 
Did you mean: 

STM32CubeProgrammer External Loader Partial Page

CRich.4
Associate III

Hello, I have made a custom external flash loader(.stldr) file for my STM32 based board. Reading the content of the external flash via CubeProgrammer works fine. But when programming i run into the following problem: CubeProgrammer tries to write partial pages, which fails.

device setup in Dev_Inf.c:

struct StorageInfo const StorageInfo = {
#endif
"W25Q_BurnerHMI_PT1_loader_v1", // Device Name
NOR_FLASH, // Device Type
0x70000000, // Device Start Address
PAGE_COUNT*MEM_PAGE_SIZE_BYTES, // Device Size in Bytes (8192 pages * 512 bytes)
MEM_PAGE_SIZE_BYTES, // Programming Page Size (512 bytes)
0xFF, // Initial Content of Erased Memory
// Specify Size and Address of Sectors (view example below)
{
{SECTOR_COUNT, MEM_SECTOR_SIZE_BYTES}, // Sector Num (512), Sector Size (8192 bytes)
{0x00000000, 0x00000000}
},
};

 

The image i'm writing has a size of 2097152 bytes (2MiB) and in the UART debug print i can see that CubeProgrammer is splitting the image like this:

Write(Address:0x70000000, Size:0x7D500, buffer:0x240052A0)
partial page: PageNum:0x3EA, OffsetIntoPage:0x0, NumBytes:0x100
Write(Address:0x7007D500, Size:0x7D500, buffer:0x240827A0)
partial page: PageNum:0x3EA, OffsetIntoPage:0x100, NumBytes:0x100
Write(Address:0x700FAA00, Size:0x7D500, buffer:0x240052A0)
partial page: PageNum:0xBBF, OffsetIntoPage:0x0, NumBytes:0x100
Write(Address:0x70177F00, Size:0x7D500, buffer:0x240827A0)
partial page: PageNum:0xBBF, OffsetIntoPage:0x100, NumBytes:0x100
Write(Address:0x701F5400, Size:0x5600, buffer:0x240052A0)
Write(Address:0x701FAA00, Size:0x5600, buffer:0x2400A8A0)

 

0x7D500 is not a multiple of the page size (512).

 

Is there any way to force CubeProgrammer to split the image into multiples of 512 bytes (full pages)?

 

 

1 ACCEPTED SOLUTION

Accepted Solutions

i think i have found the problem in my loader.

I compied the drive from a QSPI project.

and it contained this function:

u32_t page_to_addr(u32_t pageNum, u8_t pageShift) {
return pageNum * MEM_PAGE_SIZE_BYTES + pageShift;
}

 

for single memories the page size is 256, so the offset/shift fits into one byte

but for D-QSPI the page size is 512 bytes and no longer fits into a uint8_t

 

fixed:

u32_t page_to_addr(u32_t pageNum, u16_t pageShift) {
return pageNum * MEM_PAGE_SIZE_BYTES + pageShift;
}

View solution in original post

10 REPLIES 10

What exactly is the configuration of the memories here? Which Winbond W25Q devices in a pair?

In Dual mode need to read a pair of status bytes and both must indicate completion. Make sure the AutoPolling is done correctly. 

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

we're using a pair of W25Q16JV devices.

We're using the OCTOSPI peripheral in dual-quad (D-QSPI) mode.

when using the same driver in a loader with the IAR EWARM Development Environment we can write the image without problems. IAR seems to split the image always at multiples of the page size.

 

STMCubeProgrammer splits the image in a way that leads to parital pages, which should be supported by the W25Q16, but apparently our driver has problems with that.

I will check whether the status bytes of both chips are checked. Thanks for the hint.

i just checked the code, and i'm reading 2 bytes for the status regsiter (both chips) and combining the busy flags with logical or

Odd choice of part

Is this on a STM32H7A3 board? What's the pin assignment for the QSPI pins?

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

We're using the STM32H7B0VB in the LQFP100 package

the W25Q16JV chips are connected as follows:

CLK to PB2 (for both)

CS to PC11 (for both)

IO0 to PD11

IO1 to PD12

IO2 to PA7

IO3 to PD13

IO4 (IO0 of 2nd chip) to PE7

IO5 (IO1 of 2nd chip) to PE8

IO6 (IO2 of 2nd chip) to PE9

IO7 (IO3 of 2nd chip) to PE10

 

 

but i think that the pinout shouldn't be the issue

Reading the flash via the STMCubeProgrammer works fine

Programming via IAR EWARM (using the same driver in the IAR loader framework) works find

ans executing code from the external flash works fine

 

>>but I think that the pinout shouldn't be the issue

I don't think it is either, but I'm not sure my current loader is built for the chip/pin combo in question. I don't think I implemented anything for DUAL on the STM32H7Ax/7Bx as I didn't have a good platform or requests. Just need to back-port from the QSPI variants.

The STLDR should work fine whatever the Write() span is. It would be ideal if it took the block sizing cues from the StorageInfo header PageSize field, but I not convinced is does.

Really shouldn't matter, just requires the page is only written once, and the operation doesn't span, which would go to how the large write is de-blocked.

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

H7A3
W25Q16JV

PB2:AF9 CLK
PC11:AF9 NCS

PD11:AF9 OCTOSPIM_P1_IO0
PD12:AF9 OCTOSPIM_P1_IO1
PA7:AF10 OCTOSPIM_P1_IO2
PD13:AF9 OCTOSPIM_P1_IO3

PE7:AF10 OCTOSPIM_P1_IO4
PE8:AF10 OCTOSPIM_P1_IO5
PE9:AF10 OCTOSPIM_P1_IO6
PE10:AF10 OCTOSPIM_P1_IO7

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

Tentative blind build for a dual W25Q16JV

https://github.com/cturvey/stm32extldr/blob/main/h7_w25q16/CLIVEONE-W25Q16_STM32H7AX-PB2-PC11-PD11-PD12-PA7-PD13-PE7-PE8-PE9-PE10.stldr

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

Thanks for the custom build of your loader.

unfortunately it doesn't work.

I tried reading the memory with STM32CubeProgrammer, but that didn't work.

maybe it's due to a difference between H7A3 and the H7B0 we are using

 

also we are using the memory area 0x7000 0000 (OCTOSPI2), but i don't know if that makes a difference.

I seem to remember (but i don't know from where) that the specific chip/package we are using only supports one OCTOSPI unit