Intermittent flash word writes

View: New views
7 Messages — Rating Filter:   Alert me  

Intermittent flash word writes

by e.tury :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message


Greetings,

I am trying to write a look-up table to flash in an MSP430F4616.  The
clock is 1Mhz and the FCTL2 register is the default value which gives
about 333khz flash clock.

I have a 4096 word table and a table of data pairs (adc value &
distance)  that is about half that large. When I fill my table from
TABLE[0] to TABLE[4095] with the numbers 0 to 4095 (see code below) it
works perfectly. When I try to fill it with the real data it works fine
for about a third of the data then it starts skipping some values. At
about half-way it really gets bad. I don't recognize some of what's
written.

This has got me baffled. Why would it fill correctly for one loop and
not the other?

Any insight or suggestions would be appreciated.

Edd

The code which is commented out works. The other doesn't.

CODE:

void Load_Test_Calibration(void)
{
  uint16 i;

  Set_Calibration_Mode(Calibrating);  //erases flash

           //for (i=0; i<4096; i++)
           for (i=0; i<2002; i++)
           {

            if(Measurements[i] == 0xFFFF)
    {
   Flash_Write_Word((int16*) &(Measurements[Test_Calibration_Data[i]]),
Test_Calibration_Data[i+1]);

                                      //Flash_Write_Word((int16*)
&(Measurements[i]), i);

                     }
             }

  //Set_Calibration_Mode(Idle);
} // end Test_Calibration

#pragma location = 0x4000
const uint16 Measurements[MEASUREMENT_TABLE_LENGTH];                //
=4096

