diff --git a/i2c.c b/i2c.c index 2e35cae..78b50bb 100644 --- a/i2c.c +++ b/i2c.c @@ -57,13 +57,9 @@ #define I2C_MODE_ENHA 0b00001000 // Transponder is busy. #define I2C_MODE_BUSY 0b01000000 -// Transponder is free. -#define I2C_MODE_FREE 0b10111111 // Transmission interrupted. #define I2C_INTERRUPTED 0b10000000 -// Transmission not interrupted. -#define I2C_NOINTERRUPTED 0b01111111 #define I2C_ERROR 0b00000001 #define I2C_ERROR_LOW_PRIO 0b00100000 @@ -73,7 +69,7 @@ uint8_t i2c_address; // State of TWI component of MCU. -volatile uint8_t i2c_state = I2C_MODE_FREE; +volatile uint8_t i2c_state = 0; /** Wether transmission should be terminated on buffer drain. This also means @@ -207,19 +203,20 @@ uint8_t i2c_busy(void) { */ void i2c_write(uint8_t data, uint8_t last_byte) { + // Drop characters until transmission end. Transmissions to the display + // start with a command byte, so sending truncated transmissions is harmful. + if (i2c_state & I2C_ERROR) { + if (last_byte) { + i2c_state &= ~I2C_ERROR; + } + return; + } + while (i2c_should_end || ! buf_canwrite(send)) { delay_us(10); } - // Recover from error conditions by draining the buffer. - if (i2c_state & I2C_ERROR) { - while (buf_canread(send)) { - buf_pop(send, TWDR); - } - i2c_state = I2C_MODE_FREE; - } - - if (i2c_state & I2C_MODE_FREE) { + if ( ! (i2c_state & I2C_MODE_BUSY)) { // No transmission ongoing, start one. i2c_state = I2C_MODE_SAWP; TWCR = (1<