diff options
Diffstat (limited to 'src/i2c.c')
-rw-r--r-- | src/i2c.c | 30 |
1 files changed, 21 insertions, 9 deletions
@@ -37,7 +37,7 @@ * */ -void error() {} +void error() { } void i2c_init() { TWBR = 12; @@ -48,29 +48,30 @@ void i2c_init() { void i2c_start(uint8_t addr, bool rw) { TWCR = (_BV(TWSTA) | _BV(TWEN) | _BV(TWINT)); //send start signal loop_until_bit_is_set(TWCR, TWINT); - if((TWSR & 0xf8) != TW_START) { + if(((TWSR & 0xf8) != (TW_START)) && ((TWSR & 0xf8) != (TW_REP_START))) { #ifdef DEBUG_BUILD - printf("Couldn't set start condition?\n"); + printf("Couldn't set start condition? TWSR: 0x%x\r\n", TWSR & 0xf8); #endif error(); } + TWDR = (addr << 1) | rw; TWCR = _BV(TWINT) | _BV(TWEN); loop_until_bit_is_set(TWCR, TWINT); - if((TWSR & 0xf8) != TW_MT_SLA_ACK) { + if(((TWSR & 0xf8) != (TW_MT_SLA_ACK)) && (TWSR & 0xf8) != (TW_MR_SLA_ACK)) { #ifdef DEBUG_BUILD printf("unhandled NACK in address transmission\ TWCR: 0x%x\ - TWSR: 0x%x\n", TWCR, (TWSR & ~(0b11))); + TWSR: 0x%x\r\n", TWCR, (TWSR & ~(0b11))); #endif error(); } } -void i2c_stop() { TWCR = (_BV(TWSTO) | _BV(TWEN) | _BV(TWINT)); } +void i2c_stop() { TWCR = (_BV(TWSTO) | _BV(TWEN) | _BV(TWINT)); _delay_ms(500); } void i2c_send(uint8_t byte) { TWDR = byte; //fist packet is address @@ -81,7 +82,7 @@ void i2c_send(uint8_t byte) { #ifdef DEBUG_BUILD printf("unhandled NACK in data transmission\ TWCR: 0x%x\ - TWSR: 0x%x\n", TWCR, (TWSR & ~(0b11))); + TWSR: 0x%x\r\n", TWCR, (TWSR & ~(0b11))); #endif error(); } @@ -89,11 +90,14 @@ void i2c_send(uint8_t byte) { uint8_t i2c_recv() { uint8_t value; + TWCR = _BV(TWINT) | _BV(TWEN); loop_until_bit_is_set(TWCR, TWINT); value = TWDR; - if((TWSR & 0xf8) != TW_MR_SLA_ACK) { + //the eeprom supposedly doesn't return an ack here, + //as it should (according to its datasheet), but it still works? + if(((TWSR & 0xf8) != TW_MR_DATA_ACK) && ((TWSR & 0xf8) != TW_MR_DATA_NACK)) { #ifdef DEBUG_BUILD - printf("Error recieving byte from i2c device\n"); + printf("Error recieving byte from i2c device: 0x%x\r\n", TWSR & 0xf8); #endif error(); } @@ -128,3 +132,11 @@ void i2c_write_reg_multi(uint8_t device_addr, uint8_t device_reg, size_t len, ui for(size_t on_byte = 0; on_byte < len; on_byte++) i2c_send(values[on_byte]); i2c_stop(); } + +void i2c_write_reg_addr16(uint8_t device_addr, uint16_t device_reg, uint8_t data) { + i2c_start(device_addr, I2C_WRITE); + i2c_send((uint8_t)device_reg & 0xff); + i2c_send((uint8_t)device_reg >> 8); + i2c_send(data); + i2c_stop(); +} |