/* * File: INA260.c * * Created: Created: Sunday August 2025 21:52:23 * Author: Chris */ #include "INA260.h" // ============================================================================================ // Includes #include "I2C_Master.h" // ============================================================================================ // Defines #define INA260_I2CADDR_DEFAULT 0x40 ///< INA260 default i2c address #define INA260_CONGIG_RST_BIT 15 #define INA260_CONGIG_AVG0_BIT 9 #define INA260_CONGIG_VBUSCT0_BIT 6 #define INA260_CONGIG_ISHCT0_BIT 3 #define INA260_CONGIG_MODE1_BIT 0 #define INA260_ENABLE_OCL_BIT 15 #define INA260_ENABLE_APOL_BIT 1 #define INA260_ENABLE_LEN_BIT 0 #define UINT8_ARR_TO_UINT16(_U8_) ((uint16_t)(_U8_[0]) << 8) | (uint16_t)(_U8_[1]) // ============================================================================================ // Typedefs typedef enum _INA260_Mode { INA260_MODE_SHUTDOWN = 0x00, ///< SHUTDOWN: Minimize quiescient current and turn off current into the device inputs. Set another mode to exit shutown mode INA260_MODE_TRIGGERED = 0x03, ///< TRIGGERED: Trigger a one-shot measurement of current and bus voltage. Set the TRIGGERED mode again to take a new measurement INA260_MODE_CONTINUOUS = 0x07, ///< CONTINUOUS: (Default) Continuously update the current, bus voltage and power registers with new measurements } INA260_MeasurementMode; typedef enum _INA260_ConversionTime { INA260_TIME_140_us, ///< Measurement time: 140us INA260_TIME_204_us, ///< Measurement time: 204us INA260_TIME_332_us, ///< Measurement time: 332us INA260_TIME_588_us, ///< Measurement time: 588us INA260_TIME_1_1_ms, ///< Measurement time: 1.1ms (Default) INA260_TIME_2_116_ms, ///< Measurement time: 2.116ms INA260_TIME_4_156_ms, ///< Measurement time: 4.156ms INA260_TIME_8_244_ms, ///< Measurement time: 8.224ms } INA260_ConversionTime; typedef enum _count { INA260_COUNT_1, ///< Window size: 1 sample (Default) INA260_COUNT_4, ///< Window size: 4 samples INA260_COUNT_16, ///< Window size: 16 samples INA260_COUNT_64, ///< Window size: 64 samples INA260_COUNT_128, ///< Window size: 128 samples INA260_COUNT_256, ///< Window size: 256 samples INA260_COUNT_512, ///< Window size: 512 samples INA260_COUNT_1024, ///< Window size: 1024 samples } INA260_AveragingCount; typedef enum _INA260_AlertType { INA260_ALERT_CONVERSION_READY = 0x01, ///< Trigger on conversion ready INA260_ALERT_OVERPOWER = 0x02, ///< Trigger on power over limit INA260_ALERT_UNDERVOLTAGE = 0x04, ///< Trigger on bus voltage under limit INA260_ALERT_OVERVOLTAGE = 0x08 , ///< Trigger on bus voltage over limit INA260_ALERT_UNDERCURRENT = 0x10, ///< Trigger on current under limit INA260_ALERT_OVERCURRENT = 0x20, ///< Trigger on current over limit INA260_ALERT_NONE = 0x00 ///< Do not trigger alert pin (Default) } INA260_AlertType; typedef enum _INA260_AlertPolarity { INA260_ALERT_POLARITY_NORMAL = 0x0, ///< Active high open-collector (Default) INA260_ALERT_POLARITY_INVERTED = 0x1 ///< Active low open-collector } INA260_AlertPolarity; typedef enum _INA260_AlertLatch { INA260_ALERT_LATCH_ENABLED = 0x1, ///< Alert will latch until Mask/Enable register is read INA260_ALERT_LATCH_TRANSPARENT = 0x0 ///< Alert will reset when fault is cleared } INA260_AlertLatch; // ============================================================================================ // Variables static uint16_t _INA260_BusVoltage_mV; static uint16_t _INA260_Current_mA; // ============================================================================================ // Function Declarations uint16_t INA260_Read_Register(uint8_t reg_address); /******************************************************************* Functions *******************************************************************/ void INA260_Init() { _INA260_BusVoltage_mV = 0; _INA260_Current_mA = 0; uint16_t Configuration_Register_Value = (0 << INA260_CONGIG_RST_BIT) | // No Reset (INA260_COUNT_1 << INA260_CONGIG_AVG0_BIT) | // Averaging Count (INA260_TIME_8_244_ms << INA260_CONGIG_VBUSCT0_BIT) | // Bus Voltage Conversion Time (INA260_TIME_8_244_ms << INA260_CONGIG_ISHCT0_BIT) | // Shunt Current Conversion Time (INA260_MODE_CONTINUOUS << INA260_CONGIG_MODE1_BIT); // Operating Mode I2CM_Packet_Transmit(INA260_I2CADDR_DEFAULT, INA260_REG_CONFIG, 1, (uint8_t*)(&Configuration_Register_Value), 2); uint16_t Enable_Register_Value = (1 << INA260_ENABLE_OCL_BIT) | // Over Current Limit (0 << INA260_ENABLE_APOL_BIT) | // Alert Polarity Bit (1 << INA260_ENABLE_LEN_BIT); // Alert Latch Enable I2CM_Packet_Transmit(INA260_I2CADDR_DEFAULT, INA260_REG_MASK_ENABLE, 1, (uint8_t*)(&Enable_Register_Value), 2); } void INA260_Read_BusVoltage() { uint32_t INA260_BusVoltage = (uint32_t)INA260_Read_Register(INA260_REG_BUSVOLTAGE); _INA260_BusVoltage_mV = (int16_t)((INA260_BusVoltage * 1250) / 1000); } void INA260_Read_Current() { uint32_t INA260_Current = (uint32_t)INA260_Read_Register(INA260_REG_CURRENT); _INA260_Current_mA = (int16_t)((INA260_Current * 1250) / 1000); } uint16_t INA260_Get_BusVoltage_mV() { return _INA260_BusVoltage_mV; } uint16_t INA260_Get_Current_mA() { return _INA260_Current_mA; } /******************************************************************* Internal Functions *******************************************************************/ uint16_t INA260_Read_Register(uint8_t reg_address) { uint8_t Receive_Data[2]; I2CM_Packet_Receive(INA260_I2CADDR_DEFAULT, reg_address, 1, Receive_Data, 2); return UINT8_ARR_TO_UINT16(Receive_Data); }