cancel
Showing results for 
Search instead for 
Did you mean: 

FMI Troubles

tboss
Associate II
Posted on March 15, 2010 at 12:40

FMI Troubles

8 REPLIES 8
willie
Associate II
Posted on May 17, 2011 at 10:00

This is one of several FUQs (Frequently Unanswered Questions) to ST.

This (as explained in the newest Flash Programming manual) can be

prevented by executing the following instructions:

    MOV r0, #0x40000

    MCR p15,0x1,r0,c15,c1,0

The problem is that if these instructions are executed at any time except

during the initialization the ARM throws an Undefined instruction fault.

I have found that a delay solves the problem, one just have to be careful

that the compiler does not optimise the code away.

whh

robosoft2
Associate II
Posted on May 17, 2011 at 10:00

Hi ,

I have exactly the same problem. Is this problem solved ?

Pls let me know.

Posted on May 17, 2011 at 10:00

The presented code screams for the use of the volatile type.

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
robosoft2
Associate II
Posted on May 17, 2011 at 10:00

Here is my code to erase sector7 from bank0. This code is compiled to execute in RAM.

When I execute the code step by step in my debugger (Keil JLINK) it works.

Without debugger it never returns...

void Erase(void)

 

{

 

  volatile long Time_Out = 0;

 

  volatile vu32 FMI_Sector = FMI_B0S7;

 

   /* Write an erase set-up command to the sector */

 

   *(vu16 *)FMI_Sector = 0x20;

 

   /* Write an erase confirm command to the sector */

 

   *(vu16 *)FMI_Sector = 0xD0;

 

   /* Wait until operation compeletion */

   while((!((*(vu16 *)FMI_Sector) & 0x80))&&(Time_Out < TIMEOUT ))

 

   {

 

     Time_Out ++;

 

   }

 

   *(vu16 *)FMI_Sector = 0x50;

 

   /* Write a read array command */

 

   *(vu16 *)FMI_Sector = 0xFF;

 

}

regards

Luc

Posted on May 17, 2011 at 10:00

Hi,

in the past i used STR912FA and i solved the problem in this way:

void EraseSector(u32 Sector)

{

  /*

slowed down to write

la flash (FMI @48Mhz) */

  SCU_FMICLKDivisorConfig(SCU_FMICLK_Div2);

  /* Clear */

  FMI_WriteProtectionCmd(Sector, DISABLE);

  FMI_EraseSector(Sector);

  FMI_WaitForLastOperation(FMI_BANK_1);

  FMI_WriteProtectionCmd(Sector, ENABLE);

  /* Full speed (FMI @96Mhz) */

  SCU_FMICLKDivisorConfig(SCU_FMICLK_Div1);

 

}

All FMI routine of ST Library are execute in RAM.

In FMI_WaitForLastOperation disable PFQBC see errata

__ramfunc u8 FMI_WaitForLastOperation(vu32 FMI_Bank)

{

  u32 Time_Out = 0;

 

  /* Write a read status register command */

  *(vu16 *)(FMI_Bank) = 0x70;

  /* Disable PFQBC (see Errata pag 5) */

  SCU->SCR0 &=~0x1;

  /* Wait until operation compeletion */

  while((!((*(vu16 *)FMI_Bank) & 0x80))&&(Time_Out < TIMEOUT ))

  {

    Time_Out ++;  /* Time Out */

  }

  /* Write a read array command */

  *(vu16 *)FMI_Bank = 0xFF;

  /* Enable PFQBC */

  SCU->SCR0 |=0x1;

 

  if (Time_Out == TIMEOUT)

  {

    return FMI_TIME_OUT_ERROR;

  }

  else

  {

    return FMI_NO_TIME_OUT_ERROR;

  }

}

I hope

it is

useful

Paolo

robosoft2
Associate II
Posted on May 17, 2011 at 10:00

Hi Paolo,

Thanks for response.

It stil does not work. Erasing a sector from BANK0 is no problem, erasing a sector in BANK1 does not work, except step by step with JTAG debugger.

Do you still use the STR912 ? I hate this device !

Kind regards

Luc

Posted on May 17, 2011 at 10:00

So much for an appropriate use of volatile.

 

 The following would be a more consistent usage

 

 

  long Time_Out = 0;

 

  volatile vu32 *FMI_Sector = (volatile vu32 *)(FMI_B0S7);

 

   /* Write an erase set-up command to the sector */

 

   *(volatile vu16 *)FMI_Sector = 0x20;

 

   /* Write an erase confirm command to the sector */

 

   *(volatile vu16 *)FMI_Sector = 0xD0;

 

   /* Wait until operation compeletion */ ...

Or more effectively

void Erase(void)

 

{

 

  long Time_Out = 0;

 

  volatile vu16 *FMI_Sector = (volatile vu16 *)(FMI_B0S7);

 

   /* Write an erase set-up command to the sector */

 

   *FMI_Sector = 0x20;

 

   /* Write an erase confirm command to the sector */

 

   *FMI_Sector = 0xD0;

 

   /* Wait until operation compeletion */

   while((!((*FMI_Sector) & 0x0080))&&(Time_Out < TIMEOUT ))

 

   {

 

     Time_Out ++;

 

   }

 

   *FMI_Sector = 0x50;

 

   /* Write a read array command */

 

   *FMI_Sector = 0xFF;

 

} >>Do you still use the STR912 ? I hate this device !

Life would likely be easier if you used the library code, or were more familiar with C and the tool chain.
Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
robosoft2
Associate II
Posted on May 17, 2011 at 10:00

Thanks for reply. It seems to be OK now.

>>Do you still use the STR912 ? I hate this device !

>>Life would likely be easier if you used the library code, or were more familiar with >>C and the tool chain.

I use the library code. I made a *.lib and linked it in my code. The part 91x_FMI was compiled to be executed in RAM. This does not work. When I compile the 91x_FMI files separate and link it in my code, it does work.

I have been programming devices for over 20 years in C. I use this toolchain for NXP LPC2470, SAMSUING S3C2440 without problems. PIC16, PIC32 is a pleasure to work with...

And, no, I think my life would be easier if the erratasheet is a bit smaller ...

So, lets say I do not hate this device, but I never gonna love it !

Thanks anyway

Luc