start updating i2c for timeouts

This commit is contained in:
Jack Humbert 2018-06-20 16:26:43 -04:00
parent bad56a4f2b
commit 76e0d23887
2 changed files with 46 additions and 71 deletions

View file

@ -19,24 +19,19 @@ void i2c_init(void)
//TWBR = 10; //TWBR = 10;
} }
uint8_t i2c_start(uint8_t address) i2c_status_t i2c_start(uint8_t address, uint8_t timeout)
{ {
// reset TWI control register // reset TWI control register
TWCR = 0; TWCR = 0;
// transmit START condition // transmit START condition
TWCR = (1<<TWINT) | (1<<TWSTA) | (1<<TWEN); TWCR = (1<<TWINT) | (1<<TWSTA) | (1<<TWEN);
#ifdef I2C_TIMEOUT uint16_t timeout_timer = timer_read();
uint16_t timeout_timer = timer_read(); while( !(TWCR & (1<<TWINT)) ) {
while( !(TWCR & (1<<TWINT)) ) { if (timeout && (timer_read() - timeout_timer) > timeout) {
if ((timer_read() - timeout_timer) > I2C_TIMEOUT) { return I2C_STATUS_TIMEOUT;
return 2; // should make these codes standard
}
} }
#else }
// wait for end of transmission
while( !(TWCR & (1<<TWINT)) );
#endif
// check if the start condition was successfully transmitted // check if the start condition was successfully transmitted
if(((TW_STATUS & 0xF8) != TW_START) && ((TW_STATUS & 0xF8) != TW_REP_START)){ return 1; } if(((TW_STATUS & 0xF8) != TW_START) && ((TW_STATUS & 0xF8) != TW_REP_START)){ return 1; }
@ -46,17 +41,12 @@ uint8_t i2c_start(uint8_t address)
// start transmission of address // start transmission of address
TWCR = (1<<TWINT) | (1<<TWEN); TWCR = (1<<TWINT) | (1<<TWEN);
#ifdef I2C_TIMEOUT timeout_timer = timer_read();
timeout_timer = timer_read(); while( !(TWCR & (1<<TWINT)) ) {
while( !(TWCR & (1<<TWINT)) ) { if (timeout && (timer_read() - timeout_timer) > I2C_TIMEOUT) {
if ((timer_read() - timeout_timer) > I2C_TIMEOUT) { return I2C_STATUS_TIMEOUT;
return 2; // should make these codes standard
}
} }
#else }
// wait for end of transmission
while( !(TWCR & (1<<TWINT)) );
#endif
// check if the device has acknowledged the READ / WRITE mode // check if the device has acknowledged the READ / WRITE mode
uint8_t twst = TW_STATUS & 0xF8; uint8_t twst = TW_STATUS & 0xF8;
@ -65,75 +55,60 @@ uint8_t i2c_start(uint8_t address)
return 0; return 0;
} }
uint8_t i2c_write(uint8_t data) i2c_status_t i2c_write(uint8_t data, uint8_t timeout)
{ {
// load data into data register // load data into data register
TWDR = data; TWDR = data;
// start transmission of data // start transmission of data
TWCR = (1<<TWINT) | (1<<TWEN); TWCR = (1<<TWINT) | (1<<TWEN);
#ifdef I2C_TIMEOUT uint16_t timeout_timer = timer_read();
uint16_t timeout_timer = timer_read(); while( !(TWCR & (1<<TWINT)) ) {
while( !(TWCR & (1<<TWINT)) ) { if (timeout && (timer_read() - timeout_timer) > I2C_TIMEOUT) {
if ((timer_read() - timeout_timer) > I2C_TIMEOUT) { return I2C_STATUS_TIMEOUT;
return 2; // should make these codes standard
}
} }
#else }
// wait for end of transmission
while( !(TWCR & (1<<TWINT)) );
#endif
if( (TW_STATUS & 0xF8) != TW_MT_DATA_ACK ){ return 1; } if( (TW_STATUS & 0xF8) != TW_MT_DATA_ACK ){ return 1; }
return 0; return 0;
} }
uint8_t i2c_read_ack(void) i2c_status_t i2c_read_ack(uint8_t timeout)
{ {
// start TWI module and acknowledge data after reception // start TWI module and acknowledge data after reception
TWCR = (1<<TWINT) | (1<<TWEN) | (1<<TWEA); TWCR = (1<<TWINT) | (1<<TWEN) | (1<<TWEA);
#ifdef I2C_TIMEOUT uint16_t timeout_timer = timer_read();
uint16_t timeout_timer = timer_read(); while( !(TWCR & (1<<TWINT)) ) {
while( !(TWCR & (1<<TWINT)) ) { if (timeout && (timer_read() - timeout_timer) > I2C_TIMEOUT) {
if ((timer_read() - timeout_timer) > I2C_TIMEOUT) { return I2C_STATUS_TIMEOUT;
return 2; // should make these codes standard
}
} }
#else }
// wait for end of transmission
while( !(TWCR & (1<<TWINT)) );
#endif
// return received data from TWDR // return received data from TWDR
return TWDR; return TWDR;
} }
uint8_t i2c_read_nack(void) i2c_status_t i2c_read_nack(uint8_t timeout)
{ {
// start receiving without acknowledging reception // start receiving without acknowledging reception
TWCR = (1<<TWINT) | (1<<TWEN); TWCR = (1<<TWINT) | (1<<TWEN);
#ifdef I2C_TIMEOUT uint16_t timeout_timer = timer_read();
uint16_t timeout_timer = timer_read(); while( !(TWCR & (1<<TWINT)) ) {
while( !(TWCR & (1<<TWINT)) ) { if (timeout && (timer_read() - timeout_timer) > I2C_TIMEOUT) {
if ((timer_read() - timeout_timer) > I2C_TIMEOUT) { return I2C_STATUS_TIMEOUT;
return 2; // should make these codes standard
}
} }
#else }
// wait for end of transmission
while( !(TWCR & (1<<TWINT)) );
#endif
// return received data from TWDR // return received data from TWDR
return TWDR; return TWDR;
} }
uint8_t i2c_transmit(uint8_t address, uint8_t* data, uint16_t length) i2c_status_t i2c_transmit(uint8_t address, uint8_t* data, uint16_t length)
{ {
if (i2c_start(address | I2C_WRITE)) return 1; if (i2c_start(address | I2C_WRITE)) return 1;
@ -197,22 +172,17 @@ uint8_t i2c_readReg(uint8_t devaddr, uint8_t regaddr, uint8_t* data, uint16_t le
return 0; return 0;
} }
uint8_t i2c_stop(void) i2c_status_t i2c_stop(uint8_t timeout)
{ {
// transmit STOP condition // transmit STOP condition
TWCR = (1<<TWINT) | (1<<TWEN) | (1<<TWSTO); TWCR = (1<<TWINT) | (1<<TWEN) | (1<<TWSTO);
#ifdef I2C_TIMEOUT uint16_t timeout_timer = timer_read();
uint16_t timeout_timer = timer_read(); while(TWCR & (1<<TWSTO)) {
while(TWCR & (1<<TWSTO)) { if (timeout && (timer_read() - timeout_timer) > I2C_TIMEOUT) {
if ((timer_read() - timeout_timer) > I2C_TIMEOUT) { return I2C_STATUS_TIMEOUT;
return 2; // should make these codes standard
}
} }
#else }
// wait for end of transmission
while(TWCR & (1<<TWSTO));
#endif
return 0; return 0;
} }

View file

@ -8,15 +8,20 @@
#define I2C_READ 0x01 #define I2C_READ 0x01
#define I2C_WRITE 0x00 #define I2C_WRITE 0x00
typedef i2c_status_t int16_t
#define I2C_STATUS_TIMEOUT (-1)
#define I2C_NO_TIMEOUT 0
void i2c_init(void); void i2c_init(void);
uint8_t i2c_start(uint8_t address); i2c_status_t i2c_start(uint8_t address, uint8_t timeout);
uint8_t i2c_write(uint8_t data); i2c_status_t i2c_write(uint8_t data, uint8_t timeout);
uint8_t i2c_read_ack(void); i2c_status_t i2c_read_ack(uint8_t timeout);
uint8_t i2c_read_nack(void); i2c_status_t i2c_read_nack(uint8_t timeout);
uint8_t i2c_transmit(uint8_t address, uint8_t* data, uint16_t length); uint8_t i2c_transmit(uint8_t address, uint8_t* data, uint16_t length);
uint8_t i2c_receive(uint8_t address, uint8_t* data, uint16_t length); uint8_t i2c_receive(uint8_t address, uint8_t* data, uint16_t length);
uint8_t i2c_writeReg(uint8_t devaddr, uint8_t regaddr, uint8_t* data, uint16_t length); uint8_t i2c_writeReg(uint8_t devaddr, uint8_t regaddr, uint8_t* data, uint16_t length);
uint8_t i2c_readReg(uint8_t devaddr, uint8_t regaddr, uint8_t* data, uint16_t length); uint8_t i2c_readReg(uint8_t devaddr, uint8_t regaddr, uint8_t* data, uint16_t length);
uint8_t i2c_stop(void); i2c_status_t i2c_stop(uint8_t timeout);
#endif // I2C_MASTER_H #endif // I2C_MASTER_H