From c4a59a290b81cae137f8b3c2b709c9c565701eb9 Mon Sep 17 00:00:00 2001 From: Peter D'Hoye Date: Tue, 15 Aug 2006 22:54:06 +0000 Subject: [PATCH] eeprom driver for the h3x0 series, cleaned up the h1x0 series driver a bit, added debug entry for h3x0 that allows to write to the eeprom git-svn-id: svn://svn.rockbox.org/rockbox/trunk@10597 a1c6a512-1295-4272-9138-f99709370657 --- apps/debug_menu.c | 60 ++++++++++++++++++++++++++++++--- apps/main.c | 8 ++--- apps/misc.c | 2 +- apps/tagcache.c | 8 ++--- apps/tree.c | 4 +-- bootloader/main.c | 10 +++--- firmware/SOURCES | 2 ++ firmware/drivers/eeprom_24cxx.c | 55 +++++++++++++++++------------- firmware/drivers/pcf50606.c | 12 +++---- firmware/export/config-h100.h | 2 +- firmware/export/config-h120.h | 3 ++ firmware/export/config-h300.h | 3 ++ firmware/export/eeprom_24cxx.h | 5 +++ firmware/export/pcf50606.h | 8 +++++ 14 files changed, 132 insertions(+), 50 deletions(-) diff --git a/apps/debug_menu.c b/apps/debug_menu.c index 0141c77fbe..1527e8abe7 100644 --- a/apps/debug_menu.c +++ b/apps/debug_menu.c @@ -1891,13 +1891,22 @@ bool dbg_save_roms(void) fd = creat("/internal_eeprom.bin", O_WRONLY); if (fd >= 0) { + int old_irq_level; char buf[EEPROM_SIZE]; - - if (eeprom_24cxx_read(0, buf, sizeof buf)) - gui_syncsplash(HZ*3, true, "Eeprom read failure!"); + int err; + + old_irq_level = set_irq_level(HIGHEST_IRQ_LEVEL); + + err = eeprom_24cxx_read(0, buf, sizeof buf); + if (err) + gui_syncsplash(HZ*3, true, "Eeprom read failure (%d)",err); else + { write(fd, buf, sizeof buf); - + } + + set_irq_level(old_irq_level); + close(fd); } #endif @@ -1976,6 +1985,46 @@ bool dbg_set_memory_guard(void) } #endif /* CONFIG_CPU == SH7034 || defined(CPU_COLDFIRE) */ +#if defined(HAVE_EEPROM) && !defined(HAVE_EEPROM_SETTINGS) +bool dbg_write_eeprom(void) +{ + int fd; + int rc; + int old_irq_level; + char buf[EEPROM_SIZE]; + int err; + + fd = open("/internal_eeprom.bin", O_RDONLY); + + if (fd >= 0) + { + rc = read(fd, buf, EEPROM_SIZE); + + if(rc == EEPROM_SIZE) + { + old_irq_level = set_irq_level(HIGHEST_IRQ_LEVEL); + + err = eeprom_24cxx_write(0, buf, sizeof buf); + if (err) + gui_syncsplash(HZ*3, true, "Eeprom write failure (%d)",err); + + set_irq_level(old_irq_level); + } + else + { + gui_syncsplash(HZ*3, true, "File read error (%d)",rc); + } + close(fd); + } + else + { + gui_syncsplash(HZ*3, true, "Failed to open 'internal_eeprom.bin'"); + } + + return false; +} +#endif /* defined(HAVE_EEPROM) && !defined(HAVE_EEPROM_SETTINGS) */ + bool debug_menu(void) { int m; @@ -2023,6 +2072,9 @@ bool debug_menu(void) #ifdef CONFIG_TUNER { "FM Radio", dbg_fm_radio }, #endif +#if defined(HAVE_EEPROM) && !defined(HAVE_EEPROM_SETTINGS) + { "Write back EEPROM", dbg_write_eeprom }, +#endif #ifdef ROCKBOX_HAS_LOGF {"logf", logfdisplay }, {"logfdump", logfdump }, diff --git a/apps/main.c b/apps/main.c index c50af865fc..90bd13ee32 100644 --- a/apps/main.c +++ b/apps/main.c @@ -120,7 +120,7 @@ int init_dircache(bool preinit) if (global_settings.dircache) { -# ifdef HAVE_EEPROM +# ifdef HAVE_EEPROM_SETTINGS if (firmware_settings.initialized && firmware_settings.disk_clean && preinit) { @@ -371,14 +371,14 @@ void init(void) panicf("ata: %d", rc); } -#ifdef HAVE_EEPROM +#ifdef HAVE_EEPROM_SETTINGS eeprom_settings_init(); #endif usb_start_monitoring(); while (usb_detect()) { -#ifdef HAVE_EEPROM +#ifdef HAVE_EEPROM_SETTINGS firmware_settings.disk_clean = false; #endif /* enter USB mode early, before trying to mount */ @@ -444,7 +444,7 @@ void init(void) init_dircache(false); init_tagcache(); -#ifdef HAVE_EEPROM +#ifdef HAVE_EEPROM_SETTINGS if (firmware_settings.initialized) { /* In case we crash. */ diff --git a/apps/misc.c b/apps/misc.c index ffacf7ed82..19cee60993 100644 --- a/apps/misc.c +++ b/apps/misc.c @@ -507,7 +507,7 @@ static bool clean_shutdown(void (*callback)(void *), void *parameter) callback(parameter); system_flush(); -#ifdef HAVE_EEPROM +#ifdef HAVE_EEPROM_SETTINGS if (firmware_settings.initialized) { firmware_settings.disk_clean = true; diff --git a/apps/tagcache.c b/apps/tagcache.c index 179218ab1f..191c245597 100644 --- a/apps/tagcache.c +++ b/apps/tagcache.c @@ -153,7 +153,7 @@ struct ramcache_header { int entry_count[TAG_COUNT]; /* Number of entries in the indices. */ }; -# ifdef HAVE_EEPROM +# ifdef HAVE_EEPROM_SETTINGS struct statefile_header { struct ramcache_header *hdr; struct tagcache_stat stat; @@ -2829,7 +2829,7 @@ static bool allocate_tagcache(void) return true; } -# ifdef HAVE_EEPROM +# ifdef HAVE_EEPROM_SETTINGS static bool tagcache_dumpload(void) { struct statefile_header shdr; @@ -3370,7 +3370,7 @@ static void tagcache_thread(void) free_tempbuf(); #ifdef HAVE_TC_RAMCACHE -# ifdef HAVE_EEPROM +# ifdef HAVE_EEPROM_SETTINGS if (firmware_settings.initialized && firmware_settings.disk_clean) check_done = tagcache_dumpload(); @@ -3462,7 +3462,7 @@ bool tagcache_prepare_shutdown(void) if (tagcache_get_commit_step() > 0) return false; -#ifdef HAVE_EEPROM +#ifdef HAVE_EEPROM_SETTINGS if (stat.ramcache) tagcache_dumpsave(); #endif diff --git a/apps/tree.c b/apps/tree.c index 1bbb5f8ca3..75562b30c8 100644 --- a/apps/tree.c +++ b/apps/tree.c @@ -1336,7 +1336,7 @@ void tree_flush(void) if (global_settings.dircache) { global_settings.dircache_size = dircache_get_cache_size(); -# ifdef HAVE_EEPROM +# ifdef HAVE_EEPROM_SETTINGS if (dircache_is_enabled() && firmware_settings.initialized) dircache_save(DIRCACHE_FILE); # endif @@ -1352,7 +1352,7 @@ void tree_flush(void) void tree_restore(void) { -#ifdef HAVE_EEPROM +#ifdef HAVE_EEPROM_SETTINGS firmware_settings.disk_clean = false; #endif diff --git a/bootloader/main.c b/bootloader/main.c index 0b058272f1..7c2b1257a9 100644 --- a/bootloader/main.c +++ b/bootloader/main.c @@ -357,7 +357,7 @@ void main(void) power_off(); } -#ifdef HAVE_EEPROM +#ifdef HAVE_EEPROM_SETTINGS firmware_settings.initialized = false; #endif if (detect_flashed_rockbox()) @@ -365,7 +365,7 @@ void main(void) bool load_from_flash; load_from_flash = !rec_button; -#ifdef HAVE_EEPROM +#ifdef HAVE_EEPROM_SETTINGS if (eeprom_settings_init()) { /* If bootloader version has not been reset, disk might @@ -389,7 +389,7 @@ void main(void) lcd_update(); if (i == 0) { -#ifdef HAVE_EEPROM +#ifdef HAVE_EEPROM_SETTINGS eeprom_settings_store(); #endif start_firmware(); @@ -457,7 +457,7 @@ void main(void) sleep(HZ); #endif -#ifdef HAVE_EEPROM +#ifdef HAVE_EEPROM_SETTINGS if (firmware_settings.initialized) { firmware_settings.disk_clean = false; @@ -503,7 +503,7 @@ void main(void) printf("Result: %d", i); lcd_update(); -#ifdef HAVE_EEPROM +#ifdef HAVE_EEPROM_SETTINGS if (firmware_settings.initialized) eeprom_settings_store(); #endif diff --git a/firmware/SOURCES b/firmware/SOURCES index fda83ee073..23da475304 100644 --- a/firmware/SOURCES +++ b/firmware/SOURCES @@ -150,8 +150,10 @@ drivers/pcf50606.c #endif #ifdef HAVE_EEPROM drivers/eeprom_24cxx.c +#ifdef HAVE_EEPROM_SETTINGS eeprom_settings.c #endif +#endif #ifdef IPOD_ARCH drivers/pcf50605.c #endif diff --git a/firmware/drivers/eeprom_24cxx.c b/firmware/drivers/eeprom_24cxx.c index 9a8fa5d86d..66bc235052 100644 --- a/firmware/drivers/eeprom_24cxx.c +++ b/firmware/drivers/eeprom_24cxx.c @@ -35,21 +35,24 @@ #define SW_I2C_WRITE 0 #define SW_I2C_READ 1 +/* h1x0 needs its own i2c driver, + h3x0 uses the pcf i2c driver */ + +#ifdef IRIVER_H100_SERIES + /* cute little functions, atomic read-modify-write */ /* SCL is GPIO, 12 */ -#define SCL_LO and_l(~0x00001000, &GPIO_OUT) // and_b(~0x10, &PBDRL) -#define SCL_HI or_l( 0x00001000, &GPIO_OUT) // or_b( 0x10, &PBDRL) -#define SCL_INPUT and_l(~0x00001000, &GPIO_ENABLE) // and_b(~0x10, &PBIORL) -#define SCL_OUTPUT or_l( 0x00001000, &GPIO_ENABLE) // or_b( 0x10, &PBIORL) -#define SCL ( 0x00001000 & GPIO_READ) // (PBDR & 0x0010) +#define SCL ( 0x00001000 & GPIO_READ) +#define SCL_OUT_LO and_l(~0x00001000, &GPIO_OUT) +#define SCL_LO or_l( 0x00001000, &GPIO_ENABLE) +#define SCL_HI and_l(~0x00001000, &GPIO_ENABLE); while(!SCL); /* SDA is GPIO1, 13 */ -#define SDA_LO and_l(~0x00002000, &GPIO1_OUT) // and_b(~0x02, &PBDRL) -#define SDA_HI or_l( 0x00002000, &GPIO1_OUT) // or_b( 0x02, &PBDRL) -#define SDA_INPUT and_l(~0x00002000, &GPIO1_ENABLE) // and_b(~0x02, &PBIORL) -#define SDA_OUTPUT or_l( 0x00002000, &GPIO1_ENABLE) // or_b( 0x02, &PBIORL) -#define SDA ( 0x00002000 & GPIO1_READ) // (PBDR & 0x0002) +#define SDA ( 0x00002000 & GPIO1_READ) +#define SDA_OUT_LO and_l(~0x00002000, &GPIO1_OUT) +#define SDA_LO or_l( 0x00002000, &GPIO1_ENABLE) +#define SDA_HI and_l(~0x00002000, &GPIO1_ENABLE) /* delay loop to achieve 400kHz at 120MHz CPU frequency */ #define DELAY do { int _x; for(_x=0;_x<22;_x++);} while(0) @@ -61,17 +64,15 @@ static void sw_i2c_init(void) or_l(0x00002000, &GPIO1_FUNCTION); SDA_HI; SCL_HI; - SDA_OUTPUT; - SCL_OUTPUT; + SDA_OUT_LO; + SCL_OUT_LO; } static void sw_i2c_start(void) { SCL_LO; - SCL_OUTPUT; DELAY; SDA_HI; - SDA_OUTPUT; DELAY; SCL_HI; DELAY; @@ -88,7 +89,6 @@ static void sw_i2c_stop(void) DELAY; } - static void sw_i2c_ack(void) { SCL_LO; @@ -105,7 +105,7 @@ static bool sw_i2c_getack(void) int count = 10; SCL_LO; - SDA_INPUT; /* And set to input */ + SDA_HI; /* sets to input */ DELAY; SCL_HI; DELAY; @@ -118,10 +118,8 @@ static bool sw_i2c_getack(void) ret = false; SCL_LO; - SCL_OUTPUT; DELAY; SDA_LO; - SDA_OUTPUT; return ret; } @@ -143,8 +141,6 @@ static void sw_i2c_outb(unsigned char byte) SCL_HI; DELAY; } - - // SDA_LO; } static unsigned char sw_i2c_inb(void) @@ -152,7 +148,7 @@ static unsigned char sw_i2c_inb(void) int i; unsigned char byte = 0; - SDA_INPUT; /* And set to input */ + SDA_HI; /* sets to input */ /* clock in each bit, MSB first */ for ( i=0x80; i; i>>=1 ) @@ -165,13 +161,26 @@ static unsigned char sw_i2c_inb(void) DELAY; } - SDA_OUTPUT; - sw_i2c_ack(); return byte; } +#else + +#include "pcf50606.h" + +#define sw_i2c_init() /* no extra init required */ +#define sw_i2c_start() pcf50606_i2c_start() +#define sw_i2c_stop() pcf50606_i2c_stop() +#define sw_i2c_ack() pcf50606_i2c_ack(true) +#define sw_i2c_getack() pcf50606_i2c_getack() +#define sw_i2c_outb(x) pcf50606_i2c_outb(x) +#define sw_i2c_inb() pcf50606_i2c_inb(false) + +#endif /* IRIVER_H100_SERIES */ + + int sw_i2c_write(int location, const unsigned char* buf, int count) { int i; diff --git a/firmware/drivers/pcf50606.c b/firmware/drivers/pcf50606.c index 0f2d73664b..28df295988 100644 --- a/firmware/drivers/pcf50606.c +++ b/firmware/drivers/pcf50606.c @@ -52,7 +52,7 @@ void pcf50606_i2c_recalc_delay(int cpu_clock) i2c_delay = MAX(cpu_clock / (400000*2*3) - 7, 1); } -static inline void pcf50606_i2c_start(void) +inline void pcf50606_i2c_start(void) { #ifdef USE_ASM asm ( @@ -101,7 +101,7 @@ static inline void pcf50606_i2c_start(void) #endif } -static inline void pcf50606_i2c_stop(void) +inline void pcf50606_i2c_stop(void) { #ifdef USE_ASM asm ( @@ -141,7 +141,7 @@ static inline void pcf50606_i2c_stop(void) #endif } -static inline void pcf50606_i2c_ack(bool ack) +inline void pcf50606_i2c_ack(bool ack) { #ifdef USE_ASM asm ( @@ -193,7 +193,7 @@ static inline void pcf50606_i2c_ack(bool ack) #endif } -static inline bool pcf50606_i2c_getack(void) +inline bool pcf50606_i2c_getack(void) { bool ret; @@ -251,7 +251,7 @@ static inline bool pcf50606_i2c_getack(void) return ret; } -static void pcf50606_i2c_outb(unsigned char byte) +void pcf50606_i2c_outb(unsigned char byte) { #ifdef USE_ASM asm volatile ( @@ -321,7 +321,7 @@ static void pcf50606_i2c_outb(unsigned char byte) #endif } -static unsigned char pcf50606_i2c_inb(bool ack) +unsigned char pcf50606_i2c_inb(bool ack) { unsigned char byte = 0; diff --git a/firmware/export/config-h100.h b/firmware/export/config-h100.h index 88108c71f7..38f26c104b 100644 --- a/firmware/export/config-h100.h +++ b/firmware/export/config-h100.h @@ -129,7 +129,7 @@ /* Define this if there is an EEPROM chip */ /* Someone with H100 and BDM, please verify if this works. */ -// #define HAVE_EEPROM +/* #define HAVE_EEPROM */ #endif /* !SIMULATOR */ diff --git a/firmware/export/config-h120.h b/firmware/export/config-h120.h index ca618139e9..a9b0ed3039 100644 --- a/firmware/export/config-h120.h +++ b/firmware/export/config-h120.h @@ -125,6 +125,9 @@ /* Define this if there is an EEPROM chip */ #define HAVE_EEPROM +/* Define this if the EEPROM chip is used */ +#define HAVE_EEPROM_SETTINGS + #endif /* !SIMULATOR */ /* Define this for S/PDIF input available */ diff --git a/firmware/export/config-h300.h b/firmware/export/config-h300.h index f3ba076334..2a174bc4e5 100644 --- a/firmware/export/config-h300.h +++ b/firmware/export/config-h300.h @@ -133,4 +133,7 @@ /* define this if the unit can be powered or charged via USB */ #define HAVE_USB_POWER +/* Define this if there is an EEPROM chip */ +#define HAVE_EEPROM + #endif /* SIMULATOR */ diff --git a/firmware/export/eeprom_24cxx.h b/firmware/export/eeprom_24cxx.h index bc0f444f7e..c52dd830ef 100644 --- a/firmware/export/eeprom_24cxx.h +++ b/firmware/export/eeprom_24cxx.h @@ -20,8 +20,13 @@ #ifndef _EEPROM_24CXX_H #define _EEPROM_24CXX_H +#ifdef IRIVER_H300_SERIES +#define EEPROM_ADDR 0xA2 +#define EEPROM_SIZE 256 +#else #define EEPROM_ADDR 0xA0 #define EEPROM_SIZE 128 +#endif void eeprom_24cxx_init(void); int eeprom_24cxx_read_byte(unsigned int address, char *c); diff --git a/firmware/export/pcf50606.h b/firmware/export/pcf50606.h index d9f44bb577..3e567c963c 100644 --- a/firmware/export/pcf50606.h +++ b/firmware/export/pcf50606.h @@ -26,4 +26,12 @@ int pcf50606_write(int address, unsigned char val); int pcf50606_read_multiple(int address, unsigned char* buf, int count); int pcf50606_read(int address); +/* internal low level calls used by the eeprom driver for h300 */ +void pcf50606_i2c_start(void); +void pcf50606_i2c_stop(void); +void pcf50606_i2c_ack(bool ack); +bool pcf50606_i2c_getack(void); +void pcf50606_i2c_outb(unsigned char byte); +unsigned char pcf50606_i2c_inb(bool ack); + #endif