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 "sprintf.h"
#include "string.h"
#include "inttypes.h"
#include "eeprom_24cxx.h"
@ -57,6 +58,10 @@
/* delay loop to achieve 400kHz at 120MHz CPU frequency */
#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)
{
logf("sw_i2c_init");
@ -280,8 +285,12 @@ int sw_i2c_read(unsigned char location, unsigned char* byte)
void eeprom_24cxx_init(void)
{
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 ret;
@ -294,6 +303,14 @@ int eeprom_24cxx_read_byte(unsigned int address, char *c)
return -9;
}
/* Check from cache. */
if (IS_CACHED(address))
{
logf("EEPROM RCached: %d", address);
*c = data_cache[address];
return 0;
}
*c = 0;
do
{
@ -311,7 +328,11 @@ int eeprom_24cxx_read_byte(unsigned int address, char *c)
/* keep between {} as logf is whitespace in normal builds */
logf("EEPROM rOK: %d retries", count);
}
/* Cache the byte. */
data_cache[address] = byte;
SET_CACHED(address);
*c = byte;
return 0;
}
@ -327,6 +348,13 @@ int eeprom_24cxx_write_byte(unsigned int address, char c)
return -9;
}
/* Check from cache. */
if (IS_CACHED(address) && data_cache[address] == c)
{
logf("EEPROM WCached: %d", address);
return 0;
}
do
{
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);
}
SET_CACHED(address);
data_cache[address] = c;
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)
{
const char *buf = (const char *)src;
int count = 5;
int i;
bool ok;
while (count-- > 0)
for (i = 0; i < length; i++)
{
for (i = 0; i < length; i++)
eeprom_24cxx_write_byte(address+i, buf[i]);
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;
if (eeprom_24cxx_write_byte(address+i, buf[i]) < 0)
return -1;
}
return -1;
return 0;
}