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
This commit is contained in:
Peter D'Hoye 2006-08-15 22:54:06 +00:00
parent 98c9f959e5
commit c4a59a290b
14 changed files with 132 additions and 50 deletions

View file

@ -1891,13 +1891,22 @@ bool dbg_save_roms(void)
fd = creat("/internal_eeprom.bin", O_WRONLY); fd = creat("/internal_eeprom.bin", O_WRONLY);
if (fd >= 0) if (fd >= 0)
{ {
int old_irq_level;
char buf[EEPROM_SIZE]; char buf[EEPROM_SIZE];
int err;
if (eeprom_24cxx_read(0, buf, sizeof buf))
gui_syncsplash(HZ*3, true, "Eeprom read failure!"); 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 else
{
write(fd, buf, sizeof buf); write(fd, buf, sizeof buf);
}
set_irq_level(old_irq_level);
close(fd); close(fd);
} }
#endif #endif
@ -1976,6 +1985,46 @@ bool dbg_set_memory_guard(void)
} }
#endif /* CONFIG_CPU == SH7034 || defined(CPU_COLDFIRE) */ #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) bool debug_menu(void)
{ {
int m; int m;
@ -2023,6 +2072,9 @@ bool debug_menu(void)
#ifdef CONFIG_TUNER #ifdef CONFIG_TUNER
{ "FM Radio", dbg_fm_radio }, { "FM Radio", dbg_fm_radio },
#endif #endif
#if defined(HAVE_EEPROM) && !defined(HAVE_EEPROM_SETTINGS)
{ "Write back EEPROM", dbg_write_eeprom },
#endif
#ifdef ROCKBOX_HAS_LOGF #ifdef ROCKBOX_HAS_LOGF
{"logf", logfdisplay }, {"logf", logfdisplay },
{"logfdump", logfdump }, {"logfdump", logfdump },

View file

@ -120,7 +120,7 @@ int init_dircache(bool preinit)
if (global_settings.dircache) if (global_settings.dircache)
{ {
# ifdef HAVE_EEPROM # ifdef HAVE_EEPROM_SETTINGS
if (firmware_settings.initialized && firmware_settings.disk_clean if (firmware_settings.initialized && firmware_settings.disk_clean
&& preinit) && preinit)
{ {
@ -371,14 +371,14 @@ void init(void)
panicf("ata: %d", rc); panicf("ata: %d", rc);
} }
#ifdef HAVE_EEPROM #ifdef HAVE_EEPROM_SETTINGS
eeprom_settings_init(); eeprom_settings_init();
#endif #endif
usb_start_monitoring(); usb_start_monitoring();
while (usb_detect()) while (usb_detect())
{ {
#ifdef HAVE_EEPROM #ifdef HAVE_EEPROM_SETTINGS
firmware_settings.disk_clean = false; firmware_settings.disk_clean = false;
#endif #endif
/* enter USB mode early, before trying to mount */ /* enter USB mode early, before trying to mount */
@ -444,7 +444,7 @@ void init(void)
init_dircache(false); init_dircache(false);
init_tagcache(); init_tagcache();
#ifdef HAVE_EEPROM #ifdef HAVE_EEPROM_SETTINGS
if (firmware_settings.initialized) if (firmware_settings.initialized)
{ {
/* In case we crash. */ /* In case we crash. */

View file

@ -507,7 +507,7 @@ static bool clean_shutdown(void (*callback)(void *), void *parameter)
callback(parameter); callback(parameter);
system_flush(); system_flush();
#ifdef HAVE_EEPROM #ifdef HAVE_EEPROM_SETTINGS
if (firmware_settings.initialized) if (firmware_settings.initialized)
{ {
firmware_settings.disk_clean = true; firmware_settings.disk_clean = true;

View file

@ -153,7 +153,7 @@ struct ramcache_header {
int entry_count[TAG_COUNT]; /* Number of entries in the indices. */ int entry_count[TAG_COUNT]; /* Number of entries in the indices. */
}; };
# ifdef HAVE_EEPROM # ifdef HAVE_EEPROM_SETTINGS
struct statefile_header { struct statefile_header {
struct ramcache_header *hdr; struct ramcache_header *hdr;
struct tagcache_stat stat; struct tagcache_stat stat;
@ -2829,7 +2829,7 @@ static bool allocate_tagcache(void)
return true; return true;
} }
# ifdef HAVE_EEPROM # ifdef HAVE_EEPROM_SETTINGS
static bool tagcache_dumpload(void) static bool tagcache_dumpload(void)
{ {
struct statefile_header shdr; struct statefile_header shdr;
@ -3370,7 +3370,7 @@ static void tagcache_thread(void)
free_tempbuf(); free_tempbuf();
#ifdef HAVE_TC_RAMCACHE #ifdef HAVE_TC_RAMCACHE
# ifdef HAVE_EEPROM # ifdef HAVE_EEPROM_SETTINGS
if (firmware_settings.initialized && firmware_settings.disk_clean) if (firmware_settings.initialized && firmware_settings.disk_clean)
check_done = tagcache_dumpload(); check_done = tagcache_dumpload();
@ -3462,7 +3462,7 @@ bool tagcache_prepare_shutdown(void)
if (tagcache_get_commit_step() > 0) if (tagcache_get_commit_step() > 0)
return false; return false;
#ifdef HAVE_EEPROM #ifdef HAVE_EEPROM_SETTINGS
if (stat.ramcache) if (stat.ramcache)
tagcache_dumpsave(); tagcache_dumpsave();
#endif #endif

View file

@ -1336,7 +1336,7 @@ void tree_flush(void)
if (global_settings.dircache) if (global_settings.dircache)
{ {
global_settings.dircache_size = dircache_get_cache_size(); global_settings.dircache_size = dircache_get_cache_size();
# ifdef HAVE_EEPROM # ifdef HAVE_EEPROM_SETTINGS
if (dircache_is_enabled() && firmware_settings.initialized) if (dircache_is_enabled() && firmware_settings.initialized)
dircache_save(DIRCACHE_FILE); dircache_save(DIRCACHE_FILE);
# endif # endif
@ -1352,7 +1352,7 @@ void tree_flush(void)
void tree_restore(void) void tree_restore(void)
{ {
#ifdef HAVE_EEPROM #ifdef HAVE_EEPROM_SETTINGS
firmware_settings.disk_clean = false; firmware_settings.disk_clean = false;
#endif #endif

View file

@ -357,7 +357,7 @@ void main(void)
power_off(); power_off();
} }
#ifdef HAVE_EEPROM #ifdef HAVE_EEPROM_SETTINGS
firmware_settings.initialized = false; firmware_settings.initialized = false;
#endif #endif
if (detect_flashed_rockbox()) if (detect_flashed_rockbox())
@ -365,7 +365,7 @@ void main(void)
bool load_from_flash; bool load_from_flash;
load_from_flash = !rec_button; load_from_flash = !rec_button;
#ifdef HAVE_EEPROM #ifdef HAVE_EEPROM_SETTINGS
if (eeprom_settings_init()) if (eeprom_settings_init())
{ {
/* If bootloader version has not been reset, disk might /* If bootloader version has not been reset, disk might
@ -389,7 +389,7 @@ void main(void)
lcd_update(); lcd_update();
if (i == 0) if (i == 0)
{ {
#ifdef HAVE_EEPROM #ifdef HAVE_EEPROM_SETTINGS
eeprom_settings_store(); eeprom_settings_store();
#endif #endif
start_firmware(); start_firmware();
@ -457,7 +457,7 @@ void main(void)
sleep(HZ); sleep(HZ);
#endif #endif
#ifdef HAVE_EEPROM #ifdef HAVE_EEPROM_SETTINGS
if (firmware_settings.initialized) if (firmware_settings.initialized)
{ {
firmware_settings.disk_clean = false; firmware_settings.disk_clean = false;
@ -503,7 +503,7 @@ void main(void)
printf("Result: %d", i); printf("Result: %d", i);
lcd_update(); lcd_update();
#ifdef HAVE_EEPROM #ifdef HAVE_EEPROM_SETTINGS
if (firmware_settings.initialized) if (firmware_settings.initialized)
eeprom_settings_store(); eeprom_settings_store();
#endif #endif

View file

@ -150,8 +150,10 @@ drivers/pcf50606.c
#endif #endif
#ifdef HAVE_EEPROM #ifdef HAVE_EEPROM
drivers/eeprom_24cxx.c drivers/eeprom_24cxx.c
#ifdef HAVE_EEPROM_SETTINGS
eeprom_settings.c eeprom_settings.c
#endif #endif
#endif
#ifdef IPOD_ARCH #ifdef IPOD_ARCH
drivers/pcf50605.c drivers/pcf50605.c
#endif #endif

View file

@ -35,21 +35,24 @@
#define SW_I2C_WRITE 0 #define SW_I2C_WRITE 0
#define SW_I2C_READ 1 #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 */ /* cute little functions, atomic read-modify-write */
/* SCL is GPIO, 12 */ /* SCL is GPIO, 12 */
#define SCL_LO and_l(~0x00001000, &GPIO_OUT) // and_b(~0x10, &PBDRL) #define SCL ( 0x00001000 & GPIO_READ)
#define SCL_HI or_l( 0x00001000, &GPIO_OUT) // or_b( 0x10, &PBDRL) #define SCL_OUT_LO and_l(~0x00001000, &GPIO_OUT)
#define SCL_INPUT and_l(~0x00001000, &GPIO_ENABLE) // and_b(~0x10, &PBIORL) #define SCL_LO or_l( 0x00001000, &GPIO_ENABLE)
#define SCL_OUTPUT or_l( 0x00001000, &GPIO_ENABLE) // or_b( 0x10, &PBIORL) #define SCL_HI and_l(~0x00001000, &GPIO_ENABLE); while(!SCL);
#define SCL ( 0x00001000 & GPIO_READ) // (PBDR & 0x0010)
/* SDA is GPIO1, 13 */ /* SDA is GPIO1, 13 */
#define SDA_LO and_l(~0x00002000, &GPIO1_OUT) // and_b(~0x02, &PBDRL) #define SDA ( 0x00002000 & GPIO1_READ)
#define SDA_HI or_l( 0x00002000, &GPIO1_OUT) // or_b( 0x02, &PBDRL) #define SDA_OUT_LO and_l(~0x00002000, &GPIO1_OUT)
#define SDA_INPUT and_l(~0x00002000, &GPIO1_ENABLE) // and_b(~0x02, &PBIORL) #define SDA_LO or_l( 0x00002000, &GPIO1_ENABLE)
#define SDA_OUTPUT or_l( 0x00002000, &GPIO1_ENABLE) // or_b( 0x02, &PBIORL) #define SDA_HI and_l(~0x00002000, &GPIO1_ENABLE)
#define SDA ( 0x00002000 & GPIO1_READ) // (PBDR & 0x0002)
/* 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)
@ -61,17 +64,15 @@ static void sw_i2c_init(void)
or_l(0x00002000, &GPIO1_FUNCTION); or_l(0x00002000, &GPIO1_FUNCTION);
SDA_HI; SDA_HI;
SCL_HI; SCL_HI;
SDA_OUTPUT; SDA_OUT_LO;
SCL_OUTPUT; SCL_OUT_LO;
} }
static void sw_i2c_start(void) static void sw_i2c_start(void)
{ {
SCL_LO; SCL_LO;
SCL_OUTPUT;
DELAY; DELAY;
SDA_HI; SDA_HI;
SDA_OUTPUT;
DELAY; DELAY;
SCL_HI; SCL_HI;
DELAY; DELAY;
@ -88,7 +89,6 @@ static void sw_i2c_stop(void)
DELAY; DELAY;
} }
static void sw_i2c_ack(void) static void sw_i2c_ack(void)
{ {
SCL_LO; SCL_LO;
@ -105,7 +105,7 @@ static bool sw_i2c_getack(void)
int count = 10; int count = 10;
SCL_LO; SCL_LO;
SDA_INPUT; /* And set to input */ SDA_HI; /* sets to input */
DELAY; DELAY;
SCL_HI; SCL_HI;
DELAY; DELAY;
@ -118,10 +118,8 @@ static bool sw_i2c_getack(void)
ret = false; ret = false;
SCL_LO; SCL_LO;
SCL_OUTPUT;
DELAY; DELAY;
SDA_LO; SDA_LO;
SDA_OUTPUT;
return ret; return ret;
} }
@ -143,8 +141,6 @@ static void sw_i2c_outb(unsigned char byte)
SCL_HI; SCL_HI;
DELAY; DELAY;
} }
// SDA_LO;
} }
static unsigned char sw_i2c_inb(void) static unsigned char sw_i2c_inb(void)
@ -152,7 +148,7 @@ static unsigned char sw_i2c_inb(void)
int i; int i;
unsigned char byte = 0; unsigned char byte = 0;
SDA_INPUT; /* And set to input */ SDA_HI; /* sets to input */
/* clock in each bit, MSB first */ /* clock in each bit, MSB first */
for ( i=0x80; i; i>>=1 ) for ( i=0x80; i; i>>=1 )
@ -165,13 +161,26 @@ static unsigned char sw_i2c_inb(void)
DELAY; DELAY;
} }
SDA_OUTPUT;
sw_i2c_ack(); sw_i2c_ack();
return byte; 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 sw_i2c_write(int location, const unsigned char* buf, int count)
{ {
int i; int i;

View file

@ -52,7 +52,7 @@ void pcf50606_i2c_recalc_delay(int cpu_clock)
i2c_delay = MAX(cpu_clock / (400000*2*3) - 7, 1); 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 #ifdef USE_ASM
asm ( asm (
@ -101,7 +101,7 @@ static inline void pcf50606_i2c_start(void)
#endif #endif
} }
static inline void pcf50606_i2c_stop(void) inline void pcf50606_i2c_stop(void)
{ {
#ifdef USE_ASM #ifdef USE_ASM
asm ( asm (
@ -141,7 +141,7 @@ static inline void pcf50606_i2c_stop(void)
#endif #endif
} }
static inline void pcf50606_i2c_ack(bool ack) inline void pcf50606_i2c_ack(bool ack)
{ {
#ifdef USE_ASM #ifdef USE_ASM
asm ( asm (
@ -193,7 +193,7 @@ static inline void pcf50606_i2c_ack(bool ack)
#endif #endif
} }
static inline bool pcf50606_i2c_getack(void) inline bool pcf50606_i2c_getack(void)
{ {
bool ret; bool ret;
@ -251,7 +251,7 @@ static inline bool pcf50606_i2c_getack(void)
return ret; return ret;
} }
static void pcf50606_i2c_outb(unsigned char byte) void pcf50606_i2c_outb(unsigned char byte)
{ {
#ifdef USE_ASM #ifdef USE_ASM
asm volatile ( asm volatile (
@ -321,7 +321,7 @@ static void pcf50606_i2c_outb(unsigned char byte)
#endif #endif
} }
static unsigned char pcf50606_i2c_inb(bool ack) unsigned char pcf50606_i2c_inb(bool ack)
{ {
unsigned char byte = 0; unsigned char byte = 0;

View file

@ -129,7 +129,7 @@
/* Define this if there is an EEPROM chip */ /* Define this if there is an EEPROM chip */
/* Someone with H100 and BDM, please verify if this works. */ /* Someone with H100 and BDM, please verify if this works. */
// #define HAVE_EEPROM /* #define HAVE_EEPROM */
#endif /* !SIMULATOR */ #endif /* !SIMULATOR */

View file

@ -125,6 +125,9 @@
/* Define this if there is an EEPROM chip */ /* Define this if there is an EEPROM chip */
#define HAVE_EEPROM #define HAVE_EEPROM
/* Define this if the EEPROM chip is used */
#define HAVE_EEPROM_SETTINGS
#endif /* !SIMULATOR */ #endif /* !SIMULATOR */
/* Define this for S/PDIF input available */ /* Define this for S/PDIF input available */

View file

@ -133,4 +133,7 @@
/* define this if the unit can be powered or charged via USB */ /* define this if the unit can be powered or charged via USB */
#define HAVE_USB_POWER #define HAVE_USB_POWER
/* Define this if there is an EEPROM chip */
#define HAVE_EEPROM
#endif /* SIMULATOR */ #endif /* SIMULATOR */

View file

@ -20,8 +20,13 @@
#ifndef _EEPROM_24CXX_H #ifndef _EEPROM_24CXX_H
#define _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_ADDR 0xA0
#define EEPROM_SIZE 128 #define EEPROM_SIZE 128
#endif
void eeprom_24cxx_init(void); void eeprom_24cxx_init(void);
int eeprom_24cxx_read_byte(unsigned int address, char *c); int eeprom_24cxx_read_byte(unsigned int address, char *c);

View file

@ -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_multiple(int address, unsigned char* buf, int count);
int pcf50606_read(int address); 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 #endif