Final Philip EEPROM version. Now it will be merged with Master

This commit is contained in:
philsson 2016-10-04 13:29:59 +02:00
parent ad9232147c
commit fd354ccf2d
3 changed files with 269 additions and 175 deletions

View File

@ -21,27 +21,82 @@
/* Defines where emulated EEPROM starts from - OBS! Also defined in LinkerScript.id */
#define EEPROM_BASE_ADDR 0x080E0000
#define EEPROM_PROFILE_SIZE 20 // Size in uint32_t
/* The size in bytes of the profile buffers. The error handler will be called if this is too small */
#define EEPROM_PROFILE_SIZE 200
/* The profiles one can choose from */
typedef enum {
PROFILE_1 = 1,
PROFILE_2,
PROFILE_3
} ACTIVE_PROFILE;
extern uint8_t active_profile;
/* List of all header EEPROM values */
typedef enum {
EEPROM_VERSION = 0,
/* Counts the amount of system settings */
EEPROM_HEADER_COUNT
} EEPROM_HEADER_ID_t;
/* List of all system EEPROM values */
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;
/* List of all profile EEPROM values */
typedef enum {
EEPROM_PID_ROLL_KP = 0,
/* Counts the amount of settings in profile */
EEPROM_PROFILE_COUNT
} EEPROM_PROFILE_ID_t;
/* List of all footer EEPROM values */
typedef enum {
EEPROM_CRC = 0,
/* Counts the amount of system settings */
EEPROM_FOOTER_COUNT
} EEPROM_FOOTER_ID_t;
/***********************************************************************
* BRIEF: Writes EEPROM data to FLASH *
* BRIEF: Writes EEPROM data to FLASH. Requires the next active profile *
* to be selected (current profile can be used as input) *
* INFORMATION: passes all data directly from where they are defined *
***********************************************************************/
void writeEEPROM();
void writeEEPROM(ACTIVE_PROFILE new_active_profile);
/***********************************************************************
* BRIEF: Writes EEPROM data to FLASH without the need of setting next *
* active profile *
* INFORMATION: Keeps the current profile active *
***********************************************************************/
void saveEEPROM();
/***********************************************************************
* BRIEF: Reads EEPROM data from FLASH *
* INFORMATION: passes all data directly to where they are defined *
***********************************************************************/
void readEEPROM();
bool readEEPROM();
/***********************************************************************
* BRIEF: Choose a profile between 1 .. 3 *
* INFORMATION: The current changes will be saved *
***********************************************************************/
void setActiveProfile(ACTIVE_PROFILE profile);
/***********************************************************************
* BRIEF: Writes current profile values to all EEPROM profiles *
* INFORMATION: used when EEPROM is corrupt or there is a version *
* mismatch *
***********************************************************************/
void resetEEPROM(void);
#endif /* CONFIG_EEPROM_H_ */

View File

