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:
parent
98c9f959e5
commit
c4a59a290b
14 changed files with 132 additions and 50 deletions
|
@ -1891,12 +1891,21 @@ bool dbg_save_roms(void)
|
|||
fd = creat("/internal_eeprom.bin", O_WRONLY);
|
||||
if (fd >= 0)
|
||||
{
|
||||
int old_irq_level;
|
||||
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
|
||||
{
|
||||
write(fd, buf, sizeof buf);
|
||||
}
|
||||
|
||||
set_irq_level(old_irq_level);
|
||||
|
||||
close(fd);
|
||||
}
|
||||
|
@ -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 },
|
||||
|
|
|
@ -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. */
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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 */
|
||||
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in a new issue