static void i2cs_send(char c) { I2C_WAIT(); while( TW_STATUS != TW_ST_SLA_ACK && TW_STATUS != TW_ST_DATA_ACK ) { I2C_ACK(); } I2C_SEND(c); }
static char i2cs_recv(void) { I2C_WAIT(); while( TW_STATUS != TW_SR_DATA_ACK ) { I2C_ACK(); } char c = TWDR; I2C_ACK(); return c; }
int i2c_write(uint32_t bus, uint8_t address, const uint8_t len, uint8_t *buf, uint8_t nostop) { I2C_ *ib = (I2C_ *)bus; int timeout; int i, j; volatile uint32_t tmp; timeout = 0x10000; /* LSB must be zero, since it differentiates between read and write */ if (address & 0x01) { return -1; } if (i2c_start(bus)) { return -2; } /* Send address, low bit 0 for read */ ib->DR = (uint8_t)address; /* Wait until address is set */ I2C_WAIT(!(ib->SR1 & I2C_SR1_ADDR), timeout, -3); #if 0 for (i=0; i < timeout && !(ib->SR1 & I2C_SR1_ADDR); i++) { i2c_busywait(100); } if (i >= timeout) { return -81; } #endif /* Clear ADDR in SR1 by reading SR1 and SR2 */ tmp = ib->SR1; tmp = ib->SR2; for (j=0; j<len; j++) { /* Send byte */ ib->DR = buf[j]; /* Wait until byte is sent is set */ for (i=0; i < timeout && !(ib->SR1 & I2C_SR1_TXE); i++) { i2c_busywait(100); } if (i >= timeout) { /* Maybe we should do something better here? */ return -82; } } /* Wait until BTF == 1 is set */ for (i=0; i < timeout && !(ib->SR1 & I2C_SR1_BTF); i++) { i2c_busywait(100); } if (i >= timeout) { /* Maybe we should do something better here? */ return -83; } if (!nostop) { ib->CR1 |= (I2C_CR1_STOP); /* Wait until STOP is cleared by hw */ for (i=0; i < timeout && (ib->CR1 & I2C_CR1_STOP); i++) { i2c_busywait(100); } if (i >= timeout) { return -84; } } return 0; }
static void I2CM_START(void) { TWCR=_BV(TWEN)|_BV(TWINT)|_BV(TWSTA); I2C_WAIT(); }
static void I2C_NACK(void) { TWCR=_BV(TWEN)|_BV(TWINT); I2C_WAIT(); }