t

Fork of mbed-dev by mbed official

Revision:
80:bdf1132a57cf
Parent:
0:9b334a45a8ff
Child:
144:ef7eb2e8f9f7
--- a/targets/hal/TARGET_ARM_SSG/TARGET_MPS2/i2c_api.c	Wed Mar 02 10:15:13 2016 +0000
+++ b/targets/hal/TARGET_ARM_SSG/TARGET_MPS2/i2c_api.c	Wed Mar 02 14:30:11 2016 +0000
@@ -48,111 +48,161 @@
 
 #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},
-//    {EXP_SDA, I2C_2, 0},		//only used in extended version
+    {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},
-//    {EXP_SCL, I2C_2, 0},		//only used in extended version
+    {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);
+    switch ((int)obj->i2c) {
+        case I2C_0: 
             obj->i2c->CONTROLC = SCL;
             i2c_delay(TSC_TSU);
-        }
-    
-        obj->i2c->CONTROLS = SDA;
-        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;
+        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);
-            if (c & (1 << (7 - loop)))
-                obj->i2c->CONTROLS = SDA;
-            else
-                obj->i2c->CONTROLC = SDA;
-            i2c_delay(AAIC_TSU);
-            obj->i2c->CONTROLS = SCL;
+            obj->i2c->CONTROLS = SDA;
             i2c_delay(AAIC_TSU);
+        break;
+        case I2C_2: 
+        case I2C_3: 
             obj->i2c->CONTROLC = SCL;
-        }
-     
-        i2c_delay(AAIC_TSU);
-        obj->i2c->CONTROLS = SDA;
-        i2c_delay(AAIC_TSU);
-				break;
+            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;
+    int data_receive_byte, loop;
+    switch ((int)obj->i2c) {
+        case I2C_0: 
+            obj->i2c->CONTROLS = SDA;
             i2c_delay(TSC_TSU);
-            if ((obj->i2c->CONTROL & SDA))
-            	data_receive_byte += (1 << (7 - loop));
-            obj->i2c->CONTROLC = SCL;
+
+            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);
-        }
-    
-        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++) {
+        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 = SCL;
-            i2c_delay(AAIC_TSU);
-            obj->i2c->CONTROLS = SCL | SDA;
+            obj->i2c->CONTROLC = 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;
+        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;
 }
@@ -160,11 +210,13 @@
 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;
-		}
+    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;
@@ -186,13 +238,15 @@
 }
 
 
-static inline void i2c_send_ack(i2c_t *obj) 
+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;
-		}
+    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;
@@ -208,10 +262,28 @@
 
 }
 
+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;
+    }
 
-void i2c_init(i2c_t *obj, PinName sda, PinName scl) {
-	
+    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);
@@ -220,62 +292,76 @@
     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;
-		}
-				i2c_delay(delay_value);
-				obj->i2c->CONTROLS = SDA | SCL;
-				i2c_delay(delay_value);
-				obj->i2c->CONTROLC = SDA;
-				i2c_delay(delay_value);
-
-
+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;
-		}
-				i2c_delay(delay_value);
-				obj->i2c->CONTROLC = SDA;
-				i2c_delay(delay_value);
-				obj->i2c->CONTROLC = SCL;
-				i2c_delay(delay_value);
+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;
-		}
-		// 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);
+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;
+    return 0;
 }
 
 
@@ -283,103 +369,154 @@
 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 delay_value, sadr, ack, bytes_read;
-		rxdata=0;
-		switch ((int)obj->i2c) {
-			case I2C_0: 
-				delay_value = TSC_TSU; 
-				sadr = TSC_I2C_ADDR; 
-				break;
-      case I2C_1: 
-				delay_value = AAIC_TSU; 
-				sadr = AAIC_I2C_ADDR; 
-				break;
-		}
-    // Start bit
-		i2c_start(obj);
-
-    // 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);
-
+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_tsc(obj);
-		
-    // Read from serial address
-    i2c_send_byte(obj,sadr | 1);
-		ack += i2c_receive_ack(obj);
-		bytes_read = 0;
-		
-		switch ((int)obj->i2c) {
-			case I2C_0: 
-        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_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);
-     
-              rxdata = i2c_receive_byte(obj);
-							data[(length-1)-bytes_read] = (char)rxdata;
-							bytes_read++;
-						
-          }
-        }
-        break;
-      case I2C_1:
-        rxdata = i2c_receive_byte(obj);
-				data[bytes_read] = (char)rxdata;
-				bytes_read++;
-    		break;
+    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_ack(obj);
+    i2c_send_nack(obj);  
 
-    // Actual stop bit
-		i2c_stop(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;
-		switch ((int)obj->i2c) {
-			case I2C_0: sadr = TSC_I2C_ADDR; break;
-      case I2C_1: sadr = AAIC_I2C_ADDR; break;
-		}
-		for(int i = 1; i<=length; i++)
-		{
-			i2c_start(obj);
-		
-			// 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);
-			i2c_send_byte(obj, *data);
-			ack += i2c_receive_ack(obj);
-		}
+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);
 
-		i2c_stop(obj);
-		if(ack==3) { return 1; }
-		else{ return 0; }
+    // 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; }
 
 }
 
@@ -394,22 +531,3 @@
 int i2c_byte_write(i2c_t *obj, int data) {
     return 0;
 }
-
-void i2c_slave_mode(i2c_t *obj, int enable_slave) {
-}
-
-int i2c_slave_receive(i2c_t *obj) {
-	return 0;
-}
-
-int i2c_slave_read(i2c_t *obj, char *data, int length) {
-	return 0;
-}
-
-int i2c_slave_write(i2c_t *obj, const char *data, int length) {
-	return 0;
-}
-
-void i2c_slave_address(i2c_t *obj, int idx, uint32_t address, uint32_t mask) {
-}
-