Programming an external flash
Hi I'm trying program an external flash with the ST-Link Uility. I made a custom External Loader based on STM32F429ZI and the memory to program is a NOR flash S29GL128S (
http://www.cypress.com/file/177976/download
). When I try read from the external flash seems ok because I can see the content 0xFFFF inside the grid of ST-Link Utility. But when I try to program or erase sector/Chip I get errors. For example if I want program an hex I catch:12:55:11 : Device ID:0x419
12:55:11 : Device flash Size : 2MBytes
12:55:11 : Device family :STM32F42xxx/F43xxx
12:55:18 : [dcb430.hex] opened successfully.
12:55:18 : [dcb430.hex] checksum : 0x00C45668
12:55:24 : The elf loader Program function fails.
12:55:26 : The elf loader Program function fails.
12:55:26 : Memory-Loader error
12:55:26 : Error occured during program operation!
12:55:26 : Programming error @ 0x60000000!
The External Loader project has the Dev_Inf.c file with the definition based on memory flash datasheet:
struct StorageInfo const StorageInfo = {
'S29GL128S_STM3F429ZI', // Device Name + version number
NOR_FLASH, // Device Type
0x60000000, // Device Start Address
0x01000000, // Device Size in Bytes (16MBytes/128Mbits)
0x00000400, // Programming Page Size 1024 Bytes
0xFF, // Initial Content of Erased Memory
// Specify Size and Address of Sectors (view example below)
0x00000080, 0x00020000, // Sector Num : 128 ,Sector Size: 128KBytes
0x00000000, 0x00000000,
};
and
the Loader_Src.c has the implementation of Init, Read, Write, MassErase, SectorErase functions using the stm324x9i_eval_fmc_nor:Init function
int Init (void){
SystemInit();
NOR_Init();
return 1;
}
Read function Write function MassErase function SectorErase functionint Read (uint32_t Address, uint32_t Size, uint16_t* Buffer) {
uint32_t InternalAddr = Address - StartAddresse;
uint32_t ReadedData = 0;
uint32_t Counter = 0;
uint16_t TmpBuffer = 0x00000000;
if (InternalAddr%2 != 0)
{
NOR_ReadBuffer(&TmpBuffer, (InternalAddr - InternalAddr%2), 1);
for (Counter =0; (Counter<(InternalAddr%2))&&(Counter<Size); Counter++)
*((uint8_t*)Buffer+Counter) = *((uint8_t*)(&TmpBuffer)+InternalAddr%4+Counter);
ReadedData += Counter;
}
if (Size-ReadedData >= 2)
{
NOR_ReadBuffer((uint16_t*)((uint8_t*)Buffer+ReadedData), InternalAddr+ReadedData ,(Size-ReadedData)/2);
ReadedData += (((Size-ReadedData)/2)*2);
}
if (ReadedData < Size)
{
NOR_ReadBuffer(&TmpBuffer, InternalAddr+ReadedData ,1);
for (Counter =0; Counter<(Size-ReadedData); Counter++)
*((uint8_t*)Buffer+ReadedData+Counter) = *((uint8_t*)(&TmpBuffer)+Counter);
}
return 1;
}
Read function Write function MassErase function SectorErase functionint Write (uint32_t Address, uint32_t Size, uint16_t* Buffer)
{
uint32_t InternalAddr = Address - StartAddresse;
uint32_t WritedData = 0;
uint32_t Counter = 0;
uint16_t TmpBuffer = 0x00000000;
if (InternalAddr%2 != 0)
{
NOR_ReadBuffer (&TmpBuffer, (InternalAddr - InternalAddr%2),1);
for (Counter =0; (Counter<(2-InternalAddr%2))&&(Counter<Size); Counter++)
*((uint8_t*)(&TmpBuffer)+InternalAddr%2+Counter) = * ((uint8_t*)Buffer+Counter);
if (NOR_ProgramBuffer (&TmpBuffer, (InternalAddr - InternalAddr%2),1) != NOR_SUCCESS)
return 0;
WritedData += Counter;
}
if (Size-WritedData >= 2)
{
if (NOR_ProgramBuffer ((uint16_t*)((uint8_t*)Buffer+WritedData), InternalAddr+WritedData, ((Size-WritedData)/2))!=NOR_SUCCESS)
return 0;
WritedData += (((Size-WritedData)/2)*2);
}
if (WritedData < Size)
{
NOR_ReadBuffer (&TmpBuffer, InternalAddr+WritedData,1);
for (Counter =0; Counter<(Size-WritedData); Counter++)
*((uint8_t*)(&TmpBuffer)+Counter) = *((uint8_t*)Buffer+WritedData+Counter);
if (NOR_ProgramBuffer (&TmpBuffer, InternalAddr+WritedData,1)!=NOR_SUCCESS)
return 0;
}
return 1;
}
Read function Write function MassErase function SectorErase functionint MassErase (void)
{
if (NOR_EraseChip()==NOR_SUCCESS)
return 1;
else
return 0;
}
Read function Write function MassErase function SectorErase functionint SectorErase (uint32_t EraseStartAddress ,uint32_t EraseEndAddress)
{
uint32_t BlockAddr;
EraseStartAddress = EraseStartAddress - EraseStartAddress%0x20000;
while (EraseEndAddress>=EraseStartAddress)
{
BlockAddr = EraseStartAddress - StartAddresse;
if (NOR_EraseBlock(BlockAddr)!=NOR_SUCCESS)
return 0;
EraseStartAddress+=0x20000;
}
return 1;
}
Any idea what could be wrong?
Best regards
#st-link-utility #custom-loaders