All pastes #1278912 Raw Edit

Something

public text v1 · immutable
#1278912 ·published 2008-12-07 17:43 UTC
rendered paste body
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 <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();
 }
+
+