Renesas / mbed-src_GR-PEACH_rev_c_I2C

Fork of mbed-src_GR-PEACH_rev_c by Renesas

Files at this revision

API Documentation at this revision

Comitter:
1050186
Date:
Tue Apr 28 11:52:02 2015 +0000
Parent:
491:affe2fb21f3a
Commit message:
Bug fix I2C driver

Changed in this revision

targets/hal/TARGET_RENESAS/TARGET_RZ_A1H/i2c_api.c Show annotated file Show diff for this revision Revisions of this file
--- a/targets/hal/TARGET_RENESAS/TARGET_RZ_A1H/i2c_api.c	Mon Apr 06 12:35:13 2015 +0000
+++ b/targets/hal/TARGET_RENESAS/TARGET_RZ_A1H/i2c_api.c	Tue Apr 28 11:52:02 2015 +0000
@@ -58,7 +58,7 @@
 #define SR2_TEND  (1 << 6)
 #define SR2_TDRE  (1 << 7)
 
-#define WAIT_TIMEOUT    (4200)  /* Loop counter : Time-out is about 1ms. By 4200 loops, measured value is 1009ms. */
+#define WAIT_TIMEOUT    (3600000)  /* Loop counter : Time-out is about 1s. By 3600000 loops, measured value is 969ms. */
 
 static const PinMap PinMap_I2C_SDA[] = {
     {P1_1 , I2C_0, 1},
@@ -106,7 +106,7 @@
     int timeout = 0;
     
     /* There is no timeout, but the upper limit value is set to avoid an infinite loop. */
-    while (!(i2c_status(obj) & SR2_RDRF)) {
+    while ((i2c_status(obj) & SR2_RDRF) == 0) {
         timeout ++;
         if (timeout >= WAIT_TIMEOUT) {
             return -1;
@@ -120,7 +120,7 @@
     int timeout = 0;
 
     /* There is no timeout, but the upper limit value is set to avoid an infinite loop. */
-    while (!(i2c_status(obj) & SR2_TDRE)) {
+    while ((i2c_status(obj) & SR2_TDRE) == 0) {
         timeout ++;
         if (timeout >= WAIT_TIMEOUT) {
             return -1;
@@ -134,7 +134,7 @@
     int timeout = 0;
     
     /* There is no timeout, but the upper limit value is set to avoid an infinite loop. */
-    while (!(i2c_status(obj) & SR2_TEND)) {
+    while ((i2c_status(obj) & SR2_TEND) == 0) {
         timeout ++;
         if (timeout >= WAIT_TIMEOUT) {
             return -1;
@@ -149,7 +149,7 @@
     int timeout = 0;
     
     /* There is no timeout, but the upper limit value is set to avoid an infinite loop. */
-    while (!(i2c_status(obj) & SR2_START)) {
+    while ((i2c_status(obj) & SR2_START) == 0) {
         timeout ++;
         if (timeout >= WAIT_TIMEOUT) {
             return -1;
@@ -163,7 +163,7 @@
     int timeout = 0;
     
     /* There is no timeout, but the upper limit value is set to avoid an infinite loop. */
-    while (!(i2c_status(obj) & SR2_STOP)) {
+    while ((i2c_status(obj) & SR2_STOP) == 0) {
         timeout ++;
         if (timeout >= WAIT_TIMEOUT) {
             return -1;
@@ -173,6 +173,15 @@
     return 0;
 }
 
+static int i2c_set_STOP(i2c_t *obj) {
+    /* SR2.STOP = 0 */
+    REG(SR2.UINT32) &= ~SR2_STOP;
+    /* Stop condition */
+    REG(CR2.UINT32) |= CR2_SP;
+
+    return 0;
+}
+
 static void i2c_set_SR2_NACKF_STOP(i2c_t *obj) {
     /* SR2.NACKF = 0 */
     REG(SR2.UINT32) &= ~SR2_NACKF;
@@ -235,7 +244,7 @@
 inline int i2c_start(i2c_t *obj) {
     int timeout = 0;
 
-    while (REG(CR2.UINT32) & CR2_BBSY) {
+    while ((REG(CR2.UINT32) & CR2_BBSY) != 0) {
         timeout ++;
         if (timeout >= obj->bbsy_wait_cnt) {
             break;
@@ -257,16 +266,15 @@
 }
 
 inline int i2c_stop(i2c_t *obj) {
-    /* SR2.STOP = 0 */
-    REG(SR2.UINT32) &= ~SR2_STOP;
-    /* Stop condition */
-    REG(CR2.UINT32) |= CR2_SP;
-
+    (void)i2c_set_STOP(obj);
+    (void)i2c_wait_STOP(obj);
+    i2c_set_SR2_NACKF_STOP(obj);
+    
     return 0;
 }
 
 static void i2c_set_err_noslave(i2c_t *obj) {
-    (void)i2c_stop(obj);
+    (void)i2c_set_STOP(obj);
     (void)i2c_wait_STOP(obj);
     i2c_set_SR2_NACKF_STOP(obj);
     obj->last_stop_flag = 1;
@@ -275,17 +283,14 @@
 static inline int i2c_do_write(i2c_t *obj, int value) {
     int timeout = 0;
 
-    if (!(i2c_status(obj) & SR2_NACKF)) {
-        /* RIICnSR2.NACKF=0 */
+    if ((i2c_status(obj) & SR2_NACKF) == 0) {
         /* There is no timeout, but the upper limit value is set to avoid an infinite loop. */
-        while (!(i2c_status(obj) & SR2_TDRE)) {
-            /* RIICnSR2.TDRE=0 */
+        while ((i2c_status(obj) & SR2_TDRE) == 0) {
             timeout ++;
             if (timeout >= WAIT_TIMEOUT) {
                 return -1;
             }
-            if (i2c_status(obj) & SR2_NACKF) {
-                /* RIICnSR2.NACKF=1 */
+            if ((i2c_status(obj) & SR2_NACKF) != 0) {
                 return -1;
             }
         }
@@ -440,9 +445,9 @@
     /* wait RDRF */
     status = i2c_wait_RDRF(obj);
     /* check ACK/NACK */
-    if ((status != 0) || (REG(SR2.UINT32) & SR2_NACKF == 1)) {
+    if ((status != 0) || ((REG(SR2.UINT32) & SR2_NACKF) != 0)) {
         /* Slave sends NACK */
-        i2c_stop(obj);
+        (void)i2c_set_STOP(obj);
         /* dummy read */
         value = REG(DRR.UINT32);
         (void)i2c_wait_STOP(obj);
@@ -502,9 +507,9 @@
 
     /* If not repeated start, send stop. */
     if (stop) {
-        (void)i2c_stop(obj);
+        (void)i2c_set_STOP(obj);
         /* RIICnDRR read */
-        value = REG(DRR.UINT32) & 0xFF;
+        value = (REG(DRR.UINT32) & 0xFF);
         data[count] = (char)value;
         /* RIICnMR3.WAIT = 0 */
         REG(MR3.UINT32) &= ~MR3_WAIT;
@@ -513,7 +518,7 @@
     } else {
         (void)i2c_restart(obj);
         /* RIICnDRR read */
-        value = REG(DRR.UINT32) & 0xFF;
+        value = (REG(DRR.UINT32) & 0xFF);
         data[count] = (char)value;
         /* RIICnMR3.WAIT = 0 */
         REG(MR3.UINT32) &= ~MR3_WAIT;
@@ -564,7 +569,7 @@
     }
     /* If not repeated start, send stop. */
     if (stop) {
-        (void)i2c_stop(obj);
+        (void)i2c_set_STOP(obj);
         (void)i2c_wait_STOP(obj);
         i2c_set_SR2_NACKF_STOP(obj);
     } else {
@@ -579,33 +584,41 @@
 }
 
 void i2c_reset(i2c_t *obj) {
-    i2c_stop(obj);
+    (void)i2c_set_STOP(obj);
     (void)i2c_wait_STOP(obj);
     i2c_set_SR2_NACKF_STOP(obj);
 }
 
 int i2c_byte_read(i2c_t *obj, int last) {
     int status;
+    int data;
 
+    data = i2c_do_read(obj, last);
     /* wait for it to arrive */
     status = i2c_wait_RDRF(obj);
     if (status != 0) {
-        i2c_set_err_noslave(obj);
+        i2c_set_SR2_NACKF_STOP(obj);
         return I2C_ERROR_NO_SLAVE;
     }
     
-    return (i2c_do_read(obj, last));
+    return data;
 }
 
 int i2c_byte_write(i2c_t *obj, int data) {
-    int ack;
+    int ack = 0;
     int status;
+    int timeout = 0;
     
     status = i2c_do_write(obj, (data & 0xFF));
     if (status != 0) {
-        i2c_set_err_noslave(obj);
-        ack = 0;
+        i2c_set_SR2_NACKF_STOP(obj);
     } else {
+        while (((i2c_status(obj) & SR2_RDRF) == 0) && ((i2c_status(obj) & SR2_TEND) == 0)) {
+            timeout++;
+            if (timeout >= WAIT_TIMEOUT) {
+                return ack;
+            }
+        }
         ack = 1;
     }
 
@@ -624,7 +637,7 @@
     int status;
     int retval;
 
-    status = REG(SR1.UINT8[0]) & SR1_AAS0;
+    status = (REG(SR1.UINT8[0]) & SR1_AAS0);
     status |= (REG(CR2.UINT8[0]) & CR2_TRS) >> 4;
 
     switch(status) {
@@ -659,10 +672,8 @@
     }
     for (count = 0; ((count < (length + 1)) && (break_flg == 0)); count++) {
         /* There is no timeout, but the upper limit value is set to avoid an infinite loop. */
-        while ((i2c_status(obj) & SR2_STOP) || (!(i2c_status(obj) & SR2_RDRF))) {
-            /* RIICnSR2.STOP = 1 or RIICnSR2.RDRF = 0 */
-            if (i2c_status(obj) & SR2_STOP) {
-                /* RIICnSR2.STOP = 1 */
+        while (((i2c_status(obj) & SR2_STOP) != 0) || ((i2c_status(obj) & SR2_RDRF) == 0)) {
+            if ((i2c_status(obj) & SR2_STOP) != 0) {
                 break_flg = 1;
                 break;
             }
@@ -683,7 +694,7 @@
     if (break_flg == 0) {
         (void)i2c_wait_STOP(obj);
     } else {
-        if (i2c_status(obj) & SR2_RDRF) {
+        if ((i2c_status(obj) & SR2_RDRF) != 0) {
             if (count <= 1) {
                 /* fail safe */
                 /* dummy read */
@@ -728,5 +739,5 @@
 }
 
 void i2c_slave_address(i2c_t *obj, int idx, uint32_t address, uint32_t mask) {
-    REG(SAR0.UINT32) = address & 0xfffffffe;
+    REG(SAR0.UINT32) = (address & 0xfffffffe);
 }