// Fake EEPROM #include #include "feeprom.h" #include "main.h" #include "SEGGER_RTT.h" typedef struct { // Schnittstellenparameter uint32_t baudrate; uint16_t parity_mode; uint16_t stopBits; uint16_t slave_address; //--- GERTE PARAMETER GERTE SPEZIFISCH --- uint16_t temperature_shutdown; int16_t ab_middle_point_offset; uint16_t i_plus_offset; uint16_t i_minus_offset; uint16_t copper_v_drop; uint16_t copper_v_drop_adc; uint16_t shortcut_current_in_mV; uint16_t inrush_max_current_in_mV; uint16_t inrush_max_current_in_adc; uint16_t inrush_curr_period; uint16_t inrush_curr_integral_steps; uint16_t lockKey; } feeprom_data_t; typedef struct { // Eeprom Status Infos uint8_t firstStartId; uint8_t res[3]; // 4 bit alignment uint32_t writeCounter; uint16_t structureSize; uint16_t revisionInfo; } feeprom_state_t; typedef struct { // Gerteinformation uint32_t SN; uint8_t deviceInfoWritten; uint8_t resv[3]; // 4 bit alignment } device_info_t; typedef struct __attribute__((packed)) { uint16_t startup_cnt; uint16_t overtemp_error_cnt; uint16_t overcurrent_error_cnt; uint16_t overload_error_cnt; uint16_t lowbat_error_cnt; uint16_t lvp_cnt; uint16_t ovp_cnt; uint16_t switch_cnt; uint16_t mosfets_voltagedrop_error_cnt; }log_data_t; // fasse zu einer Struktur zusammen um nachher einfach darauf zugreifen zu knnen typedef struct __attribute__((packed)) { feeprom_data_t changedData; // packed feeprom_state_t feepromState; device_info_t deviceInfo; } feeprom_stored_data_t; static const feeprom_data_t defaultFeepromData = { //--- GERTE PARAMETER ALLGEMEIN --- MB_BAUDRATE_DEFAULT, MB_PARITY_MODE_DEFAULT, MB_STOPBITS_DEFAULT, MB_SLAVE_ADRESS_DEFAULT, //--- GERTE PARAMETER GERTE SPEZIFISCH --- MAX_TEMP, 0, 0, 0, COPPER_V_DROP_AT_CONTROL_CURRENT_mV, ADC_VALUE_AT_CONTROL_CURRENT, SHORTCUT_CURRENT_mV, INRUSH_CURRENT_mV, ADC_VALUE_AT_INRUSH_CURRENT, CURRENT_INTEGRATION_PERIOD, CURRENT_INTEGRATION_STEPS, 0, }; // Flash related defines #define USER_FLASH_BASE_ADDRESS FLASH_BASE #define USER_FLASH_SIZE (128*1024) // 128Kb #define USER_FLASH_PAGE_SIZE FLASH_PAGE_SIZE #define USER_FEEPROM_BASE_ADDRESS (USER_FLASH_END - (USER_FLASH_PAGE_SIZE * NUMBER_OF_PAGES)) #define USER_FLASH_END (USER_FLASH_BASE_ADDRESS + USER_FLASH_SIZE) #define FEEPROM_ADDRESS_FIRST_START_ID (USER_FEEPROM_BASE_ADDRESS + SIZEOF_CHANGED_FEEPROM_DATA) #define NUMBER_OF_PAGES 2 #define FIRST_START_ID 0x65 // GS = Green Switch #define USER_STAT_BASE_ADDRESS (USER_FLASH_END - (USER_FLASH_PAGE_SIZE * 1)) // Stat-data position // Data to store related defines #define SIZEOF_CHANGED_FEEPROM_DATA (sizeof(feeprom_data_t)) #define SIZEOF_DEVICE_INFO (sizeof(device_info_t)) #define SIZEOF_FEEPROM_STATE (sizeof(feeprom_state_t)) #define SIZEOF_FEEPROM_STORED_DATA (sizeof(feeprom_stored_data_t)) #define SIZEOF_FEEPROM_LOG_DATA (sizeof(log_data_t)) #define SIZE_OF_DATA_TO_STORE (SIZEOF_CHANGED_FEEPROM_DATA + SIZEOF_DEVICE_INFO + SIZEOF_FEEPROM_STATE) // muss modulo 8 noch hinzufgen wg 8 byte alignment #define SIZEOF_RAW_FEEPROM_DATA ((SIZE_OF_DATA_TO_STORE/8) + ((SIZE_OF_DATA_TO_STORE%8)?1:0)) #define SIZEOF_RAW_FEEPROM_LOG_DATA ((SIZEOF_FEEPROM_LOG_DATA/8) + ((SIZEOF_FEEPROM_LOG_DATA%8)?1:0)) static uint64_t feepromData[SIZEOF_RAW_FEEPROM_DATA]; static uint64_t feepromLogData[SIZEOF_RAW_FEEPROM_LOG_DATA]; extern uint16_t savedLockKey; //----------------------------------------------------------------------------- size_t FEEPROM_ConfigFreeBytes(void) { return (1 * USER_FLASH_PAGE_SIZE - SIZE_OF_DATA_TO_STORE); } //----------------------------------------------------------------------------- size_t FEEPROM_StatFreeBytes(void) { return (1 * USER_FLASH_PAGE_SIZE - SIZEOF_FEEPROM_LOG_DATA); } //----------------------------------------------------------------------------- int getFEEPROMData(size_t address, uint8_t *data, uint32_t len) { // Exiting with error, if requested data location is beyond of FLASH size if ((address + len) > USER_FLASH_END) return 1; // Reading from FLASH memory bytes, starting from
for (int i = 0; i < len; i++) data[i] = *((uint8_t*)(address + i)); return 0; // No error } //----------------------------------------------------------------------------- int WriteConfigToFLASH(void) { if (HAL_FLASH_Unlock() == HAL_OK) { __HAL_FLASH_INSTRUCTION_CACHE_DISABLE(); /* Fill EraseInit structure*/ FLASH_EraseInitTypeDef EraseInit; EraseInit.TypeErase = FLASH_TYPEERASE_PAGES; EraseInit.Page = FLASH_PAGE_NB - 2; // This page contains device critical parameters EraseInit.NbPages = 1; uint32_t PageError; /* Erase Sektoren daten drfen nicht im instuction cache liegen */ if (HAL_FLASHEx_Erase(&EraseInit, &PageError) == HAL_OK) { /* Programmiere uint64_t */ size_t Address = USER_FEEPROM_BASE_ADDRESS; uint32_t x = 0; while (Address < (USER_FEEPROM_BASE_ADDRESS + SIZE_OF_DATA_TO_STORE)) { if (HAL_FLASH_Program(FLASH_TYPEPROGRAM_DOUBLEWORD, Address, feepromData[x]) == HAL_OK) { Address = Address + 8; x++; } else { __HAL_FLASH_INSTRUCTION_CACHE_ENABLE(); HAL_FLASH_Lock(); return 3; } } } else { __HAL_FLASH_INSTRUCTION_CACHE_ENABLE(); HAL_FLASH_Lock(); return 2; } __HAL_FLASH_INSTRUCTION_CACHE_ENABLE(); } else return 1; if (HAL_FLASH_Lock() != HAL_OK) return 4; return 0; } //----------------------------------------------------------------------------- int FEEPROM_readConfig(sys_data_t *data) { feeprom_stored_data_t *dataToStore; if (getFEEPROMData(USER_FEEPROM_BASE_ADDRESS, (uint8_t*)feepromData, SIZEOF_FEEPROM_STORED_DATA)) return 1; // Error dataToStore = (feeprom_stored_data_t*)feepromData; //memcpy(data, dataToStore, SIZEOF_CHANGED_FEEPROM_DATA); data->s.baudrate = dataToStore->changedData.baudrate; data->s.parity_mode = dataToStore->changedData.parity_mode; data->s.stopBits = dataToStore->changedData.stopBits; data->s.slave_address = dataToStore->changedData.slave_address; data->s.temperature_shutdown = dataToStore->changedData.temperature_shutdown; data->s.ab_middle_point_offset = dataToStore->changedData.ab_middle_point_offset; data->s.copper_v_drop = dataToStore->changedData.copper_v_drop; data->s.copper_v_drop_adc = dataToStore->changedData.copper_v_drop_adc; data->s.shortcut_current_in_mV = dataToStore->changedData.shortcut_current_in_mV; data->s.inrush_max_current_in_mV = dataToStore->changedData.inrush_max_current_in_mV; data->s.inrush_max_current_in_adc = dataToStore->changedData.inrush_max_current_in_adc; data->s.inrush_curr_period = dataToStore->changedData.inrush_curr_period; data->s.inrush_curr_integral_steps = dataToStore->changedData.inrush_curr_integral_steps; data->s.i_plus_offset = dataToStore->changedData.i_plus_offset; data->s.i_minus_offset = dataToStore->changedData.i_minus_offset; savedLockKey = dataToStore->changedData.lockKey; if (savedLockKey != 0) data->s.writeLocked = 1 ; data->s.device_sn = dataToStore->deviceInfo.SN; // prfe Eeprom Status Infos if(dataToStore->feepromState.structureSize != SIZEOF_FEEPROM_STORED_DATA) return 2; if(dataToStore->feepromState.revisionInfo != 0) return 3; if(dataToStore->feepromState.firstStartId != FIRST_START_ID) return 4; return 0; // No error } //----------------------------------------------------------------------------- int FEEPROM_storeConfig(sys_data_t *data, uint8_t withSN) { feeprom_stored_data_t *dataToStore; /****************LESE_WERTE_AUS_SYSDATA*********************/ dataToStore = (feeprom_stored_data_t *)feepromData; // Copying values to be stored //memcpy(&dataToStore->changedData.s.baudrate, &data->s.baudrate, SIZEOF_CHANGED_FEEPROM_DATA - 10); dataToStore->changedData.baudrate = data->s.baudrate; dataToStore->changedData.parity_mode = data->s.parity_mode; dataToStore->changedData.stopBits = data->s.stopBits; dataToStore->changedData.slave_address = data->s.slave_address; dataToStore->changedData.temperature_shutdown = data->s.temperature_shutdown; dataToStore->changedData.ab_middle_point_offset = data->s.ab_middle_point_offset; dataToStore->changedData.copper_v_drop = data->s.copper_v_drop; dataToStore->changedData.copper_v_drop_adc = data->s.copper_v_drop_adc; dataToStore->changedData.shortcut_current_in_mV = data->s.shortcut_current_in_mV; dataToStore->changedData.inrush_max_current_in_mV = data->s.inrush_max_current_in_mV; dataToStore->changedData.inrush_max_current_in_adc = data->s.inrush_max_current_in_adc; dataToStore->changedData.inrush_curr_period = data->s.inrush_curr_period; dataToStore->changedData.inrush_curr_integral_steps = data->s.inrush_curr_integral_steps; dataToStore->changedData.lockKey = data->s.newLockKey; dataToStore->changedData.i_plus_offset = data->s.i_plus_offset; dataToStore->changedData.i_minus_offset = data->s.i_minus_offset; // Eeprom Status Infos dataToStore->feepromState.writeCounter++; dataToStore->feepromState.structureSize = SIZEOF_FEEPROM_STORED_DATA; dataToStore->feepromState.revisionInfo = 0; dataToStore->feepromState.firstStartId = FIRST_START_ID; if (withSN) dataToStore->deviceInfo.SN = data->s.device_sn; if (WriteConfigToFLASH()) return 1; // Error return 0; } //----------------------------------------------------------------------------- int FEEPROM_fullRestore(void/*sys_data_t *data*/) { feeprom_stored_data_t *dataToStore; /****************LESE_DEFAULT_WERTE************************/ dataToStore = (feeprom_stored_data_t *)feepromData; // Copying default values memcpy(&dataToStore->changedData, &defaultFeepromData, SIZEOF_CHANGED_FEEPROM_DATA); //uint32_t sn = 0; //if (getFEEPROMData(USER_FEEPROM_BASE_ADRESS + SIZEOF_CHANGED_FEEPROM_DATA + SIZEOF_FEEPROM_STATE, (uint8_t*)&sn, sizeof(sn))) return 1; // Error //if (sn == 0xFFFFFFFF) dataToStore->deviceInfo.SN = dataToStore->changedData.s.device_sn; //else dataToStore->deviceInfo.SN = sn; // Saving SN in special area, non-reachable for end-user //dataToStore->deviceInfo.SN = dataToStore->changedData.s.device_sn; dataToStore->feepromState.writeCounter++; dataToStore->feepromState.structureSize = SIZEOF_FEEPROM_STORED_DATA; dataToStore->feepromState.revisionInfo = 0; dataToStore->feepromState.firstStartId = FIRST_START_ID; if (WriteConfigToFLASH()) return 2; // Error return 0; // No error } //----------------------------------------------------------------------------- int FEEPROM_factoryRestore(sys_data_t *data) { return 0; } //----------------------------------------------------------------------------- int FEEPROM_isFirstStart(void) { uint8_t firstStartCatcher; /*SEGGER_RTT_printf(0, "USER_FLASH_BASE_ADRESS:\t\t0x%08X\n", USER_FLASH_BASE_ADRESS); SEGGER_RTT_printf(0, "USER_FLASH_SIZE:\t\t%d\n", USER_FLASH_SIZE); SEGGER_RTT_printf(0, "USER_FLASH_PAGE_SIZE:\t\t%d\n", USER_FLASH_PAGE_SIZE); SEGGER_RTT_printf(0, "USER_FEEPROM_BASE_ADRESS:\t0x%08X\n", USER_FEEPROM_BASE_ADRESS); SEGGER_RTT_printf(0, "USER_FLASH_END:\t\t\t0x%08X\n", USER_FLASH_END); SEGGER_RTT_printf(0, "FEEPROM_ADRESS_FIRST_START_ID:\t0x%08X\n", FEEPROM_ADRESS_FIRST_START_ID); SEGGER_RTT_printf(0, "SIZEOF_CHANGED_FEEPROM_DATA:\t%d\n", SIZEOF_CHANGED_FEEPROM_DATA); SEGGER_RTT_printf(0, "SIZEOF_DEVICE_INFO:\t\t%d\n", SIZEOF_DEVICE_INFO); SEGGER_RTT_printf(0, "SIZEOF_FEEPROM_STATE:\t\t%d\n", SIZEOF_FEEPROM_STATE); SEGGER_RTT_printf(0, "Sizeof(feeprom_stored_data_t):\t%d\n", sizeof(feeprom_stored_data_t));*/ // Trying to read first start indicator from FLASH memory if(getFEEPROMData(FEEPROM_ADDRESS_FIRST_START_ID, &firstStartCatcher, 1)) return 1; // If found indicator is not correct, then exiting with error if(firstStartCatcher != FIRST_START_ID) return 1; return 0; } //----------------------------------------------------------------------------- int WriteLogToFLASH(void) { if (HAL_FLASH_Unlock() == HAL_OK) { __HAL_FLASH_INSTRUCTION_CACHE_DISABLE(); /* Fill EraseInit structure*/ FLASH_EraseInitTypeDef EraseInit; EraseInit.TypeErase = FLASH_TYPEERASE_PAGES; EraseInit.Page = FLASH_PAGE_NB - 1; // This page contains device statistical data EraseInit.NbPages = 1; uint32_t PageError; /* Erase Sektoren daten drfen nicht im instuction cache liegen */ if (HAL_FLASHEx_Erase(&EraseInit, &PageError) == HAL_OK) { /* Programmiere uint64_t */ size_t Address = USER_STAT_BASE_ADDRESS; uint32_t x = 0; while (Address < (USER_STAT_BASE_ADDRESS + SIZEOF_FEEPROM_LOG_DATA)) { if (HAL_FLASH_Program(FLASH_TYPEPROGRAM_DOUBLEWORD, Address, feepromLogData[x]) == HAL_OK) { Address = Address + 8; x++; } else { __HAL_FLASH_INSTRUCTION_CACHE_ENABLE(); HAL_FLASH_Lock(); return 3; } } } else { __HAL_FLASH_INSTRUCTION_CACHE_ENABLE(); HAL_FLASH_Lock(); return 2; } __HAL_FLASH_INSTRUCTION_CACHE_ENABLE(); } else return 1; if (HAL_FLASH_Lock() != HAL_OK) return 4; return 0; } //----------------------------------------------------------------------------- int FEEPROM_ResetLogData(void) { log_data_t* logData; logData = (log_data_t*)feepromLogData; logData->startup_cnt = 0; logData->overtemp_error_cnt = 0; logData->overcurrent_error_cnt = 0; logData->overload_error_cnt = 0; logData->lowbat_error_cnt = 0; logData->lvp_cnt = 0; logData->ovp_cnt = 0; logData->switch_cnt = 0; logData->mosfets_voltagedrop_error_cnt = 0; if (WriteLogToFLASH()) return 2; // Error return 0; // No error } //----------------------------------------------------------------------------- int FEEPROM_ReadLogData(sys_data_t *data) { log_data_t * logData; /****************WERTE_AUS_FLASH_LESEN********************/ if(getFEEPROMData(USER_STAT_BASE_ADDRESS, (uint8_t*)feepromLogData, sizeof(feepromLogData))) return 1; logData = (log_data_t*)feepromLogData; data->s.startup_cnt = logData->startup_cnt; data->s.overtemp_error_cnt = logData->overtemp_error_cnt; data->s.overcurrent_error_cnt = logData->overcurrent_error_cnt; data->s.overload_error_cnt = logData->overload_error_cnt; data->s.lowbat_error_cnt = logData->lowbat_error_cnt; data->s.lvp_cnt = logData->lvp_cnt; data->s.ovp_cnt = logData->ovp_cnt; data->s.switch_cnt = logData->switch_cnt; data->s.mosfets_voltagedrop_error_cnt = logData->mosfets_voltagedrop_error_cnt; return 0; } //----------------------------------------------------------------------------- int FEEPROM_StoreLogData(sys_data_t *data) { log_data_t * logData; logData = (log_data_t*)feepromLogData; logData->startup_cnt = data->s.startup_cnt; logData->overtemp_error_cnt = data->s.overtemp_error_cnt; logData->overcurrent_error_cnt = data->s.overcurrent_error_cnt; logData->overload_error_cnt = data->s.overload_error_cnt; logData->lowbat_error_cnt = data->s.lowbat_error_cnt; logData->lvp_cnt = data->s.lvp_cnt; logData->ovp_cnt = data->s.ovp_cnt; logData->switch_cnt = data->s.switch_cnt; logData->mosfets_voltagedrop_error_cnt = data->s.mosfets_voltagedrop_error_cnt; if (WriteLogToFLASH()) return 2; // Error return 0; // No error }