/* sla includes all 8 bits (with r/w bit), assums master transmit */ uint8_t u8g_i2c_start(uint8_t sla) { register uint8_t status; /* send start */ TWCR = _BV(TWINT) | _BV(TWSTA) | _BV(TWEN); /* wait */ if ( u8g_i2c_wait(_BV(TWINT), 1) == 0 ) return 0; status = TW_STATUS; /* check status after start */ if ( status != TW_START && status != TW_REP_START ) { u8g_i2c_set_error(U8G_I2C_ERR_BUS, 1); return 0; } /* set slave address */ TWDR = sla; /* enable sla transfer */ TWCR = _BV(TWINT) | _BV(TWEN); /* wait */ if ( u8g_i2c_wait(_BV(TWINT), 2) == 0 ) return 0; if ( u8g_i2c_opt & U8G_I2C_OPT_NO_ACK ) { /* do not check for ACK */ } else { status = TW_STATUS; /* check status after sla */ if ( status != TW_MT_SLA_ACK ) { u8g_i2c_set_error(U8G_I2C_ERR_BUS, 2); return 0; } } return 1; }
uint8_t u8g_i2c_wait(uint8_t mask, uint8_t pos) { volatile uint16_t cnt = 2000; /* timout value should be > 280 for 50KHz Bus and 16 Mhz CPU, however the start condition might need longer */ while( !(TWCR & mask) ) { if ( cnt == 0 ) { u8g_i2c_set_error(U8G_I2C_ERR_TIMEOUT, pos); return 0; /* error */ } cnt--; } return 1; /* all ok */ }
uint8_t u8g_i2c_send_byte(uint8_t data) { register uint8_t status; TWDR = data; TWCR = _BV(TWINT) | _BV(TWEN); if ( u8g_i2c_wait(_BV(TWINT), 3) == 0 ) return 0; status = TW_STATUS; if ( status != TW_MT_DATA_ACK ) { u8g_i2c_set_error(U8G_I2C_ERR_BUS, 3); return 0; } return 1; }
uint8_t u8g_i2c_send_byte(uint8_t data) { register uint8_t status; TWDR = data; TWCR = _BV(TWINT) | _BV(TWEN); if ( u8g_i2c_wait(_BV(TWINT), 3) == 0 ) return 0; if ( u8g_i2c_opt & U8G_I2C_OPT_NO_ACK ) { /* do not check for ACK */ } else { status = TW_STATUS; if ( status != TW_MT_DATA_ACK ) { u8g_i2c_set_error(U8G_I2C_ERR_BUS, 3); return 0; } } return 1; }