Index: bootloader/fm_i2c.c =================================================================== --- bootloader/fm_i2c.c (revision 0) +++ bootloader/fm_i2c.c (revision 0) @@ -0,0 +1,100 @@ +#include "as3525.h" +#include "generic_i2c.h" + + +#define I2C_GPIO(x) GPIOB_PIN(x) +#define I2C_GPIO_DIR GPIOB_DIR +#define I2C_SCL_PIN 4 +#define I2C_SDA_PIN 5 + +static void fm_scl_hi(void) +{ + I2C_GPIO(I2C_SCL_PIN) = 1 << I2C_SCL_PIN; +} + +static void fm_scl_lo(void) +{ + I2C_GPIO(I2C_SCL_PIN) = 0; +} + +static void fm_sda_hi(void) +{ + I2C_GPIO(I2C_SDA_PIN) = 1 << I2C_SDA_PIN; +} + +static void fm_sda_lo(void) +{ + I2C_GPIO(I2C_SDA_PIN) = 0; +} + +static void fm_sda_input(void) +{ + I2C_GPIO_DIR &= ~(1 << I2C_SDA_PIN); +} + +static void fm_sda_output(void) +{ + I2C_GPIO_DIR |= 1 << I2C_SDA_PIN; +} + +static void fm_scl_input(void) +{ + I2C_GPIO_DIR &= ~(1 << I2C_SCL_PIN); +} + +static void fm_scl_output(void) +{ + I2C_GPIO_DIR |= 1 << I2C_SCL_PIN; +} + +static int fm_sda(void) +{ + return (I2C_GPIO(I2C_SDA_PIN) != 0); +} + +static int fm_scl(void) +{ + return (I2C_GPIO(I2C_SCL_PIN) != 0); +} + +static void fm_delay(void) +{ + volatile int i, j; + + j = 0; + for (i = 0; i < 20; i++) { + j++; + } +} + + +static struct i2c_interface fm_i2c_interface = { + .address = 0x10 << 1, + + .scl_hi = fm_scl_hi, + .scl_lo = fm_scl_lo, + .sda_hi = fm_sda_hi, + .sda_lo = fm_sda_lo, + .sda_input = fm_sda_input, + .sda_output = fm_sda_output, + .scl_input = fm_scl_input, + .scl_output = fm_scl_output, + .scl = fm_scl, + .sda = fm_sda, + + .delay_hd_sta = fm_delay, + .delay_hd_dat = fm_delay, + .delay_su_dat = fm_delay, + .delay_su_sto = fm_delay, + .delay_su_sta = fm_delay, + .delay_thigh = fm_delay +}; + +void fm_i2c_init(void) +{ + i2c_add_node(&fm_i2c_interface); + + GPIOB_AFSEL &= ~(1 << I2C_SCL_PIN); + GPIOB_AFSEL &= ~(1 << I2C_SDA_PIN); +} + Index: bootloader/SOURCES =================================================================== --- bootloader/SOURCES (revision 19357) +++ bootloader/SOURCES (working copy) @@ -47,4 +47,6 @@ #elif CONFIG_CPU==AS3525 sansa_as3525.c show_logo.c +fm_i2c.c +../../firmware/drivers/generic_i2c.c #endif Index: bootloader/sansa_as3525.c =================================================================== --- bootloader/sansa_as3525.c (revision 19357) +++ bootloader/sansa_as3525.c (working copy) @@ -25,6 +25,7 @@ #include #include #include +#include #include "config.h" #include "lcd.h" #include "backlight-target.h" @@ -35,6 +36,8 @@ #include "disk.h" #include "panic.h" +#include "generic_i2c.h" + int show_logo(void); void main(void) { @@ -42,10 +45,23 @@ int buffer_size; void(*kernel_entry)(void); int ret; + + static unsigned short int buf[16]; + unsigned short *ptr; + int i; system_init(); kernel_init(); + verbose = true; + + /* read i2c */ +#if 1 + fm_i2c_init(); + memset(buf, 0, sizeof(buf)); + i2c_read_data(0x20, -1, (unsigned char *)buf, 32); +#endif + lcd_init(); show_logo(); @@ -61,7 +77,16 @@ lcd_clear_display(); verbose = true; } + + /* show i2c */ + ptr = buf; + for (i = 0; i < 4; i++) { + printf("%X %04X %04X %04X %04X", (i * 4 + 0xA) % 16, ptr[0], ptr[1], ptr[2], ptr[3]); + ptr += 4; + } + while (1); /* hang */ + enable_irq(); ret = storage_init(); Index: firmware/drivers/generic_i2c.c =================================================================== --- firmware/drivers/generic_i2c.c (revision 19357) +++ firmware/drivers/generic_i2c.c (working copy) @@ -31,23 +31,48 @@ static void i2c_start(struct i2c_interface *iface) { +#if 0 iface->sda_hi(); iface->scl_hi(); iface->sda_lo(); iface->delay_hd_sta(); iface->scl_lo(); +#else + iface->scl_output(); + + iface->sda_output(); + iface->sda_hi(); + iface->scl_hi(); + iface->delay_hd_sta(); + iface->scl_output(); + iface->sda_lo(); + iface->delay_hd_sta(); + iface->scl_lo(); + iface->delay_hd_sta(); +#endif } static void i2c_stop(struct i2c_interface *iface) { +#if 0 iface->sda_lo(); iface->scl_hi(); iface->delay_su_sto(); iface->sda_hi(); +#else + iface->sda_output(); + iface->sda_lo(); + iface->delay_hd_sta(); + iface->scl_hi(); + iface->delay_su_sto(); + iface->sda_hi(); + iface->delay_hd_sta(); +#endif } static void i2c_ack(struct i2c_interface *iface, bool ack) { +#if 0 iface->scl_lo(); if ( ack ) iface->sda_lo(); @@ -58,12 +83,24 @@ iface->scl_hi(); iface->delay_thigh(); iface->scl_lo(); +#else + iface->sda_output(); + if (ack) + iface->sda_lo(); + else + iface->sda_hi(); + iface->delay_su_dat(); + iface->scl_hi(); + iface->delay_thigh(); + iface->scl_lo(); + iface->delay_hd_sta(); +#endif } static int i2c_getack(struct i2c_interface *iface) { int ret = 1; - +#if 0 iface->sda_input(); iface->delay_su_dat(); iface->scl_hi(); @@ -76,6 +113,17 @@ iface->sda_hi(); iface->sda_output(); iface->delay_hd_dat(); +#else + iface->sda_input(); + iface->delay_su_dat(); + iface->scl_hi(); + iface->delay_hd_dat(); + if (iface->sda()) + ret = 0; + iface->delay_hd_dat(); + iface->scl_lo(); + iface->delay_hd_dat(); +#endif return ret; } @@ -84,8 +132,14 @@ int i; unsigned char byte = 0; +#if 0 +#else + iface->sda_input(); +#endif + /* clock in each bit, MSB first */ for ( i=0x80; i; i>>=1 ) { +#if 0 iface->sda_input(); iface->scl_hi(); iface->delay_thigh(); @@ -94,6 +148,15 @@ iface->scl_lo(); iface->delay_hd_dat(); iface->sda_output(); +#else + iface->scl_hi(); + iface->delay_thigh(); + if (iface->sda()) + byte |= i; + iface->delay_hd_dat(); + iface->scl_lo(); + iface->delay_hd_dat(); +#endif } i2c_ack(iface, ack); @@ -105,17 +168,22 @@ { int i; +#if 0 +#else + iface->sda_output(); +#endif + /* clock out each bit, MSB first */ for (i=0x80; i; i>>=1) { - if (i & byte) - iface->sda_hi(); - else - iface->sda_lo(); - iface->delay_su_dat(); - iface->scl_hi(); - iface->delay_thigh(); - iface->scl_lo(); - iface->delay_hd_dat(); + if (i & byte) + iface->sda_hi(); + else + iface->sda_lo(); + iface->delay_su_dat(); + iface->scl_hi(); + iface->delay_thigh(); + iface->scl_lo(); + iface->delay_hd_dat(); } iface->sda_hi(); @@ -175,23 +243,27 @@ return -1; i2c_start(iface); - i2c_outb(iface, iface->address & 0xfe); + i2c_outb(iface, iface->address | 1); if (i2c_getack(iface)) { +#if 0 i2c_outb(iface, address); if (i2c_getack(iface)) { i2c_start(iface); i2c_outb(iface, iface->address | 1); if (i2c_getack(iface)) { +#endif for(i = 0;i < count-1;i++) buf[i] = i2c_inb(iface, true); buf[i] = i2c_inb(iface, false); +#if 0 } else { ret = -3; } } else { ret = -2; } +#endif } else { ret = -1; } @@ -203,4 +275,10 @@ void i2c_add_node(struct i2c_interface *iface) { i2c_if[i2c_num_ifs++] = iface; + + iface->scl_output(); + iface->scl_hi(); + iface->sda_input(); } + +