AnsweredAssumed Answered

Programming an external flash

Question asked by Mas.Jordi on Mar 17, 2017
Latest reply on Mar 30, 2017 by Mas.Jordi

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

int 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;
}

 

Write function

int 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;

}

 

MassErase function

int MassErase (void){

if (NOR_EraseChip()==NOR_SUCCESS)
   return 1;
else
   return 0;

}

 

SectorErase function

int 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

Outcomes