diff --git a/main/axp192.h b/main/axp192.h index 43b5d8d..00140e5 100644 --- a/main/axp192.h +++ b/main/axp192.h @@ -11,7 +11,7 @@ class AXP192 static const uint8_t REG_STATUS = 0x00; // bit #2 = charge/discharge, bit #0 = power-on triggered by Vbus/ACin static const uint8_t REG_MODE_CHGSTATUS = 0x01; // charge mode and status static const uint8_t REG_ID = 0x03; - static const uint8_t REG_DATA_SAVE = 0x06; // 4 bytes which can be saved as long as the battery ot backup is applied + static const uint8_t REG_DATA_SAVE = 0x06; // 4 bytes which can be saved as long as the battery or backup is applied static const uint8_t REG_EXTEN_DC2_CTL = 0x10; // [bit mask] control outputs ON/OFF static const uint8_t REG_LDO23_DC13_CTL = 0x12; // [bit mask] control outputs ON/OFF static const uint8_t REG_DC2_VOLTAGE = 0x23; @@ -94,12 +94,17 @@ class AXP192 if( (!Error) && (ID==AXP192_ID) ) { ADDR=AXP192_ADDR; return 0; } // 0 => no error and correct ID return 1; } // 1 => error or incorrect chip ID - uint8_t readStatus(void) + uint8_t readStatus(void) // read power supply status: bit #0 = boot triggered by power input { uint8_t Byte=0; Error=I2C_Read(Bus, ADDR, REG_STATUS, Byte); return Byte; } + uint8_t readSave(uint8_t Idx=0) // read one of the 4 general purpose storage bytes + { uint8_t Byte=0; Error=I2C_Read(Bus, ADDR, REG_DATA_SAVE+Idx, Byte); return Byte; } + + uint8_t writeSave(uint8_t Byte, uint8_t Idx=0) // write the general-purpose storage byte + { Error=I2C_Write(Bus, ADDR, REG_DATA_SAVE+Idx, Byte); return Error; } + uint8_t setPOK(uint8_t Byte=0xDC) - { Error=I2C_Write(Bus, ADDR, REG_POK_SET, Byte); - return Error; } + { Error=I2C_Write(Bus, ADDR, REG_POK_SET, Byte); return Error; } uint8_t setPowerOutput(uint8_t Channel, bool ON=1) // Channel: 3=LDO3, 2=LDO2, 1=DC-DC3, 0=DC-DC1 { uint8_t Byte; @@ -110,7 +115,7 @@ class AXP192 Error=I2C_Write(Bus, ADDR, REG_LDO23_DC13_CTL, Byte); return Error; } - uint8_t setDCDC1(uint16_t mV) // [mV] set voltage on DCDC1 output + uint8_t setDCDC1(uint16_t mV) // [mV] set voltage on DCDC1 output { if(mV>3500) mV=3500; else if(mV<700) mV=700; uint8_t Byte = (mV-700+12)/25; diff --git a/main/format.h b/main/format.h index f0c3ad1..dbddd79 100644 --- a/main/format.h +++ b/main/format.h @@ -3,7 +3,7 @@ #include -#define WITH_AUTOCR +// #define WITH_AUTOCR char HexDigit(uint8_t Val); diff --git a/main/gps.cpp b/main/gps.cpp index efb21f7..b50eb69 100644 --- a/main/gps.cpp +++ b/main/gps.cpp @@ -720,13 +720,13 @@ static void GPS_NMEA(void) // wh { if(Parameters.Verbose) { xSemaphoreTake(CONS_Mutex, portMAX_DELAY); Format_String(CONS_UART_Write, (const char *)NMEA.Data, 0, NMEA.Len); - Format_String(CONS_UART_Write, "\n"); + CONS_UART_Write('\r'); CONS_UART_Write('\n'); xSemaphoreGive(CONS_Mutex); } #ifdef WITH_SDLOG if(Log_Free()>=128) { xSemaphoreTake(Log_Mutex, portMAX_DELAY); Format_String(Log_Write, (const char *)NMEA.Data, 0, NMEA.Len); - Log_Write('\n'); + Log_Write('\r'); Log_Write('\n'); xSemaphoreGive(Log_Mutex); } #endif } diff --git a/main/http.cpp b/main/http.cpp index 7706f74..ffcd370 100644 --- a/main/http.cpp +++ b/main/http.cpp @@ -1193,6 +1193,7 @@ static esp_err_t SendLog_IGC(httpd_req_t *Req, const char *FileName, uint32_t Fi Len+=Format_String(Line+Len, "LGNE "); // attach APRS as LGNE record char *APRS=Line+Len; Len+=Packet.Packet.WriteAPRS(Line+Len, Time); // packet in the APRS format + Line[Len++]='\n'; Line[Len]=0; bool Own = Packet.Packet.Header.Address==Parameters.Address && Packet.Packet.Header.AddrType==Parameters.AddrType; // if(Own && !Packet.Packet.Header.NonPos && !Packet.Packet.Header.Encrypted) Len+=APRS2IGC(Line+Len, APRS, GPS_GeoidSepar); // IGC B-record @@ -1231,6 +1232,7 @@ static esp_err_t SendLog_APRS(httpd_req_t *Req, const char *FileName, uint32_t F if(!Packet.isCorrect()) continue; uint32_t Time = Packet.getTime(FileTime); // [sec] get exact time from short time in the packet and the file start time Len+=Packet.Packet.WriteAPRS(Line+Len, Time); // print the packet in the APRS format + Line[Len++]='\n'; Line[Len]=0; if(Len>850) { httpd_resp_send_chunk(Req, Line, Len); Len=0; } vTaskDelay(1); } fclose(File); diff --git a/main/lookout.h b/main/lookout.h index 6347d64..3fbe607 100644 --- a/main/lookout.h +++ b/main/lookout.h @@ -263,9 +263,9 @@ template NMEA[Len++]=','; if(Tgt) // [m] relative horizontal distance { Len+=Format_UnsDec(NMEA+Len, (uint32_t)Tgt->HorDist>>1, 1); } - NMEA[Len++]=','; if(Tgt) // ID - { uint32_t Addr=Tgt->ID; + { NMEA[Len++]=','; // + uint32_t Addr=Tgt->ID; Len+=Format_Hex(NMEA+Len, (uint8_t)(Addr>>16)); // 24-bit address: RND, ICAO, FLARM, OGN Len+=Format_Hex(NMEA+Len, (uint16_t)Addr); } // #ifdef WITH_SKYDEMON diff --git a/main/main.cpp b/main/main.cpp index 7256569..170ab6d 100644 --- a/main/main.cpp +++ b/main/main.cpp @@ -190,7 +190,7 @@ void app_main(void) #ifdef WITH_SOUND xTaskCreate(vTaskSOUND, "SOUND", 2000, 0, tskIDLE_PRIORITY+3, 0); #endif - xTaskCreate(vTaskTICK , "TICK", 1000, 0, tskIDLE_PRIORITY+3, 0); + xTaskCreate(vTaskTICK , "TICK", 1500, 0, tskIDLE_PRIORITY+3, 0); // xTaskCreate(vTaskCTRL, "CTRL", 1536, 0, tskIDLE_PRIORITY+2, 0); vTaskCTRL(0); // run directly the CTRL task, instead of creating a separate one. diff --git a/main/nmea.cpp b/main/nmea.cpp index 52f0910..4614f50 100644 --- a/main/nmea.cpp +++ b/main/nmea.cpp @@ -14,6 +14,6 @@ uint8_t NMEA_AppendCheck(uint8_t *NMEA, uint8_t Len) return 3; } // return number of characters added uint8_t NMEA_AppendCheckCRNL(uint8_t *NMEA, uint8_t Len) -{ uint8_t CheckLen=NMEA_AppendCheck(NMEA, Len); // add *XY +{ uint8_t CheckLen=NMEA_AppendCheck(NMEA, Len); // add *XY, return number of added characters (=3) Len+=CheckLen; NMEA[Len++]='\r'; NMEA[Len++]='\n'; NMEA[Len]=0; // add CR, LF, NL - return CheckLen+2; } + return CheckLen+2; } // return number of added characters (3+2=5) diff --git a/main/nmea.h b/main/nmea.h index 40adf12..d7b7b77 100644 --- a/main/nmea.h +++ b/main/nmea.h @@ -4,10 +4,10 @@ #include uint8_t NMEA_Check(uint8_t *NMEA, uint8_t Len); -uint8_t NMEA_AppendCheck(uint8_t *NMEA, uint8_t Len); -inline uint8_t NMEA_AppendCheck(char *NMEA, uint8_t Len) { return NMEA_AppendCheck((uint8_t*)NMEA, Len); } -uint8_t NMEA_AppendCheckCRNL(uint8_t *NMEA, uint8_t Len); -inline uint8_t NMEA_AppendCheckCRNL(char *NMEA, uint8_t Len) { return NMEA_AppendCheckCRNL((uint8_t*)NMEA, Len); } + uint8_t NMEA_AppendCheck(uint8_t *NMEA, uint8_t Len); +inline uint8_t NMEA_AppendCheck(char *NMEA, uint8_t Len) { return NMEA_AppendCheck((uint8_t *)NMEA, Len); } + uint8_t NMEA_AppendCheckCRNL(uint8_t *NMEA, uint8_t Len); +inline uint8_t NMEA_AppendCheckCRNL(char *NMEA, uint8_t Len) { return NMEA_AppendCheckCRNL((uint8_t *)NMEA, Len); } class NMEA_RxMsg // receiver for the NMEA sentences { public: @@ -256,6 +256,16 @@ inline uint8_t NMEA_AppendCheckCRNL(char *NMEA, uint8_t Len) { return NMEA_Appen { if(!isPOGN()) return 0; return Data[5]=='L'; } + uint8_t isPFLA(void) const // FLARM dedicated NMEA sentence + { if(Data[1]!='P') return 0; + if(Data[2]!='F') return 0; + if(Data[3]!='L') return 0; + return Data[4]=='A'; } + + uint8_t isPFLAC(void) // FLARM configuration NMEA + { if(!isPFLA()) return 0; + return Data[5]=='C'; } + } ; #endif // of __NMEA_H__ diff --git a/main/ogn1.h b/main/ogn1.h index a180083..34418a3 100644 --- a/main/ogn1.h +++ b/main/ogn1.h @@ -211,7 +211,7 @@ class OGN1_Packet // Packet structure for the OGN tracker // Out[Len++]=HexDigit(Position.AcftType); Out[Len++]=':'; // Len+=Format_SignDec(Out+Len, -(int16_t)RxRSSI/2); Out[Len++]='d'; Out[Len++]='B'; Out[Len++]='m'; // Out[Len++]=' '; - Len+=Format_UnsDec(Out+Len, (uint16_t)Position.Time, 2); + Len+=Format_UnsDec(Out+Len, (uint32_t)Position.Time, 2); Len+=Format_String(Out+Len, "s ["); Len+=Format_SignDec(Out+Len, DecodeLatitude()/6, 7, 5); Out[Len++]=','; @@ -223,9 +223,9 @@ class OGN1_Packet // Packet structure for the OGN tracker // Out[Len++]=' '; Len+=Format_UnsDec(Out+Len, (uint32_t)DecodeAltitude()); Out[Len++]='m'; Out[Len++]=' '; - Len+=Format_UnsDec(Out+Len, DecodeSpeed(), 2, 1); Out[Len++]='m'; Out[Len++]='/'; Out[Len++]='s'; + Len+=Format_UnsDec(Out+Len, (uint32_t)DecodeSpeed(), 2, 1); Out[Len++]='m'; Out[Len++]='/'; Out[Len++]='s'; Out[Len++]=' '; - Len+=Format_SignDec(Out+Len, DecodeClimbRate(), 2, 1); Out[Len++]='m'; Out[Len++]='/'; Out[Len++]='s'; + Len+=Format_SignDec(Out+Len, (int32_t)DecodeClimbRate(), 2, 1); Out[Len++]='m'; Out[Len++]='/'; Out[Len++]='s'; Out[Len]=0; return Len; } @@ -233,20 +233,20 @@ class OGN1_Packet // Packet structure for the OGN tracker { int Len=0; Out[Len++]=' '; Out[Len++]='h'; Len+=Format_Hex(Out+Len, (uint8_t)Status.Hardware); Out[Len++]=' '; Out[Len++]='v'; Len+=Format_Hex(Out+Len, (uint8_t)Status.Firmware); - Out[Len++]=' '; Len+=Format_UnsDec(Out+Len, Status.Satellites); Out[Len++]='s'; Out[Len++]='a'; Out[Len++]='t'; + Out[Len++]=' '; Len+=Format_UnsDec(Out+Len, (uint32_t)Status.Satellites); Out[Len++]='s'; Out[Len++]='a'; Out[Len++]='t'; Out[Len++]='/'; Out[Len++]='0'+Status.FixQuality; - Out[Len++]='/'; Len+=Format_UnsDec(Out+Len, Status.SatSNR+8); Out[Len++]='d'; Out[Len++]='B'; - Out[Len++]=' '; Len+=Format_SignDec(Out+Len, DecodeAltitude(), 1, 0, 1); Out[Len++]='m'; + Out[Len++]='/'; Len+=Format_UnsDec(Out+Len, (uint32_t)Status.SatSNR+8); Out[Len++]='d'; Out[Len++]='B'; + Out[Len++]=' '; Len+=Format_SignDec(Out+Len, (int32_t)DecodeAltitude(), 1, 0, 1); Out[Len++]='m'; if(Status.Pressure>0) { Out[Len++]=' '; Len+=Format_UnsDec(Out+Len, (((uint32_t)Status.Pressure<<3)+5)/10, 2, 1); Out[Len++]='h'; Out[Len++]='P'; Out[Len++]='a'; } if(hasTemperature()) - { Out[Len++]=' '; Len+=Format_SignDec(Out+Len, DecodeTemperature(), 2, 1); Out[Len++]='d'; Out[Len++]='e'; Out[Len++]='g'; Out[Len++]='C'; } + { Out[Len++]=' '; Len+=Format_SignDec(Out+Len, (int32_t)DecodeTemperature(), 2, 1); Out[Len++]='d'; Out[Len++]='e'; Out[Len++]='g'; Out[Len++]='C'; } if(hasHumidity()) - { Out[Len++]=' '; Len+=Format_SignDec(Out+Len, DecodeHumidity(), 2, 1); Out[Len++]='%'; } - Out[Len++]=' '; Len+=Format_SignDec(Out+Len, ((uint32_t)DecodeVoltage()*100+32)>>6, 3, 2); Out[Len++]='V'; - Out[Len++]=' '; Len+=Format_UnsDec(Out+Len, Status.TxPower+4); - Out[Len++]='/'; Out[Len++]='-'; Len+=Format_UnsDec(Out+Len, 5*Status.RadioNoise, 2, 1); Out[Len++]='d'; Out[Len++]='B'; Out[Len++]='m'; - Out[Len++]=' '; Len+=Format_UnsDec(Out+Len, (1<>6, 3, 2); Out[Len++]='V'; + Out[Len++]=' '; Len+=Format_UnsDec(Out+Len, (uint32_t)Status.TxPower+4); + Out[Len++]='/'; Out[Len++]='-'; Len+=Format_UnsDec(Out+Len, (uint32_t)Status.RadioNoise*5, 2, 1); Out[Len++]='d'; Out[Len++]='B'; Out[Len++]='m'; + Out[Len++]=' '; Len+=Format_UnsDec(Out+Len, ((uint32_t)1<>6, 3, 2); + if(hasTemperature()) + { Len+=Format_String(JSON+Len, ",\"temperature_deg\":"); + Len+=Format_SignDec(JSON+Len, (int32_t)DecodeTemperature(), 2, 1, 1); } + if(Status.Pressure>0) + { Len+=Format_String(JSON+Len, ",\"pressure_hPa\":"); + Len+=Format_UnsDec(JSON+Len, ((uint32_t)Status.Pressure<<3), 3, 2); } + if(Status.FixQuality) + { int32_t Altitude=DecodeAltitude(); + Len+=Format_String(JSON+Len, ",\"alt_msl_m\":"); + Len+=Format_UnsDec(JSON+Len, (uint32_t)Altitude); } + Len+=Format_String(JSON+Len, ",\"GPS_fix\":"); + JSON[Len++] = '0'+Status.FixQuality; + Len+=Format_String(JSON+Len, ",\"GPS_sats\":"); + Len+=Format_UnsDec(JSON+Len, (uint32_t)Status.Satellites); + Len+=Format_String(JSON+Len, ",\"GPS_SNR_dB\":"); + Len+=Format_UnsDec(JSON+Len, (uint32_t)Status.SatSNR+8); + Len+=Format_String(JSON+Len, ",\"Tx_power_dBm\":"); + Len+=Format_UnsDec(JSON+Len, (uint32_t)Status.TxPower+4); + Len+=Format_String(JSON+Len, ",\"Rx_rate_min\":"); + Len+=Format_UnsDec(JSON+Len, ((uint32_t)1<>10, 3); - Msg[Len++] = '/'; Msg[Len++] = 'A'; Msg[Len++] = '='; Len+=Format_UnsDec(Msg+Len, MetersToFeet(DecodeAltitude()), 6); + Msg[Len++] = '/'; Msg[Len++] = 'A'; Msg[Len++] = '='; Len+=Format_UnsDec(Msg+Len, (uint32_t)MetersToFeet(DecodeAltitude()), 6); Msg[Len++] = ' '; Msg[Len++] = '!'; @@ -681,19 +708,19 @@ class OGN1_Packet // Packet structure for the OGN tracker { Msg[Len++] = ' '; Len+=Format_SignDec(Msg+Len, ((int32_t)DecodeClimbRate()*10079+256)>>9, 3); Msg[Len++] = 'f'; Msg[Len++] = 'p'; Msg[Len++] = 'm'; } if(hasTurnRate()) - { Msg[Len++] = ' '; Len+=Format_SignDec(Msg+Len, DecodeTurnRate()/3, 2, 1); Msg[Len++] = 'r'; Msg[Len++] = 'o'; Msg[Len++] = 't'; } + { Msg[Len++] = ' '; Len+=Format_SignDec(Msg+Len, (int32_t)DecodeTurnRate()/3, 2, 1); Msg[Len++] = 'r'; Msg[Len++] = 'o'; Msg[Len++] = 't'; } if(hasBaro()) { int32_t Alt = DecodeStdAltitude(); if(Alt<0) Alt=0; Msg[Len++] = ' '; Msg[Len++] = 'F'; Msg[Len++] = 'L'; - Len+=Format_UnsDec(Msg+Len, MetersToFeet((uint32_t)Alt), 5, 2); } + Len+=Format_UnsDec(Msg+Len, (uint32_t)MetersToFeet((uint32_t)Alt), 5, 2); } uint16_t DOP=10+DecodeDOP(); uint16_t HorPrec=(DOP*2+5)/10; if(HorPrec>63) HorPrec=63; uint16_t VerPrec=(DOP*3+5)/10; if(VerPrec>63) VerPrec=63; Msg[Len++] = ' '; Msg[Len++] = 'g'; Msg[Len++] = 'p'; Msg[Len++] = 's'; - Len+=Format_UnsDec(Msg+Len, HorPrec); Msg[Len++] = 'x'; Len+=Format_UnsDec(Msg+Len, VerPrec); + Len+=Format_UnsDec(Msg+Len, (uint32_t)HorPrec); Msg[Len++] = 'x'; Len+=Format_UnsDec(Msg+Len, (uint32_t)VerPrec); // Msg[Len++]='\n'; Msg[Len]=0; @@ -703,9 +730,11 @@ class OGN1_Packet // Packet structure for the OGN tracker // calculate distance vector [LatDist, LonDist] from a given reference [RefLat, Reflon] int calcDistanceVector(int32_t &LatDist, int32_t &LonDist, int32_t RefLat, int32_t RefLon, uint16_t LatCos=3000, int32_t MaxDist=0x7FFF) - { LatDist = ((DecodeLatitude()-RefLat)*1517+0x1000)>>13; // convert from 1/600000deg to meters (40000000m = 360deg) => x 5/27 = 1517/(1<<13) + { LatDist = DecodeLatitude()-RefLat; if(abs(LatDist)>1080000) return -1; // to prevent overflow, corresponds to about 200km + LatDist = (LatDist*1517+0x1000)>>13; // convert from 1/600000deg to meters (40000000m = 360deg) => x 5/27 = 1517/(1<<13) if(abs(LatDist)>MaxDist) return -1; - LonDist = ((DecodeLongitude()-RefLon)*1517+0x1000)>>13; + LonDist = DecodeLongitude()-RefLon; if(abs(LatDist)>1080000) return -1; + LonDist = (LonDist*1517+0x1000)>>13; if(abs(LonDist)>(4*MaxDist)) return -1; LonDist = (LonDist*LatCos+0x800)>>12; if(abs(LonDist)>MaxDist) return -1; diff --git a/main/proc.cpp b/main/proc.cpp index 8c1438f..ddd1830 100644 --- a/main/proc.cpp +++ b/main/proc.cpp @@ -614,6 +614,7 @@ void vTaskPROC(void* pvParameters) PosPacket.Packet.Position.Stealth = Parameters.Stealth; #ifdef DEBUG_PRINT { uint8_t Len=PosPacket.Packet.WriteAPRS(Line, PosTime); // print on the console as APRS message + Line[Len++]='\n'; Line[Len]=0; xSemaphoreTake(CONS_Mutex, portMAX_DELAY); Format_String(CONS_UART_Write, Line, 0, Len); xSemaphoreGive(CONS_Mutex); } @@ -657,7 +658,8 @@ void vTaskPROC(void* pvParameters) ADSL_TxFIFO.Write(); #endif TxBackOff = 0; - if(AverSpeed<10 && Parameters.AcftType!=3 && Parameters.AcftType!=0xD) TxBackOff += 3+(RX_Random&0x1); + bool FloatAcft = Parameters.AcftType==3 || ( Parameters.AcftType>=0xB && Parameters.AcftType<=0xD); + if(AverSpeed<10 && !FloatAcft) TxBackOff += 3+(RX_Random&0x1); if(TX_Credit<=0) TxBackOff+=1; } Position->Sent=1; #ifdef WITH_FANET