rendered paste bodyIndex: 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 <stdio.h>
#include <system.h>
#include <inttypes.h>
+#include <string.h>
#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();
}
+
+