From f14f59f9f387964687fda05b3881a090fb7d713d Mon Sep 17 00:00:00 2001 From: Miika Pekkarinen Date: Sun, 26 Nov 2006 14:40:47 +0000 Subject: [PATCH] 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 --- firmware/drivers/eeprom_24cxx.c | 60 ++++++++++++++++++++------------- 1 file changed, 36 insertions(+), 24 deletions(-) diff --git a/firmware/drivers/eeprom_24cxx.c b/firmware/drivers/eeprom_24cxx.c index e045a13fa6..20ad1dfebe 100644 --- a/firmware/drivers/eeprom_24cxx.c +++ b/firmware/drivers/eeprom_24cxx.c @@ -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; }