Files
RP2350_MIDI_Lighter/Firmware/INA260.c
Chris 89c875e38f - First complete version of firmware. Currently being tested in the rehearsal room
- Added bunch of screens, fonts and images
 - Added script to read out frame buffer (function currently disabled in Firmware)
2025-10-26 20:57:58 +01:00

198 lines
7.3 KiB
C

/*
* File: INA260.c
*
* Created: Created: Sunday August 2025 21:52:23
* Author: Chris
*/
#include "INA260.h"
// ============================================================================================
// Includes
#include "I2C_Master.h"
#include "EEPROM_M24C64.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])
#define UINT16_SWAP_BYTES(_U16_) ((_U16_ << 8) | (_U16_ >> 8 ))
// ============================================================================================
// 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;
static uint16_t _INA260_Threshold;
static int32_t _Written_Current_Threshold;
// ============================================================================================
// Function Declarations
void INA260_Write_Register(uint8_t reg_address, uint16_t reg_data);
uint16_t INA260_Read_Register(uint8_t reg_address);
/*******************************************************************
Functions
*******************************************************************/
void INA260_Init()
{
_INA260_BusVoltage_mV = 0;
_INA260_Current_mA = 0;
_Written_Current_Threshold = -1;
uint16_t Configuration_Register_Value_Reset = (1 << INA260_CONGIG_RST_BIT);
INA260_Write_Register(INA260_REG_CONFIG, Configuration_Register_Value_Reset);
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
uint16_t Configuration_Register_Value =
(0 << INA260_CONGIG_RST_BIT) | // No Reset
(INA260_COUNT_4 << 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
sleep_ms(20);
INA260_Update_Current_Threshold();
sleep_ms(20);
INA260_Write_Register(INA260_REG_CONFIG, Configuration_Register_Value);
sleep_ms(20);
INA260_Write_Register(INA260_REG_MASK_ENABLE, Enable_Register_Value);
}
void INA260_Update_Current_Threshold()
{
if(_Written_Current_Threshold == _EEPROM_Content.Device_Configuration.Current_Threshold) {
return;
}
INA260_Write_Register(INA260_REG_ALERT_LIMIT, (uint16_t)(_EEPROM_Content.Device_Configuration.Current_Threshold * 4));
_Written_Current_Threshold = _EEPROM_Content.Device_Configuration.Current_Threshold;
}
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);
}
void INA260_Read_Threshold()
{
uint16_t INA260_Threshold = (uint16_t)INA260_Read_Register(INA260_REG_ALERT_LIMIT);
_INA260_Threshold = (uint16_t)(INA260_Threshold);
}
uint16_t INA260_Get_BusVoltage_mV()
{
return _INA260_BusVoltage_mV;
}
uint16_t INA260_Get_Current_mA()
{
return _INA260_Current_mA;
}
uint16_t INA260_Get_Threshold()
{
return _INA260_Threshold;
}
/*******************************************************************
Internal Functions
*******************************************************************/
void INA260_Write_Register(uint8_t reg_address, uint16_t reg_data)
{
uint16_t Swapped_Data = UINT16_SWAP_BYTES(reg_data);
I2CM_Packet_Transmit(INA260_I2CADDR_DEFAULT, reg_address, 1, (uint8_t*)(&Swapped_Data), 2);
}
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);
}