This repository has been archived on 2020-06-14. You can view files and clone it, but cannot push or open issues or pull requests.

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
{
}
}