t

Fork of mbed-dev by mbed official

Revision:
144:ef7eb2e8f9f7
Parent:
80:bdf1132a57cf
diff -r 423e1876dc07 -r ef7eb2e8f9f7 targets/hal/TARGET_ARM_SSG/TARGET_MPS2/i2c_api.c
--- a/targets/hal/TARGET_ARM_SSG/TARGET_MPS2/i2c_api.c	Tue Aug 02 14:07:36 2016 +0000
+++ b/targets/hal/TARGET_ARM_SSG/TARGET_MPS2/i2c_api.c	Fri Sep 02 15:07:44 2016 +0100
@@ -1,533 +1,533 @@
-/* mbed Microcontroller Library
- * Copyright (c) 2006-2015 ARM Limited
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-#include "i2c_api.h"
-#include "cmsis.h"
-#include "pinmap.h"
-#include "mbed_error.h"
-#include "SMM_MPS2.h"
-#include "wait_api.h"
-#include "fpga.h"
-
-// Types
-#undef FALSE
-#undef TRUE
-#define FALSE   0
-#define TRUE    1
-
-// TSC I2C controller
-#define TSC_I2C_ADDR          0x82
-// AACI I2C controller I2C address
-#define AAIC_I2C_ADDR          0x96
-
-#define TSC_I2C_CID           0x0811
-
-// TSC I2C controller registers
-#define TSC_I2C_CRID          0x00
-
-
-// TSSPCPSR Clock prescale register
-#define TSSPCPSR_DFLT      0x0002      // Clock prescale (use with SCR)
-
-// TSC defaults
-#define TSC_XOFF           20          // X offset
-#define TSC_YOFF           20          // Y offset
-#define TSC_MAXVAL         37000       // 0x0FFF * 10 with TSC to LCD scaling
-
-#define TSC_TSU            15          // Setup delay 600nS min
-#define AAIC_TSU            25           // Setup delay 1000nS min
-#define SHIELD_TSU            25           // Setup delay 1000nS min
-
-
-static const PinMap PinMap_I2C_SDA[] = {
-    {TSC_SDA, I2C_0, 0},
-    {AUD_SDA, I2C_1, 0},
-    {SHIELD_0_SDA, I2C_2, 0},
-    {SHIELD_1_SDA, I2C_3, 0},
-    {NC   , NC   , 0}
-};
-
-static const PinMap PinMap_I2C_SCL[] = {
-    {TSC_SCL, I2C_0, 0},
-    {AUD_SCL, I2C_1, 0},
-    {SHIELD_0_SCL, I2C_2, 0},
-    {SHIELD_1_SCL, I2C_3, 0},
-    {NC   , NC,    0}
-};
-
-static inline void i2c_send_byte(i2c_t *obj, unsigned char c)
-{
-    int loop;
-    switch ((int)obj->i2c) {
-        case I2C_0: 
-            obj->i2c->CONTROLC = SCL;
-            i2c_delay(TSC_TSU);
-
-            for (loop = 0; loop < 8; loop++)
-            {
-                if (c & (1 << (7 - loop)))
-                    obj->i2c->CONTROLS = SDA;
-                else
-                    obj->i2c->CONTROLC = SDA;
-                
-                i2c_delay(TSC_TSU);
-                obj->i2c->CONTROLS = SCL;
-                i2c_delay(TSC_TSU);
-                obj->i2c->CONTROLC = SCL;
-                i2c_delay(TSC_TSU);
-            }
-
-            obj->i2c->CONTROLS = SDA;
-            i2c_delay(TSC_TSU);
-        break;
-        case I2C_1:
-            for (loop = 0; loop < 8; loop++) {
-                i2c_delay(AAIC_TSU);
-                obj->i2c->CONTROLC = SCL;
-                i2c_delay(AAIC_TSU);
-                if (c & (1 << (7 - loop)))
-                    obj->i2c->CONTROLS = SDA;
-                else
-                    obj->i2c->CONTROLC = SDA;
-                
-                i2c_delay(AAIC_TSU);
-                obj->i2c->CONTROLS = SCL;
-                i2c_delay(AAIC_TSU);
-                obj->i2c->CONTROLC = SCL;
-            }
-
-            i2c_delay(AAIC_TSU);
-            obj->i2c->CONTROLS = SDA;
-            i2c_delay(AAIC_TSU);
-        break;
-        case I2C_2: 
-        case I2C_3: 
-            obj->i2c->CONTROLC = SCL;
-            i2c_delay(SHIELD_TSU);
-
-            for (loop = 0; loop < 8; loop++)
-            {
-                if (c & (1 << (7 - loop)))
-                    obj->i2c->CONTROLS = SDA;
-                else
-                    obj->i2c->CONTROLC = SDA;
-                
-                i2c_delay(SHIELD_TSU);
-                obj->i2c->CONTROLS = SCL;
-                i2c_delay(SHIELD_TSU);
-                obj->i2c->CONTROLC = SCL;
-                i2c_delay(SHIELD_TSU);
-            }
-
-            obj->i2c->CONTROLS = SDA;
-            i2c_delay(SHIELD_TSU);
-        break;
-    }
-}
-
-static inline unsigned char i2c_receive_byte(i2c_t *obj)
-{
-    int data_receive_byte, loop;
-    switch ((int)obj->i2c) {
-        case I2C_0: 
-            obj->i2c->CONTROLS = SDA;
-            i2c_delay(TSC_TSU);
-
-            data_receive_byte = 0;
-
-            for (loop = 0; loop < 8; loop++)
-            {
-                obj->i2c->CONTROLS = SCL;
-                i2c_delay(TSC_TSU);
-                if ((obj->i2c->CONTROL & SDA))
-                    data_receive_byte += (1 << (7 - loop));
-                
-                obj->i2c->CONTROLC = SCL;
-                i2c_delay(TSC_TSU);
-            }
-
-            obj->i2c->CONTROLC = SDA;
-            i2c_delay(TSC_TSU);
-        break;
-        case I2C_1:
-            obj->i2c->CONTROLS = SDA;
-            data_receive_byte = 0;
-
-            for (loop = 0; loop < 8; loop++) {
-                i2c_delay(AAIC_TSU);
-                obj->i2c->CONTROLC = SCL;
-                i2c_delay(AAIC_TSU);
-                obj->i2c->CONTROLS = SCL | SDA;
-                i2c_delay(AAIC_TSU);
-                if ((obj->i2c->CONTROL & SDA))
-                    data_receive_byte += (1 << (7 - loop));
-                
-                i2c_delay(AAIC_TSU);
-                obj->i2c->CONTROLC = SCL;
-            }
-
-            i2c_delay(AAIC_TSU);
-            obj->i2c->CONTROLC = SDA;
-            i2c_delay(AAIC_TSU);
-        break;
-        case I2C_2: 
-        case I2C_3:
-            obj->i2c->CONTROLS = SDA;
-            i2c_delay(SHIELD_TSU);
-
-            data_receive_byte = 0;
-
-            for (loop = 0; loop < 8; loop++)
-            {
-                obj->i2c->CONTROLS = SCL;
-                i2c_delay(SHIELD_TSU);
-                if ((obj->i2c->CONTROL & SDA))
-                    data_receive_byte += (1 << (7 - loop));
-                
-                obj->i2c->CONTROLC = SCL;
-                i2c_delay(SHIELD_TSU);
-            }
-
-            obj->i2c->CONTROLC = SDA;
-            i2c_delay(SHIELD_TSU);
-        break;
-    }
-    return data_receive_byte;
-}
-
-static inline int i2c_receive_ack(i2c_t *obj)
-{
-    int nack;
-    int delay_value;
-    switch ((int)obj->i2c) {
-        case I2C_0: delay_value = TSC_TSU; break;
-        case I2C_1: delay_value = AAIC_TSU; break;
-        case I2C_2: delay_value = SHIELD_TSU; break;
-        case I2C_3: delay_value = SHIELD_TSU; break;
-    }
-
-    i2c_delay(delay_value);
-    obj->i2c->CONTROLS = SDA;
-    i2c_delay(delay_value);
-    obj->i2c->CONTROLC = SCL;
-    i2c_delay(delay_value);
-    obj->i2c->CONTROLS = SCL;
-    i2c_delay(delay_value);
-    nack = obj->i2c->CONTROL & SDA;
-    i2c_delay(delay_value);
-    obj->i2c->CONTROLC = SCL;
-    i2c_delay(delay_value);
-    obj->i2c->CONTROLS = SDA;
-    i2c_delay(delay_value);
-    if(nack==0)
-        return 1;
-
-    return 0;
-}
-
-
-static inline void i2c_send_nack(i2c_t *obj) 
-{
-    int delay_value;
-    switch ((int)obj->i2c) {
-        case I2C_0: delay_value = TSC_TSU; break;
-        case I2C_1: delay_value = AAIC_TSU; break;
-        case I2C_2: delay_value = SHIELD_TSU; break;
-        case I2C_3: delay_value = SHIELD_TSU; break;
-    }
-
-    i2c_delay(delay_value);
-    obj->i2c->CONTROLC = SCL;
-    i2c_delay(delay_value);
-    obj->i2c->CONTROLS = SDA;
-    i2c_delay(delay_value);
-    obj->i2c->CONTROLS = SCL;
-    i2c_delay(delay_value);
-    obj->i2c->CONTROLC = SCL;
-    i2c_delay(delay_value);
-    obj->i2c->CONTROLC = SDA;
-    i2c_delay(delay_value);
-
-}
-
-static inline void i2c_send_ack(i2c_t *obj) 
-{
-    int delay_value;
-    switch ((int)obj->i2c) {
-        case I2C_0: delay_value = TSC_TSU; break;
-        case I2C_1: delay_value = AAIC_TSU; break;
-        case I2C_2: delay_value = SHIELD_TSU; break;
-        case I2C_3: delay_value = SHIELD_TSU; break;
-    }
-
-    i2c_delay(delay_value);
-    obj->i2c->CONTROLC = SDA;
-    i2c_delay(delay_value);
-    obj->i2c->CONTROLS = SCL;
-    i2c_delay(delay_value);
-    obj->i2c->CONTROLC = SCL;
-    i2c_delay(delay_value);
-
-}
-
-void i2c_init(i2c_t *obj, PinName sda, PinName scl)
-{
-    // determine the SPI to use
-    I2CName i2c_sda = (I2CName)pinmap_peripheral(sda, PinMap_I2C_SDA);
-    I2CName i2c_scl = (I2CName)pinmap_peripheral(scl, PinMap_I2C_SCL);
-    obj->i2c = (MPS2_I2C_TypeDef *)pinmap_merge(i2c_sda, i2c_scl);
-    
-    if ((int)obj->i2c == NC) {
-        error("I2C pin mapping failed");
-    }
-        
-    pinmap_pinout(sda, PinMap_I2C_SDA);
-    pinmap_pinout(scl, PinMap_I2C_SCL);
-        
-    switch ((int)obj->i2c) {
-        case I2C_2: CMSDK_GPIO0->ALTFUNCSET |= 0x8020; break;
-        case I2C_3: CMSDK_GPIO1->ALTFUNCSET |= 0x8000; 
-                                        CMSDK_GPIO2->ALTFUNCSET |= 0x0200; break;
-    }
-        
-        
-}
-
-int i2c_start(i2c_t *obj)
-{
-    int delay_value;
-    switch ((int)obj->i2c) {
-        case I2C_0: delay_value = TSC_TSU; break;
-        case I2C_1: delay_value = AAIC_TSU; break;
-        case I2C_2: delay_value = SHIELD_TSU; break;
-        case I2C_3: delay_value = SHIELD_TSU; break;
-    }
-    
-    i2c_delay(delay_value);
-    obj->i2c->CONTROLS = SDA | SCL;
-    i2c_delay(delay_value);
-    obj->i2c->CONTROLC = SDA;
-    i2c_delay(delay_value);
-
-    return 0;
-}
-
-int i2c_start_tsc(i2c_t *obj)
-{
-    int delay_value;
-    switch ((int)obj->i2c) {
-        case I2C_0: delay_value = TSC_TSU; break;
-        case I2C_1: delay_value = AAIC_TSU; break;
-        case I2C_2: delay_value = SHIELD_TSU; break;
-        case I2C_3: delay_value = SHIELD_TSU; break;
-    }
-    
-    i2c_delay(delay_value);
-    obj->i2c->CONTROLC = SDA;
-    i2c_delay(delay_value);
-    obj->i2c->CONTROLC = SCL;
-    i2c_delay(delay_value);
-
-    return 0;
-}
-
-int i2c_stop(i2c_t *obj)
-{    
-    int delay_value;
-    switch ((int)obj->i2c) {
-        case I2C_0: delay_value = TSC_TSU; break;
-        case I2C_1: delay_value = AAIC_TSU; break;
-        case I2C_2: delay_value = SHIELD_TSU; break;
-        case I2C_3: delay_value = SHIELD_TSU; break;
-    }
-    // Actual stop bit
-    i2c_delay(delay_value);
-    obj->i2c->CONTROLC = SDA;
-    i2c_delay(delay_value);
-    obj->i2c->CONTROLS = SCL;
-    i2c_delay(delay_value);
-    obj->i2c->CONTROLS = SDA;
-    i2c_delay(delay_value);
-
-    return 0;
-}
-
-
-
-void i2c_frequency(i2c_t *obj, int hz) {
-}
-
-int i2c_read(i2c_t *obj, int address, char *data, int length, int stop)
-{
-    unsigned int loop, rxdata;
-    int sadr, ack, bytes_read;
-    rxdata=0;
-    switch ((int)obj->i2c) {
-        case I2C_0: 
-            sadr = TSC_I2C_ADDR; 
-            break;
-        case I2C_1: 
-            sadr = AAIC_I2C_ADDR; 
-            break;
-        case I2C_2: 
-        case I2C_3: 
-            sadr = address;     //LM75_I2C_ADDR; or MMA7660_I2C_ADDR;
-            break;
-         }
-    bytes_read = 0;
-    // Start bit
-    i2c_start(obj);
-
-    switch ((int)obj->i2c) {
-        case I2C_0: 
-            // Set serial and register address
-            i2c_send_byte(obj,sadr);
-            ack += i2c_receive_ack(obj);
-            i2c_send_byte(obj, address);
-            ack += i2c_receive_ack(obj);
-
-            // Stop bit
-            i2c_stop(obj);
-
-            // Start bit
-            i2c_start_tsc(obj);
-
-            // Read from I2C address
-            i2c_send_byte(obj,sadr | 1);
-            ack += i2c_receive_ack(obj);
-
-            rxdata = (i2c_receive_byte(obj) & 0xFF);
-            data[((length-1)-bytes_read)] = (char)rxdata;
-            bytes_read++;
-            // Read multiple bytes
-            if ((length > 1) && (length < 5))
-            {
-                for (loop = 1; loop <= (length - 1); loop++)
-                {
-                    // Send ACK
-                    i2c_send_ack(obj);
-
-                    // Next byte
-                    //rxdata = ((rxdata << 8) & 0xFFFFFF00);
-                    //rxdata |= (i2c_receive_byte(obj) & 0xFF);
-                    rxdata = i2c_receive_byte(obj);
-                    data[(length-1)-bytes_read] = (char)rxdata;
-                    bytes_read++;
-                            
-                }
-            }
-            break;
-        case I2C_1:
-            // Set serial and register address
-            i2c_send_byte(obj,sadr);
-            ack += i2c_receive_ack(obj);
-            i2c_send_byte(obj, address);
-            ack += i2c_receive_ack(obj);
-
-            // Stop bit
-            i2c_stop(obj);
-
-            // Start bit
-            i2c_start_tsc(obj);
-            // Fall through to read data
-        case I2C_2:
-        case I2C_3:
-            // Read from preset register address pointer
-            i2c_send_byte(obj,sadr | 1);
-            ack += i2c_receive_ack(obj);
-
-            rxdata = i2c_receive_byte(obj);
-            data[bytes_read] = (char)rxdata;
-            bytes_read++;
-            // Read multiple bytes
-            if ((length > 1) && (length < 5))
-            {
-                for (loop = 1; loop <= (length - 1); loop++)
-                {
-                    // Send ACK
-                    i2c_send_ack(obj);
-
-                    // Next byte
-                    rxdata = i2c_receive_byte(obj);
-                    data[loop] = (char)rxdata;
-                    bytes_read++;
-                            
-                }
-            }
-            break;
-    }
-    i2c_send_nack(obj);  
-
-    i2c_stop(obj);    // Actual stop bit
-
-    return bytes_read;
-}
-
-int i2c_write(i2c_t *obj, int address, const char *data, int length, int stop)
-{
-    int ack=0;
-    int sadr;
-    char * ptr;
-    char addr;
-    ptr = (char*)data;
-    switch ((int)obj->i2c)
-    {
-        case I2C_0: 
-            sadr = TSC_I2C_ADDR;
-            addr = address;
-            break;
-        case I2C_1: 
-            sadr = AAIC_I2C_ADDR; 
-            addr = address;
-            break;
-        case I2C_2: 
-        case I2C_3: 
-            sadr = address; //LM75_I2C_ADDR or MMA7660_I2C_ADDR;
-            addr = *ptr++;
-            break;
-     }
-    
-//    printf("adr = %x, reg = %x\n",sadr, address);
-    i2c_start(obj);
-
-    // Set serial and register address
-    i2c_send_byte(obj,sadr);
-    ack += i2c_receive_ack(obj);
-    i2c_send_byte(obj, addr);
-    ack += i2c_receive_ack(obj);
-
-    for(int i = 1; i<length; i++)
-    {
-        i2c_send_byte(obj, *ptr++);
-        ack += i2c_receive_ack(obj);
-    }
-
-    i2c_stop(obj);
-    if(ack==3) { return 1; }
-    else{ return 0; }
-
-}
-
-void i2c_reset(i2c_t *obj) {
-    i2c_stop(obj);
-}
-
-int i2c_byte_read(i2c_t *obj, int last) {
-    return 0;
-}
-
-int i2c_byte_write(i2c_t *obj, int data) {
-    return 0;
-}
+/* mbed Microcontroller Library
+ * Copyright (c) 2006-2015 ARM Limited
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#include "i2c_api.h"
+#include "cmsis.h"
+#include "pinmap.h"
+#include "mbed_error.h"
+#include "SMM_MPS2.h"
+#include "wait_api.h"
+#include "fpga.h"
+
+// Types
+#undef FALSE
+#undef TRUE
+#define FALSE   0
+#define TRUE    1
+
+// TSC I2C controller
+#define TSC_I2C_ADDR          0x82
+// AACI I2C controller I2C address
+#define AAIC_I2C_ADDR          0x96
+
+#define TSC_I2C_CID           0x0811
+
+// TSC I2C controller registers
+#define TSC_I2C_CRID          0x00
+
+
+// TSSPCPSR Clock prescale register
+#define TSSPCPSR_DFLT      0x0002      // Clock prescale (use with SCR)
+
+// TSC defaults
+#define TSC_XOFF           20          // X offset
+#define TSC_YOFF           20          // Y offset
+#define TSC_MAXVAL         37000       // 0x0FFF * 10 with TSC to LCD scaling
+
+#define TSC_TSU            15          // Setup delay 600nS min
+#define AAIC_TSU            25           // Setup delay 1000nS min
+#define SHIELD_TSU            25           // Setup delay 1000nS min
+
+
+static const PinMap PinMap_I2C_SDA[] = {
+    {TSC_SDA, I2C_0, 0},
+    {AUD_SDA, I2C_1, 0},
+    {SHIELD_0_SDA, I2C_2, 0},
+    {SHIELD_1_SDA, I2C_3, 0},
+    {NC   , NC   , 0}
+};
+
+static const PinMap PinMap_I2C_SCL[] = {
+    {TSC_SCL, I2C_0, 0},
+    {AUD_SCL, I2C_1, 0},
+    {SHIELD_0_SCL, I2C_2, 0},
+    {SHIELD_1_SCL, I2C_3, 0},
+    {NC   , NC,    0}
+};
+
+static inline void i2c_send_byte(i2c_t *obj, unsigned char c)
+{
+    int loop;
+    switch ((int)obj->i2c) {
+        case I2C_0: 
+            obj->i2c->CONTROLC = SCL;
+            i2c_delay(TSC_TSU);
+
+            for (loop = 0; loop < 8; loop++)
+            {
+                if (c & (1 << (7 - loop)))
+                    obj->i2c->CONTROLS = SDA;
+                else
+                    obj->i2c->CONTROLC = SDA;
+                
+                i2c_delay(TSC_TSU);
+                obj->i2c->CONTROLS = SCL;
+                i2c_delay(TSC_TSU);
+                obj->i2c->CONTROLC = SCL;
+                i2c_delay(TSC_TSU);
+            }
+
+            obj->i2c->CONTROLS = SDA;
+            i2c_delay(TSC_TSU);
+        break;
+        case I2C_1:
+            for (loop = 0; loop < 8; loop++) {
+                i2c_delay(AAIC_TSU);
+                obj->i2c->CONTROLC = SCL;
+                i2c_delay(AAIC_TSU);
+                if (c & (1 << (7 - loop)))
+                    obj->i2c->CONTROLS = SDA;
+                else
+                    obj->i2c->CONTROLC = SDA;
+                
+                i2c_delay(AAIC_TSU);
+                obj->i2c->CONTROLS = SCL;
+                i2c_delay(AAIC_TSU);
+                obj->i2c->CONTROLC = SCL;
+            }
+
+            i2c_delay(AAIC_TSU);
+            obj->i2c->CONTROLS = SDA;
+            i2c_delay(AAIC_TSU);
+        break;
+        case I2C_2: 
+        case I2C_3: 
+            obj->i2c->CONTROLC = SCL;
+            i2c_delay(SHIELD_TSU);
+
+            for (loop = 0; loop < 8; loop++)
+            {
+                if (c & (1 << (7 - loop)))
+                    obj->i2c->CONTROLS = SDA;
+                else
+                    obj->i2c->CONTROLC = SDA;
+                
+                i2c_delay(SHIELD_TSU);
+                obj->i2c->CONTROLS = SCL;
+                i2c_delay(SHIELD_TSU);
+                obj->i2c->CONTROLC = SCL;
+                i2c_delay(SHIELD_TSU);
+            }
+
+            obj->i2c->CONTROLS = SDA;
+            i2c_delay(SHIELD_TSU);
+        break;
+    }
+}
+
+static inline unsigned char i2c_receive_byte(i2c_t *obj)
+{
+    int data_receive_byte, loop;
+    switch ((int)obj->i2c) {
+        case I2C_0: 
+            obj->i2c->CONTROLS = SDA;
+            i2c_delay(TSC_TSU);
+
+            data_receive_byte = 0;
+
+            for (loop = 0; loop < 8; loop++)
+            {
+                obj->i2c->CONTROLS = SCL;
+                i2c_delay(TSC_TSU);
+                if ((obj->i2c->CONTROL & SDA))
+                    data_receive_byte += (1 << (7 - loop));
+                
+                obj->i2c->CONTROLC = SCL;
+                i2c_delay(TSC_TSU);
+            }
+
+            obj->i2c->CONTROLC = SDA;
+            i2c_delay(TSC_TSU);
+        break;
+        case I2C_1:
+            obj->i2c->CONTROLS = SDA;
+            data_receive_byte = 0;
+
+            for (loop = 0; loop < 8; loop++) {
+                i2c_delay(AAIC_TSU);
+                obj->i2c->CONTROLC = SCL;
+                i2c_delay(AAIC_TSU);
+                obj->i2c->CONTROLS = SCL | SDA;
+                i2c_delay(AAIC_TSU);
+                if ((obj->i2c->CONTROL & SDA))
+                    data_receive_byte += (1 << (7 - loop));
+                
+                i2c_delay(AAIC_TSU);
+                obj->i2c->CONTROLC = SCL;
+            }
+
+            i2c_delay(AAIC_TSU);
+            obj->i2c->CONTROLC = SDA;
+            i2c_delay(AAIC_TSU);
+        break;
+        case I2C_2: 
+        case I2C_3:
+            obj->i2c->CONTROLS = SDA;
+            i2c_delay(SHIELD_TSU);
+
+            data_receive_byte = 0;
+
+            for (loop = 0; loop < 8; loop++)
+            {
+                obj->i2c->CONTROLS = SCL;
+                i2c_delay(SHIELD_TSU);
+                if ((obj->i2c->CONTROL & SDA))
+                    data_receive_byte += (1 << (7 - loop));
+                
+                obj->i2c->CONTROLC = SCL;
+                i2c_delay(SHIELD_TSU);
+            }
+
+            obj->i2c->CONTROLC = SDA;
+            i2c_delay(SHIELD_TSU);
+        break;
+    }
+    return data_receive_byte;
+}
+
+static inline int i2c_receive_ack(i2c_t *obj)
+{
+    int nack;
+    int delay_value;
+    switch ((int)obj->i2c) {
+        case I2C_0: delay_value = TSC_TSU; break;
+        case I2C_1: delay_value = AAIC_TSU; break;
+        case I2C_2: delay_value = SHIELD_TSU; break;
+        case I2C_3: delay_value = SHIELD_TSU; break;
+    }
+
+    i2c_delay(delay_value);
+    obj->i2c->CONTROLS = SDA;
+    i2c_delay(delay_value);
+    obj->i2c->CONTROLC = SCL;
+    i2c_delay(delay_value);
+    obj->i2c->CONTROLS = SCL;
+    i2c_delay(delay_value);
+    nack = obj->i2c->CONTROL & SDA;
+    i2c_delay(delay_value);
+    obj->i2c->CONTROLC = SCL;
+    i2c_delay(delay_value);
+    obj->i2c->CONTROLS = SDA;
+    i2c_delay(delay_value);
+    if(nack==0)
+        return 1;
+
+    return 0;
+}
+
+
+static inline void i2c_send_nack(i2c_t *obj) 
+{
+    int delay_value;
+    switch ((int)obj->i2c) {
+        case I2C_0: delay_value = TSC_TSU; break;
+        case I2C_1: delay_value = AAIC_TSU; break;
+        case I2C_2: delay_value = SHIELD_TSU; break;
+        case I2C_3: delay_value = SHIELD_TSU; break;
+    }
+
+    i2c_delay(delay_value);
+    obj->i2c->CONTROLC = SCL;
+    i2c_delay(delay_value);
+    obj->i2c->CONTROLS = SDA;
+    i2c_delay(delay_value);
+    obj->i2c->CONTROLS = SCL;
+    i2c_delay(delay_value);
+    obj->i2c->CONTROLC = SCL;
+    i2c_delay(delay_value);
+    obj->i2c->CONTROLC = SDA;
+    i2c_delay(delay_value);
+
+}
+
+static inline void i2c_send_ack(i2c_t *obj) 
+{
+    int delay_value;
+    switch ((int)obj->i2c) {
+        case I2C_0: delay_value = TSC_TSU; break;
+        case I2C_1: delay_value = AAIC_TSU; break;
+        case I2C_2: delay_value = SHIELD_TSU; break;
+        case I2C_3: delay_value = SHIELD_TSU; break;
+    }
+
+    i2c_delay(delay_value);
+    obj->i2c->CONTROLC = SDA;
+    i2c_delay(delay_value);
+    obj->i2c->CONTROLS = SCL;
+    i2c_delay(delay_value);
+    obj->i2c->CONTROLC = SCL;
+    i2c_delay(delay_value);
+
+}
+
+void i2c_init(i2c_t *obj, PinName sda, PinName scl)
+{
+    // determine the SPI to use
+    I2CName i2c_sda = (I2CName)pinmap_peripheral(sda, PinMap_I2C_SDA);
+    I2CName i2c_scl = (I2CName)pinmap_peripheral(scl, PinMap_I2C_SCL);
+    obj->i2c = (MPS2_I2C_TypeDef *)pinmap_merge(i2c_sda, i2c_scl);
+    
+    if ((int)obj->i2c == NC) {
+        error("I2C pin mapping failed");
+    }
+        
+    pinmap_pinout(sda, PinMap_I2C_SDA);
+    pinmap_pinout(scl, PinMap_I2C_SCL);
+        
+    switch ((int)obj->i2c) {
+        case I2C_2: CMSDK_GPIO0->ALTFUNCSET |= 0x8020; break;
+        case I2C_3: CMSDK_GPIO1->ALTFUNCSET |= 0x8000; 
+                                        CMSDK_GPIO2->ALTFUNCSET |= 0x0200; break;
+    }
+        
+        
+}
+
+int i2c_start(i2c_t *obj)
+{
+    int delay_value;
+    switch ((int)obj->i2c) {
+        case I2C_0: delay_value = TSC_TSU; break;
+        case I2C_1: delay_value = AAIC_TSU; break;
+        case I2C_2: delay_value = SHIELD_TSU; break;
+        case I2C_3: delay_value = SHIELD_TSU; break;
+    }
+    
+    i2c_delay(delay_value);
+    obj->i2c->CONTROLS = SDA | SCL;
+    i2c_delay(delay_value);
+    obj->i2c->CONTROLC = SDA;
+    i2c_delay(delay_value);
+
+    return 0;
+}
+
+int i2c_start_tsc(i2c_t *obj)
+{
+    int delay_value;
+    switch ((int)obj->i2c) {
+        case I2C_0: delay_value = TSC_TSU; break;
+        case I2C_1: delay_value = AAIC_TSU; break;
+        case I2C_2: delay_value = SHIELD_TSU; break;
+        case I2C_3: delay_value = SHIELD_TSU; break;
+    }
+    
+    i2c_delay(delay_value);
+    obj->i2c->CONTROLC = SDA;
+    i2c_delay(delay_value);
+    obj->i2c->CONTROLC = SCL;
+    i2c_delay(delay_value);
+
+    return 0;
+}
+
+int i2c_stop(i2c_t *obj)
+{    
+    int delay_value;
+    switch ((int)obj->i2c) {
+        case I2C_0: delay_value = TSC_TSU; break;
+        case I2C_1: delay_value = AAIC_TSU; break;
+        case I2C_2: delay_value = SHIELD_TSU; break;
+        case I2C_3: delay_value = SHIELD_TSU; break;
+    }
+    // Actual stop bit
+    i2c_delay(delay_value);
+    obj->i2c->CONTROLC = SDA;
+    i2c_delay(delay_value);
+    obj->i2c->CONTROLS = SCL;
+    i2c_delay(delay_value);
+    obj->i2c->CONTROLS = SDA;
+    i2c_delay(delay_value);
+
+    return 0;
+}
+
+
+
+void i2c_frequency(i2c_t *obj, int hz) {
+}
+
+int i2c_read(i2c_t *obj, int address, char *data, int length, int stop)
+{
+    unsigned int loop, rxdata;
+    int sadr, ack, bytes_read;
+    rxdata=0;
+    switch ((int)obj->i2c) {
+        case I2C_0: 
+            sadr = TSC_I2C_ADDR; 
+            break;
+        case I2C_1: 
+            sadr = AAIC_I2C_ADDR; 
+            break;
+        case I2C_2: 
+        case I2C_3: 
+            sadr = address;     //LM75_I2C_ADDR; or MMA7660_I2C_ADDR;
+            break;
+         }
+    bytes_read = 0;
+    // Start bit
+    i2c_start(obj);
+
+    switch ((int)obj->i2c) {
+        case I2C_0: 
+            // Set serial and register address
+            i2c_send_byte(obj,sadr);
+            ack += i2c_receive_ack(obj);
+            i2c_send_byte(obj, address);
+            ack += i2c_receive_ack(obj);
+
+            // Stop bit
+            i2c_stop(obj);
+
+            // Start bit
+            i2c_start_tsc(obj);
+
+            // Read from I2C address
+            i2c_send_byte(obj,sadr | 1);
+            ack += i2c_receive_ack(obj);
+
+            rxdata = (i2c_receive_byte(obj) & 0xFF);
+            data[((length-1)-bytes_read)] = (char)rxdata;
+            bytes_read++;
+            // Read multiple bytes
+            if ((length > 1) && (length < 5))
+            {
+                for (loop = 1; loop <= (length - 1); loop++)
+                {
+                    // Send ACK
+                    i2c_send_ack(obj);
+
+                    // Next byte
+                    //rxdata = ((rxdata << 8) & 0xFFFFFF00);
+                    //rxdata |= (i2c_receive_byte(obj) & 0xFF);
+                    rxdata = i2c_receive_byte(obj);
+                    data[(length-1)-bytes_read] = (char)rxdata;
+                    bytes_read++;
+                            
+                }
+            }
+            break;
+        case I2C_1:
+            // Set serial and register address
+            i2c_send_byte(obj,sadr);
+            ack += i2c_receive_ack(obj);
+            i2c_send_byte(obj, address);
+            ack += i2c_receive_ack(obj);
+
+            // Stop bit
+            i2c_stop(obj);
+
+            // Start bit
+            i2c_start_tsc(obj);
+            // Fall through to read data
+        case I2C_2:
+        case I2C_3:
+            // Read from preset register address pointer
+            i2c_send_byte(obj,sadr | 1);
+            ack += i2c_receive_ack(obj);
+
+            rxdata = i2c_receive_byte(obj);
+            data[bytes_read] = (char)rxdata;
+            bytes_read++;
+            // Read multiple bytes
+            if ((length > 1) && (length < 5))
+            {
+                for (loop = 1; loop <= (length - 1); loop++)
+                {
+                    // Send ACK
+                    i2c_send_ack(obj);
+
+                    // Next byte
+                    rxdata = i2c_receive_byte(obj);
+                    data[loop] = (char)rxdata;
+                    bytes_read++;
+                            
+                }
+            }
+            break;
+    }
+    i2c_send_nack(obj);  
+
+    i2c_stop(obj);    // Actual stop bit
+
+    return bytes_read;
+}
+
+int i2c_write(i2c_t *obj, int address, const char *data, int length, int stop)
+{
+    int ack=0;
+    int sadr;
+    char * ptr;
+    char addr;
+    ptr = (char*)data;
+    switch ((int)obj->i2c)
+    {
+        case I2C_0: 
+            sadr = TSC_I2C_ADDR;
+            addr = address;
+            break;
+        case I2C_1: 
+            sadr = AAIC_I2C_ADDR; 
+            addr = address;
+            break;
+        case I2C_2: 
+        case I2C_3: 
+            sadr = address; //LM75_I2C_ADDR or MMA7660_I2C_ADDR;
+            addr = *ptr++;
+            break;
+     }
+    
+//    printf("adr = %x, reg = %x\n",sadr, address);
+    i2c_start(obj);
+
+    // Set serial and register address
+    i2c_send_byte(obj,sadr);
+    ack += i2c_receive_ack(obj);
+    i2c_send_byte(obj, addr);
+    ack += i2c_receive_ack(obj);
+
+    for(int i = 1; i<length; i++)
+    {
+        i2c_send_byte(obj, *ptr++);
+        ack += i2c_receive_ack(obj);
+    }
+
+    i2c_stop(obj);
+    if(ack==3) { return 1; }
+    else{ return 0; }
+
+}
+
+void i2c_reset(i2c_t *obj) {
+    i2c_stop(obj);
+}
+
+int i2c_byte_read(i2c_t *obj, int last) {
+    return 0;
+}
+
+int i2c_byte_write(i2c_t *obj, int data) {
+    return 0;
+}