Sign in

username:

password:



Not a member?

Search msp430



Search tips

Subscribe to msp430



Ads

Discussion Groups

Discussion Groups | MSP430 | Intermittent flash word writes

The purpose of this group is to foster exchange of information on the Texas Instruments MSP430 family of microcontrollers and related tools. Everyone welcome, all levels of familiarity/expertise.

Intermittent flash word writes - "e.tury" - Sep 8 11:56:35 2008


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.

------------------------------------



(You need to be a member of msp430 -- send a blank email to msp430-subscribe@yahoogroups.com )


Re: Intermittent flash word writes - old_cow_yellow - Sep 8 12:50:48 2008

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 m...@yahoogroups.com, "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.
>

------------------------------------



(You need to be a member of msp430 -- send a blank email to msp430-subscribe@yahoogroups.com )

Re: Intermittent flash word writes - Hugh Molesworth - Sep 8 12:51:40 2008

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.

------------------------------------



(You need to be a member of msp430 -- send a blank email to msp430-subscribe@yahoogroups.com )

Re: Intermittent flash word writes - "e.tury" - Sep 8 13:20:32 2008

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.
>

------------------------------------



(You need to be a member of msp430 -- send a blank email to msp430-subscribe@yahoogroups.com )

Re: Intermittent flash word writes - old_cow_yellow - Sep 8 13:38:08 2008

Wrong tree.

--- In m...@yahoogroups.com, "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.
>
------------------------------------



(You need to be a member of msp430 -- send a blank email to msp430-subscribe@yahoogroups.com )

Re: Intermittent flash word writes - "e.tury" - Sep 8 14:05:45 2008

?

--- In m...@yahoogroups.com, "old_cow_yellow"
wrote:
>
> Wrong tree.
>
> --- In m...@yahoogroups.com, "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.
> > >
>
------------------------------------



(You need to be a member of msp430 -- send a blank email to msp430-subscribe@yahoogroups.com )

Re: Intermittent flash word writes - "e.tury" - Sep 8 14:27:57 2008

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 m...@yahoogroups.com, "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 m...@yahoogroups.com, "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.
>
------------------------------------



(You need to be a member of msp430 -- send a blank email to msp430-subscribe@yahoogroups.com )