@ -24,54 +24,25 @@
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];
uint8_t eeprom_profile_tmp_a[EEPROM_PROFILE_SIZE];
uint8_t eeprom_profile_tmp_b[EEPROM_PROFILE_SIZE];
/* The two temporary buffers are addressed through this array */
uint8_t * eeprom_profile_tmp_Arr[2] = {
eeprom_profile_tmp_a,
eeprom_profile_tmp_b
};
/* Created CRC */
uint8_t calculated_crc;
uint8_t read_crc;
uint8_t active_profile = 0;
/* Defines which profile is active. Should not be changed other than calling setActiveProfile() */
ACTIVE_PROFILE active_profile = 1; // Between 1 .. 3
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;
/* List of all EEPROM lists */
uint8_t eeprom_blocksize_Arr[4] = {
EEPROM_HEADER_COUNT,
EEPROM_SYS_COUNT,
@ -81,11 +52,7 @@ uint8_t eeprom_blocksize_Arr[4] = {
/***********************************************************************
* BRIEF: General EEPROM data info *
* INFORMATION: Each EEPROM parameter needs an instance of this struct *
* to be added in eepromArr *
***********************************************************************/
/* General EEPROM data info. All data addressed needs both size and pointer */
typedef struct
{
uint32_t writeTypeId;
@ -96,10 +63,7 @@ typedef struct
/***********************************************************************
* BRIEF: Data info to be passed to the write function *
* INFORMATION: passes size and data pointer *
***********************************************************************/
/* Data pointers and sizes for header content */
EEPROM_DATA_t eeprom_header_Arr[EEPROM_HEADER_COUNT] = {
[EEPROM_VERSION] =
{
@ -108,6 +72,7 @@ EEPROM_DATA_t eeprom_header_Arr[EEPROM_HEADER_COUNT] = {
}
};
/* Data pointers and sizes for sys content */
EEPROM_DATA_t eeprom_sys_Arr[EEPROM_SYS_COUNT] = {
[EEPROM_ACTIVE_PROFILE] =
{
@ -126,6 +91,7 @@ EEPROM_DATA_t eeprom_sys_Arr[EEPROM_SYS_COUNT] = {
}
};
/* Data pointers and sizes for profile content */
EEPROM_DATA_t eeprom_profile_Arr[EEPROM_PROFILE_COUNT] = {
[EEPROM_PID_ROLL_KP] =
{
@ -134,6 +100,7 @@ EEPROM_DATA_t eeprom_profile_Arr[EEPROM_PROFILE_COUNT] = {
}
};
/* Data pointers and sizes for footer content */
EEPROM_DATA_t eeprom_footer_Arr[EEPROM_FOOTER_COUNT] = {
[EEPROM_CRC] =
{
@ -142,7 +109,7 @@ EEPROM_DATA_t eeprom_footer_Arr[EEPROM_FOOTER_COUNT] = {
}
};
/* to loop through these arrays*/
/* List of all EEPROM content arrays */
EEPROM_DATA_t * eeprom_Arr_list[4] = {
eeprom_header_Arr,
eeprom_sys_Arr,
@ -150,6 +117,11 @@ EEPROM_DATA_t * eeprom_Arr_list[4] = {
eeprom_footer_Arr
};
/***********************************************************************
* BRIEF: Reads Calculates the combined size of all elements *
* in an EEPROM_DATA_t array *
* INFORMATION: return value is in bytes *
***********************************************************************/
uint16_t eepromArrSize(EEPROM_DATA_t * data)
{
int size = 0;
@ -169,7 +141,7 @@ uint16_t eepromArrSize(EEPROM_DATA_t * data)
/***********************************************************************
* BRIEF: Increments the checksum *
* INFORMATION: *
* INFORMATION: XOR operator byte per byte *
***********************************************************************/
uint8_t incrementChecksum(uint8_t crc, const void *data, uint32_t length)
{
@ -193,10 +165,11 @@ void writeEepromExtension(uint32_t addr,EEPROM_DATA_t * data, uint32_t id)
}
/***********************************************************************
* BRIEF: Writes EEPROM data to FLASH *
* BRIEF: Writes EEPROM data to FLASH. Requires the next active profile *
* to be selected (current profile can be used as input) *
* INFORMATION: passes all data directly from where they are defined *
***********************************************************************/
void writeEEPROM()
void writeEEPROM(uint8_t new_profile)
{
/* Add size and a pointer to the data for each value
* Each value when saved will store the data that it points to.
@ -205,6 +178,9 @@ void writeEEPROM()
uint32_t addrIterator = EEPROM_BASE_ADDR;
uint8_t crc = 0; // Initializing the checksum to 0
uint8_t profile_counter = 0;
uint8_t buff_counter = 0;
ACTIVE_PROFILE old_profile = active_profile;
HAL_FLASH_Unlock();
__HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_EOP | FLASH_FLAG_OPERR | FLASH_FLAG_WRPERR | FLASH_FLAG_PGAERR | FLASH_FLAG_PGSERR );
@ -214,50 +190,44 @@ void writeEEPROM()
for (int j = 0; j < 4; j++)
{
for (int i = 0; i < eeprom_blocksize_Arr[j]; i++)
// We exclude reading of profiles not active to memory
if (!((j == 2) && (profile_counter != ((uint8_t)active_profile - 1) )))
{
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);
if (j == 1) // Writing sys we store the NEW profile
active_profile = new_profile;
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);
}
if (j == 1)
active_profile = old_profile; // restore the old profile
}
else
{
if (buff_counter >= 2)
Error_Handler();
int eeprom_profile_arr_size = eepromArrSize(eeprom_profile_Arr);
for (int i = 0; i < eeprom_profile_arr_size; i ++)
HAL_FLASH_Program(FLASH_TYPEPROGRAM_BYTE, addrIterator + i , *((uint8_t*)(eeprom_profile_tmp_Arr[buff_counter] + i)));
crc = incrementChecksum(crc, eeprom_profile_tmp_Arr[buff_counter], eepromArrSize(eeprom_profile_Arr));
buff_counter++; // move on to next buffer
// Adding size of eeprom array
addrIterator += eeprom_profile_arr_size;
}
// Halt iterator j @2 (profile) for 3 iterations (3 profiles)
if ((j == 2) && (profile_counter < 2))
{
profile_counter++;
j--; // We do this to keep j = 2 for three iterations (looping through all profiles)
}
}
//
// /* 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();
}
@ -271,59 +241,52 @@ void readEepromExtension(uint32_t addr, EEPROM_DATA_t * data, uint32_t id)
*(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
/***********************************************************************
* BRIEF: Copies a profile from EEPROM into a buffer *
* INFORMATION: Run once for every buffer *
***********************************************************************/
void readEepromBuff(uint32_t addr, uint8_t * eeprom_profile_tmp, uint32_t length)
{
for (int i = 0; i < length; i++)
*(uint8_t*)(eeprom_profile_tmp + i) = *(uint8_t*)(addr + i * sizeof(uint8_t));
}
/***********************************************************************
* BRIEF: Verifies EEPROM only *
* INFORMATION: compares EEPROM version and makes CRC checks *
* Return value is true if okay *
***********************************************************************/
bool scanEEPROM(void)
{
uint8_t crc = 0;
uint8_t old_crc = calculated_crc; // store to restore
uint8_t profile_counter = 0; // To iterate through the profiles
uint32_t addrIterator = EEPROM_BASE_ADDR;
HAL_FLASH_Unlock();
HAL_Delay(100);
for (int j = 0; j < 4; j++)
for (int j = 0; j < 4; j++) // 3 to skip footer from CRC calculation
{
for (int i = 0; i < eeprom_blocksize_Arr[j]; i++)
{
// Store data only for Header (EEPROM version) and footer (CRC) while scanning
if ((eeprom_Arr_list[j] == eeprom_header_Arr) || (eeprom_Arr_list[j] == eeprom_footer_Arr))
readEepromExtension(addrIterator, eeprom_Arr_list[j], i);
// Checksum not incremented for footer
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;
}
// Halt iterator j @2 (profile) for 3 iterations (3 profiles)
if ((j == 2) && (profile_counter < 2))
{
profile_counter++;
j--; // We do this to keep j = 2 for three iterations (looping through all profiles)
}
}
// /* 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) )
{
@ -331,10 +294,13 @@ bool scanEEPROM(void)
}
else
{
// ERROR!!! CORRUPT EEPROM, RESETTING
calculated_crc = old_crc;
//Error_Handler();
// Reinitialize eeprom with default values.
return false;
Error_Handler();
resetEEPROM(); // Reinitialize eeprom with default values.
return true /* false */;
}
}
@ -342,52 +308,108 @@ bool scanEEPROM(void)
* BRIEF: Reads EEPROM data from FLASH *
* INFORMATION: passes all data directly to where they are defined *
***********************************************************************/
void readEEPROM()
bool readEEPROM()
{
bool success;
uint8_t profile_counter = 0;
uint8_t buff_counter = 0;
uint32_t addrIterator = EEPROM_BASE_ADDR;
/* This check has to be done as not to overwrite memory with bad data */
if (scanEEPROM())
if ((success = 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++)
// We exclude reading of profiles not active to memory
if (!((j == 2) && (profile_counter != (uint8_t)(active_profile - 1))))
{
readEepromExtension(addrIterator, eeprom_Arr_list[j], i);
addrIterator += eeprom_Arr_list[j][i].size;
for (int i = 0; i < eeprom_blocksize_Arr[j]; i++)
{
readEepromExtension(addrIterator, eeprom_Arr_list[j], i);
addrIterator += eeprom_Arr_list[j][i].size;
}
}
// The two not loaded profiles are stored to buffers
else
{
if (buff_counter >= 2)
Error_Handler();
// Import the data from eeprom to buffer
readEepromBuff((uint32_t*)addrIterator, (uint8_t*)eeprom_profile_tmp_Arr[buff_counter], EEPROM_PROFILE_SIZE);
buff_counter++;
// Adding size of eeprom array
addrIterator += eepromArrSize(eeprom_profile_Arr);
}
// Halt iterator j @2 (profile) for 3 iterations (3 profiles)
if ((j == 2) && (profile_counter < 2))
{
profile_counter++;
j--; // We do this to keep j = 2 for three iterations (looping through all profiles)
}
}
// /* 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
{
Error_Handler();
}
return success;
}
/***********************************************************************
* BRIEF: Choose a profile between 1 .. 3 *
* INFORMATION: The current changes will be saved *
***********************************************************************/
void setActiveProfile(ACTIVE_PROFILE new_profile)
{
// Error handler
if (new_profile < 1 || new_profile > 3)
Error_Handler();
writeEEPROM(new_profile);
readEEPROM();
}
/***********************************************************************
* BRIEF: Writes current profile values to all EEPROM profiles *
* INFORMATION: used when EEPROM is corrupt or there is a version *
* mismatch *
***********************************************************************/
void resetEEPROM(void)
{
/* check so that the profile buffer sizes are not smaller than the size of one profile */
if (EEPROM_PROFILE_SIZE < eepromArrSize(eeprom_profile_Arr) )
Error_Handler(); // We need to increment the EEPROM_PROFILE_SIZE
uint32_t bufferIterator = 0;
//Loop through all the values in the EEPROM profile
for (int j = 0; j < EEPROM_PROFILE_COUNT; j++)
{
//for each value loop on its byte size and then write byte by byte to the buffers
for (int i = 0; i < eeprom_profile_Arr[i].size; i++)
{
*(uint8_t*)(eeprom_profile_tmp_Arr[0] + bufferIterator) = *(uint8_t*)(eeprom_profile_Arr[j].dataPtr + i);
*(uint8_t*)(eeprom_profile_tmp_Arr[1] + bufferIterator) = *(uint8_t*)(eeprom_profile_Arr[j].dataPtr + i);
bufferIterator++;
}
}
writeEEPROM(active_profile);
}
/***********************************************************************
* BRIEF: Writes EEPROM data to FLASH without the need of setting next *
* active profile *
* INFORMATION: Keeps the current profile active *
***********************************************************************/
void saveEEPROM()
{
writeEEPROM(active_profile);
}

View File

@ -20,7 +20,7 @@
#include "drivers/uart1_inverter.h"
// for test
uint8_t pid_pitch_pk = 0;
uint8_t pid_pitch_pk = 10;
int main(void)
@ -32,22 +32,39 @@ int main(void)
// Configure the system clock to 100 MHz
system_clock_config();
adcScaleStruct_t.vcc_scale = 20;
adcScaleStruct_t.i_scale_right = 10;
adcScaleStruct_t.i_scale_left = 30;
pid_pitch_pk = 10;
setActiveProfile(1);
resetEEPROM();
for(;;)
{
writeEEPROM();
adcScaleStruct_t.vcc_scale = 0;
adcScaleStruct_t.i_scale_right = 0;
adcScaleStruct_t.i_scale_left = 0;
setActiveProfile(3);
pid_pitch_pk = 0;
uart1_rx_inverter = 0;
pid_pitch_pk++;
setActiveProfile(1);
pid_pitch_pk++;
readEEPROM();
adcScaleStruct_t.vcc_scale ++;
adcScaleStruct_t.i_scale_right ++;
adcScaleStruct_t.i_scale_left ++;
uart1_rx_inverter = !uart1_rx_inverter;
pid_pitch_pk = 200;
setActiveProfile(2);
pid_pitch_pk = 0;
readEEPROM();
pid_pitch_pk = 250;
resetEEPROM();
setActiveProfile(3);
int kalle = pid_pitch_pk;
setActiveProfile(2);
kalle = pid_pitch_pk;
setActiveProfile(3);
kalle = pid_pitch_pk;
}