Just a Question:
It is a little difficult to get a picture of external EEPROM (24 or 25 Type, SPI or I2C) drivers. I found the following examples:
https://github.com/ChibiOS/ChibiOS-Contrib/tree/master/testhal/STM32/STM32F3xx/EEProm
https://github.com/timonwong/ChibiOS-EEPROM
https://github.com/barthess/24aa
and there is also some code in trunk/os/ex.
What i need: A possibility to store configuration data (structs) in a non-volatile storage. For now i have an external RTC (DS2331) with a 24C32 EEPROM on-board: https://www.ebay.de/itm/272449019914 and i want to use it.
Some guidance please.
Thank you.
Q: Status of external EEPROM Support
Moderators: RoccoMarco, lbednarz, utzig, tfAteba, barthess
- Giovanni
- Site Admin
- Posts: 14457
- Joined: Wed May 27, 2009 8:48 am
- Location: Salerno, Italy
- Has thanked: 1076 times
- Been thanked: 922 times
- Contact:
Re: Q: Status of external EEPROM Support
Hi,
There is no official EEPROM driver, what we have is a Flash driver and a "Managed Storage" module. All the links you found are external contributions and have to be discussed with authors.
Giovanni
There is no official EEPROM driver, what we have is a Flash driver and a "Managed Storage" module. All the links you found are external contributions and have to be discussed with authors.
Giovanni
Re: Q: Status of external EEPROM Support
Thank you for your reply. Quick as always
Did you mean the discussion here: http://www.chibios.com/forum/viewtopic.php?t=3320 ?
I think this is the code in trunk/os/ex right?
Can i use this for I2C EEPROM 24c32?
I know this is not really Chibios Support, it would just be nice to have some directions here and maybe some examples.
best regards,
robert.
Did you mean the discussion here: http://www.chibios.com/forum/viewtopic.php?t=3320 ?
I think this is the code in trunk/os/ex right?
Can i use this for I2C EEPROM 24c32?
I know this is not really Chibios Support, it would just be nice to have some directions here and maybe some examples.
best regards,
robert.
- Giovanni
- Site Admin
- Posts: 14457
- Joined: Wed May 27, 2009 8:48 am
- Location: Salerno, Italy
- Has thanked: 1076 times
- Been thanked: 922 times
- Contact:
Re: Q: Status of external EEPROM Support
Hi,
That is a flash driver, EEPROM has different requirements, there are no sectors, erase operation etc.
Giovanni
That is a flash driver, EEPROM has different requirements, there are no sectors, erase operation etc.
Giovanni
Re: Q: Status of external EEPROM Support
Thank you, mobyfab.
I actually did exactliy that and i now have the driver patially working but still have some questions.
First: this is my code for writing my variabls to eeprom:
i made a struct with arrays of pointer to whatever and sizes of the array elements:
the three pointers point to the following:
And this are the values:
my Questions:
Thats all for now.
When i manage to finish the eprom read i will post the code on bitbucket:
https://bitbucket.org/100prozent/rob-rt-stm32f100-discovery-shell-eeprom/src/default/
I actually did exactliy that and i now have the driver patially working but still have some questions.
First: this is my code for writing my variabls to eeprom:
i made a struct with arrays of pointer to whatever and sizes of the array elements:
Code: Select all
typedef struct {
void* ptr[3];
uint16_t sz[3];
} eeprom_data_t;
the three pointers point to the following:
Code: Select all
#define LENGTH 11
typedef struct{
float in[LENGTH]; // Array of x-coordinates
float out[LENGTH]; // Array of y-coordinates
uint8_t t_length; // Number of data points
} table_1d_t ;
typedef struct {
uint8_t screen; // screen
uint8_t bl; // backlight
uint8_t con; // contrast
} DisplayData_t;
typedef struct {
float corr_mult; // ADC Factors
int16_t corr_add;
uint8_t principle;
} correction_t;
And this are the values:
Code: Select all
correction_t corr_val[6] = {
{1.2, 0, 1},
{1.5, 0, 1},
{0.876, 0, 1},
{1.0, 0, 3},
{1.9, 0, 2},
{0.5, 12, 3}
};
table_1d_t tables[4] = {
{
{0, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1.0}, //in
{1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0}, //out
11 //length
},
{
{0, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1.0}, //in
{1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0}, //out
11 //length
},
{
{0, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1.0}, //in
{1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0}, //out
11, //length
},
{
{0, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1.0}, //in
{1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0}, //out
11 //length
}
};
DisplayData_t DisplayData = {
0, //screen
127, //backlight
50 //contrast
};
eeprom_data_t ee_data = {
{tables, &DisplayData, corr_val}, //pointers to structs, array of structs,...
{sizeof(table_1d_t)*4, sizeof(DisplayData_t), sizeof(correction_t)*6} //sizes
};
Code: Select all
void cmd_dumpvar(BaseSequentialStream *chp, int argc, char *argv[]){
(void)argc;
(void)* argv;
uint16_t sz, bs, szc;
uint16_t i, idx, adr;
int16_t pos;
uint8_t* p;
uint8_t* b;
uint8_t buf[EEPROM_PAGE_SIZE];
uint8_t temp;
b=buf;
chprintf(chp, "Dumps Struct Variable\r\n");
sz = sizeof(ee_data.ptr)/sizeof(void*); //How many pointers are there
chprintf(chp, "Pointers: %d\r\n", sz);
szc = 0; //reset total size
adr = EEPROM_SETTINGS_START; //set start address
pos = eepfs_lseek(&EepromFile, adr);
if (pos != eepfs_getposition(&EepromFile)){
chprintf(chp, "EEPROM fseek Error\r\n");
return;
}
for (idx = 0; idx<sz; idx++){ //go through all the pointers
bs = ee_data.sz[idx]; //size of this data
szc += bs;
chprintf(chp, "size of ptr: %d\r\n", bs);
}
chprintf(chp, "size complete: %d\r\n", szc);
chprintf(chp, "%d pages\r\n", szc/EEPROM_PAGE_SIZE);
chprintf(chp, "%d rest\r\n", szc%EEPROM_PAGE_SIZE);
if (szc > EEPROM_SETTINGS_SIZE){
chprintf(chp, "size too big for eeprom!\r\n");
return;
}
idx = 0;
bs = ee_data.sz[idx]; //reusing variable
p=(uint8_t*)ee_data.ptr[idx]; //move pointer to first data bloc
for (i=0; i<szc; i++){ //go through ALL the bytes
if (i >= bs){ //we are at the end of one bloc
chprintf(chp, "old val: %x\r\n", temp);
p=(uint8_t*)ee_data.ptr[idx++]; //move pointer to next data bloc
bs += ee_data.sz[idx]; //calculate next boundary
chprintf(chp, "next bloc: %d\r\n", i);
chprintf(chp, "new val: %x\r\n", *p);
}
if ((i % EEPROM_PAGE_SIZE == 0) && (i>0)){ //if buffer is full...
fileStreamWrite(&EepromFile, buf, EEPROM_PAGE_SIZE);
b=buf; //reset buffer
chThdSleepMilliseconds(100);
chprintf(chp, "Page written\r\n");
adr += EEPROM_PAGE_SIZE; //next page
pos = eepfs_lseek(&EepromFile, adr);
if (pos != eepfs_getposition(&EepromFile)){
chprintf(chp, "EEPROM fseek Error\r\n");
return;
}
}
if (i%8 == 0){ //beautyfy the output a little
cli_println("");
}
chprintf(chp, "%x ", *p); //print val
*b = *p; //copy to buffer
temp = *p;
b++;
p++;
}
cli_println("");
if (szc > adr){
chprintf(chp, "More Data to write, szc: %d, adr: %d, pos: %d\r\n", szc, adr, eepfs_getposition(&EepromFile));
}
fileStreamWrite(&EepromFile, buf, (szc-adr));
for (i=0;i<szc-adr; i++){
chprintf(chp, "%x ", buf[i]); //print val
}
cli_println("");
}
my Questions:
- do i have to take care of the time the eprom needs to write or can i dump the whole buffer to fileStreamWrite?
do i have to read first and compare to avoid uneccessary writes or does the driver do that?
is fileStreamWrite the correct function to write many bytes and do i have to take care of the page size?
Thats all for now.
When i manage to finish the eprom read i will post the code on bitbucket:
https://bitbucket.org/100prozent/rob-rt-stm32f100-discovery-shell-eeprom/src/default/
-
- Posts: 483
- Joined: Sat Nov 19, 2011 6:47 pm
- Location: Le Mans, France
- Has thanked: 21 times
- Been thanked: 30 times
Re: Q: Status of external EEPROM Support
You should replicate what's in the demo.
You need to use SPIEepromFileOpen or I2CEepromFileOpen provided with the configs including eeprom size, page write time, etc. That way you can write any size of data directly.
You have to compare what you want to write, the driver does not check that.
fileStreamWrite works fine.
You need to use SPIEepromFileOpen or I2CEepromFileOpen provided with the configs including eeprom size, page write time, etc. That way you can write any size of data directly.
You have to compare what you want to write, the driver does not check that.
fileStreamWrite works fine.
Re: Q: Status of external EEPROM Support
Thank you, the driver works fine. The demo is unfortunately for a SPI EPROM but i figured out how to use it.
To reduce the write occurences i could read one bloc into RAM, compare byte by byte and write only the different ones, would you agree?
The bitbucket link contains my code for writing a configuration and reading it back.
I have implemented:
-data is saved by pointing to the data set and supplying the size (see my last post for the struct)
-easy to maintain, no counting bytes no unions, no taking care of byte order,...
-doesn't matter if the struct is packed or not
-implemented checksum and version
todo:
-read back data and change only different ones
-better checksum algorithm
-more testing
when i am finished i will post in user projects.
Thank you all for your help and for an amazing operating system.
best regards,
robert
To reduce the write occurences i could read one bloc into RAM, compare byte by byte and write only the different ones, would you agree?
The bitbucket link contains my code for writing a configuration and reading it back.
I have implemented:
-data is saved by pointing to the data set and supplying the size (see my last post for the struct)
-easy to maintain, no counting bytes no unions, no taking care of byte order,...
-doesn't matter if the struct is packed or not
-implemented checksum and version
todo:
-read back data and change only different ones
-better checksum algorithm
-more testing
when i am finished i will post in user projects.
Thank you all for your help and for an amazing operating system.
best regards,
robert
Re: Q: Status of external EEPROM Support
Hello robert_o.
You can adapt any Arduino Driver to use in ChibiOS , just change Arduino SPI driver (I2C or whatever Interface) calls to ChibiOS HAL driver calls. EEPROM is volatile memory which will not erase after power cycle. Unlike Flash EEPROM has more small blocks which you can modify (8 bit , 16 bit , 32 bit blocks size, dephends on manufacturer and EEPROM type, see in Datasheet). Each block has its Address. Each EEPROM chip has communication Interface via specific Interface(SPI, I2C and so on). If you want to write Struct or any C type of data (float, int32_t, char and so on including arrays), you just need to reference on this types like on arrays of memory and send them byte by byte or few bytes if block size is more than 8 bit. for example if you want to send float variable to EEPROM for storage, you can do so like this:
same about data structs:
You can adapt any Arduino Driver to use in ChibiOS , just change Arduino SPI driver (I2C or whatever Interface) calls to ChibiOS HAL driver calls. EEPROM is volatile memory which will not erase after power cycle. Unlike Flash EEPROM has more small blocks which you can modify (8 bit , 16 bit , 32 bit blocks size, dephends on manufacturer and EEPROM type, see in Datasheet). Each block has its Address. Each EEPROM chip has communication Interface via specific Interface(SPI, I2C and so on). If you want to write Struct or any C type of data (float, int32_t, char and so on including arrays), you just need to reference on this types like on arrays of memory and send them byte by byte or few bytes if block size is more than 8 bit. for example if you want to send float variable to EEPROM for storage, you can do so like this:
Code: Select all
float my_var = 3.14; //32 bit float
EEPROM_Write(0, (uint8_t *)my_var, sizeof(my_var)) //EEPROM library function takes address, reference of memory and memory size in bytes
same about data structs:
Code: Select all
struct MyCostomStruct my_struct; //32 bit float
EEPROM_Write(20, (uint8_t *)my_struct, sizeof(my_struct)) //EEPROM library function takes address, reference of memory and memory size in bytes
-
- Posts: 483
- Joined: Sat Nov 19, 2011 6:47 pm
- Location: Le Mans, France
- Has thanked: 21 times
- Been thanked: 30 times
Re: Q: Status of external EEPROM Support
robert_o wrote:Thank you, the driver works fine. The demo is unfortunately for a SPI EPROM but i figured out how to use it.
To reduce the write occurences i could read one bloc into RAM, compare byte by byte and write only the different ones, would you agree?
The bitbucket link contains my code for writing a configuration and reading it back.
I have implemented:
-data is saved by pointing to the data set and supplying the size (see my last post for the struct)
-easy to maintain, no counting bytes no unions, no taking care of byte order,...
-doesn't matter if the struct is packed or not
-implemented checksum and version
todo:
-read back data and change only different ones
-better checksum algorithm
-more testing
when i am finished i will post in user projects.
Thank you all for your help and for an amazing operating system.
best regards,
robert
You can check my code here: https://github.com/fpoussin/MotoLink/bl ... /storage.c
I use the STM32's hardware CRC and implemented wear leveling for "table" (arrays) functions. ("writeTablesToEE", "readTablesFromEE", etc)
You can do a simple function to read data and compare before writing.
Byte by byte might be slower but you will have less writes than page by page.
Who is online
Users browsing this forum: No registered users and 37 guests