diff --git a/sw/airborne/booz/actuators/booz_actuators_asctec.c b/sw/airborne/booz/actuators/booz_actuators_asctec.c index 040901ae16..9f2ecb53de 100644 --- a/sw/airborne/booz/actuators/booz_actuators_asctec.c +++ b/sw/airborne/booz/actuators/booz_actuators_asctec.c @@ -37,7 +37,7 @@ void actuators_init(void) { actuators_asctec.cmd = NONE; actuators_asctec.cur_addr = FRONT; actuators_asctec.new_addr = FRONT; - actuators_asctec.i2c_done = TRUE; + actuators_asctec.i2c_trans.status = I2CTransSuccess; actuators_asctec.nb_err = 0; #if defined BOOZ_START_DELAY && ! defined SITL @@ -63,7 +63,7 @@ void actuators_set(bool_t motors_on) { } #endif - if (!actuators_asctec.i2c_done) + if (!actuators_asctec.i2c_trans.status == I2CTransSuccess) actuators_asctec.nb_err++; #ifdef KILL_MOTORS @@ -88,59 +88,65 @@ void actuators_set(bool_t motors_on) { switch (actuators_asctec.cmd) { case TEST: - DeviceBuf[0] = 251; - DeviceBuf[1] = actuators_asctec.cur_addr; - DeviceBuf[2] = 0; - DeviceBuf[3] = 231 + actuators_asctec.cur_addr; + actuators_asctec.i2c_trans.buf[0] = 251; + actuators_asctec.i2c_trans.buf[1] = actuators_asctec.cur_addr; + actuators_asctec.i2c_trans.buf[2] = 0; + actuators_asctec.i2c_trans.buf[3] = 231 + actuators_asctec.cur_addr; break; case REVERSE: - DeviceBuf[0] = 254; - DeviceBuf[1] = actuators_asctec.cur_addr; - DeviceBuf[2] = 0; - DeviceBuf[3] = 234 + actuators_asctec.cur_addr; + actuators_asctec.i2c_trans.buf[0] = 254; + actuators_asctec.i2c_trans.buf[1] = actuators_asctec.cur_addr; + actuators_asctec.i2c_trans.buf[2] = 0; + actuators_asctec.i2c_trans.buf[3] = 234 + actuators_asctec.cur_addr; break; case SET_ADDR: - DeviceBuf[0] = 250; - DeviceBuf[1] = actuators_asctec.cur_addr; - DeviceBuf[2] = actuators_asctec.new_addr; - DeviceBuf[3] = 230 + actuators_asctec.cur_addr + actuators_asctec.new_addr; + actuators_asctec.i2c_trans.buf[0] = 250; + actuators_asctec.i2c_trans.buf[1] = actuators_asctec.cur_addr; + actuators_asctec.i2c_trans.buf[2] = actuators_asctec.new_addr; + actuators_asctec.i2c_trans.buf[3] = 230 + actuators_asctec.cur_addr + actuators_asctec.new_addr; actuators_asctec.cur_addr = actuators_asctec.new_addr; break; case NONE: - DeviceBuf[0] = 100 - actuators_asctec.cmds[PITCH]; - DeviceBuf[1] = 100 + actuators_asctec.cmds[ROLL]; - DeviceBuf[2] = 100 - actuators_asctec.cmds[YAW]; - DeviceBuf[3] = actuators_asctec.cmds[THRUST]; + actuators_asctec.i2c_trans.buf[0] = 100 - actuators_asctec.cmds[PITCH]; + actuators_asctec.i2c_trans.buf[1] = 100 + actuators_asctec.cmds[ROLL]; + actuators_asctec.i2c_trans.buf[2] = 100 - actuators_asctec.cmds[YAW]; + actuators_asctec.i2c_trans.buf[3] = actuators_asctec.cmds[THRUST]; break; default: break; } actuators_asctec.cmd = NONE; - actuators_asctec.i2c_done = FALSE; - DeviceTransmit(0x02, 4, &actuators_asctec.i2c_done); + + i2c_submit(&i2c1,&actuators_asctec.i2c_trans); + // actuators_asctec.i2c_done = FALSE; + // DeviceTransmit(0x02, 4, &actuators_asctec.i2c_done); + } #else /* ! ACTUATORS_ASCTEC_V2_PROTOCOL */ void actuators_set(bool_t motors_on) { if (!cpu_time_sec) return; // FIXME supervision_run(motors_on, FALSE, booz2_commands); #ifdef KILL_MOTORS - DeviceBuf[0] = 0; - DeviceBuf[1] = 0; - DeviceBuf[2] = 0; - DeviceBuf[3] = 0; - DeviceBuf[4] = 0xAA; + actuators_asctec.i2c_trans.buf[0] = 0; + actuators_asctec.i2c_trans.buf[1] = 0; + actuators_asctec.i2c_trans.buf[2] = 0; + actuators_asctec.i2c_trans.buf[3] = 0; + actuators_asctec.i2c_trans.buf[4] = 0xAA; #else - DeviceBuf[0] = supervision.commands[SERVO_FRONT]; - DeviceBuf[1] = supervision.commands[SERVO_BACK]; - DeviceBuf[2] = supervision.commands[SERVO_LEFT]; - DeviceBuf[3] = supervision.commands[SERVO_RIGHT]; - DeviceBuf[4] = 0xAA + DeviceBuf[0] + DeviceBuf[1] + DeviceBuf[2] + DeviceBuf[3]; + actuators_asctec.i2c_trans.buf[0] = supervision.commands[SERVO_FRONT]; + actuators_asctec.i2c_trans.buf[1] = supervision.commands[SERVO_BACK]; + actuators_asctec.i2c_trans.buf[2] = supervision.commands[SERVO_LEFT]; + actuators_asctec.i2c_trans.buf[3] = supervision.commands[SERVO_RIGHT]; + actuators_asctec.i2c_trans.buf[4] = 0xAA + actuators_asctec.i2c_trans.buf[0] + actuators_asctec.i2c_trans.buf[1] + + actuators_asctec.i2c_trans.buf[2] + actuators_asctec.i2c_trans.buf[3]; #endif - if (actuators_asctec.i2c_done) { - actuators_asctec.i2c_done = FALSE; - DeviceTransmit(0x02, 5, &actuators_asctec.i2c_done); - } + i2c_submit(&i2c1,&actuators_asctec.i2c_trans); + // if (actuators_asctec.i2c_done) { + //actuators_asctec.i2c_done = FALSE; + // DeviceTransmit(0x02, 5, &actuators_asctec.i2c_done); + // } + } #endif /* ACTUATORS_ASCTEC_V2_PROTOCOL */ diff --git a/sw/airborne/booz/actuators/booz_actuators_asctec.h b/sw/airborne/booz/actuators/booz_actuators_asctec.h index 59316f66c4..337f0060d3 100644 --- a/sw/airborne/booz/actuators/booz_actuators_asctec.h +++ b/sw/airborne/booz/actuators/booz_actuators_asctec.h @@ -24,6 +24,8 @@ #ifndef BOOZ_ACTUATORS_ASCTEC_H #define BOOZ_ACTUATORS_ASCTEC_H +#include "i2c.h" + enum actuators_astec_cmd { NONE, TEST, REVERSE, @@ -46,7 +48,7 @@ struct ActuatorsAsctec { enum actuators_astec_addr cur_addr; enum actuators_astec_addr new_addr; int32_t cmds[CMD_NB]; - volatile bool_t i2c_done; + struct i2c_transaction i2c_trans; volatile uint32_t nb_err; }; diff --git a/sw/airborne/booz/arch/stm32/imu/booz_imu_aspirin_arch.c b/sw/airborne/booz/arch/stm32/imu/booz_imu_aspirin_arch.c index 33a2ea0aa5..ebd8e76d30 100644 --- a/sw/airborne/booz/arch/stm32/imu/booz_imu_aspirin_arch.c +++ b/sw/airborne/booz/arch/stm32/imu/booz_imu_aspirin_arch.c @@ -239,7 +239,7 @@ void exti15_10_irq_handler(void) { imu_aspirin.i2c_trans_gyro.slave_addr = ITG3200_ADDR; imu_aspirin.i2c_trans_gyro.len_w = 1; imu_aspirin.i2c_trans_gyro.len_r = 6; - i2c_submit(&i2c2,&imu_aspirin.i2c_trans_gyro); + if (!i2c_submit(&i2c2,&imu_aspirin.i2c_trans_gyro)) while(1); imu_aspirin.status = AspirinStatusReadingGyro; } diff --git a/sw/airborne/i2c.c b/sw/airborne/i2c.c index c0a8079134..bb05e2734f 100644 --- a/sw/airborne/i2c.c +++ b/sw/airborne/i2c.c @@ -71,55 +71,16 @@ 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; -volatile uint8_t i2c1_len_w; -volatile uint16_t i2c1_index; -volatile uint8_t i2c1_slave_addr; -volatile uint8_t i2c1_trx; - -volatile bool_t* i2c1_finished; +struct i2c_periph i2c1; void i2c1_init(void) { - i2c1_status = I2C_IDLE; - i2c1_hw_init(); - i2c1_finished = NULL; -} - - -void i2c1_receive(uint8_t slave_addr, uint16_t len, volatile bool_t* finished) { - i2c1_trx = 0; - i2c1_len_r = len; - i2c1_slave_addr = slave_addr | I2C_RECEIVE; - i2c1_finished = finished; - i2c1_status = I2C_BUSY; - I2c1SendStart(); -} - -void i2c1_transmit(uint8_t slave_addr, uint8_t len, volatile bool_t* finished) { - i2c1_trx = 0; - i2c1_len_w = len; - i2c1_slave_addr = slave_addr & ~I2C_RECEIVE; - i2c1_finished = finished; - i2c1_status = I2C_BUSY; - I2c1SendStart(); -} - -void i2c1_transceive(uint8_t slave_addr, uint8_t len_w, uint16_t len_r, volatile bool_t* finished) { - i2c1_trx = 1; - i2c1_len_w = len_w; - i2c1_len_r = len_r; - i2c1_slave_addr = slave_addr & ~I2C_RECEIVE; - i2c1_finished = finished; - i2c1_status = I2C_BUSY; - I2c1SendStart(); + i2c_init(&i2c2); + i2c2_hw_init(); } #endif /* USE_I2C1 */ + #ifdef USE_I2C2 #include "booz/booz2_debug.h" @@ -131,6 +92,8 @@ void i2c2_init(void) { i2c2_hw_init(); } +#endif /* USE_I2C2 */ + void i2c_init(struct i2c_periph* p) { p->trans_insert_idx = 0; p->trans_extract_idx = 0; @@ -138,5 +101,3 @@ void i2c_init(struct i2c_periph* p) { } -#endif /* USE_I2C2 */ - diff --git a/sw/airborne/i2c.h b/sw/airborne/i2c.h index d36af3fe16..6448b81549 100644 --- a/sw/airborne/i2c.h +++ b/sw/airborne/i2c.h @@ -107,28 +107,6 @@ extern volatile bool_t* i2c0_finished; #ifdef USE_I2C1 -extern void i2c1_init(void); -extern void i2c1_receive(uint8_t slave_addr, uint16_t len, volatile bool_t* finished); -extern void i2c1_transmit(uint8_t slave_addr, uint8_t len, volatile bool_t* finished); -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 -#endif - -extern volatile uint8_t i2c1_buf[I2C1_BUF_LEN]; -extern volatile uint16_t i2c1_len_r; -extern volatile uint8_t i2c1_len_w; -extern volatile uint16_t i2c1_index; -extern volatile uint8_t i2c1_slave_addr; -extern volatile uint8_t i2c1_trx; - -extern volatile bool_t* i2c1_finished; - - extern struct i2c_periph i2c1; extern void i2c1_init(void); diff --git a/sw/airborne/stm32/i2c_hw.c b/sw/airborne/stm32/i2c_hw.c index 2b5d593926..22a96aa523 100644 --- a/sw/airborne/stm32/i2c_hw.c +++ b/sw/airborne/stm32/i2c_hw.c @@ -18,6 +18,9 @@ _i2c_err.er_irq_cnt = 0; \ } +static void start_transaction(struct i2c_periph* p); + + #ifdef USE_I2C1 @@ -26,7 +29,6 @@ struct i2c_errors i2c1_errors; #include "my_debug_servo.h" #define I2C1_APPLY_CONFIG() { \ - \ I2C_InitTypeDef I2C_InitStructure; \ I2C_InitStructure.I2C_Mode = I2C_Mode_I2C; \ I2C_InitStructure.I2C_DutyCycle = I2C_DutyCycle_2; \ @@ -35,20 +37,31 @@ struct i2c_errors i2c1_errors; I2C_InitStructure.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit; \ I2C_InitStructure.I2C_ClockSpeed = 200000; \ I2C_Init(I2C1, &I2C_InitStructure); \ - \ + } + +#define I2C1_END_OF_TRANSACTION() { \ + i2c1.trans_extract_idx++; \ + if (i2c1.trans_extract_idx>=I2C_TRANSACTION_QUEUE_LEN) \ + i2c1.trans_extract_idx = 0; \ + /* if we have no more transaction to process, stop here */ \ + if (i2c1.trans_extract_idx == i2c1.trans_insert_idx) \ + i2c1.status = I2CIdle; \ + /* if not, start next transaction */ \ + else \ + start_transaction(&i2c1); \ } #define I2C1_ABORT_AND_RESET() { \ - \ - if (i2c1_finished) \ - *i2c1_finished = TRUE; \ - i2c1_status = I2C_IDLE; \ + struct i2c_transaction* trans = i2c1.trans[i2c1.trans_extract_idx]; \ + trans->status = I2CTransFailed; \ + i2c1.status = I2CFailed; \ I2C_ITConfig(I2C1, I2C_IT_EVT | I2C_IT_BUF | I2C_IT_ERR, DISABLE); \ I2C_Cmd(I2C1, DISABLE); \ + I2C_DeInit(I2C1); \ I2C_Cmd(I2C1, ENABLE); \ I2C1_APPLY_CONFIG(); \ I2C_ITConfig(I2C1, I2C_IT_ERR, ENABLE); \ - \ + I2C1_END_OF_TRANSACTION(); \ } // @@ -63,6 +76,8 @@ struct i2c_errors i2c1_errors; void i2c1_hw_init(void) { + i2c1.reg_addr = I2C1; + /* zeros error counter */ ZEROS_ERR_COUNTER(i2c1_errors); @@ -115,16 +130,17 @@ void i2c1_hw_init(void) { void i2c1_ev_irq_handler(void) { uint32_t event = I2C_GetLastEvent(I2C1); + struct i2c_transaction* trans = i2c2.trans[i2c2.trans_extract_idx]; switch (event) { /* EV5 */ case I2C_EVENT_MASTER_MODE_SELECT: - if (i2c1.transaction == I2CTransTx || i2c1.transaction == I2CTransTxRx) { + if (trans->type == I2CTransTx || trans->type == I2CTransTxRx) { /* Master Transmitter : Send slave Address for write */ - I2C_Send7bitAddress(I2C1, (i2c1_slave_addr&0xFE), I2C_Direction_Transmitter); + I2C_Send7bitAddress(I2C1, (trans->slave_addr&0xFE), I2C_Direction_Transmitter); } else { /* Master Receiver : Send slave Address for read */ - I2C_Send7bitAddress(I2C1, (i2c1_slave_addr&0xFE), I2C_Direction_Receiver); + I2C_Send7bitAddress(I2C1, (trans->slave_addr&0xFE), I2C_Direction_Receiver); } break; @@ -133,18 +149,18 @@ void i2c1_ev_irq_handler(void) { case I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED: /* enable empty dr if we have more than one byte to send */ // if (i2c1_len_w > 1) - I2C_ITConfig(I2C1, I2C_IT_BUF, ENABLE); + I2C_ITConfig(I2C1, I2C_IT_BUF, ENABLE); /* Send the first data */ - I2C_SendData(I2C1, i2c1_buf[0]); - i2c1_index = 1; + I2C_SendData(I2C1, trans->buf[0]); + i2c1.idx_buf = 1; break; /* Test on I2C1 EV8 and clear it */ case I2C_EVENT_MASTER_BYTE_TRANSMITTING: /* Without BTF, EV8 */ // DEBUG_S5_TOGGLE(); - if(i2c1_index < i2c1_len_w) { - I2C_SendData(I2C1, i2c1_buf[i2c1_index]); - i2c1_index++; + if(i2c1.idx_buf < trans->len_w) { + I2C_SendData(I2C1, trans->buf[i2c1.idx_buf]); + i2c1.idx_buf++; } else { I2C_GenerateSTOP(I2C1, ENABLE); @@ -155,19 +171,16 @@ void i2c1_ev_irq_handler(void) { case I2C_EVENT_MASTER_BYTE_TRANSMITTED: /* With BTF EV8-2 */ // DEBUG_S6_TOGGLE(); - if(i2c1_index < i2c1_len_w) { - I2C_SendData(I2C1, i2c1_buf[i2c1_index]); - i2c1_index++; + if(i2c1.idx_buf < trans->len_w) { + I2C_SendData(I2C1, trans->buf[i2c1.idx_buf]); + i2c1.idx_buf++; } else { - if (i2c1_finished) - *i2c1_finished = TRUE; - i2c1_status = I2C_IDLE; - // I2C_GenerateSTOP(I2C1, ENABLE); + trans->status = I2CTransSuccess; I2C_ITConfig(I2C1, I2C_IT_EVT, DISABLE); + I2C1_END_OF_TRANSACTION(); } - // while (I2C_GetFlagStatus(I2C1, I2C_FLAG_MSL)); - // I2c1StopHandler(); + // while (I2C_GetFlagStatus(I2C1, I2C_FLAG_MSL)); break; default: @@ -238,7 +251,6 @@ void i2c1_er_irq_handler(void) { // 196610 30002 BUSY MSL | ADDR // -static void start_transaction(struct i2c_periph* p); struct i2c_errors i2c2_errors; @@ -334,6 +346,33 @@ static inline void on_status_restart_requested(struct i2c_transaction* trans, ui #define OUT_OF_SYNC_STATE_MACHINE(_status, _event) {} #endif + +#define I2C2_END_OF_TRANSACTION() { \ + i2c2.trans_extract_idx++; \ + if (i2c2.trans_extract_idx>=I2C_TRANSACTION_QUEUE_LEN) \ + i2c2.trans_extract_idx = 0; \ + /* if we have no more transaction to process, stop here */ \ + if (i2c2.trans_extract_idx == i2c2.trans_insert_idx) \ + i2c2.status = I2CIdle; \ + /* if not, start next transaction */ \ + else \ + start_transaction(&i2c2); \ + } + +#define I2C2_ABORT_AND_RESET() { \ + struct i2c_transaction* trans = i2c2.trans[i2c2.trans_extract_idx]; \ + trans->status = I2CTransFailed; \ + I2C_ITConfig(I2C2, I2C_IT_EVT | I2C_IT_BUF | I2C_IT_ERR, DISABLE); \ + I2C_Cmd(I2C2, DISABLE); \ + I2C_DeInit(I2C2); \ + I2C_Cmd(I2C2, ENABLE); \ + I2C2_APPLY_CONFIG(); \ + I2C_ITConfig(I2C2, I2C_IT_ERR, ENABLE); \ + I2C2_END_OF_TRANSACTION(); \ + } + + + /* * Start Requested * @@ -446,14 +485,7 @@ static inline void on_status_stop_requested(struct i2c_transaction* trans, uint3 } I2C_ITConfig(I2C2, I2C_IT_EVT|I2C_IT_BUF, DISABLE); // should only need to disable evt, buf already disabled trans->status = I2CTransSuccess; - - i2c2.trans_extract_idx = (i2c2.trans_extract_idx+1)%I2C_TRANSACTION_QUEUE_LEN; - /* if we have no more transacation to process, stop here */ - if (i2c2.trans_extract_idx == i2c2.trans_insert_idx) - i2c2.status = I2CIdle; - /* if not, start next transaction */ - else - start_transaction(&i2c2); + I2C2_END_OF_TRANSACTION(); } /* @@ -618,26 +650,6 @@ void i2c2_ev_irq_handler(void) { } -#define I2C2_ABORT_AND_RESET() { \ - struct i2c_transaction* trans = i2c2.trans[i2c2.trans_extract_idx]; \ - trans->status = I2CTransFailed; \ - i2c2.status = I2CFailed; \ - I2C_ITConfig(I2C2, I2C_IT_EVT | I2C_IT_BUF | I2C_IT_ERR, DISABLE); \ - I2C_Cmd(I2C2, DISABLE); \ - I2C_DeInit(I2C2); \ - I2C_Cmd(I2C2, ENABLE); \ - I2C2_APPLY_CONFIG(); \ - I2C_ITConfig(I2C2, I2C_IT_ERR, ENABLE); \ - \ - i2c2.trans_extract_idx++; \ - /* if we have no more transacation to process, stop here */ \ - if (i2c2.trans_extract_idx == i2c2.trans_insert_idx) \ - i2c2.status = I2CIdle; \ - /* if not, start next transaction */ \ - else \ - start_transaction(&i2c2); \ - } - void i2c2_er_irq_handler(void) { // DEBUG_S5_ON(); i2c2_errors.er_irq_cnt; @@ -687,7 +699,8 @@ void i2c2_er_irq_handler(void) { bool_t i2c_submit(struct i2c_periph* p, struct i2c_transaction* t) { uint8_t temp; - temp = (p->trans_insert_idx + 1) % I2C_TRANSACTION_QUEUE_LEN; + temp = p->trans_insert_idx + 1; + if (temp >= I2C_TRANSACTION_QUEUE_LEN) temp = 0; if (temp == p->trans_extract_idx) return FALSE; // queue full diff --git a/sw/airborne/stm32/i2c_hw.h b/sw/airborne/stm32/i2c_hw.h index b103e96c97..c64d23c46c 100644 --- a/sw/airborne/stm32/i2c_hw.h +++ b/sw/airborne/stm32/i2c_hw.h @@ -34,47 +34,24 @@ #ifdef USE_I2C1 +extern struct i2c_errors i2c1_errors; + extern void i2c1_hw_init(void); extern void i2c1_ev_irq_handler(void); extern void i2c1_er_irq_handler(void); -extern struct i2c_errors i2c1_errors; - -#define I2c1SendStart() { I2C_GenerateSTART(I2C1, ENABLE); I2C_ITConfig(I2C1, I2C_IT_EVT|I2C_IT_BUF, ENABLE);} - -#ifdef I2C1_STOP_HANDLER -#include I2C1_STOP_HANDLER_HEADER -#define I2c1StopHandler() I2C1_STOP_HANDLER() -#else -#define I2c1StopHandler() {} -#endif /* I2C1_STOP_HANDLER */ - #endif /* USE_I2C1 */ #ifdef USE_I2C2 -/* - This is a hook for a caller module to provide - code to be called in the interrupt handler - at the end of a transfert -*/ -#ifdef I2C2_STOP_HANDLER -#include I2C2_STOP_HANDLER_HEADER -#define I2c2StopHandler() I2C2_STOP_HANDLER() -#else -#define I2c2StopHandler() {} -#endif /* I2C2_STOP_HANDLER */ - +extern struct i2c_errors i2c2_errors; extern void i2c2_hw_init(void); extern void i2c2_ev_irq_handler(void); extern void i2c2_er_irq_handler(void); -extern struct i2c_errors i2c2_errors; - -//#define I2c2SendStart() {I2C_GenerateSTART(I2C2, ENABLE); I2C_ITConfig(I2C2, I2C_IT_EVT, ENABLE);} #include #define I2C_ZERO_EVENTS() { \ i2c2_errors.irq_cnt = 0; \