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);
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 },

View file

@ -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. */

View file

@ -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;

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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;

View file

@ -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;

View file

@ -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 */

View file

@ -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 */

View file

@ -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 */

View file

@ -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);

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(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