|
View:
New views
7 Messages
—
Rating Filter:
Alert me
|
|
|
Intermittent flash word writesGreetings, 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 writesThe 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 writesYou 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 writesThe 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 > 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 > =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 writesWrong 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?
--- 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 > > > 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 > > [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 > > > flash clock. > > > > > > |
|
|
Re: Intermittent flash word writesBoy, 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. > > 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 > > 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 > > =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 > > flash clock. > > > |
| Free Forum Powered by Nabble | Forum Help |