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:
parent
11e2e565ca
commit
f14f59f9f3
1 changed files with 36 additions and 24 deletions
|
@ -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
|
||||
{
|
||||
|
@ -312,6 +329,10 @@ int eeprom_24cxx_read_byte(unsigned int address, char *c)
|
|||
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++)
|
||||
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 0;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue