#ifndef __PARAMETERS_H__ #define __PARAMETERS_H__ #include #include #if defined(WITH_STM32) || defined(WITH_ESP32) #include "hal.h" #endif #include "ogn.h" #ifdef WITH_ESP32 #include "nvs.h" #endif #ifdef WITH_SAMD21 #include "flashsize.h" #endif #ifdef WITH_STM32 #include "stm32f10x_flash.h" #include "flashsize.h" #endif #include "nmea.h" #include "format.h" // Parameters stored in Flash class FlashParameters { public: union { uint32_t AcftID; // identification: Private:AcftType:AddrType:Address - must be different for every tracker struct { uint32_t Address:24; // address (ID) uint8_t AddrType:2; // 0=RND, 1=ICAO, 2=FLR, 3=OGN uint8_t AcftType:4; // 1=glider, 2=towplane, 3=helicopter, etc. bool NoTrack:1; // unused bool Stealth:1; // unused } ; } ; int16_t RFchipFreqCorr; // [0.1ppm] frequency correction for crystal frequency offset int8_t RFchipTxPower; // [dBm] highest bit set => HW module (up to +20dBm Tx power) int8_t RFchipTempCorr; // [degC] correction to the temperature measured in the RF chip union { uint32_t Console; struct { uint32_t CONbaud:24; // [bps] Console baud rate uint8_t CONprot: 8; // [bit-mask] Console protocol mask: 0=minGPS, 1=allGPS, 2=Baro, 3=UBX, 4=OGN, 5=FLARM, 6=GDL90, 7=$PGAV5 } ; } ; int16_t PressCorr; // [0.25Pa] pressure correction for the baro union { uint16_t Flags; struct { bool SaveToFlash:1; // Save parameters from the config file to Flash bool hasBT:1; // has BT interface on the console bool BT_ON:1; // BT on after power up bool manGeoidSepar:1; // GeoidSepar is manually configured as the GPS or MAVlink are not able to deliver it bool Encrypt:1; // encrypt the position uint8_t NavMode:3; // GPS navigation mode/model uint8_t NavRate:2; // [Hz] uint8_t Verbose:2; // int8_t TimeCorr:4; // [sec] it appears for ArduPilot you need to correct time by 3 seconds } ; } ; // int16_t GeoidSepar; // [0.1m] Geoid-Separation, apparently ArduPilot MAVlink does not give this value (although present in the format) // or it could be a problem of some GPSes uint8_t PPSdelay; // [ms] delay between the PPS and the data burst starts on the GPS UART (used when PPS failed or is not there) uint8_t FreqPlan; // force given frequency hopping plan static const uint8_t InfoParmLen = 16; // [char] max. size of an infp-parameter static const uint8_t InfoParmNum = 14; // [int] number of info-parameters char *InfoParmValue(uint8_t Idx) { return Idx>16)); Format_Hex(Call+5, (uint16_t)Address); Call[9]=0; return 9; } public: void setDefault(void) { setDefault(getUniqueAddress()); } void setDefault(uint32_t UniqueAddr) { AcftID = ((uint32_t)DEFAULT_AcftType<<26) | 0x03000000 | (UniqueAddr&0x00FFFFFF); RFchipFreqCorr = 0; // [0.1ppm] #ifdef WITH_RFM69W RFchipTxPower = 13; // [dBm] for RFM69W #else RFchipTxPower = 0x80 | 14; // [dBm] for RFM69HW #endif Flags = 0; #ifdef WITH_GPS_UBX NavMode = 6; // Avionic mode 1g for UBX #endif #ifdef WITH_GPS_MTK NavMode = 2; // Avionic mode for MTK #endif NavRate = 1; // [Hz] Verbose = 1; RFchipTempCorr = 0; // [degC] CONbaud = DEFAULT_CONbaud; // [bps] CONprot = 0xFF; PressCorr = 0; // [0.25Pa] TimeCorr = 0; // [sec] GeoidSepar = 10*DEFAULT_GeoidSepar; // [0.1m] FreqPlan = DEFAULT_FreqPlan; // [0..5] PPSdelay = DEFAULT_PPSdelay; // [ms] #ifdef WITH_ENCRYPT for(uint8_t Idx=0; Idx<4; Idx++) EncryptKey[Idx]=0; #endif for(uint8_t Idx=0; IdxADDR.reg = ((uint32_t)Addr)>>1; NVMCTRL->CTRLA.reg = NVMCTRL_CTRLA_CMDEX_KEY | NVMCTRL_CTRLA_CMD_ER; while (!NVMCTRL->INTFLAG.bit.READY) { } } void EraseSize(volatile uint32_t *Addr, uint32_t Size=1024) const // erase multiple pages for given size { for( ; ; ) { if(Size==0) break; ErasePage4x64(Addr); // if(Size<256) break; Addr+=64; Size-=256; } } int WritePage64(volatile uint32_t *Addr, const uint32_t *Data, uint32_t Words) const { // NVMCTRL->ADDR.reg = ((uint32_t)Addr)>>1; NVMCTRL->CTRLB.bit.MANW = 1; // disable Automatic Page Write NVMCTRL->CTRLA.reg = NVMCTRL_CTRLA_CMDEX_KEY | NVMCTRL_CTRLA_CMD_PBC; // execute Page Buffer Clear while (NVMCTRL->INTFLAG.bit.READY == 0) { } uint32_t Idx=0; for(Idx=0; (Idx<16) && (IdxCTRLA.reg = NVMCTRL_CTRLA_CMDEX_KEY | NVMCTRL_CTRLA_CMD_WP; // execute Write Page while (NVMCTRL->INTFLAG.bit.READY == 0) { } return Idx; } int WriteSize(volatile uint32_t *Addr, const uint32_t *Data, uint32_t Words) { for( ; ; ) { int Len = WritePage64(Addr, Data, Words); Addr+=Len; Data+=Len; Words-=Len; if(Words==0) break; } return 0; } int8_t WriteToFlash(volatile uint32_t *Addr=0) // write parameters to Flash { if(Addr==0) Addr = DefaultFlashAddr(); setCheckSum(); const uint32_t Words=sizeof(FlashParameters)/sizeof(uint32_t); EraseSize(Addr, Words); WriteSize(Addr, (const uint32_t *)this, Words); if(calcCheckSum(Addr, Words)!=0) return -1; // verify check-sum in Flash return 0; } #endif // WITH_SAMD21 #ifdef WITH_STM32 /* uint32_t static CheckSum(const uint32_t *Word, uint32_t Words) // calculate check-sum of pointed data { uint32_t Check=CheckInit; for(uint32_t Idx=0; Idx='0') && (ch<='9') ) return 1; // numbers if( (ch>='A') && (ch<='Z') ) return 1; // uppercase letters if( (ch>='a') && (ch<='z') ) return 1; // lowercase letters if(strchr(".@-+_/#", ch)) return 1; // any of the listed special characters return 0; } static int8_t Read_String(char *Value, const char *Inp, uint8_t MaxLen) { const char *Val = SkipBlanks(Inp); uint8_t Idx; for(Idx=0; Idx' ') break; Inp++; } return Inp; } bool ReadParam(const char *Name, const char *Value) // interprete "Name = Value" line { if(strcmp(Name, "Address")==0) { uint32_t Addr=0; if(Read_Int(Addr, Value)<=0) return 0; Address=Addr; return 1; } if(strcmp(Name, "AddrType")==0) { uint32_t Type=0; if(Read_Int(Type, Value)<=0) return 0; AddrType=Type; return 1; } if(strcmp(Name, "AcftType")==0) { uint32_t Type=0; if(Read_Int(Type, Value)<=0) return 0; AcftType=Type; return 1; } if(strcmp(Name, "CONbaud")==0) { uint32_t Baud=0; if(Read_Int(Baud, Value)<=0) return 0; CONbaud=Baud; return 1; } if(strcmp(Name, "CONprot")==0) { uint32_t Prot=0; if(Read_Int(Prot, Value)<=0) return 0; CONprot=Prot; return 1; } if(strcmp(Name, "TxHW")==0) { int32_t HW=1; if(Read_Int(HW, Value)<=0) return 0; if(HW) setTxTypeHW(); else clrTxTypeHW(); } if(strcmp(Name, "TxPower")==0) { int32_t TxPower=0; if(Read_Int(TxPower, Value)<=0) return 0; setTxPower(TxPower); return 1; } if(strcmp(Name, "PPSdelay")==0) { uint32_t Delay=0; if(Read_Int(Delay, Value)<=0) return 0; if(Delay>0xFF) Delay=0xFF; PPSdelay=Delay; return 1; } if(strcmp(Name, "FreqPlan")==0) { uint32_t Plan=0; if(Read_Int(Plan, Value)<=0) return 0; if(Plan>5) Plan=5; FreqPlan=Plan; return 1; } if(strcmp(Name, "FreqCorr")==0) { int32_t Corr=0; if(Read_Float1(Corr, Value)<=0) return 0; RFchipFreqCorr=Corr; return 1; } if(strcmp(Name, "PressCorr")==0) { int32_t Corr=0; if(Read_Float1(Corr, Value)<=0) return 0; PressCorr=4*Corr/10; return 1; } if(strcmp(Name, "TimeCorr")==0) { int32_t Corr=0; if(Read_Int(Corr, Value)<=0) return 0; TimeCorr=Corr; return 1; } if(strcmp(Name, "GeoidSepar")==0) { return Read_Float1(GeoidSepar, Value)<=0; } if(strcmp(Name, "manGeoidSepar")==0) { int32_t Man=0; if(Read_Int(Man, Value)<=0) return 0; manGeoidSepar=Man; return 1; } if(strcmp(Name, "NavMode")==0) { int32_t Mode=0; if(Read_Int(Mode, Value)<=0) return 0; NavMode=Mode; return 1; } if(strcmp(Name, "NavRate")==0) { int32_t Mode=0; if(Read_Int(Mode, Value)<=0) return 0; if(Mode<1) Mode=1; NavRate=Mode; return 1; } if(strcmp(Name, "PageMask")==0) { int32_t Mode=0; if(Read_Int(Mode, Value)<=0) return 0; PageMask=Mode; return 1; } if(strcmp(Name, "Verbose")==0) { int32_t Mode=0; if(Read_Int(Mode, Value)<=0) return 0; Verbose=Mode; return 1; } #ifdef WITH_ENCRYPT if(strcmp(Name, "Encrypt")==0) { int32_t Encr=0; if(Read_Int(Encr, Value)<=0) return 0; Encrypt=Encr; return 1; } if(strcmp(Name, "EncryptKey")==0) { for( uint8_t Idx=0; Idx<4; Idx++) { uint32_t Key; uint8_t Len=Read_Hex(Key, Value); if(Len!=8) break; EncryptKey[Idx]=Key; Value+=Len; if((*Value)!=':') break; Value++; } return 1; } #endif #ifdef WITH_BT_PWR if(strcmp(Name, "Bluetooth")==0) { int32_t bton=0; if(Read_Int(bton, Value)<=0) return 0; // if (bton==2) //WAR: disable usart1 in order to be able to configure BT over 2nd USB // { USART1_Disable(); // bton=1; } BT_ON=bton; return 1; } #endif for(uint8_t Idx=0; Idx=0) && (Idx=0) && (Idx