394 lines
12 KiB
C
394 lines
12 KiB
C
/**********************************************************************
|
|
* NAME: eeprom.c *
|
|
* AUTHOR: Philip Johansson *
|
|
* PURPOSE: Virtual EEPROM driver *
|
|
* INFORMATION: *
|
|
* This file mainly has two functions of which one brings the settings *
|
|
* from EEPROM and the other stores them *
|
|
* *
|
|
* All values we want in EEPROM have to be added to the EEPROM_ID_t *
|
|
* struct as well as defined in eeprom_Arr with a pointer to the data *
|
|
* *
|
|
* GLOBAL VARIABLES: *
|
|
* Variable Type Description *
|
|
* -------- ---- ----------- *
|
|
* *
|
|
**********************************************************************/
|
|
#include "config/eeprom.h"
|
|
#include "drivers/adc.h"
|
|
#include "drivers/uart1_inverter.h"
|
|
#include "system_variables.h"
|
|
#include "utilities.h"
|
|
|
|
/* Reads the EEPROM version from EEPROM - Is compared to EEPROM_SYS_VERSION */
|
|
uint8_t stored_eeprom_identifier;
|
|
|
|
/* Buffer where we temporarily store profiles we not use as we erase eeprom before write */
|
|
uint32_t eeprom_profile_tmp_a[EEPROM_PROFILE_SIZE];
|
|
uint32_t eeprom_profile_tmp_b[EEPROM_PROFILE_SIZE];
|
|
|
|
|
|
/* Created CRC */
|
|
uint8_t calculated_crc;
|
|
uint8_t read_crc;
|
|
|
|
uint8_t active_profile = 0;
|
|
|
|
typedef enum {
|
|
EEPROM_VERSION = 0,
|
|
|
|
/* Counts the amount of system settings */
|
|
EEPROM_HEADER_COUNT
|
|
} EEPROM_HEADER_ID_t;
|
|
|
|
/***********************************************************************
|
|
* BRIEF: List of all System EEPROM values *
|
|
* INFORMATION: This content of this struct will be used in EEPROM *
|
|
***********************************************************************/
|
|
typedef enum {
|
|
EEPROM_ACTIVE_PROFILE = 0,
|
|
EEPROM_ADC_SCALES,
|
|
EEPROM_UART1_RX_INV,
|
|
|
|
/* Counts the amount of system settings */
|
|
EEPROM_SYS_COUNT
|
|
} EEPROM_SYS_ID_t;
|
|
|
|
/***********************************************************************
|
|
* BRIEF: List of all Profile EEPROM values *
|
|
* INFORMATION: This content of this struct will be used in EEPROM *
|
|
***********************************************************************/
|
|
typedef enum {
|
|
EEPROM_PID_ROLL_KP = 0,
|
|
|
|
/* Counts the amount of settings in profile */
|
|
EEPROM_PROFILE_COUNT
|
|
} EEPROM_PROFILE_ID_t;
|
|
|
|
typedef enum {
|
|
EEPROM_CRC = 0,
|
|
|
|
/* Counts the amount of system settings */
|
|
EEPROM_FOOTER_COUNT
|
|
} EEPROM_FOOTER_ID_t;
|
|
|
|
uint8_t eeprom_blocksize_Arr[4] = {
|
|
EEPROM_HEADER_COUNT,
|
|
EEPROM_SYS_COUNT,
|
|
EEPROM_PROFILE_COUNT,
|
|
EEPROM_FOOTER_COUNT
|
|
};
|
|
|
|
|
|
|
|
/***********************************************************************
|
|
* BRIEF: General EEPROM data info *
|
|
* INFORMATION: Each EEPROM parameter needs an instance of this struct *
|
|
* to be added in eepromArr *
|
|
***********************************************************************/
|
|
typedef struct
|
|
{
|
|
uint32_t writeTypeId;
|
|
uint32_t size; //Size of the data
|
|
void * dataPtr; //pointer to the data, that should be saved to EEPROM
|
|
} EEPROM_DATA_t;
|
|
|
|
|
|
|
|
|
|
/***********************************************************************
|
|
* BRIEF: Data info to be passed to the write function *
|
|
* INFORMATION: passes size and data pointer *
|
|
***********************************************************************/
|
|
EEPROM_DATA_t eeprom_header_Arr[EEPROM_HEADER_COUNT] = {
|
|
[EEPROM_VERSION] =
|
|
{
|
|
.size = sizeof(stored_eeprom_identifier),
|
|
.dataPtr = &stored_eeprom_identifier,
|
|
}
|
|
};
|
|
|
|
EEPROM_DATA_t eeprom_sys_Arr[EEPROM_SYS_COUNT] = {
|
|
[EEPROM_ACTIVE_PROFILE] =
|
|
{
|
|
.size = sizeof(active_profile),
|
|
.dataPtr = &active_profile,
|
|
},
|
|
[EEPROM_ADC_SCALES] =
|
|
{
|
|
.size = sizeof(adcScaleStruct_t),
|
|
.dataPtr = &adcScaleStruct_t,
|
|
},
|
|
[EEPROM_UART1_RX_INV] =
|
|
{
|
|
.size = sizeof(bool),
|
|
.dataPtr = &uart1_rx_inverter,
|
|
}
|
|
};
|
|
|
|
EEPROM_DATA_t eeprom_profile_Arr[EEPROM_PROFILE_COUNT] = {
|
|
[EEPROM_PID_ROLL_KP] =
|
|
{
|
|
.size = sizeof(pid_pitch_pk),
|
|
.dataPtr = &pid_pitch_pk,
|
|
}
|
|
};
|
|
|
|
EEPROM_DATA_t eeprom_footer_Arr[EEPROM_FOOTER_COUNT] = {
|
|
[EEPROM_CRC] =
|
|
{
|
|
.size = sizeof(calculated_crc),
|
|
.dataPtr = &calculated_crc,
|
|
}
|
|
};
|
|
|
|
/* to loop through these arrays*/
|
|
EEPROM_DATA_t * eeprom_Arr_list[4] = {
|
|
eeprom_header_Arr,
|
|
eeprom_sys_Arr,
|
|
eeprom_profile_Arr,
|
|
eeprom_footer_Arr
|
|
};
|
|
|
|
uint16_t eepromArrSize(EEPROM_DATA_t * data)
|
|
{
|
|
int size = 0;
|
|
for (int j = 0; j < 4; j++)
|
|
{
|
|
if (data == eeprom_Arr_list[j])
|
|
for (int i = 0; i < eeprom_blocksize_Arr[j]; i++)
|
|
{
|
|
size += data[i].size;
|
|
}
|
|
}
|
|
if (size == 0)
|
|
Error_Handler(); // We should never get here
|
|
return size;
|
|
}
|
|
|
|
|
|
/***********************************************************************
|
|
* BRIEF: Increments the checksum *
|
|
* INFORMATION: *
|
|
***********************************************************************/
|
|
uint8_t incrementChecksum(uint8_t crc, const void *data, uint32_t length)
|
|
{
|
|
const uint8_t * addrIterator = (const uint8_t *)data;
|
|
const uint8_t * addrEnd = addrIterator + length;
|
|
|
|
for (;addrIterator != addrEnd; addrIterator++)
|
|
crc ^= *addrIterator;
|
|
|
|
return crc;
|
|
}
|
|
|
|
/***********************************************************************
|
|
* BRIEF: Stores one data type at the time from eepromArr to EEPROM *
|
|
* INFORMATION: Writes byte per byte until end of data *
|
|
***********************************************************************/
|
|
void writeEepromExtension(uint32_t addr,EEPROM_DATA_t * data, uint32_t id)
|
|
{
|
|
for (int i = 0; i < data[id].size; i ++)
|
|
HAL_FLASH_Program(FLASH_TYPEPROGRAM_BYTE, addr + i , *((uint8_t*)(data[id].dataPtr + i)));
|
|
}
|
|
|
|
/***********************************************************************
|
|
* BRIEF: Writes EEPROM data to FLASH *
|
|
* INFORMATION: passes all data directly from where they are defined *
|
|
***********************************************************************/
|
|
void writeEEPROM()
|
|
{
|
|
/* Add size and a pointer to the data for each value
|
|
* Each value when saved will store the data that it points to.
|
|
* When loaded the system will know what the value for each id should
|
|
* point to and it can read the data directly to that value which is pointed to*/
|
|
|
|
uint32_t addrIterator = EEPROM_BASE_ADDR;
|
|
uint8_t crc = 0; // Initializing the checksum to 0
|
|
|
|
HAL_FLASH_Unlock();
|
|
__HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_EOP | FLASH_FLAG_OPERR | FLASH_FLAG_WRPERR | FLASH_FLAG_PGAERR | FLASH_FLAG_PGSERR );
|
|
FLASH_Erase_Sector(((uint32_t)FLASH_SECTOR_11),VOLTAGE_RANGE_3);
|
|
|
|
stored_eeprom_identifier = (uint8_t)EEPROM_SYS_VERSION;
|
|
|
|
for (int j = 0; j < 4; j++)
|
|
{
|
|
for (int i = 0; i < eeprom_blocksize_Arr[j]; i++)
|
|
{
|
|
if (eeprom_Arr_list[j] == eeprom_footer_Arr)
|
|
calculated_crc = crc;
|
|
writeEepromExtension(addrIterator, eeprom_Arr_list[j], i);
|
|
addrIterator += eeprom_Arr_list[j][i].size;
|
|
crc = incrementChecksum(crc, eeprom_Arr_list[j][i].dataPtr, eeprom_Arr_list[j][i].size);
|
|
}
|
|
}
|
|
|
|
//
|
|
// /* Write the Header and calc CRC */
|
|
// for (int i = 0; i < EEPROM_HEADER_COUNT; i ++)
|
|
// {
|
|
// writeEepromExtension(addrIterator, eeprom_header_Arr, i);
|
|
// addrIterator += eeprom_header_Arr[i].size;
|
|
// crc = incrementChecksum(crc, eeprom_header_Arr[i].dataPtr, eeprom_header_Arr[i].size);
|
|
// }
|
|
//
|
|
// /* Write the system settings and calc CRC */
|
|
// for (int i = 0; i < EEPROM_SYS_COUNT; i ++)
|
|
// {
|
|
// writeEepromExtension(addrIterator, eeprom_sys_Arr, i);
|
|
// addrIterator += eeprom_sys_Arr[i].size;
|
|
// crc = incrementChecksum(crc, eeprom_sys_Arr[i].dataPtr, eeprom_sys_Arr[i].size);
|
|
// }
|
|
// /* Write the profile and calc CRC */
|
|
// for (int i = 0; i < EEPROM_PROFILE_COUNT; i ++)
|
|
// {
|
|
// writeEepromExtension(addrIterator, eeprom_profile_Arr, i);
|
|
// addrIterator += eeprom_profile_Arr[i].size;
|
|
// crc = incrementChecksum(crc, eeprom_profile_Arr[i].dataPtr, eeprom_profile_Arr[i].size);
|
|
// }
|
|
//
|
|
// // Updating the calculated crc value before writing to EEPROM
|
|
// calculated_crc = crc;
|
|
//
|
|
// /* Write the CRC to footer */
|
|
// for (int i = 0; i < EEPROM_FOOTER_COUNT; i ++)
|
|
// {
|
|
// writeEepromExtension(addrIterator, eeprom_footer_Arr, i);
|
|
// addrIterator += eeprom_footer_Arr[i].size;
|
|
// }
|
|
|
|
HAL_FLASH_Lock();
|
|
}
|
|
|
|
/***********************************************************************
|
|
* BRIEF: Restores one data type at the time from eepromArr from EEPROM *
|
|
* INFORMATION: *
|
|
***********************************************************************/
|
|
void readEepromExtension(uint32_t addr, EEPROM_DATA_t * data, uint32_t id)
|
|
{
|
|
for (int i = 0; i < data[id].size; i++)
|
|
*(uint8_t*)(data[id].dataPtr + i) = *( uint8_t*)(addr + i * sizeof(uint8_t));
|
|
}
|
|
|
|
// Verifies that eeprom is not corrupt and that the EEPROM version is correct
|
|
bool scanEEPROM(void)
|
|
{
|
|
uint8_t crc = 0;
|
|
uint8_t old_crc = calculated_crc; // store to restore
|
|
uint32_t addrIterator = EEPROM_BASE_ADDR;
|
|
HAL_FLASH_Unlock();
|
|
HAL_Delay(100);
|
|
|
|
for (int j = 0; j < 4; j++)
|
|
{
|
|
for (int i = 0; i < eeprom_blocksize_Arr[j]; i++)
|
|
{
|
|
if ((eeprom_Arr_list[j] == eeprom_header_Arr) || (eeprom_Arr_list[j] == eeprom_footer_Arr))
|
|
readEepromExtension(addrIterator, eeprom_Arr_list[j], i);
|
|
if (eeprom_Arr_list[j] != eeprom_footer_Arr)
|
|
crc = incrementChecksum(crc, (int*)addrIterator, eeprom_Arr_list[j][i].size);
|
|
addrIterator += eeprom_Arr_list[j][i].size;
|
|
}
|
|
}
|
|
|
|
// /* Read the Header */
|
|
// for (int i = 0; i < EEPROM_HEADER_COUNT; i ++)
|
|
// {
|
|
// readEepromExtension(addrIterator, eeprom_header_Arr, i);
|
|
// crc = incrementChecksum(crc, addrIterator, eeprom_header_Arr[i].size);
|
|
// addrIterator += eeprom_header_Arr[i].size;
|
|
// }
|
|
//
|
|
// /* Read the system array */
|
|
// for (int i = 0; i < EEPROM_SYS_COUNT; i ++)
|
|
// {
|
|
// crc = incrementChecksum(crc, addrIterator, eeprom_sys_Arr[i].size);
|
|
// addrIterator += eeprom_sys_Arr[i].size;
|
|
// }
|
|
//
|
|
// /* Read the profile array */
|
|
// for (int i = 0; i < EEPROM_PROFILE_COUNT; i ++)
|
|
// {
|
|
// crc = incrementChecksum(crc, addrIterator, eeprom_profile_Arr[i].size);
|
|
// addrIterator += eeprom_profile_Arr[i].size;
|
|
// }
|
|
//
|
|
// /* Read the Footer */
|
|
// for (int i = 0; i < EEPROM_FOOTER_COUNT; i ++)
|
|
// {
|
|
// readEepromExtension(addrIterator, eeprom_footer_Arr, i);
|
|
// addrIterator += eeprom_footer_Arr[i].size;
|
|
// }
|
|
|
|
HAL_FLASH_Lock();
|
|
|
|
|
|
/* Check to see if CRC matches */
|
|
if ( (crc == calculated_crc) && (stored_eeprom_identifier == (uint8_t)EEPROM_SYS_VERSION) )
|
|
{
|
|
return true;
|
|
}
|
|
else
|
|
{
|
|
calculated_crc = old_crc;
|
|
//Error_Handler();
|
|
// Reinitialize eeprom with default values.
|
|
return false;
|
|
}
|
|
}
|
|
|
|
/***********************************************************************
|
|
* BRIEF: Reads EEPROM data from FLASH *
|
|
* INFORMATION: passes all data directly to where they are defined *
|
|
***********************************************************************/
|
|
void readEEPROM()
|
|
{
|
|
uint32_t addrIterator = EEPROM_BASE_ADDR;
|
|
|
|
/* This check has to be done as not to overwrite memory with bad data */
|
|
if (scanEEPROM())
|
|
{
|
|
HAL_FLASH_Unlock();
|
|
HAL_Delay(100);
|
|
|
|
for (int j = 0; j < 3; j++) // 3 excludes the footer
|
|
{
|
|
for (int i = 0; i < eeprom_blocksize_Arr[j]; i++)
|
|
{
|
|
readEepromExtension(addrIterator, eeprom_Arr_list[j], i);
|
|
addrIterator += eeprom_Arr_list[j][i].size;
|
|
}
|
|
}
|
|
|
|
// /* Read the Header */
|
|
// for (int i = 0; i < EEPROM_HEADER_COUNT; i ++)
|
|
// {
|
|
// readEepromExtension(addrIterator, eeprom_header_Arr, i);
|
|
// addrIterator += eeprom_header_Arr[i].size;
|
|
// }
|
|
//
|
|
// /* Read the system array */
|
|
// for (int i = 0; i < EEPROM_SYS_COUNT; i ++)
|
|
// {
|
|
// readEepromExtension(addrIterator, eeprom_sys_Arr, i);
|
|
// addrIterator += eeprom_sys_Arr[i].size;
|
|
// }
|
|
//
|
|
// /* Read the profile array */
|
|
// for (int i = 0; i < EEPROM_PROFILE_COUNT; i ++)
|
|
// {
|
|
// readEepromExtension(addrIterator, eeprom_profile_Arr, i);
|
|
// addrIterator += eeprom_profile_Arr[i].size;
|
|
// }
|
|
|
|
// Now there is no need to read the footer
|
|
|
|
HAL_FLASH_Lock();
|
|
}
|
|
else
|
|
{
|
|
|
|
}
|
|
}
|