summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rwxr-xr-xdrivers/avr/i2c_master.c102
-rwxr-xr-xdrivers/avr/i2c_master.h15
2 files changed, 46 insertions, 71 deletions
diff --git a/drivers/avr/i2c_master.c b/drivers/avr/i2c_master.c
index 97f6900436..caca2179e0 100755
--- a/drivers/avr/i2c_master.c
+++ b/drivers/avr/i2c_master.c
@@ -19,24 +19,19 @@ void i2c_init(void)
//TWBR = 10;
}
-uint8_t i2c_start(uint8_t address)
+i2c_status_t i2c_start(uint8_t address, uint8_t timeout)
{
// reset TWI control register
TWCR = 0;
// transmit START condition
TWCR = (1<<TWINT) | (1<<TWSTA) | (1<<TWEN);
- #ifdef I2C_TIMEOUT
- uint16_t timeout_timer = timer_read();
- while( !(TWCR & (1<<TWINT)) ) {
- if ((timer_read() - timeout_timer) > I2C_TIMEOUT) {
- return 2; // should make these codes standard
- }
+ uint16_t timeout_timer = timer_read();
+ while( !(TWCR & (1<<TWINT)) ) {
+ if (timeout && (timer_read() - timeout_timer) > timeout) {
+ return I2C_STATUS_TIMEOUT;
}
- #else
- // wait for end of transmission
- while( !(TWCR & (1<<TWINT)) );
- #endif
+ }
// check if the start condition was successfully transmitted
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
TWCR = (1<<TWINT) | (1<<TWEN);
- #ifdef I2C_TIMEOUT
- timeout_timer = timer_read();
- while( !(TWCR & (1<<TWINT)) ) {
- if ((timer_read() - timeout_timer) > I2C_TIMEOUT) {
- return 2; // should make these codes standard
- }
+ timeout_timer = timer_read();
+ while( !(TWCR & (1<<TWINT)) ) {
+ if (timeout && (timer_read() - timeout_timer) > I2C_TIMEOUT) {
+ return I2C_STATUS_TIMEOUT;
}
- #else
- // wait for end of transmission
- while( !(TWCR & (1<<TWINT)) );
- #endif
+ }
// check if the device has acknowledged the READ / WRITE mode
uint8_t twst = TW_STATUS & 0xF8;
@@ -65,75 +55,60 @@ uint8_t i2c_start(uint8_t address)
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
TWDR = data;
// start transmission of data
TWCR = (1<<TWINT) | (1<<TWEN);
- #ifdef I2C_TIMEOUT
- uint16_t timeout_timer = timer_read();
- while( !(TWCR & (1<<TWINT)) ) {
- if ((timer_read() - timeout_timer) > I2C_TIMEOUT) {
- return 2; // should make these codes standard
- }
+ uint16_t timeout_timer = timer_read();
+ while( !(TWCR & (1<<TWINT)) ) {
+ if (timeout && (timer_read() - timeout_timer) > I2C_TIMEOUT) {
+ return I2C_STATUS_TIMEOUT;
}
- #else
- // wait for end of transmission
- while( !(TWCR & (1<<TWINT)) );
- #endif
+ }
if( (TW_STATUS & 0xF8) != TW_MT_DATA_ACK ){ return 1; }
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
TWCR = (1<<TWINT) | (1<<TWEN) | (1<<TWEA);
- #ifdef I2C_TIMEOUT
- uint16_t timeout_timer = timer_read();
- while( !(TWCR & (1<<TWINT)) ) {
- if ((timer_read() - timeout_timer) > I2C_TIMEOUT) {
- return 2; // should make these codes standard
- }
+ uint16_t timeout_timer = timer_read();
+ while( !(TWCR & (1<<TWINT)) ) {
+ if (timeout && (timer_read() - timeout_timer) > I2C_TIMEOUT) {
+ return I2C_STATUS_TIMEOUT;
}
- #else
- // wait for end of transmission
- while( !(TWCR & (1<<TWINT)) );
- #endif
+ }
// return received data from TWDR
return TWDR;
}
-uint8_t i2c_read_nack(void)
+i2c_status_t i2c_read_nack(uint8_t timeout)
{
// start receiving without acknowledging reception
TWCR = (1<<TWINT) | (1<<TWEN);
- #ifdef I2C_TIMEOUT
- uint16_t timeout_timer = timer_read();
- while( !(TWCR & (1<<TWINT)) ) {
- if ((timer_read() - timeout_timer) > I2C_TIMEOUT) {
- return 2; // should make these codes standard
- }
+ uint16_t timeout_timer = timer_read();
+ while( !(TWCR & (1<<TWINT)) ) {
+ if (timeout && (timer_read() - timeout_timer) > I2C_TIMEOUT) {
+ return I2C_STATUS_TIMEOUT;
}
- #else
- // wait for end of transmission
- while( !(TWCR & (1<<TWINT)) );
- #endif
+ }
// return received data from 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;
@@ -197,22 +172,17 @@ uint8_t i2c_readReg(uint8_t devaddr, uint8_t regaddr, uint8_t* data, uint16_t le
return 0;
}
-uint8_t i2c_stop(void)
+i2c_status_t i2c_stop(uint8_t timeout)
{
// transmit STOP condition
TWCR = (1<<TWINT) | (1<<TWEN) | (1<<TWSTO);
- #ifdef I2C_TIMEOUT
- uint16_t timeout_timer = timer_read();
- while(TWCR & (1<<TWSTO)) {
- if ((timer_read() - timeout_timer) > I2C_TIMEOUT) {
- return 2; // should make these codes standard
- }
+ uint16_t timeout_timer = timer_read();
+ while(TWCR & (1<<TWSTO)) {
+ if (timeout && (timer_read() - timeout_timer) > I2C_TIMEOUT) {
+ return I2C_STATUS_TIMEOUT;
}
- #else
- // wait for end of transmission
- while(TWCR & (1<<TWSTO));
- #endif
+ }
return 0;
}
diff --git a/drivers/avr/i2c_master.h b/drivers/avr/i2c_master.h
index 8686807146..3c7731e8dc 100755
--- a/drivers/avr/i2c_master.h
+++ b/drivers/avr/i2c_master.h
@@ -8,15 +8,20 @@
#define I2C_READ 0x01
#define I2C_WRITE 0x00
+typedef i2c_status_t int16_t
+#define I2C_STATUS_TIMEOUT (-1)
+
+#define I2C_NO_TIMEOUT 0
+
void i2c_init(void);
-uint8_t i2c_start(uint8_t address);
-uint8_t i2c_write(uint8_t data);
-uint8_t i2c_read_ack(void);
-uint8_t i2c_read_nack(void);
+i2c_status_t i2c_start(uint8_t address, uint8_t timeout);
+i2c_status_t i2c_write(uint8_t data, uint8_t timeout);
+i2c_status_t i2c_read_ack(uint8_t timeout);
+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_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_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