Line data Source code
1 : #pragma once 2 : 3 : #include "AP_BattMonitor_config.h" 4 : 5 : #if AP_BATTERY_INA3221_ENABLED 6 : 7 : /* 8 : * 9 : * Datasheet: https://www.ti.com/lit/ds/symlink/ina3221.pdf?ts=1597369254046 10 : */ 11 : 12 : // The INA3221 takes two measurements for each channel: one for shunt voltage 13 : // and one for bus voltage. Each measurement can be independently or 14 : // sequentially measured, based on the mode setting (bits 2-0 in the 15 : // Configuration register). When the INA3221 is in normal operating mode 16 : // (that is, the MODE bits of the Configuration register are set to 111), the 17 : // device continuously converts a shunt-voltage reading followed by a 18 : // bus-voltage reading. This procedure converts one channel, and then continues 19 : // to the shunt voltage reading of the next enabled channel, followed by the 20 : // bus-voltage reading for that channel, and so on, until all enabled channels 21 : // have been measured. The programmed Configuration register mode setting 22 : // applies to all channels. Any channels that are not enabled are bypassed in 23 : // the measurement sequence, regardless of mode setting. 24 : 25 : 26 : // 8.3.3 Software Reset 27 : // The INA3221 features a software reset that reinitializes the device and 28 : // register settings to default power-up values without having to cycle power 29 : // to the device. Use bit 15 (RST) of the Configuration register to perform a 30 : // software reset. Setting RST reinitializes all registers and settings to the 31 : // default power state with the exception of the power-valid output state. If a 32 : // software reset is issued, the INA3221 holds the output of the PV pin until 33 : // the power-valid detection sequence completes. The Power-Valid UpperLimit and 34 : // Power-Valid Lowerlimit registers return to the default state when the 35 : // software reset has been issued. Therefore, any reprogrammed limit registers 36 : // are reset, resulting in the original power-valid thresholds validating the 37 : // power-valid conditions. This architecture prevents interruption to circuitry 38 : // connected to the powervalid output during a software reset event. 39 : 40 : // The INA3221 has programmable conversion times for both the shunt- and 41 : // bus-voltage measurements. The selectable conversion times for these 42 : // measurements range from 140μs to 8.244ms. 43 : 44 : 45 : #include "AP_BattMonitor.h" 46 : #include "AP_BattMonitor_Backend.h" 47 : 48 : #ifndef HAL_BATTMON_INA3221_MAX_DEVICES 49 : #define HAL_BATTMON_INA3221_MAX_DEVICES 1 50 : #endif 51 : 52 : class AP_BattMonitor_INA3221 : public AP_BattMonitor_Backend 53 : { 54 : public: 55 : /// Constructor 56 : AP_BattMonitor_INA3221(AP_BattMonitor &mon, 57 : AP_BattMonitor::BattMonitor_State &mon_state, 58 : AP_BattMonitor_Params ¶ms); 59 : 60 : void init() override; 61 : 62 : /// Read the battery voltage and current. Should be called at 10hz 63 : void read() override; 64 : 65 1392 : bool has_current() const override { 66 1392 : return true; 67 : } 68 : 69 : static const struct AP_Param::GroupInfo var_info[]; 70 : 71 : private: 72 : 73 : AP_Int8 i2c_bus; 74 : AP_Int8 i2c_address; 75 : AP_Int8 channel; 76 : 77 : static struct AddressDriver { 78 : bool read_register(uint8_t addr, uint16_t &ret); 79 : bool write_register(uint8_t addr, uint16_t val); 80 : bool write_config(void); 81 : void timer(void); 82 : void register_timer(); 83 : 84 : AP_HAL::I2CDevice *dev; 85 : uint8_t bus; 86 : uint8_t address; 87 : uint8_t channel_mask; 88 : uint8_t dev_channel_mask; 89 : 90 : struct StateList { 91 : struct StateList *next; 92 : HAL_Semaphore sem; 93 : uint8_t channel; 94 : 95 : bool healthy; 96 : float voltage; 97 : float current_amps; 98 : float delta_mah; 99 : float delta_wh; 100 : uint32_t last_time_micros; 101 : }; 102 : StateList *statelist; 103 : 104 : } address_driver[HAL_BATTMON_INA3221_MAX_DEVICES]; 105 : static uint8_t address_driver_count; 106 : 107 : AddressDriver::StateList *address_driver_state; 108 : }; 109 : 110 : #endif // AP_BATTERY_INA3221_ENABLED