Data cache for the EEPROM driver to speed up reading/writing. This

will be my last iriver commit for a while due to a bricked H140.


git-svn-id: svn://svn.rockbox.org/rockbox/trunk@11602 a1c6a512-1295-4272-9138-f99709370657
This commit is contained in:
Miika Pekkarinen 2006-11-26 14:40:47 +00:00
parent 11e2e565ca
commit f14f59f9f3

View file

@ -25,6 +25,7 @@
#include "logf.h" #include "logf.h"
#include "sprintf.h" #include "sprintf.h"
#include "string.h" #include "string.h"
#include "inttypes.h"
#include "eeprom_24cxx.h" #include "eeprom_24cxx.h"
@ -57,6 +58,10 @@
/* delay loop to achieve 400kHz at 120MHz CPU frequency */ /* delay loop to achieve 400kHz at 120MHz CPU frequency */
#define DELAY do { int _x; for(_x=0;_x<22;_x++);} while(0) #define DELAY do { int _x; for(_x=0;_x<22;_x++);} while(0)
/* Use cache to speedup writing to the chip. */
static char data_cache[EEPROM_SIZE];
static uint8_t cached_bitfield[EEPROM_SIZE/8];
static void sw_i2c_init(void) static void sw_i2c_init(void)
{ {
logf("sw_i2c_init"); logf("sw_i2c_init");
@ -280,8 +285,12 @@ int sw_i2c_read(unsigned char location, unsigned char* byte)
void eeprom_24cxx_init(void) void eeprom_24cxx_init(void)
{ {
sw_i2c_init(); sw_i2c_init();
memset(cached_bitfield, 0, sizeof cached_bitfield);
} }
#define IS_CACHED(addr) (cached_bitfield[addr/8] & (1 << (addr % 8)))
#define SET_CACHED(addr) (cached_bitfield[addr/8] |= 1 << (addr % 8))
int eeprom_24cxx_read_byte(unsigned int address, char *c) int eeprom_24cxx_read_byte(unsigned int address, char *c)
{ {
int ret; int ret;
@ -294,6 +303,14 @@ int eeprom_24cxx_read_byte(unsigned int address, char *c)
return -9; return -9;
} }
/* Check from cache. */
if (IS_CACHED(address))
{
logf("EEPROM RCached: %d", address);
*c = data_cache[address];
return 0;
}
*c = 0; *c = 0;
do do
{ {
@ -311,7 +328,11 @@ int eeprom_24cxx_read_byte(unsigned int address, char *c)
/* keep between {} as logf is whitespace in normal builds */ /* keep between {} as logf is whitespace in normal builds */
logf("EEPROM rOK: %d retries", count); logf("EEPROM rOK: %d retries", count);
} }
/* Cache the byte. */
data_cache[address] = byte;
SET_CACHED(address);
*c = byte; *c = byte;
return 0; return 0;
} }
@ -327,6 +348,13 @@ int eeprom_24cxx_write_byte(unsigned int address, char c)
return -9; return -9;
} }
/* Check from cache. */
if (IS_CACHED(address) && data_cache[address] == c)
{
logf("EEPROM WCached: %d", address);
return 0;
}
do do
{ {
ret = sw_i2c_write_byte(address, c); ret = sw_i2c_write_byte(address, c);
@ -344,6 +372,9 @@ int eeprom_24cxx_write_byte(unsigned int address, char c)
logf("EEPROM wOK: %d retries", count); logf("EEPROM wOK: %d retries", count);
} }
SET_CACHED(address);
data_cache[address] = c;
return 0; return 0;
} }
@ -366,33 +397,14 @@ int eeprom_24cxx_read(unsigned char address, void *dest, int length)
int eeprom_24cxx_write(unsigned char address, const void *src, int length) int eeprom_24cxx_write(unsigned char address, const void *src, int length)
{ {
const char *buf = (const char *)src; const char *buf = (const char *)src;
int count = 5;
int i; int i;
bool ok;
while (count-- > 0) for (i = 0; i < length; i++)
{ {
for (i = 0; i < length; i++) if (eeprom_24cxx_write_byte(address+i, buf[i]) < 0)
eeprom_24cxx_write_byte(address+i, buf[i]); return -1;
ok = true;
for (i = 0; i < length; i++)
{
char byte;
eeprom_24cxx_read_byte(address+i, &byte);
if (byte != buf[i])
{
logf("Verify failed: %d/%d", address+i, count);
ok = false;
break;
}
}
if (ok)
return 0;
} }
return -1; return 0;
} }