diff --git a/conf/telemetry/AGGIEAIR/aggieair_rotorcraft.xml b/conf/telemetry/AGGIEAIR/aggieair_rotorcraft.xml index 2ed92de2fa..633107ed63 100644 --- a/conf/telemetry/AGGIEAIR/aggieair_rotorcraft.xml +++ b/conf/telemetry/AGGIEAIR/aggieair_rotorcraft.xml @@ -32,7 +32,6 @@ - diff --git a/sw/airborne/modules/adcs/battery_monitor.c b/sw/airborne/modules/adcs/battery_monitor.c index 51da5c3871..010fbde9d9 100644 --- a/sw/airborne/modules/adcs/battery_monitor.c +++ b/sw/airborne/modules/adcs/battery_monitor.c @@ -60,23 +60,23 @@ static void send_batmon(struct transport_tx *trans, struct link_device *dev) uint8_t batmonbal1_bus_trans_status = batmonbal1.bus_trans.status; uint8_t batmonbal2_bus_trans_status = batmonbal2.bus_trans.status; pprz_msg_send_BATTERY_MONITOR(trans, dev, AC_ID, - &version, - &batmonbus.bus_status, - &batmonbus_bus_trans_status, - &batmonbus.bus_current_mvolts, - &batmonbus.bus_current, - &batmonbus.bus_voltage_mvolts, - TEMP_SENSORS_NB, - batmonbus.bus_tempsensors_mvolts, - TEMP_SENSORS_NB, - batmonbus.bus_temp, - &batmonbal1_bus_trans_status, - BATTERY_CELLS_NB, - batmonbal1.bat_cell_mvolts, - &batmonbal2_bus_trans_status, - BATTERY_CELLS_NB, - batmonbal2.bat_cell_mvolts, - &power_status); + &version, + &batmonbus.bus_status, + &batmonbus_bus_trans_status, + &batmonbus.bus_current_mvolts, + &batmonbus.bus_current, + &batmonbus.bus_voltage_mvolts, + TEMP_SENSORS_NB, + batmonbus.bus_tempsensors_mvolts, + TEMP_SENSORS_NB, + batmonbus.bus_temp, + &batmonbal1_bus_trans_status, + BATTERY_CELLS_NB, + batmonbal1.bat_cell_mvolts, + &batmonbal2_bus_trans_status, + BATTERY_CELLS_NB, + batmonbal2.bat_cell_mvolts, + &power_status); } #endif @@ -110,7 +110,7 @@ void battery_monitor_init_bus(void){ // transactions batmonbus.bus_trans.status = I2CTransDone; batmonbus.addr = BATTERY_MONITOR_BUS_ADC_I2C_ADDR; - batmonbus.bus_status = BATTERY_MONITOR_BUS_CURRENT; // device status + batmonbus.bus_status = BATTERY_MONITOR_BUS_CURRENT_REQ; // device status // Current readings batmonbus.bus_current_mvolts = 0; // mV batmonbus.bus_current = 0; // A @@ -125,7 +125,7 @@ void battery_monitor_init_bus(void){ } /** - * Initalizes balance ADC 1 + * Initalizes balance ADC */ void battery_monitor_init_balance(struct BatMonBal* batmonbal){ batmonbal->bus_trans.status = I2CTransDone; @@ -156,9 +156,39 @@ void battery_monitor_init(void) { /** * Event function + * Check i2c transaction status for each device */ void battery_monitor_event(void){ - // Empty for now + battery_monitor_check_i2c_transaction(&batmonbal1.bus_trans); + battery_monitor_check_i2c_transaction(&batmonbal2.bus_trans); + battery_monitor_check_i2c_transaction(&batmonbus.bus_trans); +} + +/** + * Complete i2c transactions once they succeed or fail + */ +void battery_monitor_check_i2c_transaction(struct i2c_transaction* t){ + switch (t->status) { + case I2CTransPending: + // wait and do nothing + break; + case I2CTransRunning: + // wait and do nothing + break; + case I2CTransSuccess: + // set to done + t->status = I2CTransDone; + break; + case I2CTransFailed: + // set to done + t->status = I2CTransDone; + break; + case I2CTransDone: + // do nothing + break; + default: + break; + } } /** @@ -168,126 +198,137 @@ void battery_monitor_read_bus(void){ batmonbus.data = 0; // erase at each iteration switch (batmonbus.bus_status) { - case BATTERY_MONITOR_BUS_CURRENT: + // reqtest BUS_CURRENT measurement + case BATTERY_MONITOR_BUS_CURRENT_REQ: // set ADC to current channel batmonbus.bus_trans.buf[0] = battery_monitor_get_address( - (uint8_t)BATTERY_MONITOR_BUS_CURRENT_CHANNEL); + (uint8_t)BATTERY_MONITOR_BUS_CURRENT_CHANNEL); //set to zero so we can detect an error batmonbus.bus_current = 0; - // blocking transaction - if (i2c_transceive(&BATTERY_MONITOR_I2C_DEV, &batmonbus.bus_trans, batmonbus.addr, 1, 2)){ - // proceed only if transaction was submitted successfully - if (batmonbus.bus_trans.status == I2CTransSuccess) { - // read data - batmonbus.data = (uint16_t) (batmonbus.bus_trans.buf[0] << 8 | batmonbus.bus_trans.buf[1]); - // NOTE: we are not using the ALERT_FLAG at the moment, - // get counts - batmonbus.bus_current_mvolts = batmonbus.data & 0xFFF; - // shift right by 2 bits if 10-bit reads only - if (BATTERY_MONITOR_BIT_RES == 10){ - batmonbus.bus_current_mvolts = (batmonbus.bus_current_mvolts) >> 2; - } - // convert to mV - batmonbus.bus_current_mvolts = (uint16_t)( - (float)batmonbus.bus_current_mvolts * BATTERY_MONITOR_VREF_MULT); - // convert to [A] - batmonbus.bus_current = ((float)batmonbus.bus_current_mvolts + - (float)batmon_current_offset) / batmon_current_sensitivity; - } - // optional: check for errors and reset i2c transaction - // shouldn't be needed - // update status - batmonbus.bus_status = BATTERY_MONITOR_BUS_VOLTAGE; + // non-blocking transaction + if (i2c_transceive(&BATTERY_MONITOR_I2C_DEV, &batmonbus.bus_trans, batmonbus.addr, 1, 2)){ + batmonbus.bus_status = BATTERY_MONITOR_BUS_CURRENT_READ; } - //update electrical subsystem, current in mAs - electrical.current = (int32_t)(batmonbus.bus_current*1000); break; - case BATTERY_MONITOR_BUS_VOLTAGE: + // read BUS_CURRENT data + case BATTERY_MONITOR_BUS_CURRENT_READ: + if (batmonbus.bus_trans.status == I2CTransDone) { + // read data + batmonbus.data = (uint16_t) (batmonbus.bus_trans.buf[0] << 8 | batmonbus.bus_trans.buf[1]); + // NOTE: we are not using the ALERT_FLAG at the moment, + // get counts + batmonbus.bus_current_mvolts = batmonbus.data & 0xFFF; + // shift right by 2 bits if 10-bit reads only + if (BATTERY_MONITOR_BIT_RES == 10){ + batmonbus.bus_current_mvolts = (batmonbus.bus_current_mvolts) >> 2; + } + // convert to mV + batmonbus.bus_current_mvolts = (uint16_t)( + (float)batmonbus.bus_current_mvolts * BATTERY_MONITOR_VREF_MULT); + // convert to [A] + batmonbus.bus_current = ((float)batmonbus.bus_current_mvolts + + (float)batmon_current_offset) / batmon_current_sensitivity; + //update electrical subsystem, current in mAs + electrical.current = (int32_t)(batmonbus.bus_current*1000); + + // increment status + batmonbus.bus_status = BATTERY_MONITOR_BUS_VOLTAGE_REQ; + } + break; + + // request voltage data + case BATTERY_MONITOR_BUS_VOLTAGE_REQ: // set ADC to voltage channel batmonbus.bus_trans.buf[0] = battery_monitor_get_address( - (uint8_t)BATTERY_MONITOR_BUS_VOLTAGE_CHANNEL); + (uint8_t)BATTERY_MONITOR_BUS_VOLTAGE_CHANNEL); //set to zero so we can detect an error batmonbus.bus_voltage_mvolts = 0; - // blocking transaction + + // non-blocking transaction if (i2c_transceive(&BATTERY_MONITOR_I2C_DEV, &batmonbus.bus_trans, batmonbus.addr, 1, 2)){ - // proceed only if transaction was submitted successfully - if (batmonbus.bus_trans.status == I2CTransSuccess) { - // read data - batmonbus.data = (uint16_t) (batmonbus.bus_trans.buf[0] << 8 | batmonbus.bus_trans.buf[1]); - // NOTE: we are not using the ALERT_FLAG at the moment, - // get counts - batmonbus.bus_voltage_mvolts = batmonbus.data & 0xFFF; - // shift right by 2 bits if 10-bit reads only - if (BATTERY_MONITOR_BIT_RES == 10){ - batmonbus.bus_voltage_mvolts = (batmonbus.bus_voltage_mvolts) >> 2; - } - // convert to mV - batmonbus.bus_voltage_mvolts = (uint16_t)( - (float)batmonbus.bus_voltage_mvolts * BATTERY_MONITOR_VREF_MULT); - // convert to actual voltage - batmonbus.bus_voltage_mvolts = (uint16_t)( - (float)batmonbus.bus_voltage_mvolts * BatmonVbusGain); - } - // optional: check for errors and reset i2c transaction - // shouldn't be needed - - // update status - batmonbus.bus_status = BATTERY_MONITOR_BUS_TEMPERATURE; - } - - //update electrical subsystem, voltage in decivolts - if (batmonbus.bus_voltage_mvolts != 0) { - electrical.vsupply = (uint16_t)(batmonbus.bus_voltage_mvolts/100); - } - else { - electrical.vsupply = 0; + batmonbus.bus_status = BATTERY_MONITOR_BUS_VOLTAGE_READ; } break; - case BATTERY_MONITOR_BUS_TEMPERATURE: + // read voltage data + case BATTERY_MONITOR_BUS_VOLTAGE_READ: + if (batmonbus.bus_trans.status == I2CTransDone) { + // read data + batmonbus.data = (uint16_t) (batmonbus.bus_trans.buf[0] << 8 | batmonbus.bus_trans.buf[1]); + // NOTE: we are not using the ALERT_FLAG at the moment, + // get counts + batmonbus.bus_voltage_mvolts = batmonbus.data & 0xFFF; + // shift right by 2 bits if 10-bit reads only + if (BATTERY_MONITOR_BIT_RES == 10){ + batmonbus.bus_voltage_mvolts = (batmonbus.bus_voltage_mvolts) >> 2; + } + // convert to mV + batmonbus.bus_voltage_mvolts = (uint16_t)( + (float)batmonbus.bus_voltage_mvolts * BATTERY_MONITOR_VREF_MULT); + // convert to actual voltage + batmonbus.bus_voltage_mvolts = (uint16_t)( + (float)batmonbus.bus_voltage_mvolts * BatmonVbusGain); + + //update electrical subsystem, voltage in decivolts + if (batmonbus.bus_voltage_mvolts != 0) { + electrical.vsupply = (uint16_t)(batmonbus.bus_voltage_mvolts/100); + } + else { + electrical.vsupply = 0; + } + + // update status + batmonbus.bus_status = BATTERY_MONITOR_BUS_TEMPERATURE_REQ; + } + break; + + // request temperature data + case BATTERY_MONITOR_BUS_TEMPERATURE_REQ: // set ADC to correct temperature channel batmonbus.bus_trans.buf[0] = battery_monitor_get_address( - battery_monitor_tempmap[batmonbus.t_idx]); + battery_monitor_tempmap[batmonbus.t_idx]); //set to zero so we can detect an error batmonbus.bus_temp[batmonbus.t_idx] = 0; - // blocking transaction - if (i2c_transceive(&BATTERY_MONITOR_I2C_DEV, &batmonbus.bus_trans, batmonbus.addr, 1, 2)){ - // proceed only if transaction was submitted successfully - if (batmonbus.bus_trans.status == I2CTransSuccess) { - // read data - batmonbus.data = (uint16_t) (batmonbus.bus_trans.buf[0] << 8 | batmonbus.bus_trans.buf[1]); - // NOTE: we are not using the ALERT_FLAG at the moment, - // get counts - batmonbus.bus_tempsensors_mvolts[batmonbus.t_idx] = batmonbus.data & 0xFFF; - // shift right by 2 bits if 10-bit reads only - if (BATTERY_MONITOR_BIT_RES == 10){ - batmonbus.bus_tempsensors_mvolts[batmonbus.t_idx] = - (batmonbus.bus_tempsensors_mvolts[batmonbus.t_idx]) >> 2; - } - // convert to mV - batmonbus.bus_tempsensors_mvolts[batmonbus.t_idx] = (uint16_t)( - (float)batmonbus.bus_tempsensors_mvolts[batmonbus.t_idx] * BATTERY_MONITOR_VREF_MULT); - // convert to temperature[C] - batmonbus.bus_temp[batmonbus.t_idx] = - ((float)batmonbus.bus_tempsensors_mvolts[batmonbus.t_idx] + - (float)batmon_temp_offset ) / batmon_temp_sensitivity; - } - } - // optional: check for errors and reset i2c transaction - // shouldn't be needed - // increment counter - batmonbus.t_idx++; - if (batmonbus.t_idx == TEMP_SENSORS_NB) { - batmonbus.t_idx = 0; - batmonbus.bus_status = BATTERY_MONITOR_BUS_CURRENT; // to loop through + // non-blocking transaction + if (i2c_transceive(&BATTERY_MONITOR_I2C_DEV, &batmonbus.bus_trans, batmonbus.addr, 1, 2)){ + batmonbus.bus_status = BATTERY_MONITOR_BUS_TEMPERATURE_READ; + } + break; + + // read temperature data + case BATTERY_MONITOR_BUS_TEMPERATURE_READ: + if (batmonbus.bus_trans.status == I2CTransDone) { + // read data + batmonbus.data = (uint16_t) (batmonbus.bus_trans.buf[0] << 8 | batmonbus.bus_trans.buf[1]); + // NOTE: we are not using the ALERT_FLAG at the moment, + // get counts + batmonbus.bus_tempsensors_mvolts[batmonbus.t_idx] = batmonbus.data & 0xFFF; + // shift right by 2 bits if 10-bit reads only + if (BATTERY_MONITOR_BIT_RES == 10){ + batmonbus.bus_tempsensors_mvolts[batmonbus.t_idx] = + (batmonbus.bus_tempsensors_mvolts[batmonbus.t_idx]) >> 2; + } + // convert to mV + batmonbus.bus_tempsensors_mvolts[batmonbus.t_idx] = (uint16_t)( + (float)batmonbus.bus_tempsensors_mvolts[batmonbus.t_idx] * BATTERY_MONITOR_VREF_MULT); + // convert to temperature[C] + batmonbus.bus_temp[batmonbus.t_idx] = + ((float)batmonbus.bus_tempsensors_mvolts[batmonbus.t_idx] + + (float)batmon_temp_offset ) / batmon_temp_sensitivity; + // increment counter + batmonbus.t_idx++; + if (batmonbus.t_idx == TEMP_SENSORS_NB) { + batmonbus.t_idx = 0; + batmonbus.bus_status = BATTERY_MONITOR_BUS_CURRENT_REQ; // to loop through + } } break; default: // a recovery in case of a glitch - batmonbus.bus_status = BATTERY_MONITOR_BUS_CURRENT; + batmonbus.bus_status = BATTERY_MONITOR_BUS_CURRENT_REQ; break; } } @@ -311,51 +352,52 @@ void battery_monitor_read_balance_ports_2(void) { * Read balance ADC */ void battery_monitor_read_balance_ports(struct BatMonBal* batmonbal) { - batmonbal->data = 0; // erase at each iteration - - // set the right address into ADC - // cell_index is the number of the cell we want to probe - // battery_monitor_cellmap1 contains the mapping of channels for given cell number - // i.e. Cell_1 (cell_idx = 0) has channel 2 - // this gets translated into hexadecimal number representing the channel internally - batmonbal->bus_trans.buf[0] = - battery_monitor_get_address((uint8_t)battery_monitor_cellmap[batmonbal->cell_index]); - - //set to zero so we can detect an error - batmonbal->bat_cell_mvolts[batmonbal->cell_index] = 0; - - // blocking transaction - if (i2c_transceive(&BATTERY_MONITOR_I2C_DEV, &batmonbal->bus_trans, batmonbal->addr, 1, 2)){ - // proceed only if transaction was submitted successfully - if (batmonbal->bus_trans.status == I2CTransSuccess) { - // read data - batmonbal->data = (uint16_t) (batmonbal->bus_trans.buf[0] << 8 | batmonbal->bus_trans.buf[1]); - // NOTE: we are not using the ALERT_FLAG at the moment, - // get counts - batmonbal->bat_cell_mvolts[batmonbal->cell_index] = batmonbal->data & 0xFFF; - // shift right by 2 bits if 10-bit reads only - if (BATTERY_MONITOR_BIT_RES == 10){ - batmonbal->bat_cell_mvolts[batmonbal->cell_index] = - (batmonbal->bat_cell_mvolts[batmonbal->cell_index]) >> 2; - } - // convert to mV + // non-blocking transaction + // if transaction is done, request another measurement + // NOTE: optionally add startup delay, but it shouldn't be necessary + if (batmonbal->bus_trans.status == I2CTransDone) { + // read data first (worst case we get some zeros) + batmonbal->data = (uint16_t) (batmonbal->bus_trans.buf[0] << 8 | batmonbal->bus_trans.buf[1]); + // NOTE: we are not using the ALERT_FLAG at the moment, + // get counts + batmonbal->bat_cell_mvolts[batmonbal->cell_index] = batmonbal->data & 0xFFF; + // shift right by 2 bits if 10-bit reads only + if (BATTERY_MONITOR_BIT_RES == 10){ batmonbal->bat_cell_mvolts[batmonbal->cell_index] = - (uint16_t)((float)batmonbal->bat_cell_mvolts[batmonbal->cell_index] * BATTERY_MONITOR_VREF_MULT); - // convert to actual voltage - // we get the multiplier from battery_monitor_cellgains array, which contains multipliers - // for cells 1-6(in this order) battery_monitor_cellgains[0] gives us multiplier for cell_1 - // and so on - batmonbal->bat_cell_mvolts[batmonbal->cell_index] = - (uint16_t)((float)batmonbal->bat_cell_mvolts[batmonbal->cell_index] * - battery_monitor_cellgains[batmonbal->cell_index]); + (batmonbal->bat_cell_mvolts[batmonbal->cell_index]) >> 2; } - // optional: check for errors and reset i2c transaction - // shouldn't be needed - } + // convert to mV + batmonbal->bat_cell_mvolts[batmonbal->cell_index] = + (uint16_t)((float)batmonbal->bat_cell_mvolts[batmonbal->cell_index] * BATTERY_MONITOR_VREF_MULT); + // convert to actual voltage + // we get the multiplier from battery_monitor_cellgains array, which contains multipliers + // for cells 1-6(in this order) battery_monitor_cellgains[0] gives us multiplier for cell_1 + // and so on + batmonbal->bat_cell_mvolts[batmonbal->cell_index] = + (uint16_t)((float)batmonbal->bat_cell_mvolts[batmonbal->cell_index] * + battery_monitor_cellgains[batmonbal->cell_index]); - // increment counter - batmonbal->cell_index++; - if (batmonbal->cell_index == BATTERY_CELLS_NB) { - batmonbal->cell_index = 0; + // increment counter + batmonbal->cell_index++; + if (batmonbal->cell_index == BATTERY_CELLS_NB) { + batmonbal->cell_index = 0; + } + + // erase data + batmonbal->data = 0; // erase at each iteration + + //set to zero so we can detect an error + batmonbal->bat_cell_mvolts[batmonbal->cell_index] = 0; + + // set the right address into ADC + // cell_index is the number of the cell we want to probe + // battery_monitor_cellmap1 contains the mapping of channels for given cell number + // i.e. Cell_1 (cell_idx = 0) has channel 2 + // this gets translated into hexadecimal number representing the channel internally + batmonbal->bus_trans.buf[0] = + battery_monitor_get_address((uint8_t)battery_monitor_cellmap[batmonbal->cell_index]); + + // request more data + i2c_transceive(&BATTERY_MONITOR_I2C_DEV, &batmonbal->bus_trans, batmonbal->addr, 1, 2); } } diff --git a/sw/airborne/modules/adcs/battery_monitor.h b/sw/airborne/modules/adcs/battery_monitor.h index fd400f5688..033d665127 100644 --- a/sw/airborne/modules/adcs/battery_monitor.h +++ b/sw/airborne/modules/adcs/battery_monitor.h @@ -195,9 +195,12 @@ extern float batmon_temp_sensitivity; * Status for Bus ADC */ enum BatmonBusStatus { - BATTERY_MONITOR_BUS_CURRENT, - BATTERY_MONITOR_BUS_VOLTAGE, - BATTERY_MONITOR_BUS_TEMPERATURE + BATTERY_MONITOR_BUS_CURRENT_REQ, + BATTERY_MONITOR_BUS_CURRENT_READ, + BATTERY_MONITOR_BUS_VOLTAGE_REQ, + BATTERY_MONITOR_BUS_VOLTAGE_READ, + BATTERY_MONITOR_BUS_TEMPERATURE_REQ, + BATTERY_MONITOR_BUS_TEMPERATURE_READ }; /** @@ -255,6 +258,7 @@ void battery_monitor_read_balance_ports_2(void); void battery_monitor_read_balance_ports(struct BatMonBal *); void battery_monitor_event(void); +void battery_monitor_check_i2c_transaction(struct i2c_transaction* t); uint8_t battery_monitor_get_address(uint8_t channel);