Mbed for VNG board

Fork of mbed-src by mbed official

Revision:
430:d406b7919023
Parent:
427:8eeb5157dee4
--- a/targets/hal/TARGET_RENESAS/TARGET_RZ_A1H/i2c_api.c	Tue Dec 09 14:15:07 2014 +0000
+++ b/targets/hal/TARGET_RENESAS/TARGET_RZ_A1H/i2c_api.c	Tue Dec 09 14:30:09 2014 +0000
@@ -110,6 +110,23 @@
 }
 
 
+static int i2c_wait_STOP(i2c_t *obj) {
+    volatile uint32_t work_reg;
+
+    /* wait SR2.STOP = 1 */
+    work_reg = REG(SR2.UINT32);
+    while ((work_reg & (1 << 3)) == 0) {
+        work_reg = REG(SR2.UINT32);
+    }
+    /* SR2.NACKF = 0 */
+    REG(SR2.UINT32) &= ~(1 << 4);
+    /* SR2.STOP  = 0 */
+    REG(SR2.UINT32) &= ~(1 << 3);
+    
+    return 0;
+}
+
+
 static inline void i2c_power_enable(i2c_t *obj) {
     volatile uint8_t dummy;
     switch ((int)obj->i2c) {
@@ -126,7 +143,6 @@
     I2CName i2c_sda = (I2CName)pinmap_peripheral(sda, PinMap_I2C_SDA);
     I2CName i2c_scl = (I2CName)pinmap_peripheral(scl, PinMap_I2C_SCL);
     obj->i2c = pinmap_merge(i2c_sda, i2c_scl);
-    obj->dummy = 1;
     MBED_ASSERT((int)obj->i2c != NC);
 
     // enable power
@@ -146,25 +162,17 @@
     if (REG(CR2.UINT32) & (1 << 7)) { // BBSY check
         return 0xff;
     }
-    REG(CR2.UINT8[0]) |= 0x62; // start
+    REG(CR2.UINT8[0]) |= 0x02; // start
 
     return 0x10;
 }
 
 inline int i2c_stop(i2c_t *obj) {
-    volatile int timeout = 0;
-
+    /* SR2.STOP  = 0 */
+    REG(SR2.UINT32) &= ~(1 << 3);
     // write the stop bit
     REG(CR2.UINT32) |= (1 << 3);
 
-    // wait for SP bit to reset
-    while(REG(CR2.UINT32) & (1 << 3)) {
-        timeout ++;
-        if (timeout > 100000) return 1;
-    }
-
-    obj->dummy = 1;
-    REG(CR2.UINT32) &= ~ (1 << 3);
     return 0;
 }
 
@@ -194,10 +202,14 @@
         REG(MR3.UINT32) |= (1 << 6);
     } else if (last == 1) {
         // send a NOT ACK
+        REG(MR3.UINT32) |= (1 <<4);
         REG(MR3.UINT32) |=  (1 <<3);
+        REG(MR3.UINT32) &= ~(1 <<4);
     } else {
         // send a ACK
+        REG(MR3.UINT32) |= (1 <<4);
         REG(MR3.UINT32) &= ~(1 <<3);
+        REG(MR3.UINT32) &= ~(1 <<4);
     }
 
     // return the data
@@ -269,20 +281,22 @@
     int value;
     volatile uint32_t work_reg = 0;
 
-
     // full reset
     i2c_reg_reset(obj);
-
+    obj->dummy = 1;
+    
     status = i2c_start(obj);
 
     if (status == 0xff) {
         i2c_stop(obj);
+        i2c_wait_STOP(obj);
         return I2C_ERROR_BUS_BUSY;
     }
 
     status = i2c_do_write(obj, (address | 0x01));
     if (status & 0x01) {
         i2c_stop(obj);
+        i2c_wait_STOP(obj);
         return I2C_ERROR_NO_SLAVE;
     }
     
@@ -292,11 +306,14 @@
     if ((REG(SR2.UINT32) & (1 << 4) == 1)) {
         /* Slave sends NACK */
         i2c_stop(obj);
+        // dummy read
+        value = REG(DRR.UINT32);
+        i2c_wait_STOP(obj);
         return I2C_ERROR_NO_SLAVE;
     }
     
     // Read in all except last byte
