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 "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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue