diff --git a/Core/Inc/eepromsys.h b/Core/Inc/eepromsys.h new file mode 100644 index 00000000..d35c5d59 --- /dev/null +++ b/Core/Inc/eepromsys.h @@ -0,0 +1,132 @@ +#ifndef EEPROMSYS_H +#define EEPROMSYS_H + +#include +#include + +// EEPROM's Root Address +#define EEPROM_BASE_ADD 0 +// Number of Faults EEPROM will Store +#define NUM_EEPROM_FAULTS 5 +// Number of Telemetry points to store +#define NUM_EEPROM_TELEM 10 +// Number of Sections (2) +#define NUM_EEPROM_SECS 2 + +/** + * @brief EEPROM + * + */ +struct eeprom { + char *key; + uint16_t size; + uint16_t address; +}; + +/** + * @brief This struct is used to organize the two types of data for the EEPROM to store + * + */ +struct eeprom eeprom_data[NUM_EEPROM_SECS]; + +/** + * @brief This array will collect all the faults when read_faults() is called + * + */ +static uint32_t eeprom_faults[NUM_EEPROM_FAULTS]; + +/** + * @brief This array will collect all the data when read_data() is called + * + */ +static uint32_t eeprom_pts[NUM_EEPROM_TELEM]; + +/** + * @brief Partitions eeprom addresses given table of data and size + * + */ +void eepromInit(); + +/** + * @brief Fetches the latest memory address saved to the first byte of the eeprom partition + * + * @param key Name of the eeprom partition + * @return uint16_t The memory address to update and write to next + */ +uint16_t eeprom_get_index(char *key); + +/** + * @brief This function writes the data to the newest memory address of one of the EEPROM partitions + * + * @param key The EEPROM partition to write to + * @param data Undetermined datatype + * @param size Expected size of data + * @return true If HAL writes properly + * @return false If HAL fails to write + */ +bool eeprom_write_key(char *key, void *data, uint16_t size); + +/** + * @brief This function reads the data at the most recently used memory address of + * a specific EEPROM partition + * + * @param key Name of the EEPROM partition + * @param data Data of undetermined type + * @param size Expected size of data + * @return true If this reads properly using HAL + * @return false If this fails to read with HAL + */ +bool eeprom_read_key(char *key, void *data, uint16_t size); + +/** + * @brief Function to read data from EEPROM based on the latest address stored in the partition + * + * @param id The address associated with the section of EEPROM memory + * @param data Variable to store collected data + * @param size Size of expected data + * @return true Successful + * @return false Unsuccessful + */ +bool eeprom_read_data_address(uint16_t address, void *data, uint16_t size); + +/** + * @brief Function to write data to EEPROM with updated address + * + * @param address The next available address in the memory based on its size + * @param data Data being written + * @param size Size of data write + * @return true Successful + * @return false Unsuccessful + */ +bool eeprom_write_data_address(uint16_t address, void *data, uint16_t size); + +/** + * @brief Accepts a fault, updates the register saved in the eeprom partition, and + * writes a new fault to the EEPROM + * + * @param fault_code The code to be written to the EEPROM fault partition + */ +void write_faults(uint32_t fault_code); + +/** + * @brief Iterates through the memory in the EEPROM based on its initial index and + * stores the extracted faults in an array + * + */ +void read_faults(); + +/** + * @brief Accepts a data point, updates the register saved in the eeprom partition, and + * writes a new data point to the EEPROM + * + * @param data_point The code to be written to the EEPROM fault partition + */ +void write_data(uint32_t data_point); + +/** + * @brief Iterates through the memory in the EEPROM based on its initial index and + * stores the extracted data in an array + * + */ +void read_data(); +#endif // EEPROMSYS_H \ No newline at end of file diff --git a/Core/Src/eepromsys.c b/Core/Src/eepromsys.c new file mode 100644 index 00000000..15b3f2e7 --- /dev/null +++ b/Core/Src/eepromsys.c @@ -0,0 +1,198 @@ +#include "eepromsys.h" +#include "m24c32.h" + +void eepromInit() +{ + // Need to setup a Telemetry Section in Memory + // Establish size for 10 values of size 32 bytes + eeprom_data[0].key = (char *)("DATA"); + + eeprom_data[0].size = 1 + (32 * NUM_EEPROM_TELEM); + + // Need to setup a Faults Section in Memory + // Establish Size for 5 values of size 4 bytes + eeprom_data[1].key = (char *)("FAULTS"); + eeprom_data[1].size = 1 + (4 * NUM_EEPROM_FAULTS); + + // Initialize Address of the Data which will cover memory addresses starting at 0 + eeprom_data[0].address = EEPROM_BASE_ADD; + + int offset = 0; + int i = 1; + // While Loop Initializes the Sections After the Initial Section at Index 0 + while (eeprom_data[i].key != NULL) { + offset += eeprom_data[i - 1].size; + eeprom_data[i].address = offset; + i++; + } +} + +// Use by Writes/Reads with the EEPROM key +uint16_t eeprom_get_index(char *key) +{ + int i = 0; + while (eeprom_data[i].key != NULL) { + if (eeprom_data[i].key == key) { + return eeprom_data[i].address; + } + i++; + } + return -1; +} + +bool eeprom_write_key(char *key, void *data, uint16_t size) +{ + if (!data) { + return false; + } + + int address = eeprom_get_index(key); + eeprom_write(address, data, size); + return true; +} + +bool eeprom_read_key(char *key, void *data, uint16_t size) +{ + if (!data) { + return false; + } + + int address = eeprom_get_index(key); + eeprom_read(address, data, size); + return true; +} + +// Using the addresses to get +// Calls the driver function to read from EEPROM +bool eeprom_read_data_address(uint16_t address, void *data, uint16_t size) +{ + if (!data) { + return false; + } + /* read data from eeprom given index */ + eeprom_read(address, data, size); + return true; +} + +// Calls the driver function to write to EEPROM +bool eeprom_write_data_address(uint16_t address, void *data, uint16_t size) +{ + if (!data) { + return false; + } + /* write data to eeprom given page, offset, and size of data */ + eeprom_write(address, data, size); + return true; +} + +void write_faults(uint32_t fault_code) +{ + // THIS CODE ASSUMES THE FAULT IS 4 BYTES -> AN INTEGER + + // Copy fault into new value + uint32_t fault = fault_code; + + uint8_t reg_to_write; + + // Get's the data address to be written to next (8 bit number, up to 128) + eeprom_read_data_address(eeprom_get_index((char *)("FAULTS")), + ®_to_write, 1); + + // This will get the initial address the EEPROM "FAULTS" began with + uint8_t startInd = + eeprom_data[eeprom_get_index((char *)("FAULTS"))].address; + + // This will get the size of the EEPROM "FAULTS" section to determine where to put the new fault + uint8_t size = eeprom_data[eeprom_get_index((char *)("FAULTS"))].size; + + uint8_t available_space = (startInd + size) - reg_to_write; + if (available_space < 4) { + // If there's only 3 bytes available for the data + reg_to_write = startInd + 1; + } else { + // Else increment it to the next open place in memory + reg_to_write += 4; + } + + eeprom_write_data_address(reg_to_write, &fault, 4); +} + +void read_faults() +{ + // This will get the initial address the EEPROM "FAULTS" began with + uint8_t startAdd = + eeprom_data[eeprom_get_index((char *)("FAULTS"))].address; + + // This will get the size of the EEPROM "FAULTS" section to determine where to put the new fault + uint8_t size = eeprom_data[eeprom_get_index((char *)("FAULTS"))].size; + + // Iterating with the current register + uint8_t curr_reg = startAdd + 1; + + int numFaults = 0; + while (numFaults < NUM_EEPROM_FAULTS) { + eeprom_read_data_address(curr_reg, &eeprom_faults[numFaults], + 4); + numFaults++; + + if (curr_reg == size + startAdd - 3) { + curr_reg = startAdd + 1; + } else { + curr_reg += 4; + } + } +} + +void write_data(uint32_t data_point) +{ + uint32_t data = data_point; + + uint8_t reg_to_write; + + // Get's the data address to be written to next (8 bit number, up to 128) + eeprom_read_data_address(eeprom_get_index((char *)("DATA")), + ®_to_write, 1); + + // This will get the initial address the EEPROM "FAULTS" began with + uint8_t startInd = + eeprom_data[eeprom_get_index((char *)("DATA"))].address; + + // This will get the size of the EEPROM "FAULTS" section to determine where to put the new fault + uint8_t size = eeprom_data[eeprom_get_index((char *)("DATA"))].size; + + uint8_t available_space = (startInd + size) - reg_to_write; + if (available_space < 32) { + // If there's only 3 bytes available for the data + reg_to_write = startInd + 1; + } else { + // Else increment it to the next open place in memory + reg_to_write = reg_to_write + 32; + } + + eeprom_write_data_address(reg_to_write, &data, 32); +} + +void read_data() +{ + // This will get the initial address the EEPROM "FAULTS" began with + uint8_t startAdd = + eeprom_data[eeprom_get_index((char *)("DATA"))].address; + + // This will get the size of the EEPROM "FAULTS" section to determine where to put the new fault + uint8_t size = eeprom_data[eeprom_get_index((char *)("DATA"))].size; + + // Iterating with the current register + uint8_t curr_reg = 1 + startAdd; + + int numPts = 0; + while (numPts < NUM_EEPROM_TELEM) { + eeprom_read_data_address(curr_reg, &eeprom_pts[numPts], 32); + numPts++; + + if (curr_reg + 32 >= size + startAdd) { + curr_reg = startAdd + 1; + } else { + curr_reg += 32; + } + } +} diff --git a/Makefile b/Makefile index e8160754..d8913965 100644 --- a/Makefile +++ b/Makefile @@ -50,10 +50,12 @@ Core/Src/monitor.c \ Core/Src/fault.c \ Core/Src/can_handler.c \ Core/Src/serial_monitor.c \ +Core/Src/eepromsys.c \ Core/Src/dti.c \ Core/Src/state_machine.c \ Core/Src/bms.c \ Core/Src/nero.c \ +Core/Src/ \ Core/Src/torque.c \ Core/Src/pdu.c \ Core/Src/mpu.c \ @@ -82,6 +84,7 @@ Drivers/Embedded-Base/general/src/max7314.c \ Drivers/Embedded-Base/platforms/stm32f405/src/can.c \ Drivers/Embedded-Base/general/src/pi4ioe.c \ Drivers/Embedded-Base/general/src/pca9539.c \ +Drivers/Embedded-Base/general/src/m24c32.c \ Drivers/Embedded-Base/middleware/src/timer.c \ Drivers/Embedded-Base/middleware/src/ringbuffer.c \ Drivers/Embedded-Base/middleware/src/c_utils.c \