-    if (length > 1) {
+    if (length > 2) {
         for (count = 0; count < (length - 1); count++) {
             if (count == (length - 2)) {
                 value = i2c_do_read(obj, 1);
@@ -308,41 +325,55 @@
             status = i2c_status(obj);
             if (status & 0x10) {
                 i2c_stop(obj);
+                i2c_wait_STOP(obj);
                 return count;
             }
             data[count] = (char) value;
         }
+    } else if (length == 2) {
+        /* Set MR3 WATI bit is 1 */;
+        REG(MR3.UINT32) |= (1 << 6);
+        // dummy read
+        value = REG(DRR.UINT32);
+        // wait for it to arrive
+        i2c_wait_RDRF(obj);
+        // send a NOT ACK
+        REG(MR3.UINT32) |= (1 <<4);
+        REG(MR3.UINT32) |=  (1 <<3);
+        REG(MR3.UINT32) &= ~(1 <<4);
+        data[count] = (char)REG(DRR.UINT32);
+        count++;
+    } else if (length == 1) {
+        /* Set MR3 WATI bit is 1 */;
+        REG(MR3.UINT32) |= (1 << 6);
+        // send a NOT ACK
+        REG(MR3.UINT32) |= (1 <<4);
+        REG(MR3.UINT32) |=  (1 <<3);
+        REG(MR3.UINT32) &= ~(1 <<4);
+        // dummy read
+        value = REG(DRR.UINT32);
+    } else {
+        // Do Nothing
     }
 
     // read in last byte
     i2c_wait_RDRF(obj);
-    /* RIICnSR2.STOP = 0 */
-    REG(SR2.UINT32) &= ~(1 << 3);
-    /* RIICnCR2.SP   = 1 */
-    REG(CR2.UINT32) |= (1 << 3);
-    /* RIICnDRR read */
-    value = REG(DRR.UINT32) & 0xFF;
-    /* RIICnMR3.WAIT = 0 */
-    REG(MR3.UINT32) &= ~(1 << 6);
-    /* wait SR2.STOP = 1 */
-    while ((work_reg & (1 << 3)) == (1 << 3)) {
-        work_reg = REG(SR2.UINT32);
-    }
-    /* SR2.NACKF = 0 */
-    REG(SR2.UINT32) &= ~(1 << 4);
-    /* SR2.STOP  = 0 */
-    REG(SR2.UINT32) &= ~(1 << 3);
-    status = i2c_status(obj);
-    if (status & 0x10) {
-        i2c_stop(obj);
-        return length - 1;
-    }
-
-    data[count] = (char) value;
-
     // If not repeated start, send stop.
     if (stop) {
-        i2c_stop(obj);
+        /* RIICnSR2.STOP = 0 */
+        REG(SR2.UINT32) &= ~(1 << 3);
+        /* RIICnCR2.SP   = 1 */
+        REG(CR2.UINT32) |= (1 << 3);
+        /* RIICnDRR read */
+        value = REG(DRR.UINT32) & 0xFF;
+        data[count] = (char) value;
+        /* RIICnMR3.WAIT = 0 */
+        REG(MR3.UINT32) &= ~(1 << 6);
+        i2c_wait_STOP(obj);
+    } else {
+        /* RIICnDRR read */
+        value = REG(DRR.UINT32) & 0xFF;
+        data[count] = (char) value;
     }
 
     return length;
@@ -358,19 +389,35 @@
 
     if ((status == 0xff)) {
         i2c_stop(obj);
+        i2c_wait_STOP(obj);
         return I2C_ERROR_BUS_BUSY;
     }
+    
+    /**/
+    status = REG(CR2.UINT32);
+    status = REG(SR2.UINT32);
+    /**/
 
     status = i2c_do_write(obj, address);
     if (status & 0x10) {
         i2c_stop(obj);
+        i2c_wait_STOP(obj);
         return I2C_ERROR_NO_SLAVE;
     }
 
+    /**/
+    status = REG(CR2.UINT32);
+    status = REG(SR2.UINT32);
+    /**/
     for (i=0; i<length; i++) {
+    /**/
+    status = REG(CR2.UINT32);
+    status = REG(SR2.UINT32);
+    /**/
         status = i2c_do_write(obj, data[i]);
         if(status & 0x10) {
             i2c_stop(obj);
+            i2c_wait_STOP(obj);
             return i;
         }
     }
@@ -380,6 +427,7 @@
     // If not repeated start, send stop.
     if (stop) {
         i2c_stop(obj);
+        i2c_wait_STOP(obj);
     }
 
     return length;
@@ -387,9 +435,12 @@
 
 void i2c_reset(i2c_t *obj) {
     i2c_stop(obj);
+    i2c_wait_STOP(obj);
 }
 
 int i2c_byte_read(i2c_t *obj, int last) {
+    obj->dummy = 1;
+    
     return (i2c_do_read(obj, last) & 0xFF);
 }
 
@@ -432,10 +483,7 @@
     int count = 0;
     int status;
 
-    if (obj->dummy) {
-        volatile int dummy = REG(DRR.UINT32) ;
-        obj->dummy = 0;
-    }
+    volatile int dummy = REG(DRR.UINT32) ;
 
     do {
         i2c_wait_RDRF(obj);
@@ -448,6 +496,7 @@
 
     if(status & 0x10) {
         i2c_stop(obj);
+        i2c_wait_STOP(obj);
     }
 
     //i2c_clear_TDRE(obj);
@@ -470,6 +519,7 @@
 
     if (!(status & 0x10)) {
         i2c_stop(obj);
+        i2c_wait_STOP(obj);
     }
 
     i2c_clear_TDRE(obj);