BSP+Drivers for EE24+INA
This commit is contained in:
3
.gitmodules
vendored
3
.gitmodules
vendored
@@ -13,3 +13,6 @@
|
||||
[submodule "lib/ulog"]
|
||||
path = lib/ulog
|
||||
url = https://github.com/rdpoor/ulog.git
|
||||
[submodule "lib/ee24"]
|
||||
path = lib/ee24
|
||||
url = git@git.lan:oliver/ee24.git
|
||||
|
||||
244
Application/BSP/BSP_EE24.c
Normal file
244
Application/BSP/BSP_EE24.c
Normal file
@@ -0,0 +1,244 @@
|
||||
/***
|
||||
* @file BSP_EE24.c
|
||||
* This file contains functions to interact with an EEPROM driver and perform
|
||||
* read and write operations on it. The driver uses I2C protocol and supports
|
||||
* multiple partitions, which can be used to store different types of data.
|
||||
*/
|
||||
|
||||
#include "BSP_EE24.h"
|
||||
#include "ee24.h"
|
||||
#include "i2c.h"
|
||||
#include "cmsis_os2.h"
|
||||
#include "gpio.h"
|
||||
|
||||
#define BSP_EE24_I2C &hi2c2
|
||||
#define BSP_EE24_ADDRESS EE24_ADDRESS_DEFAULT
|
||||
#define BSP_EE24_TIMEOUT 500
|
||||
#define BSP_EE24_MUTEXT_TIMEOUT osWaitForever
|
||||
|
||||
// Main Pariton Table
|
||||
static BSP_EE24_Partion PartionTable[__BSP_EE24_PART_MAX__] = {
|
||||
[BSP_EE24_PART_HEAD_PARTION] = {
|
||||
.address = -1,
|
||||
.len = sizeof(BSP_EE24_TableHeader)
|
||||
},
|
||||
[BSP_EE24_PART_GLOBAL_LIGHT] = {
|
||||
.address = -1,
|
||||
.len = 64,
|
||||
},
|
||||
[BSP_EE24_PART_RESERVED] = {
|
||||
.address = -1,
|
||||
.len = 128,
|
||||
}
|
||||
};
|
||||
static const uint32_t PartionTableVersion = 1;
|
||||
static EE24_HandleTypeDef hee24 = {0};
|
||||
static osMutexId_t ee24_lock;
|
||||
|
||||
void BSP_EE24_TableMigrate(uint32_t ee_version);
|
||||
|
||||
/**
|
||||
* Initializes the EEPROM Partition Table.
|
||||
*
|
||||
* This function calculates the addresses of each element in the Partition Table
|
||||
* based on their lengths and the previous element's address. It assumes that the
|
||||
* Partition Table is ordered by ascending addresses, and that there are no gaps
|
||||
* between elements.
|
||||
*/
|
||||
void BSP_EE24_InitTable() {
|
||||
uint32_t address = 0; // Start at address 0
|
||||
for (int i = 1; i < __BSP_EE24_PART_MAX__; i++) {
|
||||
if (PartionTable[i].len > 0) {
|
||||
PartionTable[i].address = address;
|
||||
address += PartionTable[i].len;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Initializes the EEPROM driver and performs any necessary migrations.
|
||||
*/
|
||||
bool BSP_EE24_Init(void) {
|
||||
// Initialize the EE24 driver with the I2C interface and address
|
||||
bool status = EE24_Init(&hee24,BSP_EE24_I2C,BSP_EE24_ADDRESS);
|
||||
if(!status) {
|
||||
return status;
|
||||
}
|
||||
|
||||
// os mutext
|
||||
ee24_lock = osMutexNew(NULL);
|
||||
|
||||
// wc control high disables write
|
||||
HAL_GPIO_WritePin(EEPROM_WC_GPIO_Port, EEPROM_WC_Pin, GPIO_PIN_SET);
|
||||
|
||||
// Read the Partition Table header from the EEPROM
|
||||
BSP_EE24_TableHeader header = {0};
|
||||
status = BSP_EE24_PartRead(BSP_EE24_PART_HEAD_PARTION, (uint8_t*)&header, sizeof(header));
|
||||
if(!status) {
|
||||
return status;
|
||||
}
|
||||
|
||||
// Check if the Partition Table version is different from the expected version
|
||||
uint32_t fw_table_version = PartionTableVersion;
|
||||
uint32_t ee_table_version = header.version;
|
||||
if(ee_table_version != fw_table_version) {
|
||||
BSP_EE24_TableMigrate(ee_table_version);
|
||||
if(!status) {
|
||||
return status;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Reads data from the EEPROM.
|
||||
* This function is blocking for the operation to complete.
|
||||
*
|
||||
* @param[in] Address The starting address of the data to be read.
|
||||
* @param[out] Data A pointer to a buffer where the data will be stored.
|
||||
* @param[in] Len The number of bytes to be read.
|
||||
* @return true if the operation was successful, false otherwise.
|
||||
*/
|
||||
bool BSP_EE24_Read(uint32_t Address, uint8_t *Data, size_t Len) {
|
||||
osMutexAcquire(ee24_lock,BSP_EE24_MUTEXT_TIMEOUT);
|
||||
bool status = EE24_Read(&hee24,Address,Data,Len,BSP_EE24_TIMEOUT);
|
||||
osMutexRelease(ee24_lock);
|
||||
return status;
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes data to the EEPROM.
|
||||
* This function is blocking for the operation to complete.
|
||||
*
|
||||
* @param[in] Address The starting address of the data to be written.
|
||||
* @param[out] Data A pointer to a buffer containing the data to be written.
|
||||
* @param[in] Len The number of bytes to be written.
|
||||
* @return true if the operation was successful, false otherwise.
|
||||
*/
|
||||
bool BSP_EE24_Write(uint32_t Address, uint8_t *Data, size_t Len) {
|
||||
osMutexAcquire(ee24_lock,BSP_EE24_MUTEXT_TIMEOUT);
|
||||
HAL_GPIO_WritePin(EEPROM_WC_GPIO_Port, EEPROM_WC_Pin, GPIO_PIN_RESET); // low enables write;
|
||||
bool status = EE24_Write(&hee24,Address,Data,Len,BSP_EE24_TIMEOUT);
|
||||
HAL_GPIO_WritePin(EEPROM_WC_GPIO_Port, EEPROM_WC_Pin, GPIO_PIN_SET); // high disables write;
|
||||
osMutexRelease(ee24_lock);
|
||||
return status;
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads data from a specific partition in the EEPROM.
|
||||
* This function is blocking for the operation to complete.
|
||||
*
|
||||
* @param[in] part The identifier of the partition to read from.
|
||||
* Must be one of the BSP_EE24_PART_* constants.
|
||||
* @param[out] Data A pointer to a buffer where the data will be stored.
|
||||
* @param[in] LenBuffer The maximum number of bytes to be read from the partition.
|
||||
* @return true if the operation was successful, false otherwise.
|
||||
*/
|
||||
bool BSP_EE24_PartRead(BSP_EE24_PartionEntry_e part, uint8_t *Data, size_t LenBuffer) {
|
||||
// Check if the partition is valid and has data to read
|
||||
if (!(part < __BSP_EE24_PART_MAX__ && PartionTable[part].len > 0)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Read the Partion address
|
||||
uint32_t Address = PartionTable[part].address;
|
||||
|
||||
// Calculate the length to be read
|
||||
uint32_t Len = 0;
|
||||
if (PartionTable[part].len < LenBuffer) {
|
||||
Len = PartionTable[part].len;
|
||||
} else {
|
||||
Len = LenBuffer;
|
||||
}
|
||||
|
||||
return BSP_EE24_Read(Address,Data,Len);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes data to a specific partition in the EEPROM.
|
||||
* This function is blocking for the operation to complete.
|
||||
*
|
||||
* @param[in] part The identifier of the partition to write to.
|
||||
* Must be one of the BSP_EE24_PART_* constants.
|
||||
* @param[out] Data A pointer to a buffer containing the data to be written.
|
||||
* @param[in] LenBuffer The maximum number of bytes to be written to the partition.
|
||||
* @return true if the operation was successful, false otherwise.
|
||||
*/
|
||||
bool BSP_EE24_PartWrite(BSP_EE24_PartionEntry_e part, uint8_t *Data, size_t LenBuffer) {
|
||||
// Check if the partition is valid and has data to read
|
||||
if (!(part < __BSP_EE24_PART_MAX__ && PartionTable[part].len > 0)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Read the Partion address
|
||||
uint32_t Address = PartionTable[part].address;
|
||||
|
||||
// Calculate the length to be read
|
||||
uint32_t Len = 0;
|
||||
if (PartionTable[part].len < LenBuffer) {
|
||||
Len = PartionTable[part].len;
|
||||
} else {
|
||||
Len = LenBuffer;
|
||||
}
|
||||
|
||||
return BSP_EE24_Write(Address,Data,Len);
|
||||
}
|
||||
|
||||
static inline size_t MIN_MEM(size_t a, size_t b) { return((a) < (b) ? a : b); }
|
||||
|
||||
|
||||
/**
|
||||
* Clear a new or undefined eeprom
|
||||
*/
|
||||
void BSP_EE24_FullClear() {
|
||||
size_t len = 0;
|
||||
for (int i = 1; i < __BSP_EE24_PART_MAX__; i++) {
|
||||
len += PartionTable[i].len;
|
||||
}
|
||||
|
||||
BSP_EE24_TableHeader header = {
|
||||
.version = PartionTableVersion,
|
||||
.used_len = len,
|
||||
.reserved = {0},
|
||||
};
|
||||
|
||||
// write header
|
||||
BSP_EE24_PartWrite(BSP_EE24_PART_HEAD_PARTION, (uint8_t*)&header, sizeof(header));
|
||||
|
||||
// Calculate the start address and length of the clear operation
|
||||
uint32_t clear_start = PartionTable[BSP_EE24_PART_HEAD_PARTION].address + PartionTable[BSP_EE24_PART_HEAD_PARTION].len;
|
||||
uint32_t clear_len = header.used_len - PartionTable[BSP_EE24_PART_HEAD_PARTION].len;
|
||||
|
||||
// Use a 16-byte buffer to perform the write operation in chunks of 16 bytes
|
||||
uint8_t clear_buffer[16] = {0};
|
||||
|
||||
while (clear_start < header.used_len) {
|
||||
size_t chunk_size = MIN_MEM(clear_len, sizeof(clear_buffer));
|
||||
BSP_EE24_Write(clear_start, clear_buffer, chunk_size);
|
||||
clear_start += chunk_size;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* migrate form diffrent versions of the eeprom
|
||||
*/
|
||||
void BSP_EE24_TableMigrate(uint32_t ee_version) {
|
||||
|
||||
if(ee_version == PartionTableVersion) {
|
||||
// current fw version, do nothing
|
||||
return;
|
||||
}
|
||||
|
||||
switch (ee_version)
|
||||
{
|
||||
|
||||
default: // undefined write zeros.
|
||||
BSP_EE24_FullClear();
|
||||
break;
|
||||
}
|
||||
}
|
||||
51
Application/BSP/BSP_EE24.h
Normal file
51
Application/BSP/BSP_EE24.h
Normal file
@@ -0,0 +1,51 @@
|
||||
#pragma once
|
||||
/**
|
||||
* @file BSP_EE24.h
|
||||
* This file contains functions to interact with an EEPROM driver and perform
|
||||
* read and write operations on it. The driver uses I2C protocol and supports
|
||||
* multiple partitions, which can be used to store different types of data.
|
||||
*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stddef.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
typedef struct BSP_EE24_Partion_s
|
||||
{
|
||||
uint32_t address;
|
||||
size_t len;
|
||||
}BSP_EE24_Partion;
|
||||
|
||||
|
||||
typedef struct BSP_EE24_TableHeader_s
|
||||
{
|
||||
uint32_t version;
|
||||
size_t used_len;
|
||||
uint8_t reserved[16];
|
||||
} BSP_EE24_TableHeader;
|
||||
|
||||
|
||||
typedef enum BSP_EE24_PartionEntry {
|
||||
BSP_EE24_PART_HEAD_PARTION,
|
||||
BSP_EE24_PART_GLOBAL_LIGHT,
|
||||
BSP_EE24_PART_RESERVED,
|
||||
__BSP_EE24_PART_MAX__,
|
||||
}BSP_EE24_PartionEntry_e;
|
||||
|
||||
|
||||
bool BSP_EE24_Init(void);
|
||||
bool BSP_EE24_Read(uint32_t Address, uint8_t *Data, size_t Len);
|
||||
bool BSP_EE24_Write(uint32_t Address, uint8_t *Data, size_t Len);
|
||||
|
||||
|
||||
bool BSP_EE24_PartRead(BSP_EE24_PartionEntry_e part, uint8_t *Data, size_t LenCheck);
|
||||
bool BSP_EE24_PartWrite(BSP_EE24_PartionEntry_e part, uint8_t *Data, size_t LenCheck);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
3
Application/BSP/BSP_GPIO.h
Normal file
3
Application/BSP/BSP_GPIO.h
Normal file
@@ -0,0 +1,3 @@
|
||||
// GPIOs access functions
|
||||
// External Interrupts
|
||||
// Shordhand functions to read improtant pins
|
||||
79
Application/BSP/BSP_INA.c
Normal file
79
Application/BSP/BSP_INA.c
Normal file
@@ -0,0 +1,79 @@
|
||||
/**
|
||||
* @file BSP_INA.c
|
||||
* @brief Driver for the BSP INA219 module
|
||||
*
|
||||
* This file provides a driver for the BSP INA219 module, which is used to measure voltage and current values.
|
||||
* The driver includes functions for initializing the module, reading the current and voltage values, and calculating the power value.
|
||||
* All of these functions are wrapped in a mutex lock to ensure consistent reading of the values.
|
||||
*/
|
||||
|
||||
#include "BSP_INA.h"
|
||||
#include "i2c.h"
|
||||
#include "INA219.h"
|
||||
#include "cmsis_os2.h"
|
||||
|
||||
#define BSP_INA_I2C &hi2c1
|
||||
#define BSP_INA_ADDRESS INA219_ADDRESS | 0x05
|
||||
#define BSP_INA_MUTEX_TIMEOUT osWaitForever
|
||||
|
||||
static INA219_t hina = {0};
|
||||
static osMutexId_t ina_lock = NULL;
|
||||
|
||||
/**
|
||||
* @brief Initializes the INA219 module and sets up the I2C bus.
|
||||
*/
|
||||
void BSP_INA_Init(void) {
|
||||
INA219_Init(&hina, BSP_INA_I2C, BSP_INA_ADDRESS);
|
||||
|
||||
ina_lock = osMutexNew(NULL);
|
||||
// default done by Init
|
||||
// INA219_Reset(ina219);
|
||||
// INA219_setCalibration_32V_2A(&hina);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief Reads the voltage value from the INA219.
|
||||
*
|
||||
* This function acquires a mutex to ensure that the voltage value is read consistently.
|
||||
* The mutex is released after the value has been read.
|
||||
*
|
||||
* @return The voltage value in milli Volts (mV)
|
||||
*/
|
||||
uint16_t BSP_INA_Voltage() {
|
||||
osMutexAcquire(ina_lock,BSP_INA_MUTEX_TIMEOUT);
|
||||
uint16_t result = INA219_ReadBusVoltage(&hina);
|
||||
osMutexRelease(ina_lock);
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Reads the current value from the INA219.
|
||||
*
|
||||
* This function acquires a mutex to ensure that the current value is read consistently.
|
||||
* The mutex is released after the value has been read.
|
||||
*
|
||||
* @return The current value in 10 milli Amperes (10mA)
|
||||
*/
|
||||
uint16_t BSP_INA_Current() {
|
||||
osMutexAcquire(ina_lock,BSP_INA_MUTEX_TIMEOUT);
|
||||
uint16_t result = INA219_ReadCurrent(&hina);
|
||||
osMutexRelease(ina_lock);
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Reads the power value from the INA219.
|
||||
*
|
||||
* This function acquires a mutex to ensure that the power value is read consistently.
|
||||
* The mutex is released after the value has been read.
|
||||
*
|
||||
* @return The power value in micro Watts (uW)
|
||||
*/
|
||||
uint32_t BSP_INA_Power() {
|
||||
osMutexAcquire(ina_lock,BSP_INA_MUTEX_TIMEOUT);
|
||||
uint16_t result_current = INA219_ReadCurrent(&hina);
|
||||
uint16_t result_voltage = INA219_ReadBusVoltage(&hina);
|
||||
osMutexRelease(ina_lock);
|
||||
return (result_current*10) * result_voltage;
|
||||
}
|
||||
18
Application/BSP/BSP_INA.h
Normal file
18
Application/BSP/BSP_INA.h
Normal file
@@ -0,0 +1,18 @@
|
||||
#pragma once
|
||||
/**
|
||||
* @file BSP_INA.h
|
||||
* @brief Driver for the BSP INA219 module
|
||||
*
|
||||
* This file provides a driver for the BSP INA219 module, which is used to measure voltage and current values.
|
||||
* The driver includes functions for initializing the module, reading the current and voltage values, and calculating the power value.
|
||||
* All of these functions are wrapped in a mutex lock to ensure consistent reading of the values.
|
||||
*/
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
|
||||
void BSP_INA_Init(void);
|
||||
|
||||
uint16_t BSP_INA_Voltage();
|
||||
uint16_t BSP_INA_Current();
|
||||
uint32_t BSP_INA_Power();
|
||||
4
Application/BSP/BSP_POWER.h
Normal file
4
Application/BSP/BSP_POWER.h
Normal file
@@ -0,0 +1,4 @@
|
||||
// Driver for standby and sleep managment
|
||||
// Timer for automatic standby
|
||||
// Wakeup Pin Setting
|
||||
// also shutdown procedure
|
||||
4
Application/BSP/BSP_SDLogger.h
Normal file
4
Application/BSP/BSP_SDLogger.h
Normal file
@@ -0,0 +1,4 @@
|
||||
// SD logger steam is logged to sd card
|
||||
// buffernd logger collect logs until some amount of data is collected.
|
||||
// needs to be flushed before shutdown
|
||||
// used with ULOG
|
||||
8
Application/BSP/CMakeLists.txt
Normal file
8
Application/BSP/CMakeLists.txt
Normal file
@@ -0,0 +1,8 @@
|
||||
|
||||
add_library(BSP STATIC
|
||||
BSP_EE24.c
|
||||
BSP_INA.c
|
||||
)
|
||||
|
||||
target_include_directories(BSP PUBLIC ./)
|
||||
target_link_libraries(BSP PRIVATE EE24 INA219)
|
||||
@@ -1,3 +1,4 @@
|
||||
add_subdirectory(Tasks)
|
||||
add_subdirectory(CLS_BSP)
|
||||
add_subdirectory(CLS)
|
||||
add_subdirectory(CLS)
|
||||
add_subdirectory(BSP)
|
||||
2
Application/Tasks/PowerMonitor.Task.h
Normal file
2
Application/Tasks/PowerMonitor.Task.h
Normal file
@@ -0,0 +1,2 @@
|
||||
// Task to Monitor the Power Usage of the CLS system
|
||||
//
|
||||
@@ -137,7 +137,7 @@ include_directories(${PROJECT_BINARY_DIR})
|
||||
add_executable(${CMAKE_PROJECT_NAME})
|
||||
target_sources(${CMAKE_PROJECT_NAME} PUBLIC ${sources_SRCS})
|
||||
|
||||
target_link_libraries(${CMAKE_PROJECT_NAME} PUBLIC Tasks CLS CLS_BSP ulog)
|
||||
target_link_libraries(${CMAKE_PROJECT_NAME} PUBLIC Tasks CLS CLS_BSP BSP EE24 INA219 ulog)
|
||||
#target_link_libraries(${CMAKE_PROJECT_NAME} PUBLIC PROTOS)
|
||||
target_link_libraries(${CMAKE_PROJECT_NAME} PUBLIC uart_driver)
|
||||
#target_link_libraries(${CMAKE_PROJECT_NAME} PUBLIC lwrb)
|
||||
|
||||
@@ -32,6 +32,8 @@
|
||||
#include "ulog.h"
|
||||
#include "stdio.h"
|
||||
#include "tim.h"
|
||||
#include "BSP_EE24.h"
|
||||
#include "BSP_INA.h"
|
||||
/* USER CODE END Includes */
|
||||
|
||||
/* Private typedef -----------------------------------------------------------*/
|
||||
@@ -57,7 +59,7 @@
|
||||
osThreadId_t defaultTaskHandle;
|
||||
const osThreadAttr_t defaultTask_attributes = {
|
||||
.name = "defaultTask",
|
||||
.stack_size = 128 * 4,
|
||||
.stack_size = 512 * 4,
|
||||
.priority = (osPriority_t) osPriorityNormal,
|
||||
};
|
||||
|
||||
@@ -175,11 +177,28 @@ void StartDefaultTask(void *argument)
|
||||
|
||||
uint8_t light_data[2] = {0};
|
||||
|
||||
BSP_EE24_Init();
|
||||
|
||||
BSP_INA_Init();
|
||||
|
||||
char INA_LOG[72];
|
||||
|
||||
/* Infinite loop */
|
||||
for(;;)
|
||||
{
|
||||
osDelay(1000);
|
||||
|
||||
uint16_t current = BSP_INA_Current()*10;
|
||||
uint16_t voltage = BSP_INA_Voltage();
|
||||
uint32_t power = (current * voltage)/1000; // milli watts
|
||||
float power_W = (float)power/1000.0;
|
||||
float voltage_V =(float) voltage /1000.0;
|
||||
|
||||
|
||||
|
||||
snprintf(INA_LOG, sizeof(INA_LOG),"Voltage[mV] %.2f Current[mA] %d P[W]: %.2f", voltage_V, current, power_W);
|
||||
ULOG_INFO(INA_LOG);
|
||||
|
||||
light_data[0]++;
|
||||
light_data[1] = (light_data[0]/10)%4;
|
||||
|
||||
|
||||
@@ -1,4 +1,8 @@
|
||||
add_subdirectory(lwrb)
|
||||
add_subdirectory(uart_driver)
|
||||
add_subdirectory(nanopb)
|
||||
add_subdirectory(ulog)
|
||||
add_subdirectory(ulog)
|
||||
add_subdirectory(ina219)
|
||||
|
||||
add_library(EE24 STATIC "ee24/ee24.c")
|
||||
target_include_directories(EE24 PUBLIC "ee24")
|
||||
1
lib/ee24
Submodule
1
lib/ee24
Submodule
Submodule lib/ee24 added at 4a2d7958fc
7
lib/ina219/CMakeLists.txt
Normal file
7
lib/ina219/CMakeLists.txt
Normal file
@@ -0,0 +1,7 @@
|
||||
|
||||
add_library(INA219 STATIC
|
||||
"INA219.c"
|
||||
"INA219.h"
|
||||
)
|
||||
|
||||
target_include_directories(INA219 PUBLIC ./)
|
||||
179
lib/ina219/INA219.c
Normal file
179
lib/ina219/INA219.c
Normal file
@@ -0,0 +1,179 @@
|
||||
/*
|
||||
* INA219.c
|
||||
*
|
||||
* Created on: Dec 30, 2020
|
||||
* Author: Piotr Smolen <komuch@gmail.com>
|
||||
*/
|
||||
|
||||
#include "main.h"
|
||||
#include "INA219.h"
|
||||
|
||||
uint16_t ina219_calibrationValue =0;
|
||||
int16_t ina219_currentDivider_mA =0;
|
||||
int16_t ina219_powerMultiplier_mW=0;
|
||||
|
||||
uint16_t Read16(INA219_t *ina219, uint8_t Register)
|
||||
{
|
||||
uint8_t Value[2] = {0};
|
||||
|
||||
HAL_I2C_Mem_Read(ina219->ina219_i2c, (ina219->Address<<1), Register, 1, Value, 2, 1000);
|
||||
|
||||
return ((Value[0] << 8) | Value[1]);
|
||||
}
|
||||
|
||||
|
||||
void Write16(INA219_t *ina219, uint8_t Register, uint16_t Value)
|
||||
{
|
||||
uint8_t addr[2];
|
||||
addr[0] = (Value >> 8) & 0xff; // upper byte
|
||||
addr[1] = (Value >> 0) & 0xff; // lower byte
|
||||
HAL_I2C_Mem_Write(ina219->ina219_i2c, (ina219->Address<<1), Register, 1, (uint8_t*)addr, 2, 1000);
|
||||
}
|
||||
|
||||
uint16_t INA219_ReadBusVoltage(INA219_t *ina219)
|
||||
{
|
||||
uint16_t result = Read16(ina219, INA219_REG_BUSVOLTAGE);
|
||||
|
||||
return ((result >> 3 ) * 4);
|
||||
|
||||
}
|
||||
|
||||
int16_t INA219_ReadCurrent_raw(INA219_t *ina219)
|
||||
{
|
||||
int16_t result = Read16(ina219, INA219_REG_CURRENT);
|
||||
|
||||
return (result );
|
||||
}
|
||||
|
||||
int16_t INA219_ReadCurrent(INA219_t *ina219)
|
||||
{
|
||||
int16_t result = INA219_ReadCurrent_raw(ina219);
|
||||
|
||||
return (result / ina219_currentDivider_mA );
|
||||
}
|
||||
|
||||
uint16_t INA219_ReadShuntVolage(INA219_t *ina219)
|
||||
{
|
||||
uint16_t result = Read16(ina219, INA219_REG_SHUNTVOLTAGE);
|
||||
|
||||
return (result * 0.01 );
|
||||
}
|
||||
|
||||
void INA219_Reset(INA219_t *ina219)
|
||||
{
|
||||
Write16(ina219, INA219_REG_CONFIG, INA219_CONFIG_RESET);
|
||||
HAL_Delay(1);
|
||||
}
|
||||
|
||||
void INA219_setCalibration(INA219_t *ina219, uint16_t CalibrationData)
|
||||
{
|
||||
Write16(ina219, INA219_REG_CALIBRATION, CalibrationData);
|
||||
}
|
||||
|
||||
uint16_t INA219_getConfig(INA219_t *ina219)
|
||||
{
|
||||
uint16_t result = Read16(ina219, INA219_REG_CONFIG);
|
||||
return result;
|
||||
}
|
||||
|
||||
void INA219_setConfig(INA219_t *ina219, uint16_t Config)
|
||||
{
|
||||
Write16(ina219, INA219_REG_CONFIG, Config);
|
||||
}
|
||||
|
||||
void INA219_setCalibration_32V_2A(INA219_t *ina219)
|
||||
{
|
||||
uint16_t config = INA219_CONFIG_BVOLTAGERANGE_32V |
|
||||
INA219_CONFIG_GAIN_8_320MV | INA219_CONFIG_BADCRES_12BIT |
|
||||
INA219_CONFIG_SADCRES_12BIT_1S_532US |
|
||||
INA219_CONFIG_MODE_SANDBVOLT_CONTINUOUS;
|
||||
|
||||
ina219_calibrationValue = 4096;
|
||||
ina219_currentDivider_mA = 10; // Current LSB = 100uA per bit (1000/100 = 10)
|
||||
ina219_powerMultiplier_mW = 2; // Power LSB = 1mW per bit (2/1)
|
||||
|
||||
INA219_setCalibration(ina219, ina219_calibrationValue);
|
||||
INA219_setConfig(ina219, config);
|
||||
}
|
||||
|
||||
void INA219_setCalibration_32V_1A(INA219_t *ina219)
|
||||
{
|
||||
uint16_t config = INA219_CONFIG_BVOLTAGERANGE_32V |
|
||||
INA219_CONFIG_GAIN_8_320MV | INA219_CONFIG_BADCRES_12BIT |
|
||||
INA219_CONFIG_SADCRES_12BIT_1S_532US |
|
||||
INA219_CONFIG_MODE_SANDBVOLT_CONTINUOUS;
|
||||
|
||||
ina219_calibrationValue = 10240;
|
||||
ina219_currentDivider_mA = 25; // Current LSB = 40uA per bit (1000/40 = 25)
|
||||
ina219_powerMultiplier_mW = 0.8f; // Power LSB = 800uW per bit
|
||||
|
||||
INA219_setCalibration(ina219, ina219_calibrationValue);
|
||||
INA219_setConfig(ina219, config);
|
||||
}
|
||||
|
||||
void INA219_setCalibration_16V_400mA(INA219_t *ina219)
|
||||
{
|
||||
uint16_t config = INA219_CONFIG_BVOLTAGERANGE_16V |
|
||||
INA219_CONFIG_GAIN_1_40MV | INA219_CONFIG_BADCRES_12BIT |
|
||||
INA219_CONFIG_SADCRES_12BIT_1S_532US |
|
||||
INA219_CONFIG_MODE_SANDBVOLT_CONTINUOUS;
|
||||
|
||||
ina219_calibrationValue = 8192;
|
||||
ina219_currentDivider_mA = 20; // Current LSB = 50uA per bit (1000/50 = 20)
|
||||
ina219_powerMultiplier_mW = 1.0f; // Power LSB = 1mW per bit
|
||||
|
||||
INA219_setCalibration(ina219, ina219_calibrationValue);
|
||||
INA219_setConfig(ina219, config);
|
||||
}
|
||||
|
||||
void INA219_setPowerMode(INA219_t *ina219, uint8_t Mode)
|
||||
{
|
||||
uint16_t config = INA219_getConfig(ina219);
|
||||
|
||||
switch (Mode) {
|
||||
case INA219_CONFIG_MODE_POWERDOWN:
|
||||
config = (config & ~INA219_CONFIG_MODE_MASK) | (INA219_CONFIG_MODE_POWERDOWN & INA219_CONFIG_MODE_MASK);
|
||||
INA219_setConfig(ina219, config);
|
||||
break;
|
||||
|
||||
case INA219_CONFIG_MODE_SANDBVOLT_TRIGGERED:
|
||||
config = (config & ~INA219_CONFIG_MODE_MASK) | (INA219_CONFIG_MODE_SANDBVOLT_TRIGGERED & INA219_CONFIG_MODE_MASK);
|
||||
INA219_setConfig(ina219, config);
|
||||
break;
|
||||
|
||||
case INA219_CONFIG_MODE_SANDBVOLT_CONTINUOUS:
|
||||
config = (config & ~INA219_CONFIG_MODE_MASK) | (INA219_CONFIG_MODE_SANDBVOLT_CONTINUOUS & INA219_CONFIG_MODE_MASK);
|
||||
INA219_setConfig(ina219, config);
|
||||
break;
|
||||
|
||||
case INA219_CONFIG_MODE_ADCOFF:
|
||||
config = (config & ~INA219_CONFIG_MODE_MASK) | (INA219_CONFIG_MODE_ADCOFF & INA219_CONFIG_MODE_MASK);
|
||||
INA219_setConfig(ina219, config);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
uint8_t INA219_Init(INA219_t *ina219, I2C_HandleTypeDef *i2c, uint8_t Address)
|
||||
{
|
||||
ina219->ina219_i2c = i2c;
|
||||
ina219->Address = Address;
|
||||
|
||||
ina219_currentDivider_mA = 0;
|
||||
ina219_powerMultiplier_mW = 0;
|
||||
|
||||
uint8_t ina219_isReady = HAL_I2C_IsDeviceReady(i2c, (Address << 1), 3, 2);
|
||||
|
||||
if(ina219_isReady == HAL_OK)
|
||||
{
|
||||
|
||||
INA219_Reset(ina219);
|
||||
INA219_setCalibration_32V_2A(ina219);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
97
lib/ina219/INA219.h
Normal file
97
lib/ina219/INA219.h
Normal file
@@ -0,0 +1,97 @@
|
||||
/*
|
||||
* INA219.h
|
||||
*
|
||||
* Created on: Dec 30, 2020
|
||||
* Author: Piotr Smolen <komuch@gmail.com>
|
||||
*/
|
||||
|
||||
#ifndef INC_INA219_H_
|
||||
#define INC_INA219_H_
|
||||
|
||||
#define INA219_ADDRESS (0x40)
|
||||
|
||||
//
|
||||
// Registers
|
||||
//
|
||||
#define INA219_REG_CONFIG (0x00)
|
||||
#define INA219_REG_SHUNTVOLTAGE (0x01)
|
||||
#define INA219_REG_BUSVOLTAGE (0x02)
|
||||
#define INA219_REG_POWER (0x03)
|
||||
#define INA219_REG_CURRENT (0x04)
|
||||
#define INA219_REG_CALIBRATION (0x05)
|
||||
//
|
||||
#define INA219_CONFIG_RESET (0x8000)
|
||||
//
|
||||
#define INA219_CONFIG_BVOLTAGERANGE_16V (0x0000) // 0-16V Range
|
||||
#define INA219_CONFIG_BVOLTAGERANGE_32V (0x2000) // 0-32V Range
|
||||
|
||||
#define INA219_CONFIG_GAIN_1_40MV (0x0000) // Gain 1, 40mV Range
|
||||
#define INA219_CONFIG_GAIN_2_80MV (0x0800) // Gain 2, 80mV Range
|
||||
#define INA219_CONFIG_GAIN_4_160MV (0x1000) // Gain 4, 160mV Range
|
||||
#define INA219_CONFIG_GAIN_8_320MV (0x1800) // Gain 8, 320mV Range
|
||||
|
||||
#define INA219_CONFIG_BADCRES_9BIT (0x0000) // 9-bit bus res = 0..511
|
||||
#define INA219_CONFIG_BADCRES_10BIT (0x0080) // 10-bit bus res = 0..1023
|
||||
#define INA219_CONFIG_BADCRES_11BIT (0x0100) // 11-bit bus res = 0..2047
|
||||
#define INA219_CONFIG_BADCRES_12BIT (0x0180) // 12-bit bus res = 0..4097
|
||||
#define INA219_CONFIG_BADCRES_12BIT_2S_1060US (0x0480) // 2 x 12-bit bus samples averaged together
|
||||
#define INA219_CONFIG_BADCRES_12BIT_4S_2130US (0x0500) // 4 x 12-bit bus samples averaged together
|
||||
#define INA219_CONFIG_BADCRES_12BIT_8S_4260US (0x0580) // 8 x 12-bit bus samples averaged together
|
||||
#define INA219_CONFIG_BADCRES_12BIT_16S_8510US (0x0600) // 16 x 12-bit bus samples averaged together
|
||||
#define INA219_CONFIG_BADCRES_12BIT_32S_17MS (0x0680) // 32 x 12-bit bus samples averaged together
|
||||
#define INA219_CONFIG_BADCRES_12BIT_64S_34MS (0x0700) // 64 x 12-bit bus samples averaged together
|
||||
#define INA219_CONFIG_BADCRES_12BIT_128S_69MS (0x0780) // 128 x 12-bit bus samples averaged together
|
||||
|
||||
#define INA219_CONFIG_SADCRES_9BIT_1S_84US (0x0000) // 1 x 9-bit shunt sample
|
||||
#define INA219_CONFIG_SADCRES_10BIT_1S_148US (0x0008) // 1 x 10-bit shunt sample
|
||||
#define INA219_CONFIG_SADCRES_11BIT_1S_276US (0x0010) // 1 x 11-bit shunt sample
|
||||
#define INA219_CONFIG_SADCRES_12BIT_1S_532US (0x0018) // 1 x 12-bit shunt sample
|
||||
#define INA219_CONFIG_SADCRES_12BIT_2S_1060US (0x0048) // 2 x 12-bit shunt samples averaged together
|
||||
#define INA219_CONFIG_SADCRES_12BIT_4S_2130US (0x0050) // 4 x 12-bit shunt samples averaged together
|
||||
#define INA219_CONFIG_SADCRES_12BIT_8S_4260US (0x0058) // 8 x 12-bit shunt samples averaged together
|
||||
#define INA219_CONFIG_SADCRES_12BIT_16S_8510US (0x0060) // 16 x 12-bit shunt samples averaged together
|
||||
#define INA219_CONFIG_SADCRES_12BIT_32S_17MS (0x0068) // 32 x 12-bit shunt samples averaged together
|
||||
#define INA219_CONFIG_SADCRES_12BIT_64S_34MS (0x0070) // 64 x 12-bit shunt samples averaged together
|
||||
#define INA219_CONFIG_SADCRES_12BIT_128S_69MS (0x0078) // 128 x 12-bit shunt samples averaged together
|
||||
//
|
||||
#define INA219_CONFIG_MODE_MASK (0x07)
|
||||
#define INA219_CONFIG_MODE_POWERDOWN 0x00 /**< power down */
|
||||
#define INA219_CONFIG_MODE_SVOLT_TRIGGERED 0x01 /**< shunt voltage triggered */
|
||||
#define INA219_CONFIG_MODE_BVOLT_TRIGGERED 0x02 /**< bus voltage triggered */
|
||||
#define INA219_CONFIG_MODE_SANDBVOLT_TRIGGERED 0x03 /**< shunt and bus voltage triggered */
|
||||
#define INA219_CONFIG_MODE_ADCOFF 0x04 /**< ADC off */
|
||||
#define INA219_CONFIG_MODE_SVOLT_CONTINUOUS 0x05 /**< shunt voltage continuous */
|
||||
#define INA219_CONFIG_MODE_BVOLT_CONTINUOUS 0x06 /**< bus voltage continuous */
|
||||
#define INA219_CONFIG_MODE_SANDBVOLT_CONTINUOUS 0x07
|
||||
|
||||
typedef struct
|
||||
{
|
||||
I2C_HandleTypeDef *ina219_i2c;
|
||||
uint8_t Address;
|
||||
} INA219_t;
|
||||
|
||||
extern uint16_t ina219_calibrationValue;
|
||||
extern int16_t ina219_currentDivider_mA;
|
||||
extern int16_t ina219_powerMultiplier_mW;
|
||||
|
||||
uint8_t INA219_Init(INA219_t *ina219, I2C_HandleTypeDef *i2c, uint8_t Address);
|
||||
uint16_t INA219_ReadBusVoltage(INA219_t *ina219);
|
||||
int16_t INA219_ReadCurrent(INA219_t *ina219);
|
||||
int16_t INA219_ReadCurrent_raw(INA219_t *ina219);
|
||||
uint16_t INA219_ReadShuntVolage(INA219_t *ina219);
|
||||
|
||||
void INA219_Reset(INA219_t *ina219);
|
||||
void INA219_setCalibration(INA219_t *ina219, uint16_t CalibrationData);
|
||||
uint16_t INA219_getConfig(INA219_t *ina219);
|
||||
void INA219_setConfig(INA219_t *ina219, uint16_t Config);
|
||||
void INA219_setCalibration_32V_2A(INA219_t *ina219);
|
||||
void INA219_setCalibration_32V_1A(INA219_t *ina219);
|
||||
void INA219_setCalibration_16V_400mA(INA219_t *ina219);
|
||||
void INA219_setPowerMode(INA219_t *ina219, uint8_t Mode);
|
||||
|
||||
uint16_t Read16(INA219_t *ina219, uint8_t Register);
|
||||
void Write16(INA219_t *ina219, uint8_t Register, uint16_t Value);
|
||||
|
||||
|
||||
|
||||
#endif /* INC_INA219_H_ */
|
||||
Reference in New Issue
Block a user