t
Fork of mbed-dev by
Diff: targets/hal/TARGET_ARM_SSG/TARGET_MPS2/i2c_api.c
- 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) { -} -