Current-Users archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

mistake the i2c_bitbang direction



Hi! tsutsui-san,


I see this message on evbppc(OPENBLOCKS266) since i2c_bitbang.c,v 1.11.
arch/powerpc/ibm4xx/dev/gpiic_bitbang.c is very severe and a bit noisy.
X-<

  mountroot: trying ffs...
  root file system type: ffs
  gpiic_read_bits: Read in output mode
  gpiic_read_bits: Read in output mode
  gpiic_read_bits: Read in output mode
  gpiic_read_bits: Read in output mode
  gpiic_read_bits: Read in output mode
  gpiic_read_bits: Read in output mode
  gpiic_read_bits: Read in output mode
  gpiic_read_bits: Read in output mode
  gpiic_read_bits: Read in output mode
  gpiic_set_bits: SDA low with no output enable
  gpiic_set_bits: SDA low with no output enable
  :
  :

I think mistake to set the direction.  We necessary DIR(INPUT) before READ,
and DIR(OUTPUT) before SETBITS().
Please fix.

Attached patch provide very quiet and peace for world on OPENBLOCKS266. ;-)

Thanks,
--
kiyohara

Index: i2c_bitbang.c
===================================================================
RCS file: /cvsroot/src/sys/dev/i2c/i2c_bitbang.c,v
retrieving revision 1.11
diff -u -r1.11 i2c_bitbang.c
--- i2c_bitbang.c       1 Jun 2008 01:13:18 -0000       1.11
+++ i2c_bitbang.c       7 Jul 2008 17:49:13 -0000
@@ -67,6 +67,7 @@
 {
        int bail = 0;
 
+       DIR(INPUT);
        while (((READ & SCL) == 0) && (bail < SCL_BAIL_COUNT)) {
                delay(1);
                bail++;
@@ -94,6 +95,7 @@
        delay(4);               /* start hold time (4.0 us) */
 
        /* leave SCL=L and SDL=L to avoid unexpected start/stop condition */
+       DIR(OUTPUT);
        SETBITS(  0 |   0);
 
        return 0;
@@ -163,12 +165,11 @@
 
        /* assume SCL=L, SDA=L here */
 
-       DIR(INPUT);
-
        for (i = 0; i < 8; i++) {
                val <<= 1;
 
                /* data is set at SCL H->L edge */
+               DIR(OUTPUT);
                SETBITS(  0 |   0);
                delay(5);       /* clock low time (4.7 us) */
 
@@ -181,11 +182,11 @@
                delay(4);       /* clock high time (4.0 us) */
        }
        /* set SCL H->L before set SDA direction OUTPUT */
+       DIR(OUTPUT);
        SETBITS(  0 |   0);
 
        /* set ack after SCL H->L edge */
        bit = (flags & I2C_F_LAST) ? SDA : 0;
-       DIR(OUTPUT);
        SETBITS(bit |   0);
        delay(5);       /* clock low time (4.7 us) */
 
@@ -196,10 +197,10 @@
        delay(4);       /* clock high time (4.0 us) */
 
        /* set SCL H->L for next data; don't change SDA here */
+       DIR(OUTPUT);
        SETBITS(bit |   0);
 
        /* leave SCL=L and SDL=L to avoid unexpected start/stop condition */
-       DIR(INPUT);
        SETBITS(  0 |   0);
 
 
@@ -219,12 +220,11 @@
 
        /* assume at SCL=L, SDA=L here */
 
-       DIR(OUTPUT);
-
        for (mask = 0x80; mask != 0; mask >>= 1) {
                bit = (val & mask) ? SDA : 0;
 
                /* set data after SCL H->L edge */
+               DIR(OUTPUT);
                SETBITS(bit |   0);
                delay(5);       /* clock low time (4.7 us) */
 
@@ -235,14 +235,15 @@
                delay(4);       /* clock high time (4.0 us) */
 
                /* put SCL H->L edge; don't change SDA here */
+               DIR(OUTPUT);
                SETBITS(bit |   0);
        }
 
        /* ack is set at H->L edge */
-       DIR(INPUT);
        delay(5);       /* clock low time (4.7 us) */
 
        /* read ack at L->H edge */
+       DIR(OUTPUT);
        SETBITS(  0 | SCL);
        if (i2c_wait_for_scl(v, ops) != 0)
                return EIO;
@@ -251,8 +252,8 @@
 
        /* leave SCL=L and SDL=L to avoid unexpected start/stop condition */
        /* set SCL H->L before set SDA direction OUTPUT */
-       SETBITS(  0 |   0);
        DIR(OUTPUT);
+       SETBITS(  0 |   0);
 
        if (flags & I2C_F_STOP)
                (void) i2c_bitbang_send_stop(v, flags, ops);


Home | Main Index | Thread Index | Old Index