diff options
author | Miika Pekkarinen <miipekk@ihme.org> | 2006-11-26 14:40:47 +0000 |
---|---|---|
committer | Miika Pekkarinen <miipekk@ihme.org> | 2006-11-26 14:40:47 +0000 |
commit | f14f59f9f387964687fda05b3881a090fb7d713d (patch) | |
tree | 2aac54f0b333430e003965341962651e3dc8b821 /firmware | |
parent | 11e2e565ca65e9555bcc19ddb256775e9e911edb (diff) | |
download | rockbox-f14f59f9f387964687fda05b3881a090fb7d713d.tar.gz rockbox-f14f59f9f387964687fda05b3881a090fb7d713d.zip |
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
Diffstat (limited to 'firmware')
-rw-r--r-- | firmware/drivers/eeprom_24cxx.c | 60 |
1 files 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 @@ | |||
25 | #include "logf.h" | 25 | #include "logf.h" |
26 | #include "sprintf.h" | 26 | #include "sprintf.h" |
27 | #include "string.h" | 27 | #include "string.h" |
28 | #include "inttypes.h" | ||
28 | 29 | ||
29 | #include "eeprom_24cxx.h" | 30 | #include "eeprom_24cxx.h" |
30 | 31 | ||
@@ -57,6 +58,10 @@ | |||
57 | /* delay loop to achieve 400kHz at 120MHz CPU frequency */ | 58 | /* delay loop to achieve 400kHz at 120MHz CPU frequency */ |
58 | #define DELAY do { int _x; for(_x=0;_x<22;_x++);} while(0) | 59 | #define DELAY do { int _x; for(_x=0;_x<22;_x++);} while(0) |
59 | 60 | ||
61 | /* Use cache to speedup writing to the chip. */ | ||
62 | static char data_cache[EEPROM_SIZE]; | ||
63 | static uint8_t cached_bitfield[EEPROM_SIZE/8]; | ||
64 | |||
60 | static void sw_i2c_init(void) | 65 | static void sw_i2c_init(void) |
61 | { | 66 | { |
62 | logf("sw_i2c_init"); | 67 | logf("sw_i2c_init"); |
@@ -280,8 +285,12 @@ int sw_i2c_read(unsigned char location, unsigned char* byte) | |||
280 | void eeprom_24cxx_init(void) | 285 | void eeprom_24cxx_init(void) |
281 | { | 286 | { |
282 | sw_i2c_init(); | 287 | sw_i2c_init(); |
288 | memset(cached_bitfield, 0, sizeof cached_bitfield); | ||
283 | } | 289 | } |
284 | 290 | ||
291 | #define IS_CACHED(addr) (cached_bitfield[addr/8] & (1 << (addr % 8))) | ||
292 | #define SET_CACHED(addr) (cached_bitfield[addr/8] |= 1 << (addr % 8)) | ||
293 | |||
285 | int eeprom_24cxx_read_byte(unsigned int address, char *c) | 294 | int eeprom_24cxx_read_byte(unsigned int address, char *c) |
286 | { | 295 | { |
287 | int ret; | 296 | int ret; |
@@ -294,6 +303,14 @@ int eeprom_24cxx_read_byte(unsigned int address, char *c) | |||
294 | return -9; | 303 | return -9; |
295 | } | 304 | } |
296 | 305 | ||
306 | /* Check from cache. */ | ||
307 | if (IS_CACHED(address)) | ||
308 | { | ||
309 | logf("EEPROM RCached: %d", address); | ||
310 | *c = data_cache[address]; | ||
311 | return 0; | ||
312 | } | ||
313 | |||
297 | *c = 0; | 314 | *c = 0; |
298 | do | 315 | do |
299 | { | 316 | { |
@@ -311,7 +328,11 @@ int eeprom_24cxx_read_byte(unsigned int address, char *c) | |||
311 | /* keep between {} as logf is whitespace in normal builds */ | 328 | /* keep between {} as logf is whitespace in normal builds */ |
312 | logf("EEPROM rOK: %d retries", count); | 329 | logf("EEPROM rOK: %d retries", count); |
313 | } | 330 | } |
314 | 331 | ||
332 | /* Cache the byte. */ | ||
333 | data_cache[address] = byte; | ||
334 | SET_CACHED(address); | ||
335 | |||
315 | *c = byte; | 336 | *c = byte; |
316 | return 0; | 337 | return 0; |
317 | } | 338 | } |
@@ -327,6 +348,13 @@ int eeprom_24cxx_write_byte(unsigned int address, char c) | |||
327 | return -9; | 348 | return -9; |
328 | } | 349 | } |
329 | 350 | ||
351 | /* Check from cache. */ | ||
352 | if (IS_CACHED(address) && data_cache[address] == c) | ||
353 | { | ||
354 | logf("EEPROM WCached: %d", address); | ||
355 | return 0; | ||
356 | } | ||
357 | |||
330 | do | 358 | do |
331 | { | 359 | { |
332 | ret = sw_i2c_write_byte(address, c); | 360 | ret = sw_i2c_write_byte(address, c); |
@@ -344,6 +372,9 @@ int eeprom_24cxx_write_byte(unsigned int address, char c) | |||
344 | logf("EEPROM wOK: %d retries", count); | 372 | logf("EEPROM wOK: %d retries", count); |
345 | } | 373 | } |
346 | 374 | ||
375 | SET_CACHED(address); | ||
376 | data_cache[address] = c; | ||
377 | |||
347 | return 0; | 378 | return 0; |
348 | } | 379 | } |
349 | 380 | ||
@@ -366,33 +397,14 @@ int eeprom_24cxx_read(unsigned char address, void *dest, int length) | |||
366 | int eeprom_24cxx_write(unsigned char address, const void *src, int length) | 397 | int eeprom_24cxx_write(unsigned char address, const void *src, int length) |
367 | { | 398 | { |
368 | const char *buf = (const char *)src; | 399 | const char *buf = (const char *)src; |
369 | int count = 5; | ||
370 | int i; | 400 | int i; |
371 | bool ok; | ||
372 | 401 | ||
373 | while (count-- > 0) | 402 | for (i = 0; i < length; i++) |
374 | { | 403 | { |
375 | for (i = 0; i < length; i++) | 404 | if (eeprom_24cxx_write_byte(address+i, buf[i]) < 0) |
376 | eeprom_24cxx_write_byte(address+i, buf[i]); | 405 | return -1; |
377 | |||
378 | ok = true; | ||
379 | for (i = 0; i < length; i++) | ||
380 | { | ||
381 | char byte; | ||
382 | |||
383 | eeprom_24cxx_read_byte(address+i, &byte); | ||
384 | if (byte != buf[i]) | ||
385 | { | ||
386 | logf("Verify failed: %d/%d", address+i, count); | ||
387 | ok = false; | ||
388 | break; | ||
389 | } | ||
390 | } | ||
391 | |||
392 | if (ok) | ||
393 | return 0; | ||
394 | } | 406 | } |
395 | 407 | ||
396 | return -1; | 408 | return 0; |
397 | } | 409 | } |
398 | 410 | ||