#include #include "Arduino.h" #include "config.h" #include "def.h" #include "types.h" #include "EEPROM.h" #include "MultiWii.h" #include "Alarms.h" #include "GPS.h" void LoadDefaults(void); uint8_t calculate_sum(uint8_t *cb , uint8_t siz) { uint8_t sum=0x55; // checksum init while(--siz) sum += *cb++; // calculate checksum (without checksum byte) return sum; } void readGlobalSet() { eeprom_read_block((void*)&global_conf, (void*)0, sizeof(global_conf)); if(calculate_sum((uint8_t*)&global_conf, sizeof(global_conf)) != global_conf.checksum) { global_conf.currentSet = 0; global_conf.accZero[ROLL] = 5000; // for config error signalization } } bool readEEPROM() { uint8_t i; int8_t tmp; uint8_t y; #ifdef MULTIPLE_CONFIGURATION_PROFILES if(global_conf.currentSet>2) global_conf.currentSet=0; #else global_conf.currentSet=0; #endif eeprom_read_block((void*)&conf, (void*)(global_conf.currentSet * sizeof(conf) + sizeof(global_conf)), sizeof(conf)); if(calculate_sum((uint8_t*)&conf, sizeof(conf)) != conf.checksum) { blinkLED(6,100,3); SET_ALARM_BUZZER(ALRM_FAC_CONFIRM, ALRM_LVL_CONFIRM_ELSE); LoadDefaults(); // force load defaults return false; // defaults loaded, don't reload constants (EEPROM life saving) } // 500/128 = 3.90625 3.9062 * 3.9062 = 15.259 1526*100/128 = 1192 for(i=0;i<5;i++) { lookupPitchRollRC[i] = (1526+conf.rcExpo8*(i*i-15))*i*(int32_t)conf.rcRate8/1192; } for(i=0;i<11;i++) { tmp = 10*i-conf.thrMid8; y = conf.thrMid8; if (tmp>0) y = 100-y; lookupThrottleRC[i] = 100*conf.thrMid8 + tmp*( (int32_t)conf.thrExpo8*(tmp*tmp)/((uint16_t)y*y)+100-conf.thrExpo8 ); // [0;10000] lookupThrottleRC[i] = conf.minthrottle + (uint32_t)((uint16_t)(MAXTHROTTLE-conf.minthrottle))* lookupThrottleRC[i]/10000; // [0;10000] -> [conf.minthrottle;MAXTHROTTLE] } #if defined(POWERMETER) pAlarm = (uint32_t) conf.powerTrigger1 * (uint32_t) PLEVELSCALE * (uint32_t) PLEVELDIV; // need to cast before multiplying #endif #if GPS GPS_set_pids(); // at this time we don't have info about GPS init done recallGPSconf(); // Load gps parameters #endif #if defined(ARMEDTIMEWARNING) ArmedTimeWarningMicroSeconds = (conf.armedtimewarning *1000000); #endif return true; // setting is OK } void writeGlobalSet(uint8_t b) { global_conf.checksum = calculate_sum((uint8_t*)&global_conf, sizeof(global_conf)); eeprom_write_block((const void*)&global_conf, (void*)0, sizeof(global_conf)); if (b == 1) blinkLED(15,20,1); SET_ALARM_BUZZER(ALRM_FAC_CONFIRM, ALRM_LVL_CONFIRM_1); } void writeParams(uint8_t b) { #ifdef MULTIPLE_CONFIGURATION_PROFILES if(global_conf.currentSet>2) global_conf.currentSet=0; #else global_conf.currentSet=0; #endif conf.checksum = calculate_sum((uint8_t*)&conf, sizeof(conf)); eeprom_write_block((const void*)&conf, (void*)(global_conf.currentSet * sizeof(conf) + sizeof(global_conf)), sizeof(conf)); #if GPS writeGPSconf(); //Write GPS parameters recallGPSconf(); //Read it to ensure correct eeprom content #endif readEEPROM(); if (b == 1) blinkLED(15,20,1); SET_ALARM_BUZZER(ALRM_FAC_CONFIRM, ALRM_LVL_CONFIRM_1); } void update_constants() { #if defined(GYRO_SMOOTHING) { uint8_t s[3] = GYRO_SMOOTHING; for(uint8_t i=0;i<3;i++) conf.Smoothing[i] = s[i]; } #endif #if defined (FAILSAFE) conf.failsafe_throttle = FAILSAFE_THROTTLE; #endif #ifdef VBAT conf.vbatscale = VBATSCALE; conf.vbatlevel_warn1 = VBATLEVEL_WARN1; conf.vbatlevel_warn2 = VBATLEVEL_WARN2; conf.vbatlevel_crit = VBATLEVEL_CRIT; #endif #ifdef POWERMETER conf.pint2ma = PINT2mA; #endif #ifdef POWERMETER_HARD conf.psensornull = PSENSORNULL; #endif #ifdef MMGYRO conf.mmgyro = MMGYRO; #endif #if defined(ARMEDTIMEWARNING) conf.armedtimewarning = ARMEDTIMEWARNING; #endif conf.minthrottle = MINTHROTTLE; #if MAG conf.mag_declination = (int16_t)(MAG_DECLINATION * 10); #endif #ifdef GOVERNOR_P conf.governorP = GOVERNOR_P; conf.governorD = GOVERNOR_D; #endif #ifdef YAW_COLL_PRECOMP conf.yawCollPrecomp = YAW_COLL_PRECOMP; conf.yawCollPrecompDeadband = YAW_COLL_PRECOMP_DEADBAND; #endif #if defined(MY_PRIVATE_DEFAULTS) #include MY_PRIVATE_DEFAULTS #endif #if GPS loadGPSdefaults(); #endif writeParams(0); // this will also (p)reset checkNewConf with the current version number again. } void LoadDefaults() { uint8_t i; #ifdef SUPPRESS_DEFAULTS_FROM_GUI // do nothing #elif defined(MY_PRIVATE_DEFAULTS) // #include MY_PRIVATE_DEFAULTS // do that at the last possible moment, so we can override virtually all defaults and constants #else #if PID_CONTROLLER == 1 conf.pid[ROLL].P8 = 33; conf.pid[ROLL].I8 = 30; conf.pid[ROLL].D8 = 23; conf.pid[PITCH].P8 = 33; conf.pid[PITCH].I8 = 30; conf.pid[PITCH].D8 = 23; conf.pid[PIDLEVEL].P8 = 90; conf.pid[PIDLEVEL].I8 = 10; conf.pid[PIDLEVEL].D8 = 100; #elif PID_CONTROLLER == 2 conf.pid[ROLL].P8 = 28; conf.pid[ROLL].I8 = 10; conf.pid[ROLL].D8 = 7; conf.pid[PITCH].P8 = 28; conf.pid[PITCH].I8 = 10; conf.pid[PITCH].D8 = 7; conf.pid[PIDLEVEL].P8 = 30; conf.pid[PIDLEVEL].I8 = 32; conf.pid[PIDLEVEL].D8 = 0; #endif conf.pid[YAW].P8 = 68; conf.pid[YAW].I8 = 45; conf.pid[YAW].D8 = 0; conf.pid[PIDALT].P8 = 64; conf.pid[PIDALT].I8 = 25; conf.pid[PIDALT].D8 = 24; conf.pid[PIDPOS].P8 = POSHOLD_P * 100; conf.pid[PIDPOS].I8 = POSHOLD_I * 100; conf.pid[PIDPOS].D8 = 0; conf.pid[PIDPOSR].P8 = POSHOLD_RATE_P * 10; conf.pid[PIDPOSR].I8 = POSHOLD_RATE_I * 100; conf.pid[PIDPOSR].D8 = POSHOLD_RATE_D * 1000; conf.pid[PIDNAVR].P8 = NAV_P * 10; conf.pid[PIDNAVR].I8 = NAV_I * 100; conf.pid[PIDNAVR].D8 = NAV_D * 1000; conf.pid[PIDMAG].P8 = 40; conf.pid[PIDVEL].P8 = 0; conf.pid[PIDVEL].I8 = 0; conf.pid[PIDVEL].D8 = 0; conf.rcRate8 = 90; conf.rcExpo8 = 65; conf.rollPitchRate = 0; conf.yawRate = 0; conf.dynThrPID = 0; conf.thrMid8 = 50; conf.thrExpo8 = 0; for(i=0;i254) return; mission_step.checksum = calculate_sum((uint8_t*)&mission_step, sizeof(mission_step)); eeprom_write_block((void*)&mission_step, (void*)(PROFILES * sizeof(conf) + sizeof(global_conf) + sizeof(GPS_conf) +(sizeof(mission_step)*mission_step.number)),sizeof(mission_step)); } // Read the given number of WP from the eeprom, supposedly we can use this during flight. // Returns true when reading is successfull and returns false if there were some error (for example checksum) bool recallWP(uint8_t wp_number) { if (wp_number > 254) return false; eeprom_read_block((void*)&mission_step, (void*)(PROFILES * sizeof(conf) + sizeof(global_conf)+sizeof(GPS_conf)+(sizeof(mission_step)*wp_number)), sizeof(mission_step)); if(calculate_sum((uint8_t*)&mission_step, sizeof(mission_step)) != mission_step.checksum) return false; return true; } // Returns the maximum WP number that can be stored in the EEPROM, calculated from conf and plog sizes, and the eeprom size uint8_t getMaxWPNumber() { uint16_t first_avail = PROFILES*sizeof(conf) + sizeof(global_conf)+sizeof(GPS_conf)+ 1; //Add one byte for addtnl separation uint16_t last_avail = E2END - PLOG_SIZE - 4; //keep the last 4 bytes intakt uint16_t wp_num = (last_avail-first_avail)/sizeof(mission_step); if (wp_num>254) wp_num = 254; return wp_num; } #endif