#pragma location = 0x6000
const uint16 Test_Calibration_Data[] = {
3453,0,
3449,1,
3447,2,
3444,3,
3441,4,...................etc.    // less than 4096


void Flash_Write_Word(int16 *data_pointer, int16 word)
{
  FCTL3 = FWKEY; // Clear LOCK
  FCTL1 = FWKEY + WRT; // Enable WRITE

  *data_pointer = word; // program Flash word

  FCTL1 = FWKEY; // Clear WRITE
  FCTL3 = FWKEY + LOCK; // Set LOCK
}

FCTL2 is the reset value which, for a 1mhz clock should give ~333khz
flash clock.



Re: Intermittent flash word writes

by old_cow_yellow :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

The problem is the way you stored the Test_Calibration_Data[] and the
way you wrote them are inconsistent.

You have:
> const uint16 Test_Calibration_Data[] = {
> 3453,0,
> 3449,1,
> 3447,2,
> 3444,3,
> 3441,4,...................etc.

And you try to do:
> Flash_Write_Word(
>   (int16*) &(Measurements[Test_Calibration_Data[i]]),
>   Test_Calibration_Data[i+1]
> );

Thus:
when i=0, you wrote 0 to 3453
when i=1, you wrote 3449 to 0
when i=2, you wr0te 1 to 3449
when i=3, you wrote 3447 to 1
... etc.

You could have destroyed the program itself or changed contents of
registers and RAM. Consider yourself lucky!

--- In msp430@..., "e.tury" <e.tury@...> wrote:

>
>
> Greetings,
>
> I am trying to write a look-up table to flash in an MSP430F4616.  The
> clock is 1Mhz and the FCTL2 register is the default value which gives
> about 333khz flash clock.
>
> I have a 4096 word table and a table of data pairs (adc value &
> distance)  that is about half that large. When I fill my table from
> TABLE[0] to TABLE[4095] with the numbers 0 to 4095 (see code below) it
> works perfectly. When I try to fill it with the real data it works fine
> for about a third of the data then it starts skipping some values. At
> about half-way it really gets bad. I don't recognize some of what's
> written.
>
> This has got me baffled. Why would it fill correctly for one loop and
> not the other?
>
> Any insight or suggestions would be appreciated.
>
> Edd
>
> The code which is commented out works. The other doesn't.
>
> CODE:
>
> void Load_Test_Calibration(void)
> {
>   uint16 i;
>
>   Set_Calibration_Mode(Calibrating);  //erases flash
>
>            //for (i=0; i<4096; i++)
>            for (i=0; i<2002; i++)
>            {
>
>             if(Measurements[i] == 0xFFFF)
>     {
>    Flash_Write_Word((int16*) &(Measurements[Test_Calibration_Data[i]]),
> Test_Calibration_Data[i+1]);
>
>                                       //Flash_Write_Word((int16*)
> &(Measurements[i]), i);
>
>                      }
>              }
>
>   //Set_Calibration_Mode(Idle);
> } // end Test_Calibration
>
> #pragma location = 0x4000
> const uint16 Measurements[MEASUREMENT_TABLE_LENGTH];                //
> =4096
>
> #pragma location = 0x6000
> const uint16 Test_Calibration_Data[] = {
> 3453,0,
> 3449,1,
> 3447,2,
> 3444,3,
> 3441,4,...................etc.    // less than 4096
>
>
> void Flash_Write_Word(int16 *data_pointer, int16 word)
> {
>   FCTL3 = FWKEY; // Clear LOCK
>   FCTL1 = FWKEY + WRT; // Enable WRITE
>
>   *data_pointer = word; // program Flash word
>
>   FCTL1 = FWKEY; // Clear WRITE
>   FCTL3 = FWKEY + LOCK; // Set LOCK
> }
>
> FCTL2 is the reset value which, for a 1mhz clock should give ~333khz
> flash clock.
>



Re: Intermittent flash word writes

by Hugh Molesworth :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

You don't show the flash erase for each segment; at a guess I'd say
that you don't erase them, and therefore you are overloading prior
data with new data. You can only set each bit in flash from a '1' to
a '0', and you can't even do that properly if you don't observe the
cumulative write time. If you want to write the entire array at
Measurements[] you have to first erase every flash segment which is
used by Measurements[]. Each flash segment is 512 bytes in length. TI
cover this in great detail in various application notes and user manuals.

Hugh

At 08:56 AM 9/8/2008, you wrote:

Greetings,

I am trying to write a look-up table to flash in an MSP430F4616.  The
clock is 1Mhz and the FCTL2 register is the default value which gives
about 333khz flash clock.

I have a 4096 word table and a table of data pairs (adc value &
distance)  that is about half that large. When I fill my table from
TABLE[0] to TABLE[4095] with the numbers 0 to 4095 (see code below) it
works perfectly. When I try to fill it with the real data it works fine
for about a third of the data then it starts skipping some values. At
about half-way it really gets bad. I don't recognize some of what's
written.

This has got me baffled. Why would it fill correctly for one loop and
not the other?

Any insight or suggestions would be appreciated.

Edd

The code which is commented out works. The other doesn't.

CODE:

void Load_Test_Calibration(void)
{
   uint16 i;

   Set_Calibration_Mode(Calibrating);  //erases flash

            //for (i=0; i<4096; i++)
            for (i=0; i<2002; i++)
            {

             if(Measurements[i] == 0xFFFF)
     {
    Flash_Write_Word((int16*) &(Measurements[Test_Calibration_Data[i]]),
Test_Calibration_Data[i+1]);

                                       //Flash_Write_Word((int16*)
&(Measurements[i]), i);

                      }
              }

   //Set_Calibration_Mode(Idle);
} // end Test_Calibration

#pragma location = 0x4000
const uint16 Measurements[MEASUREMENT_TABLE_LENGTH];                //
=4096

#pragma location = 0x6000
const uint16 Test_Calibration_Data[] = {
3453,0,
3449,1,
3447,2,
3444,3,
3441,4,...................etc.    // less than 4096


void Flash_Write_Word(int16 *data_pointer, int16 word)
{
   FCTL3 = FWKEY; // Clear LOCK
   FCTL1 = FWKEY + WRT; // Enable WRITE

   *data_pointer = word; // program Flash word

   FCTL1 = FWKEY; // Clear WRITE
   FCTL3 = FWKEY + LOCK; // Set LOCK
}

FCTL2 is the reset value which, for a 1mhz clock should give ~333khz
flash clock.



Re: Intermittent flash word writes

by e.tury :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

The flash is getting erased. I just don't show the code. Besides,
that doesn't explaing why the simple counting loop writes correctly
every time.

Here is the code for completeness:

void Erase_Calibration_Table(void)
{
        int16* address;
        int16 i;
       
        // erase Flash memory for new calibration table
        address =( int16*)Measurements;
        for (i=0; i<16; i++)
        {
                Flash_Erase_Segment(address);
                address += 256;
        }
} // end Erase_Calibration_Table
>
> You don't show the flash erase for each segment; at a guess I'd say
> that you don't erase them, and therefore you are overloading prior
> data with new data. You can only set each bit in flash from a '1'
to
> a '0', and you can't even do that properly if you don't observe the
> cumulative write time. If you want to write the entire array at
> Measurements[] you have to first erase every flash segment which is
> used by Measurements[]. Each flash segment is 512 bytes in length.
TI
> cover this in great detail in various application notes and user
manuals.
>
> Hugh
>
> At 08:56 AM 9/8/2008, you wrote:
>
> Greetings,
>
> I am trying to write a look-up table to flash in an MSP430F4616.  
The
> clock is 1Mhz and the FCTL2 register is the default value which
gives
> about 333khz flash clock.
>
> I have a 4096 word table and a table of data pairs (adc value &
> distance)  that is about half that large. When I fill my table from
> TABLE[0] to TABLE[4095] with the numbers 0 to 4095 (see code below)
it
> works perfectly. When I try to fill it with the real data it works
fine
> for about a third of the data then it starts skipping some values.
At
> about half-way it really gets bad. I don't recognize some of what's
> written.
>
> This has got me baffled. Why would it fill correctly for one loop
and

> not the other?
>
> Any insight or suggestions would be appreciated.
>
> Edd
>
> The code which is commented out works. The other doesn't.
>
> CODE:
>
> void Load_Test_Calibration(void)
> {
>    uint16 i;
>
>    Set_Calibration_Mode(Calibrating);  //erases flash
>
>             //for (i=0; i<4096; i++)
>             for (i=0; i<2002; i++)
>             {
>
>              if(Measurements[i] == 0xFFFF)
>      {
>     Flash_Write_Word((int16*) &(Measurements[Test_Calibration_Data
[i]]),

> Test_Calibration_Data[i+1]);
>
>                                        //Flash_Write_Word((int16*)
> &(Measurements[i]), i);
>
>                       }
>               }
>
>    //Set_Calibration_Mode(Idle);
> } // end Test_Calibration
>
> #pragma location = 0x4000
> const uint16 Measurements
[MEASUREMENT_TABLE_LENGTH];                //

> =4096
>
> #pragma location = 0x6000
> const uint16 Test_Calibration_Data[] = {
> 3453,0,
> 3449,1,
> 3447,2,
> 3444,3,
> 3441,4,...................etc.    // less than 4096
>
>
> void Flash_Write_Word(int16 *data_pointer, int16 word)
> {
>    FCTL3 = FWKEY; // Clear LOCK
>    FCTL1 = FWKEY + WRT; // Enable WRITE
>
>    *data_pointer = word; // program Flash word
>
>    FCTL1 = FWKEY; // Clear WRITE
>    FCTL3 = FWKEY + LOCK; // Set LOCK
> }
>
> FCTL2 is the reset value which, for a 1mhz clock should give ~333khz
> flash clock.
>



Re: Intermittent flash word writes

by old_cow_yellow :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Wrong tree.

--- In msp430@..., "e.tury" <e.tury@...> wrote:

>
> The flash is getting erased. I just don't show the code. Besides,
> that doesn't explaing why the simple counting loop writes correctly
> every time.
>
> Here is the code for completeness:
>
> void Erase_Calibration_Table(void)
> {
> int16* address;
> int16 i;
>
> // erase Flash memory for new calibration table
> address =( int16*)Measurements;
> for (i=0; i<16; i++)
> {
> Flash_Erase_Segment(address);
> address += 256;
> }
> } // end Erase_Calibration_Table
> >
> > You don't show the flash erase for each segment; at a guess I'd say
> > that you don't erase them, and therefore you are overloading prior
> > data with new data. You can only set each bit in flash from a '1'
> to
> > a '0', and you can't even do that properly if you don't observe the
> > cumulative write time. If you want to write the entire array at
> > Measurements[] you have to first erase every flash segment which is
> > used by Measurements[]. Each flash segment is 512 bytes in length.
> TI
> > cover this in great detail in various application notes and user
> manuals.
> >
> > Hugh
> >
> > At 08:56 AM 9/8/2008, you wrote:
> >
> > Greetings,
> >
> > I am trying to write a look-up table to flash in an MSP430F4616.  
> The
> > clock is 1Mhz and the FCTL2 register is the default value which
> gives
> > about 333khz flash clock.
> >
> > I have a 4096 word table and a table of data pairs (adc value &
> > distance)  that is about half that large. When I fill my table from
> > TABLE[0] to TABLE[4095] with the numbers 0 to 4095 (see code below)
> it
> > works perfectly. When I try to fill it with the real data it works
> fine
> > for about a third of the data then it starts skipping some values.
> At
> > about half-way it really gets bad. I don't recognize some of what's
> > written.
> >
> > This has got me baffled. Why would it fill correctly for one loop
> and
> > not the other?
> >
> > Any insight or suggestions would be appreciated.
> >
> > Edd
> >
> > The code which is commented out works. The other doesn't.
> >
> > CODE:
> >
> > void Load_Test_Calibration(void)
> > {
> >    uint16 i;
> >
> >    Set_Calibration_Mode(Calibrating);  //erases flash
> >
> >             //for (i=0; i<4096; i++)
> >             for (i=0; i<2002; i++)
> >             {
> >
> >              if(Measurements[i] == 0xFFFF)
> >      {
> >     Flash_Write_Word((int16*) &(Measurements[Test_Calibration_Data
> [i]]),
> > Test_Calibration_Data[i+1]);
> >
> >                                        //Flash_Write_Word((int16*)
> > &(Measurements[i]), i);
> >
> >                       }
> >               }
> >
> >    //Set_Calibration_Mode(Idle);
> > } // end Test_Calibration
> >
> > #pragma location = 0x4000
> > const uint16 Measurements
> [MEASUREMENT_TABLE_LENGTH];                //
> > =4096
> >
> > #pragma location = 0x6000
> > const uint16 Test_Calibration_Data[] = {
> > 3453,0,
> > 3449,1,
> > 3447,2,
> > 3444,3,
> > 3441,4,...................etc.    // less than 4096
> >
> >
> > void Flash_Write_Word(int16 *data_pointer, int16 word)
> > {
> >    FCTL3 = FWKEY; // Clear LOCK
> >    FCTL1 = FWKEY + WRT; // Enable WRITE
> >
> >    *data_pointer = word; // program Flash word
> >
> >    FCTL1 = FWKEY; // Clear WRITE
> >    FCTL3 = FWKEY + LOCK; // Set LOCK
> > }
> >
> > FCTL2 is the reset value which, for a 1mhz clock should give ~333khz
> > flash clock.
> >
>



Re: Intermittent flash word writes

by e.tury :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

?

--- In msp430@..., "old_cow_yellow" <old_cow_yellow@...>
wrote:
>
> Wrong tree.
>
> --- In msp430@..., "e.tury" <e.tury@> wrote:
> >
> > The flash is getting erased. I just don't show the code. Besides,
> > that doesn't explaing why the simple counting loop writes
correctly

> > every time.
> >
> > Here is the code for completeness:
> >
> > void Erase_Calibration_Table(void)
> > {
> > int16* address;
> > int16 i;
> >
> > // erase Flash memory for new calibration table
> > address =( int16*)Measurements;
> > for (i=0; i<16; i++)
> > {
> > Flash_Erase_Segment(address);
> > address += 256;
> > }
> > } // end Erase_Calibration_Table
> > >
> > > You don't show the flash erase for each segment; at a guess I'd
say
> > > that you don't erase them, and therefore you are overloading
prior
> > > data with new data. You can only set each bit in flash from
a '1'
> > to
> > > a '0', and you can't even do that properly if you don't observe
the
> > > cumulative write time. If you want to write the entire array at
> > > Measurements[] you have to first erase every flash segment
which is
> > > used by Measurements[]. Each flash segment is 512 bytes in
length.
> > TI
> > > cover this in great detail in various application notes and
user
> > manuals.
> > >
> > > Hugh
> > >
> > > At 08:56 AM 9/8/2008, you wrote:
> > >
> > > Greetings,
> > >
> > > I am trying to write a look-up table to flash in an
MSP430F4616.  
> > The
> > > clock is 1Mhz and the FCTL2 register is the default value which
> > gives
> > > about 333khz flash clock.
> > >
> > > I have a 4096 word table and a table of data pairs (adc value &
> > > distance)  that is about half that large. When I fill my table
from
> > > TABLE[0] to TABLE[4095] with the numbers 0 to 4095 (see code
below)
> > it
> > > works perfectly. When I try to fill it with the real data it
works
> > fine
> > > for about a third of the data then it starts skipping some
values.
> > At
> > > about half-way it really gets bad. I don't recognize some of
what's
> > > written.
> > >
> > > This has got me baffled. Why would it fill correctly for one
loop

> > and
> > > not the other?
> > >
> > > Any insight or suggestions would be appreciated.
> > >
> > > Edd
> > >
> > > The code which is commented out works. The other doesn't.
> > >
> > > CODE:
> > >
> > > void Load_Test_Calibration(void)
> > > {
> > >    uint16 i;
> > >
> > >    Set_Calibration_Mode(Calibrating);  //erases flash
> > >
> > >             //for (i=0; i<4096; i++)
> > >             for (i=0; i<2002; i++)
> > >             {
> > >
> > >              if(Measurements[i] == 0xFFFF)
> > >      {
> > >     Flash_Write_Word((int16*) &(Measurements
[Test_Calibration_Data
> > [i]]),
> > > Test_Calibration_Data[i+1]);
> > >
> > >                                        //Flash_Write_Word
((int16*)

> > > &(Measurements[i]), i);
> > >
> > >                       }
> > >               }
> > >
> > >    //Set_Calibration_Mode(Idle);
> > > } // end Test_Calibration
> > >
> > > #pragma location = 0x4000
> > > const uint16 Measurements
> > [MEASUREMENT_TABLE_LENGTH];                //
> > > =4096
> > >
> > > #pragma location = 0x6000
> > > const uint16 Test_Calibration_Data[] = {
> > > 3453,0,
> > > 3449,1,
> > > 3447,2,
> > > 3444,3,
> > > 3441,4,...................etc.    // less than 4096
> > >
> > >
> > > void Flash_Write_Word(int16 *data_pointer, int16 word)
> > > {
> > >    FCTL3 = FWKEY; // Clear LOCK
> > >    FCTL1 = FWKEY + WRT; // Enable WRITE
> > >
> > >    *data_pointer = word; // program Flash word
> > >
> > >    FCTL1 = FWKEY; // Clear WRITE
> > >    FCTL3 = FWKEY + LOCK; // Set LOCK
> > > }
> > >
> > > FCTL2 is the reset value which, for a 1mhz clock should give
~333khz
> > > flash clock.
> > >
> >
>



Re: Intermittent flash word writes

by e.tury :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Boy, talk about being brain dead. Thanks so much.
I need to bump "i" a second time after the write to keep it aligned.


--- In msp430@..., "old_cow_yellow" <old_cow_yellow@...>
wrote:
>
> The problem is the way you stored the Test_Calibration_Data[] and
the

> way you wrote them are inconsistent.
>
> You have:
> > const uint16 Test_Calibration_Data[] = {
> > 3453,0,
> > 3449,1,
> > 3447,2,
> > 3444,3,
> > 3441,4,...................etc.
>
> And you try to do:
> > Flash_Write_Word(
> >   (int16*) &(Measurements[Test_Calibration_Data[i]]),
> >   Test_Calibration_Data[i+1]
> > );
>
> Thus:
> when i=0, you wrote 0 to 3453
> when i=1, you wrote 3449 to 0
> when i=2, you wr0te 1 to 3449
> when i=3, you wrote 3447 to 1
> ... etc.
>
> You could have destroyed the program itself or changed contents of
> registers and RAM. Consider yourself lucky!
>
> --- In msp430@..., "e.tury" <e.tury@> wrote:
> >
> >
> > Greetings,
> >
> > I am trying to write a look-up table to flash in an MSP430F4616.  
The
> > clock is 1Mhz and the FCTL2 register is the default value which
gives
> > about 333khz flash clock.
> >
> > I have a 4096 word table and a table of data pairs (adc value &
> > distance)  that is about half that large. When I fill my table
from
> > TABLE[0] to TABLE[4095] with the numbers 0 to 4095 (see code
below) it
> > works perfectly. When I try to fill it with the real data it
works fine
> > for about a third of the data then it starts skipping some
values. At
> > about half-way it really gets bad. I don't recognize some of
what's
> > written.
> >
> > This has got me baffled. Why would it fill correctly for one loop
and

> > not the other?
> >
> > Any insight or suggestions would be appreciated.
> >
> > Edd
> >
> > The code which is commented out works. The other doesn't.
> >
> > CODE:
> >
> > void Load_Test_Calibration(void)
> > {
> >   uint16 i;
> >
> >   Set_Calibration_Mode(Calibrating);  //erases flash
> >
> >            //for (i=0; i<4096; i++)
> >            for (i=0; i<2002; i++)
> >            {
> >
> >             if(Measurements[i] == 0xFFFF)
> >     {
> >    Flash_Write_Word((int16*) &(Measurements[Test_Calibration_Data
[i]]),

> > Test_Calibration_Data[i+1]);
> >
> >                                       //Flash_Write_Word((int16*)
> > &(Measurements[i]), i);
> >
> >                      }
> >              }
> >
> >   //Set_Calibration_Mode(Idle);
> > } // end Test_Calibration
> >
> > #pragma location = 0x4000
> > const uint16 Measurements
[MEASUREMENT_TABLE_LENGTH];                //

> > =4096
> >
> > #pragma location = 0x6000
> > const uint16 Test_Calibration_Data[] = {
> > 3453,0,
> > 3449,1,
> > 3447,2,
> > 3444,3,
> > 3441,4,...................etc.    // less than 4096
> >
> >
> > void Flash_Write_Word(int16 *data_pointer, int16 word)
> > {
> >   FCTL3 = FWKEY; // Clear LOCK
> >   FCTL1 = FWKEY + WRT; // Enable WRITE
> >
> >   *data_pointer = word; // program Flash word
> >
> >   FCTL1 = FWKEY; // Clear WRITE
> >   FCTL3 = FWKEY + LOCK; // Set LOCK
> > }
> >
> > FCTL2 is the reset value which, for a 1mhz clock should give
~333khz
> > flash clock.
> >
>


LightInTheBox - Buy quality products at wholesale price!