View previous topic :: View next topic |
Author |
Message |
Guest
|
read default eeprom values |
Posted: Mon Nov 16, 2009 7:41 am |
|
|
Hey all, I'm trying to compare a freshly programmed eeprom value as a floating point variable to see whether or not it's the first run since being programmed. I'm using this function to read floating point values from eeprom:
Code: |
float read_float_from_eeprom(int8 addr)
{
int8 i;
float data;
for(i = 0; i < 4; i++)
*((int8*)&data + i) = read_eeprom(addr + i);
return(data);
}
|
In mplab, I see that the default value for the entire eeprom is all F's.
I've tried doing the following:
Code: |
float = read_float_from_eeprom(0);
if (float == 0xFF)
{ do something useful }
if (float == 0xFFFF)
{ do something useful }
|
and neither worked. Any suggestions?
Thanks |
|
|
Wayne_
Joined: 10 Oct 2007 Posts: 681
|
|
Posted: Mon Nov 16, 2009 8:19 am |
|
|
You could try
f = read_float_from_eeprom(0);
if (f == (float)0xFFFFFFFF)
DO NOT USE float as a var name. It is a defined type and CCS is NOT case sensitive. |
|
|
Ttelmah Guest
|
|
Posted: Mon Nov 16, 2009 8:20 am |
|
|
The individual _bytes_ are 0xFF. The float won't be.
I don't think you can actually generate the float that this represents easily (it is one of the very few 'impossible' values, with an exponent of 80, and a -ve sign, and all the bits in the mantissa set. It has an exponent one larger than the maximum normally supported. The best way to test it is as the bytes when you retrieve them. If all four are 0xFF then the ROM is empty.
If you 'must' do it on the float, declare a union, between the float, and an int32. If this is 4294967295, or 0xFFFFFFFF, then you have your invalid value.
Best Wishes |
|
|
Ttelmah Guest
|
|
Posted: Mon Nov 16, 2009 10:59 am |
|
|
To the other reply, no. Using a cast, converts the value to the type, but not on a bit by bit basis, it converts the number to the nearest representation in the other type. Casting 0xFFFFFFFF to a float, will result in the 'float' byte pattern 9F000000, which is the 'float' representation of 4.2949673E9 (which is what 0xFFFFFFFF evaluates to as a decimal value).
You won't get a match from this....
Best Wishes |
|
|
Wayne_
Joined: 10 Oct 2007 Posts: 681
|
|
Posted: Mon Nov 16, 2009 11:13 am |
|
|
Ttelmah wrote: | To the other reply, no. Using a cast, converts the value to the type, but not on a bit by bit basis, it converts the number to the nearest representation in the other type. Casting 0xFFFFFFFF to a float, will result in the 'float' byte pattern 9F000000, which is the 'float' representation of 4.2949673E9 (which is what 0xFFFFFFFF evaluates to as a decimal value).
You won't get a match from this....
Best Wishes |
I wasn't sure it would work. Thought he could have tried though. I wasn't going to
Wayne |
|
|
Guest
|
|
Posted: Mon Nov 16, 2009 2:17 pm |
|
|
Ok guys,
Thanks for all the replies.
I've tried:
Code: |
float foo = read_float_from_eeprom(0);
if (foo == 4294967295)
{ do stuff }
if (foo == 0xFFFFFFFF)
{ do stuff }
if (foo == (int32)0xFFFFFFFF)
{ do stuff }
|
all with no success :( |
|
|
Ttelmah Guest
|
|
Posted: Mon Nov 16, 2009 3:39 pm |
|
|
The point is that you have to use a union to convert the type.
So, something like:
Code: |
union {
int32 ival;
float fpval;
} val;
val.fpval=read_float_from_eeprom(0);
if (val.ival==0xFFFFFFFF) {
//do stuff here
}
|
Funnily, all bytes 'ff', I think represents the only 'impossible' float value in CCS format.
Best Wishes |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Mon Nov 16, 2009 3:52 pm |
|
|
I think conceptually, the simple way would be to read the 4 bytes as
an int32. If they're all 0xFF, then the eeprom location is blank.
Code: |
#include <18F452.h>
#fuses XT,NOWDT,PUT,BROWNOUT,NOLVP
#use delay(clock=4000000)
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7, ERRORS)
#include <24256.c>
#include <internal_eeprom.c>
//======================================
void main(void)
{
int8 eeprom_blank = TRUE;
if(read_int32_eeprom(0) == 0xFFFFFFFF)
eeprom_blank = TRUE;
else
eeprom_blank = FALSE;
// Do other stuff here.
while(1);
} |
|
|
|
bkamen
Joined: 07 Jan 2004 Posts: 1615 Location: Central Illinois, USA
|
|
Posted: Mon Nov 16, 2009 4:01 pm |
|
|
Also considering adding another number that could act as a "magic" number. I do that a lot. And I save my config info in a struct and then save the struct.
Code: |
struct config_map {
float f_num;
int8 magic;
} config;
enum loadsave {save, load, reset};
// ============================================
// 0 = write
// 1 = read
void config_loadsave ( int mode ) {
unsigned int i;
for ( i=0 ; i < sizeof(config) ; i++ ) {
switch (rw) {
case load : *(((int8 *)&config) + i) = read_eeprom(i);
break;
case save : write_eeprom( i, *(((int8 *)&config) + i) );
break;
}
}
}
|
Now you can go back and add to the config.. just make sure there's no clashing with uninitialized data.. (I have another routine for that)
-Ben _________________ Dazed and confused? I don't think so. Just "plain lost" will do. :D |
|
|
Guest
|
|
Posted: Tue Nov 17, 2009 7:40 am |
|
|
Again, thanks for all the replies guys, I simply used a 'magic bit' as someone said at address 0 in the eeprom to tell whether or not it was freshly programmed or not, rather than trying to compare against the union....seemed a little hackish. But I definitely learned something in the process... |
|
|
|