diff --git a/sw/airborne/i2c.c b/sw/airborne/i2c.c index 90afebd877..ece354c7ab 100644 --- a/sw/airborne/i2c.c +++ b/sw/airborne/i2c.c @@ -71,6 +71,8 @@ void i2c0_transceive(uint8_t slave_addr, uint8_t len_w, uint16_t len_r, volatile #ifdef USE_I2C1 +struct i2c i2c1; + volatile uint8_t i2c1_status; volatile uint8_t i2c1_buf[I2C1_BUF_LEN]; volatile uint16_t i2c1_len_r; @@ -120,43 +122,62 @@ void i2c1_transceive(uint8_t slave_addr, uint8_t len_w, uint16_t len_r, volatile #ifdef USE_I2C2 -struct I2C2_P i2c2; +#include "booz/booz2_debug.h" + +struct i2c i2c2; void i2c2_init(void) { - i2c2.status = I2C_IDLE; + i2c2.status = I2CIdle; i2c2.finished = NULL; i2c2_hw_init(); } void i2c2_receive(uint8_t slave_addr, uint8_t len, volatile bool_t* finished) { - i2c2.direction = I2CDirRx; + MY_ASSERT((i2c2.status == I2CIdle) || (i2c2.status == I2CComplete) || (i2c2.status == I2CFailed)); + i2c2.transaction = I2CTransRx; i2c2.slave_addr = slave_addr; i2c2.len_r = len; i2c2.finished = finished; if (finished) *finished = FALSE; - i2c2.status = I2C_BUSY; - I2c2SendStart(); + i2c2.index = 0; + I2C_AcknowledgeConfig(I2C2, ENABLE); + i2c2.status = I2CStartRequested; + I2C_ZERO_EVENTS(); + // I2c2SendStart(); + I2C_ITConfig(I2C2, I2C_IT_EVT, ENABLE); + I2C_GenerateSTART(I2C2, ENABLE); } void i2c2_transmit(uint8_t slave_addr, uint8_t len, volatile bool_t* finished) { - i2c2.direction = I2CDirTx; + MY_ASSERT((i2c2.status == I2CIdle) || (i2c2.status == I2CComplete) || (i2c2.status == I2CFailed)); + i2c2.transaction = I2CTransTx; i2c2.slave_addr = slave_addr; i2c2.len_w = len; i2c2.finished = finished; if (finished) *finished = FALSE; - i2c2.status = I2C_BUSY; - I2c2SendStart(); + i2c2.index = 0; + i2c2.status = I2CStartRequested; + I2C_ZERO_EVENTS(); + // I2c2SendStart(); + I2C_ITConfig(I2C2, I2C_IT_EVT, ENABLE); + I2C_GenerateSTART(I2C2, ENABLE); } void i2c2_transceive(uint8_t slave_addr, uint8_t len_w, uint16_t len_r, volatile bool_t* finished) { - i2c2.direction = I2CDirTxRx; + MY_ASSERT((i2c2.status == I2CIdle) || (i2c2.status == I2CComplete) || (i2c2.status == I2CFailed)); + i2c2.transaction = I2CTransTxRx; i2c2.slave_addr = slave_addr; i2c2.len_w = len_w; i2c2.len_r = len_r; i2c2.finished = finished; if (finished) *finished = FALSE; - i2c2.status = I2C_BUSY; - I2c2SendStart(); + i2c2.index = 0; + I2C_AcknowledgeConfig(I2C2, ENABLE); + i2c2.status = I2CStartRequested; + I2C_ZERO_EVENTS(); + // I2c2SendStart(); + I2C_ITConfig(I2C2, I2C_IT_EVT, ENABLE); + I2C_GenerateSTART(I2C2, ENABLE); } diff --git a/sw/airborne/i2c.h b/sw/airborne/i2c.h index 619004f5f4..9de9f883fe 100644 --- a/sw/airborne/i2c.h +++ b/sw/airborne/i2c.h @@ -5,6 +5,59 @@ #include "i2c_hw.h" +enum I2CTransaction { + I2CTransTx, + I2CTransRx, + I2CTransTxRx +}; + +enum I2CStatus { + I2CIdle, + I2CStartRequested, + I2CAddrWrSent, + I2CAddrRdSent, + I2CSendingByte, + I2CSendingLastByte, + I2CReadingByte, + I2CReadingLastByte, + I2CStopRequested, + I2CRestartRequested, + I2CComplete, + I2CFailed +}; + +#ifndef I2C_BUF_LEN +#define I2C_BUF_LEN 32 +#endif + +struct i2c { + volatile enum I2CStatus status; + volatile enum I2CTransaction transaction; + volatile uint8_t slave_addr; + volatile uint16_t len_r; + volatile uint8_t len_w; + volatile bool_t stop_after_transmit; + volatile uint8_t index; + volatile bool_t* finished; + volatile uint8_t buf[I2C_BUF_LEN]; +}; + +struct i2c_errors { + volatile uint16_t ack_fail_cnt; + volatile uint16_t miss_start_stop_cnt; + volatile uint16_t arb_lost_cnt; + volatile uint16_t over_under_cnt; + volatile uint16_t pec_recep_cnt; + volatile uint16_t timeout_tlow_cnt; + volatile uint16_t smbus_alert_cnt; + volatile uint16_t unexpected_event_cnt; + volatile uint32_t last_unexpected_event; + volatile uint32_t er_irq_cnt; + volatile uint32_t irq_cnt; + volatile uint32_t event_chain[16]; + volatile enum I2CStatus status_chain[16]; +}; + #define I2C_START 0x08 #define I2C_RESTART 0x10 @@ -114,6 +167,7 @@ extern void i2c1_transmit(uint8_t slave_addr, uint8_t len, volatile bool_t* fini extern void i2c1_transceive(uint8_t slave_addr, uint8_t len_w, uint16_t len_r, volatile bool_t* finished); extern volatile uint8_t i2c1_status; +extern struct i2c i2c1; #ifndef I2C1_BUF_LEN #define I2C1_BUF_LEN 16 @@ -189,25 +243,8 @@ extern volatile bool_t* i2c1_finished; #ifdef USE_I2C2 -#ifndef I2C2_BUF_LEN -#define I2C2_BUF_LEN 32 -#endif -enum I2CDirection { I2CDirTx, I2CDirRx, I2CDirTxRx }; - -struct I2C2_P { - volatile uint8_t status; - enum I2CDirection direction; - volatile uint8_t slave_addr; - volatile uint16_t len_r; - volatile uint8_t len_w; - volatile bool_t stop_after_transmit; - volatile uint8_t index; - volatile bool_t* finished; - volatile uint8_t buf[I2C2_BUF_LEN]; -}; - -extern struct I2C2_P i2c2; +extern struct i2c i2c2; extern void i2c2_init(void); extern void i2c2_receive(uint8_t slave_addr, uint8_t len, volatile bool_t* finished);