123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461 |
- /*
- * settings.c
- *
- * Created on: Jan 12, 2021
- * Author: David Original work by Jose (PTDreamer), 2017
- */
- #include "settings.h"
- #include "pid.h"
- #include "iron.h"
- #include "gui.h"
- #include "ssd1306.h"
- #include "tempsensors.h"
- systemSettings_t systemSettings;
- flashSettings_t* flashSettings = (flashSettings_t*)FLASH_ADDR;
- void settingsChkErr(void);
- void ProfileChkErr(void);
- void Flash_error(void);
- void Button_reset(void);
- void Diag_init(void);
- void ErrCountDown(uint8_t Start,uint8_t xpos, uint8_t ypos);
- // Check for changes in system settings.
- void checkSettings(void){
- static uint32_t prevSysChecksum=0, newSysChecksum=0, prevTipChecksum=0, newTipChecksum=0, checksumtime=0;
- uint32_t CurrentTime = HAL_GetTick();
- // Don't check if in: Calibration mode, Setup mode, Save delay==0, failure error active
- if( (systemSettings.setupMode==setup_On) || (Iron.calibrating==calibration_On) || (systemSettings.settings.saveSettingsDelay==0) || (Iron.Error.failState!=noError) || (CurrentTime-checksumtime<999)){
- return;
- }
- checksumtime=CurrentTime; // Store current time
- newSysChecksum=ChecksumSettings(&systemSettings.settings); // Calculate system checksum
- newTipChecksum=ChecksumProfile(&systemSettings.Profile); // Calculate tip profile checksum
- if((systemSettings.settingsChecksum!=newSysChecksum)||(systemSettings.ProfileChecksum!=newTipChecksum)){ // If anything was changed (Checksum mismatch)
- if((prevSysChecksum!=newSysChecksum)||(prevTipChecksum!=newTipChecksum)){ // If different from the previous calculated checksum (settings are being changed quickly, don't save every time).
- prevSysChecksum=newSysChecksum; // Store last computed checksum
- prevTipChecksum=newTipChecksum;
- Iron.LastSysChangeTime=CurrentTime; // Reset timer (we don't save anything until we pass a certain time without changes)
- }
- else if((CurrentTime-Iron.LastSysChangeTime)>((uint32_t)systemSettings.settings.saveSettingsDelay*1000)){ // If different from the previous calculated checksum, and timer expired (No changes for enough time)
- saveSettings(saveKeepingProfiles); // Data was saved (so any pending interrupt knows this)
- }
- }
- }
- void saveSettings(bool wipeAllProfileData) {
- uint32_t error=0;
- //Read stored data, as everything will be erased and we don't store data for all iron tips in ram (only the current tip type)
- flashSettings_t flashBuffer=*flashSettings;
- // Check init flags
- if( (systemSettings.settings.NotInitialized!=initialized) || (systemSettings.Profile.NotInitialized!=initialized) ){
- Error_Handler();
- }
- // Compute checksum of current system settings
- systemSettings.settingsChecksum = ChecksumSettings(&systemSettings.settings);
- // Transfer system settings to flash buffer
- flashBuffer.settingsChecksum=systemSettings.settingsChecksum;
- flashBuffer.settings=systemSettings.settings;
- if(!wipeAllProfileData){ // If wipe all tips is not set
- if(systemSettings.settings.currentProfile!=profile_None){ // If current tip is initialized
- if((systemSettings.settings.currentProfile<=profile_C210) && // Check valid Profile
- (systemSettings.Profile.ID == systemSettings.settings.currentProfile )){ // Ensure profile ID is correct
- systemSettings.ProfileChecksum = ChecksumProfile(&systemSettings.Profile); // Compute checksum
- flashBuffer.ProfileChecksum[systemSettings.settings.currentProfile]=systemSettings.ProfileChecksum;
- memcpy(&flashBuffer.Profile[systemSettings.settings.currentProfile],&systemSettings.Profile,sizeof(profile_t)); // Transfer system profile to flash buffer
- }
- else{
- Error_Handler(); // Invalid tip (uncontrolled state)
- }
- }
- }
- else{ // Wipe all tip data
- for(uint8_t x=0;x<ProfileSize;x++){
- flashBuffer.Profile[x].NotInitialized=0xFF;
- flashBuffer.ProfileChecksum[x]=0xFF;
- memset(&flashBuffer.Profile[x],0xFF,sizeof(profile_t));
- }
- }
- __disable_irq();
- HAL_FLASH_Unlock();
- __enable_irq();
- FLASH_EraseInitTypeDef erase;
- erase.NbPages = (1024*StoreSize)/FLASH_PAGE_SIZE;
- erase.PageAddress = FLASH_ADDR;
- erase.TypeErase = FLASH_TYPEERASE_PAGES;
- //Erase flash page
- __disable_irq();
- HAL_IWDG_Refresh(&hiwdg);
- if((HAL_FLASHEx_Erase(&erase, &error)!=HAL_OK) || (error!=0xFFFFFFFF)){
- Flash_error();
- }
- __enable_irq();
- __disable_irq();
- HAL_FLASH_Lock();
- __enable_irq();
- // Ensure flash was erased
- for (uint16_t i = 0; i < sizeof(flashSettings_t)/2; i++) {
- if( *(uint16_t*)(FLASH_ADDR+(i*2)) != 0xFFFF){
- Flash_error();
- }
- }
- __disable_irq();
- HAL_FLASH_Unlock();
- __enable_irq();
- uint32_t dest = (uint32_t)flashSettings;
- uint16_t *data = (uint16_t*)&flashBuffer;
- // Store settings
- // written = number of 16-bit values written
- for(uint16_t written=0; written < (sizeof(flashSettings_t)/2); written++){
- __disable_irq();
- if(HAL_FLASH_Program(FLASH_TYPEPROGRAM_HALFWORD, dest, *data ) != HAL_OK){
- Flash_error();
- }
- dest += 2; // address +2 because we write 16 bit data
- data++; // +1 because it's 16Bit pointer
- __enable_irq();
- }
- __disable_irq();
- HAL_FLASH_Lock();
- __enable_irq();
- if(!wipeAllProfileData){
- uint32_t ProfileFlash = ChecksumProfile(&flashSettings->Profile[systemSettings.settings.currentProfile]);
- uint32_t ProfileRam = ChecksumProfile(&systemSettings.Profile);
- // Check flash and system tip profile have same checksum and profile type
- if((ProfileFlash != ProfileRam) || (flashSettings->settings.currentProfile != systemSettings.settings.currentProfile)){
- Flash_error(); // Error if data mismatchº
- }
- }
- // Check flash and system settings have same checksum
- uint32_t SettingsFlash = ChecksumSettings(&flashSettings->settings);
- uint32_t SettingsRam = ChecksumSettings(&systemSettings.settings);
- if(SettingsFlash != SettingsRam){ // Check flash and system settings have same checksum
- Flash_error(); // Error if data mismatch
- }
- }
- void restoreSettings() {
- #ifdef NOSAVESETTINGS // Stop erasing the flash every time while in debug mode
- resetSystemSettings(); // TODO not tested with the new profile system
- setupPID(systemSettings.Profile.tip[systemSettings.settings.currentTip[systemSettings.settings.currentProfile]].PID);
- return;
- #endif
- if(flashSettings->settings.NotInitialized!=initialized){ // If flash not initialized (Erased flash is always read "1")
- resetSystemSettings();
- saveSettings(saveWipingProfiles);
- }
- else{
- Button_reset(); // Check for button reset
- }
- systemSettings.settings=flashSettings->settings; // Load system settings from flash
- systemSettings.settingsChecksum=flashSettings->settingsChecksum; // Load stored checksum
- loadProfile(systemSettings.settings.currentProfile); // Load current tip data into system memory
- // Compare loaded checksum with calculated checksum
- if( (systemSettings.settings.version != SETTINGS_VERSION) || (ChecksumSettings(&systemSettings.settings)!=systemSettings.settingsChecksum) ){
- settingsChkErr();
- }
- setContrast(systemSettings.settings.contrast);
- }
- uint32_t ChecksumSettings(settings_t* settings){
- uint32_t checksum;
- checksum = HAL_CRC_Calculate(&hcrc, (uint32_t*)settings, sizeof(settings_t)/sizeof(uint32_t) );
- return checksum;
- }
- uint32_t ChecksumProfile(profile_t* profile){
- uint32_t checksum;
- checksum = HAL_CRC_Calculate(&hcrc, (uint32_t*)profile, sizeof(profile_t)/sizeof(uint32_t));
- return checksum;
- }
- void resetSystemSettings(void) {
- systemSettings.settings.version = SETTINGS_VERSION;
- systemSettings.settings.contrast = 255;
- systemSettings.settings.screenDimming = true;
- systemSettings.settings.OledOffset = 2;
- systemSettings.settings.errorDelay = 100;
- systemSettings.settings.guiUpdateDelay = 200;
- systemSettings.settings.tempUnit = mode_Celsius;
- systemSettings.settings.tempStep = 10; // 10º steps
- systemSettings.settings.activeDetection = true;
- systemSettings.settings.saveSettingsDelay = 5; // 5s
- systemSettings.settings.lvp = 110; // 11.0V Low voltage
- systemSettings.settings.currentProfile = profile_None;
- systemSettings.settings.initMode = mode_run;
- systemSettings.settings.buzzerMode = buzzer_Off;
- systemSettings.settings.wakeOnButton = wakeButton_On;
- systemSettings.settings.wakeOnShake = wakeShake_On;
- systemSettings.settings.WakeInputMode = wakeInputmode_shake;
- systemSettings.settings.StandMode = mode_sleep;
- systemSettings.settings.EncoderMode = RE_Mode_One;
- systemSettings.settings.NotInitialized = initialized;
- }
- void resetCurrentProfile(void){
- #ifdef NOSAVESETTINGS
- systemSettings.settings.currentProfile=profile_T12; /// Force T12 when debugging. TODO this is not tested with the profiles update!
- #endif
- char str[TipCharSize];
- for(uint8_t x=0;x<TipCharSize;x++){
- str[x] = ' ';
- }
- str[TipCharSize-1] = 0;
- if(systemSettings.settings.currentProfile==profile_T12){
- systemSettings.Profile.ID = profile_T12;
- for(uint8_t x = 0; x < TipSize; x++) {
- systemSettings.Profile.tip[x].calADC_At_250 = T12_Cal250;
- systemSettings.Profile.tip[x].calADC_At_350 = T12_Cal350; // These values are way lower, but better to be safe than sorry
- systemSettings.Profile.tip[x].calADC_At_450 = T12_Cal450; // User needs to calibrate its station
- systemSettings.Profile.tip[x].PID.Kp = 7500; // val = /1.000.000
- systemSettings.Profile.tip[x].PID.Ki = 4000; // val = /1.000.000
- systemSettings.Profile.tip[x].PID.Kd = 1000; // val = /1.000.000
- systemSettings.Profile.tip[x].PID.maxI = 40; // val = /100
- systemSettings.Profile.tip[x].PID.minI = 0; // val = /100
- strcpy(systemSettings.Profile.tip[x].name, str); // Empty name
- }
- strcpy(systemSettings.Profile.tip[0].name, "BC3 "); // Put some generic name
- systemSettings.Profile.currentNumberOfTips = 1;
- systemSettings.Profile.currentTip = 0;
- systemSettings.Profile.impedance = 80; // 8.0 Ohms
- systemSettings.Profile.power = 80; // 80W
- systemSettings.Profile.noIronValue = 4000;
- systemSettings.Profile.Cal250_default = T12_Cal250;
- systemSettings.Profile.Cal350_default = T12_Cal350;
- systemSettings.Profile.Cal450_default = T12_Cal450;
- }
- else if(systemSettings.settings.currentProfile==profile_C245){
- systemSettings.Profile.ID = profile_C245;
- for(uint8_t x = 0; x < TipSize; x++) {
- systemSettings.Profile.tip[x].calADC_At_250 = C245_Cal250;
- systemSettings.Profile.tip[x].calADC_At_350 = C245_Cal350;
- systemSettings.Profile.tip[x].calADC_At_450 = C245_Cal450;
- systemSettings.Profile.tip[x].PID.Kp = 7500; // val = /1.000.000
- systemSettings.Profile.tip[x].PID.Ki = 4000; // val = /1.000.000
- systemSettings.Profile.tip[x].PID.Kd = 1000; // val = /1.000.000
- systemSettings.Profile.tip[x].PID.maxI = 40; // val = /100
- systemSettings.Profile.tip[x].PID.minI = 0; // val = /100
- strcpy(systemSettings.Profile.tip[x].name, str); // Empty name
- }
- strcpy(systemSettings.Profile.tip[0].name, "C245");
- systemSettings.Profile.currentNumberOfTips = 1;
- systemSettings.Profile.currentTip = 0;
- systemSettings.Profile.impedance = 26;
- systemSettings.Profile.power = 150;
- systemSettings.Profile.noIronValue = 4000;
- systemSettings.Profile.Cal250_default = C245_Cal250;
- systemSettings.Profile.Cal350_default = C245_Cal350;
- systemSettings.Profile.Cal450_default = C245_Cal450;
- }
- else if(systemSettings.settings.currentProfile==profile_C210){
- systemSettings.Profile.ID = profile_C210;
- for(uint8_t x = 0; x < TipSize; x++) {
- systemSettings.Profile.tip[x].calADC_At_250 = C210_Cal250;
- systemSettings.Profile.tip[x].calADC_At_350 = C210_Cal350;
- systemSettings.Profile.tip[x].calADC_At_450 = C210_Cal450;
- systemSettings.Profile.tip[x].PID.Kp = 7500; // val = /1.000.000
- systemSettings.Profile.tip[x].PID.Ki = 4000; // val = /1.000.000
- systemSettings.Profile.tip[x].PID.Kd = 1000; // val = /1.000.000
- systemSettings.Profile.tip[x].PID.maxI = 40; // val = /100
- systemSettings.Profile.tip[x].PID.minI = 0; // val = /100
- strcpy(systemSettings.Profile.tip[x].name, str); // Empty name
- }
- strcpy(systemSettings.Profile.tip[0].name, "C210");
- systemSettings.Profile.currentNumberOfTips = 1;
- systemSettings.Profile.currentTip = 0;
- systemSettings.Profile.power = 80;
- systemSettings.Profile.impedance = 21;
- systemSettings.Profile.noIronValue = 1200;
- systemSettings.Profile.Cal250_default = C210_Cal250;
- systemSettings.Profile.Cal350_default = C210_Cal350;
- systemSettings.Profile.Cal450_default = C210_Cal450;
- }
- else{
- Error_Handler(); // We shouldn't get here!
- }
- systemSettings.Profile.CalNTC = 25;
- systemSettings.Profile.sleepTimeout = 5;
- systemSettings.Profile.standbyTimeout = 5;
- systemSettings.Profile.standbyTemperature = 180;
- systemSettings.Profile.UserSetTemperature = 180;
- systemSettings.Profile.MaxSetTemperature = 450;
- systemSettings.Profile.MinSetTemperature = 180;
- systemSettings.Profile.pwmPeriod = 19999;
- systemSettings.Profile.pwmDelay = 1999;
- systemSettings.Profile.filterFactor = 2;
- systemSettings.Profile.tempUnit = mode_Celsius;
- systemSettings.Profile.NotInitialized = initialized;
- }
- void loadProfile(uint8_t profile){
- systemSettings.settings.currentProfile=profile; // Update system profile
- if(profile<=profile_C210){ // If current tip type is valid
- systemSettings.Profile = flashSettings->Profile[profile]; // Load stored tip data
- systemSettings.ProfileChecksum = flashSettings->ProfileChecksum[profile]; // Load stored checksum
- if(systemSettings.Profile.NotInitialized!=initialized){ // Check if initialized
- resetCurrentProfile(); // Load defaults if not
- systemSettings.ProfileChecksum = ChecksumProfile(&systemSettings.Profile); // Compute checksum
- }
- // Calculate data checksum and compare with stored checksum, also ensure the stored ID is the same as the requested profile
- if( (profile!=systemSettings.Profile.ID) || (systemSettings.ProfileChecksum != ChecksumProfile(&systemSettings.Profile)) ){
- ProfileChkErr(); // Checksum mismatch, reset current tip data
- }
- setUserTemperature(systemSettings.Profile.UserSetTemperature); // Load user set temperature
- setCurrentTip(systemSettings.Profile.currentTip); // Load TIP data
- Iron.updatePwm=needs_update; // Apply profile PWM settings
- }
- else if(profile==profile_None){
- return; // Profiles not initialized, load nothing
- }
- else{ // Unknown profile
- Error_Handler();
- }
- if(systemSettings.settings.tempUnit != systemSettings.Profile.tempUnit){ // If stored temps are in different units
- setSystemTempUnit(systemSettings.settings.tempUnit); // Convert temperatures
- systemSettings.Profile.tempUnit = systemSettings.settings.tempUnit; // Store unit in profile
- }
- }
- void Diag_init(void){
- setContrast(255);
- FillBuffer(BLACK,fill_soft);
- u8g2_SetFont(&u8g2,default_font );
- u8g2_SetDrawColor(&u8g2, WHITE);
- }
- void Flash_error(void){
- __disable_irq();
- HAL_FLASH_Lock();
- __enable_irq();
- Diag_init();
- putStrAligned("FLASH ERROR!", 16, align_center);
- putStrAligned("HALTING SYSTEM", 32, align_center);
- update_display();
- while(1){
- HAL_IWDG_Refresh(&hiwdg);
- }
- }
- void settingsChkErr(void){
- Diag_init();
- systemSettings.settings.OledOffset = 2; // Set default value
- putStrAligned("SETTING ERR!", 10, align_center);
- putStrAligned("RESTORING", 26, align_center);
- putStrAligned("DEFAULTS...", 42, align_center);
- update_display();
- ErrCountDown(3,117,50);
- if(systemSettings.settings.currentProfile<=profile_C210){ // If current tip type is valid
- if(systemSettings.ProfileChecksum==ChecksumProfile(&systemSettings.Profile)){ // If current profile checksum is correct
- uint8_t tip = systemSettings.settings.currentProfile; // save current tip
- resetSystemSettings(); // reset settings
- systemSettings.settings.currentProfile=tip; // Restore tip type
- saveSettings(saveKeepingProfiles); // Save settings preserving tip data
- }
- else{ // If checksum wrong
- resetSystemSettings(); // reset settings
- saveSettings(saveWipingProfiles); // Save settings erasing tip data
- }
- }
- else{ // If current tip not valid
- resetSystemSettings(); // Assume something went wrong, reset settings
- saveSettings(saveKeepingProfiles); // Save keeping tip data
- }
- }
- void ProfileChkErr(void){
- Diag_init();
- putStrAligned("PROFILE ERR!", 10, align_center);
- putStrAligned("RESTORING", 26, align_center);
- putStrAligned("DEFAULTS...", 42, align_center);
- update_display();
- ErrCountDown(3,117,50);
- resetCurrentProfile(); // Reset current tip type data only
- }
- void Button_reset(void){
- uint16_t ResetTimer= HAL_GetTick();
- if(!BUTTON_input()){
- Diag_init();
- putStrAligned("HOLD BUTTON", 10, align_center);
- putStrAligned("TO RESTORE", 26, align_center);
- putStrAligned("DEFAULTS", 42, align_center);
- update_display();
- while(!BUTTON_input()){
- HAL_IWDG_Refresh(&hiwdg);
- if((HAL_GetTick()-ResetTimer)>5000){
- FillBuffer(BLACK,fill_dma);
- putStrAligned("RELEASE", 16, align_center);
- putStrAligned("BUTTON NOW", 32, align_center);
- update_display();
- while(!BUTTON_input()){
- HAL_IWDG_Refresh(&hiwdg);
- }
- resetSystemSettings();
- saveSettings(saveWipingProfiles);
- }
- }
- }
- }
- //Max 99 seconds countdown.
- void ErrCountDown(uint8_t Start,uint8_t xpos, uint8_t ypos){
- uint32_t timErr = 0;
- char str[4];
- uint8_t length;
- if(Start>99){Start=99;}
- if(Start>9){
- length=2;
- }
- else{
- length=1;
- }
- HAL_IWDG_Refresh(&hiwdg);
- while(oled.status!=oled_idle); // Wait for the screen to be idle (few mS at most). Hanging here will cause a watchdog reset.
- while(Start){
- timErr=HAL_GetTick();
- u8g2_SetDrawColor(&u8g2, BLACK);
- u8g2_DrawBox(&u8g2,xpos,ypos,u8g2_GetStrWidth(&u8g2,str),u8g2_GetMaxCharHeight(&u8g2));
- u8g2_SetDrawColor(&u8g2, WHITE);
- sprintf(&str[0],"%*u",length-1,Start--);
- u8g2_DrawStr(&u8g2,xpos,ypos,str);
- update_display();
- while( (HAL_GetTick()-timErr)<999 ){
- HAL_IWDG_Refresh(&hiwdg); // Clear watchdog
- }
- }
- }
|