2022-09-08 12:52 AM
Hi everyone,
I've a strange problem when I write to an external flash memory (S29GL512T) throught a STM32F767 MCU and a custom external loader loaded in the STM32CubeProgrammer.
After debugging the external loader several times, I've found that the contents of the buffer that CubeProgrammer gives me for the write operation has partially invalid data. I have done this test in 2 contexts:
So I don't understand why, when you use FMC to program the external flash, the contents of the given buffer are manipulated.
This follows shows the original data I want program at address 0x60060000 and the log generated during the programm procedure.
# Sector erase 0
Init...<LF>
S29GL512T11 found!<LF>
Read mode<LF>
Sector erase at 0x0<LF>
Sector erase done!<LF>
# Sector erase 1, 2, 3
Init...<LF>
S29GL512T11 found!<LF>
Read mode<LF>
Sector erase at 0x20000<LF>
Sector erase done!<LF>
Sector erase at 0x40000<LF>
Sector erase done!<LF>
Sector erase at 0x60000<LF>
Sector erase done!<LF>
# Programm 16 bytes at 0x60000000
Init...<LF>
S29GL512T11 found!<LF>
Programming at 0x60000000<LF>
Programming size:16<LF>
Pointer Buffer 0x20004f00<LF>
# Programm 16 bytes at 0x60000000
# I think in this scenario the whole of data to program is loaded in RAM and splitted in 2 consecutive buffers (one with 149044 bytes and the other 149040 bytes). Then I can check a knowed position of this buffer if it matches with a original data (In this case, I use the 0x60060000 addres beacuse never matches with betwen buffer and the original content).
Init...<LF>
S29GL512T11 found!<LF>
Programming at 0x60020000<LF>
Programming size:149044<LF>
Pointer Buffer 0x20004f00<LF>
# Check the content of buffer where represents the content of 0x60060000. Has an invalid data 0x997dccd9b != 0x00000000.
0x20044f00: 0x997dcd9b<LF>
Programming at 0x60044634<LF>
Programming size:149040<LF>
Pointer Buffer 0x20029534<LF>
# Check again the content of buffer where represents the content of 0x60060000. Has an invalid data 0x997dccd9b != 0x00000000.
0x20044f00: 0x997dcd9b<LF>
2022-09-09 09:14 AM
Not a memory I'm using.
I'd perhaps test all of the read, erase and write functionality from application space, then move to the loader.
If the STM32 Cube Programmer is providing the wrong data, that's going to be very difficult to fix. Here we tend to CRC the memory space in the debug version of the loader, so we can cross check content/expectations quickly.
Would check that the programmer is loading the object file properly, and there's not some issue at that level.
Does the content of the buffer write properly, and verify, or does that fail at a similar point?
The new memory has different write buffering internally, and has a wider address bus.
2022-09-13 08:20 AM
Hi Tesla DeLoren,
thank you for your suggestions. I've made a new project in application space with the source (partially) of the external loader. I've had to change some values of FMC configuration to work fine. This application check the initial content with CRC32, erase 4 sectors, program this sectors with the content 0xAAAA and check again the content with CRC32.
This is the output of the application
SWV ITM Data Console - ITM Port: 0
Test S29GL512T
Manufacturer: 0x1
Code1: 0x227E
Code2: 0x2223
Code3: 0x2201
Read from 0x60020000 131072 bytes to 0x200000FC
0xCC3FED57 <-> 0x4FAE1A88 ..... :(
Read from 0x60040000 131072 bytes to 0x200000FC
0xCC3FED57 <-> 0x4FAE1A88 ..... :(
Read from 0x60060000 131072 bytes to 0x200000FC
0xCC3FED57 <-> 0x4FAE1A88 ..... :(
Read from 0x60080000 131072 bytes to 0x200000FC
0xCC3FED57 <-> 0x4FAE1A88 ..... :(
Sector erase from 0x60020000 to 0x60080000
Read from 0x60020000 131072 bytes to 0x200000FC
0xCC3FED57 <-> 0xCC3FED57 ..... MATCHES
Read from 0x60040000 131072 bytes to 0x200000FC
0xCC3FED57 <-> 0xCC3FED57 ..... MATCHES
Read from 0x60060000 131072 bytes to 0x200000FC
0xCC3FED57 <-> 0xCC3FED57 ..... MATCHES
Read from 0x60080000 131072 bytes to 0x200000FC
0xCC3FED57 <-> 0xCC3FED57 ..... MATCHES
Programming to 0x60020000 131072 bytes from 0x200200FC
Programming to 0x60040000 131072 bytes from 0x200200FC
Programming to 0x60060000 131072 bytes from 0x200200FC
Programming to 0x60080000 131072 bytes from 0x200200FC
Read from 0x60020000 131072 bytes to 0x200000FC
0x4FAE1A88 <-> 0x4FAE1A88 ..... MATCHES
Read from 0x60040000 131072 bytes to 0x200000FC
0x4FAE1A88 <-> 0x4FAE1A88 ..... MATCHES
Read from 0x60060000 131072 bytes to 0x200000FC
0x4FAE1A88 <-> 0x4FAE1A88 ..... MATCHES
Read from 0x60080000 131072 bytes to 0x200000FC
0x4FAE1A88 <-> 0x4FAE1A88 ..... MATCHES
I will made the changes mader in the application to the external loader and I will check again. I keep you updated.
About your questions,
2024-05-17 04:53 AM
Hello again,
I come back with a similar issue with a different memory, now is a NOR flash S29GL128S.
I can read and write any address of external memory properly. Also I can do sector erase and full chip erase. A corruption data to write happens when it tries a program block of 342324 bytes in the external memory. I guess CubeProgrammer splits the block in 2 blocks because Write function is called 2 times, one with 171164 bytes and another with 171160 bytes. In the second time when Write function is called is when I catch a corruption data.
int Write(uint32_t Address, uint32_t Size, uint16_t* Buffer) {
uint32_t i_write = 0;
uint32_t word = 0;
uint16_t data;
#if DEBUG
PRINT_HEX_EX("Programming at ", Address);
PRINT_DEC_EX("Programming size:", Size);
#endif
for (i_write = 0; i_write < Size; i_write += 2) {
data = Buffer[word];
#if DEBUG
// Here is where checks data of some address where threre's corruption
if (Address == 0x6004EE80) {
PRINT_HEX(data);
} else if (Address == 0x6004EEA0) {
PRINT_HEX(data);
}
#endif
HAL_NOR_Program(&hnor1, (uint32_t *) Address, &data);
if ((HAL_NOR_GetStatus(&hnor1, Address, NOR_DEV_TIMEOUT))
!= HAL_NOR_STATUS_SUCCESS) {
HAL_NOR_ReturnToReadMode(&hnor1);
#if DEBUG
PRINT_TEXT("Progamming Error!");
#endif
return 0;
}
Address += 2;
word++;
}
#if DEBUG
PRINT_TEXT("Progamming done!");
#endif
return 1;
}
The following image is a log generated by the external loader. The lines "0x3401<LF>" and "0xb510<LF>" is the data I was checking to see if there's corruption or not. The correct lines should be "0x0<LF>"
Removing HAL_NOR_Program from the Write function, there's no corruption data. Also using an old memory compatible with this actual there's no corruption.
Another strange thing is if I use the external loader with the old tool StLink Utility also there's no corruption. The only thing I can see is there is only one call of Write function instead of 2 times in CubeProgrammer. The following image is the log generated by external loader when StLink Utility is used
I don't know where is the problem, if there's wrong in my external loader or there's some bug in the CubeProgrammer.