Mbed for VNG board

Fork of mbed-src by mbed official

Files at this revision

API Documentation at this revision

Comitter:
mbed_official
Date:
Tue Dec 02 15:15:06 2014 +0000
Parent:
421:cc1c4962551c
Child:
423:560d1a9f3083
Commit message:
Synchronized with git revision 7442855e9ccc71565c0ed4fdeea9c66a3212c1af

Full URL: https://github.com/mbedmicro/mbed/commit/7442855e9ccc71565c0ed4fdeea9c66a3212c1af/

Targets: RZ_A1H - Fixed I2C bug

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	Thu Nov 27 14:00:07 2014 +0000
+++ b/targets/hal/TARGET_RENESAS/TARGET_RZ_A1H/i2c_api.c	Tue Dec 02 15:15:06 2014 +0000
@@ -20,6 +20,8 @@
 
 
 #include "riic_iodefine.h"
+#include "RZ_A1_Init.h"
+#include "MBRZA1H.h"
 
 volatile struct st_riic *RIIC[] = RIIC_ADDRESS_LIST;
 
@@ -198,13 +200,66 @@
 }
 
 void i2c_frequency(i2c_t *obj, int hz) {
-    uint32_t PCLK = 6666666;
-
-    uint32_t pulse = PCLK / (hz * 2);
+    int freq;
+    int oldfreq = 0;
+    int newfreq = 0;
+    uint32_t pclk;
+    uint32_t pclk_base;
+    uint32_t tmp_width;
+    uint32_t width = 0;
+    uint8_t count;
+    uint8_t pclk_bit = 0;
+    
+    /* set PCLK */
+    if (false == RZ_A1_IsClockMode0())
+    {
+        pclk_base = (uint32_t)CM1_RENESAS_RZ_A1_P0_CLK;
+    } else {
+        pclk_base = (uint32_t)CM0_RENESAS_RZ_A1_P0_CLK;
+    }
+    
+    /* Min 10kHz, Max 400kHz */
+    if (hz < 10000) {
+        freq = 10000;
+    } else if (hz > 400000) {
+        freq = 400000;
+    } else {
+        freq = hz;
+    }
+    
+    for (count = 0; count < 7; count++) {
+        // IIC phi = P0 phi / rate
+        pclk = pclk_base / (2 << count);
+        // In case of "CLE = 1, NFE = 1, CKS != 000( IIC phi < P0 phi ), nf = 1"
+        // freq = 1 / {[( BRH + 2 + 1 ) + ( BRL + 2 + 1 )] / pclk }
+        // BRH is regarded as same value with BRL
+        // 2( BRH + 3 ) / pclk  = 1 / freq
+        tmp_width = ((pclk / freq) / 2) - 3;
+        // Carry in a decimal point
+        tmp_width += 1;
+        if ((tmp_width >= 0x00000001) && (tmp_width <= 0x0000001F)) {
+            // Calculate theoretical value, and Choose max value of them
+            newfreq = pclk / (tmp_width + 3) / 2;
+            if (newfreq >= oldfreq) {
+                oldfreq  = newfreq;
+                width    = tmp_width;
+                pclk_bit = (uint8_t)(0x10 * (count + 1));
+            }
+        }
+    }
 
-    // I2C Rate
-    REG(BRL.UINT32) = pulse;
-    REG(BRH.UINT32) = pulse;
+    if (width != 0) {
+        // I2C Rate
+        REG(MR1.UINT8[0])  |=  pclk_bit;  // P_phi / xx
+        width |= 0x000000E0;
+        REG(BRL.UINT32) = width;
+        REG(BRH.UINT32) = width;
+    } else {
+        // Default 
+        REG(MR1.UINT8[0])  |=  0x00;  // P_phi / 1
+        REG(BRL.UINT32) = 0x000000FF;
+        REG(BRH.UINT32) = 0x000000FF;
+    }
 }
 
 int i2c_read(i2c_t *obj, int address, char *data, int length, int stop) {