BSP+Drivers for EE24+INA

This commit is contained in:
2024-02-24 19:24:00 +01:00
parent 26022126e1
commit af18558f1a
18 changed files with 728 additions and 4 deletions

244
Application/BSP/BSP_EE24.c Normal file
View 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;
}
}