Mbed for VNG board
Fork of mbed-src by
Diff: targets/hal/TARGET_RENESAS/TARGET_RZ_A1H/i2c_api.c
- Revision:
- 430:d406b7919023
- Parent:
- 427:8eeb5157dee4
--- a/targets/hal/TARGET_RENESAS/TARGET_RZ_A1H/i2c_api.c Tue Dec 09 14:15:07 2014 +0000 +++ b/targets/hal/TARGET_RENESAS/TARGET_RZ_A1H/i2c_api.c Tue Dec 09 14:30:09 2014 +0000 @@ -110,6 +110,23 @@ } +static int i2c_wait_STOP(i2c_t *obj) { + volatile uint32_t work_reg; + + /* wait SR2.STOP = 1 */ + work_reg = REG(SR2.UINT32); + while ((work_reg & (1 << 3)) == 0) { + work_reg = REG(SR2.UINT32); + } + /* SR2.NACKF = 0 */ + REG(SR2.UINT32) &= ~(1 << 4); + /* SR2.STOP = 0 */ + REG(SR2.UINT32) &= ~(1 << 3); + + return 0; +} + + static inline void i2c_power_enable(i2c_t *obj) { volatile uint8_t dummy; switch ((int)obj->i2c) { @@ -126,7 +143,6 @@ I2CName i2c_sda = (I2CName)pinmap_peripheral(sda, PinMap_I2C_SDA); I2CName i2c_scl = (I2CName)pinmap_peripheral(scl, PinMap_I2C_SCL); obj->i2c = pinmap_merge(i2c_sda, i2c_scl); - obj->dummy = 1; MBED_ASSERT((int)obj->i2c != NC); // enable power @@ -146,25 +162,17 @@ if (REG(CR2.UINT32) & (1 << 7)) { // BBSY check return 0xff; } - REG(CR2.UINT8[0]) |= 0x62; // start + REG(CR2.UINT8[0]) |= 0x02; // start return 0x10; } inline int i2c_stop(i2c_t *obj) { - volatile int timeout = 0; - + /* SR2.STOP = 0 */ + REG(SR2.UINT32) &= ~(1 << 3); // write the stop bit REG(CR2.UINT32) |= (1 << 3); - // wait for SP bit to reset - while(REG(CR2.UINT32) & (1 << 3)) { - timeout ++; - if (timeout > 100000) return 1; - } - - obj->dummy = 1; - REG(CR2.UINT32) &= ~ (1 << 3); return 0; } @@ -194,10 +202,14 @@ REG(MR3.UINT32) |= (1 << 6); } else if (last == 1) { // send a NOT ACK + REG(MR3.UINT32) |= (1 <<4); REG(MR3.UINT32) |= (1 <<3); + REG(MR3.UINT32) &= ~(1 <<4); } else { // send a ACK + REG(MR3.UINT32) |= (1 <<4); REG(MR3.UINT32) &= ~(1 <<3); + REG(MR3.UINT32) &= ~(1 <<4); } // return the data @@ -269,20 +281,22 @@ int value; volatile uint32_t work_reg = 0; - // full reset i2c_reg_reset(obj); - + obj->dummy = 1; + status = i2c_start(obj); if (status == 0xff) { i2c_stop(obj); + i2c_wait_STOP(obj); return I2C_ERROR_BUS_BUSY; } status = i2c_do_write(obj, (address | 0x01)); if (status & 0x01) { i2c_stop(obj); + i2c_wait_STOP(obj); return I2C_ERROR_NO_SLAVE; } @@ -292,11 +306,14 @@ if ((REG(SR2.UINT32) & (1 << 4) == 1)) { /* Slave sends NACK */ i2c_stop(obj); + // dummy read + value = REG(DRR.UINT32); + i2c_wait_STOP(obj); return I2C_ERROR_NO_SLAVE; } // Read in all except last byte - if (length > 1) { + if (length > 2) { for (count = 0; count < (length - 1); count++) { if (count == (length - 2)) { value = i2c_do_read(obj, 1); @@ -308,41 +325,55 @@ status = i2c_status(obj); if (status & 0x10) { i2c_stop(obj); + i2c_wait_STOP(obj); return count; } data[count] = (char) value; } + } else if (length == 2) { + /* Set MR3 WATI bit is 1 */; + REG(MR3.UINT32) |= (1 << 6); + // dummy read + value = REG(DRR.UINT32); + // wait for it to arrive + i2c_wait_RDRF(obj); + // send a NOT ACK + REG(MR3.UINT32) |= (1 <<4); + REG(MR3.UINT32) |= (1 <<3); + REG(MR3.UINT32) &= ~(1 <<4); + data[count] = (char)REG(DRR.UINT32); + count++; + } else if (length == 1) { + /* Set MR3 WATI bit is 1 */; + REG(MR3.UINT32) |= (1 << 6); + // send a NOT ACK + REG(MR3.UINT32) |= (1 <<4); + REG(MR3.UINT32) |= (1 <<3); + REG(MR3.UINT32) &= ~(1 <<4); + // dummy read + value = REG(DRR.UINT32); + } else { + // Do Nothing } // read in last byte i2c_wait_RDRF(obj); - /* RIICnSR2.STOP = 0 */ - REG(SR2.UINT32) &= ~(1 << 3); - /* RIICnCR2.SP = 1 */ - REG(CR2.UINT32) |= (1 << 3); - /* RIICnDRR read */ - value = REG(DRR.UINT32) & 0xFF; - /* RIICnMR3.WAIT = 0 */ - REG(MR3.UINT32) &= ~(1 << 6); - /* wait SR2.STOP = 1 */ - while ((work_reg & (1 << 3)) == (1 << 3)) { - work_reg = REG(SR2.UINT32); - } - /* SR2.NACKF = 0 */ - REG(SR2.UINT32) &= ~(1 << 4); - /* SR2.STOP = 0 */ - REG(SR2.UINT32) &= ~(1 << 3); - status = i2c_status(obj); - if (status & 0x10) { - i2c_stop(obj); - return length - 1; - } - - data[count] = (char) value; - // If not repeated start, send stop. if (stop) { - i2c_stop(obj); + /* RIICnSR2.STOP = 0 */ + REG(SR2.UINT32) &= ~(1 << 3); + /* RIICnCR2.SP = 1 */ + REG(CR2.UINT32) |= (1 << 3); + /* RIICnDRR read */ + value = REG(DRR.UINT32) & 0xFF; + data[count] = (char) value; + /* RIICnMR3.WAIT = 0 */ + REG(MR3.UINT32) &= ~(1 << 6); + i2c_wait_STOP(obj); + } else { + /* RIICnDRR read */ + value = REG(DRR.UINT32) & 0xFF; + data[count] = (char) value; } return length; @@ -358,19 +389,35 @@ if ((status == 0xff)) { i2c_stop(obj); + i2c_wait_STOP(obj); return I2C_ERROR_BUS_BUSY; } + + /**/ + status = REG(CR2.UINT32); + status = REG(SR2.UINT32); + /**/ status = i2c_do_write(obj, address); if (status & 0x10) { i2c_stop(obj); + i2c_wait_STOP(obj); return I2C_ERROR_NO_SLAVE; } + /**/ + status = REG(CR2.UINT32); + status = REG(SR2.UINT32); + /**/ for (i=0; i<length; i++) { + /**/ + status = REG(CR2.UINT32); + status = REG(SR2.UINT32); + /**/ status = i2c_do_write(obj, data[i]); if(status & 0x10) { i2c_stop(obj); + i2c_wait_STOP(obj); return i; } } @@ -380,6 +427,7 @@ // If not repeated start, send stop. if (stop) { i2c_stop(obj); + i2c_wait_STOP(obj); } return length; @@ -387,9 +435,12 @@ void i2c_reset(i2c_t *obj) { i2c_stop(obj); + i2c_wait_STOP(obj); } int i2c_byte_read(i2c_t *obj, int last) { + obj->dummy = 1; + return (i2c_do_read(obj, last) & 0xFF); } @@ -432,10 +483,7 @@ int count = 0; int status; - if (obj->dummy) { - volatile int dummy = REG(DRR.UINT32) ; - obj->dummy = 0; - } + volatile int dummy = REG(DRR.UINT32) ; do { i2c_wait_RDRF(obj); @@ -448,6 +496,7 @@ if(status & 0x10) { i2c_stop(obj); + i2c_wait_STOP(obj); } //i2c_clear_TDRE(obj); @@ -470,6 +519,7 @@ if (!(status & 0x10)) { i2c_stop(obj); + i2c_wait_STOP(obj); } i2c_clear_TDRE(obj);