Add IGC header with HF fields

pull/30/head
Pawel Jalocha 2020-09-26 23:54:32 +01:00
rodzic 906229814e
commit 8c7108fa56
5 zmienionych plików z 92 dodań i 25 usunięć

Wyświetl plik

@ -29,7 +29,7 @@ class FlightMonitor
// TakeoffCount=0;
}
static char NameCode(int Num) // coding of numbers in IGC file names
static char Code36(int Num) // coding of numbers in IGC file names
{ if(Num<=0) return '0';
if(Num<10) return '0'+Num;
if(Num<36) return 'A'+(Num-10);
@ -41,11 +41,11 @@ class FlightMonitor
static int ShortName(char *Name, const GPS_Position &Takeoff, uint8_t TakeoffNum, const char *Serial)
{ int Len=0;
Name[Len++]='0'+Takeoff.Year%10; // Year (last digit)
Name[Len++]=NameCode(Takeoff.Month); // encoded month
Name[Len++]=NameCode(Takeoff.Day); // encoded day
Name[Len++]=Code36(Takeoff.Month); // encoded month
Name[Len++]=Code36(Takeoff.Day); // encoded day
Name[Len++]='O'; // OGN
Len+=Format_String(Name+Len, Serial); // three-digit serial
Name[Len++]=NameCode(TakeoffNum); // flight of the day
Len+=Format_String(Name+Len, Serial); // three-letter serial
Name[Len++]=Code36(TakeoffNum); // flight of the day
Len+=Format_String(Name+Len, ".IGC"); // extension
Name[Len]=0;
// printf("ShortName[%d]: %s\n", Len, Name);

Wyświetl plik

@ -29,7 +29,8 @@ static const char *FlashLog_Ext = ".TLG"; // extension for log files, co
static const uint32_t FlashLog_MaxTime = 3600; // 1 hour max. per single log file
static const uint32_t FlashLog_MaxSize = 0x10000; // 64KB max. per single log file
#ifdef WITH_SPIFFS_FAT
static const uint32_t FlashLog_FlushSize = 4096; // 4kB file flush step
static const uint32_t FlashLog_SavePeriod = 30; // [sec] reopen the file every 30sec
static const uint32_t FlashLog_SaveSize = 4096; // [bytes] reopen the file every 4KB
#endif
bool FlashLog_SaveReq=0; // request to save the log right away, like after landing or before shutdown
@ -291,7 +292,7 @@ static int FlashLog_Open(uint32_t Time) // open a new
if(FlashLog_File==0) FlashLog_Clean(0, 4); // if the file cannot be open clean again
return FlashLog_File!=0; } // 1=success, 0=failure: new log file could not be open
static void FlashLog_Save(void)
static void FlashLog_Reopen(void)
{ if(FlashLog_File)
{ fclose(FlashLog_File);
FlashLog_File = fopen(FlashLog_FileName, "ab");
@ -317,7 +318,7 @@ static int FlashLog_Record(OGN_LogPacket<OGN_Packet> *Packet, int Packets, uint3
{ fclose(FlashLog_File); FlashLog_File=0; FlashLog_Clean(0, 4); return -1; } // if failure then close the log file and report error
#ifdef WITH_SPIFFS_FAT
uint32_t WritePos = ftell(FlashLog_File);
if(WritePos-FlashLog_FileFlush>FlashLog_FlushSize) FlashLog_Save();
if(WritePos-FlashLog_FileFlush>FlashLog_SaveSize) FlashLog_Reopen();
#endif
return Packets; } // report success
#endif // WITH_SPIFFS
@ -383,7 +384,7 @@ void vTaskLOG(void* pvParameters)
TickType_t PrevTick = 0;
for( ; ; )
{ // vTaskDelay(200); // wait idle 0.2sec
if(FlashLog_SaveReq) FlashLog_Save(); // if requested then save the current log (close + reopen)
if(FlashLog_SaveReq) FlashLog_Reopen(); // if requested then save the current log (close + reopen)
TickType_t Tick=xTaskGetTickCount(); // system tick count now
size_t Packets = FlashLog_FIFO.Full(); // how many packets in the queue ?
// #ifdef DEBUG_PRINT

Wyświetl plik

@ -139,10 +139,10 @@ class OGN1_Packet // Packet structure for the OGN tracker
// void recvBytes(const uint8_t *SrcPacket) { memcpy(Byte(), SrcPacket, Bytes); } // load data bytes e.g. from a demodulator
static const uint8_t InfoParmNum = 14; // [int] number of info-parameters and their names
static const uint8_t InfoParmNum = 15; // [int] number of info-parameters and their names
static const char *InfoParmName(uint8_t Idx) { static const char *Name[InfoParmNum] =
{ "Pilot", "Manuf", "Model", "Type", "SN", "Reg", "ID", "Class",
"Task" , "Base" , "ICE" , "PilotID", "Hard", "Soft" } ;
"Task" , "Base" , "ICE" , "PilotID", "Hard", "Soft", "Crew" } ;
return Idx<InfoParmNum ? Name[Idx]:0; }
#ifndef __AVR__

Wyświetl plik

@ -75,7 +75,7 @@ class FlashParameters
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
static const uint8_t InfoParmNum = 15; // [int] number of info-parameters
char *InfoParmValue(uint8_t Idx) { return Idx<InfoParmNum ? Pilot + Idx*InfoParmLen:0; }
uint8_t InfoParmValueLen(uint8_t Idx) { return strlen(InfoParmValue(Idx)); }
// const char *InfoParmName(uint8_t Idx) const { static const char *Name[InfoParmNum] =
@ -96,6 +96,7 @@ class FlashParameters
char PilotID[InfoParmLen]; // Pilot ID based on his BT or WiFi MAC
char Hard[InfoParmLen]; // Hardware
char Soft[InfoParmLen]; // Software
char Crew[InfoParmLen]; // Crew/2nd pilot name
// char Copilot[16]
// char Category[16]

Wyświetl plik

@ -18,7 +18,7 @@ static FILE *LogFile = 0;
static uint16_t LogDate = 0; // [~days] date = FatTime>>16
static TickType_t LogOpenTime; // [msec] when was the log file (re)open
static const TickType_t LogReopen = 30000; // [msec] when to close and re-open the log file
static const TickType_t LogReopen = 20000; // [msec] when to close and re-open the log file
const size_t FIFOsize = 16384;
static FIFO<char, FIFOsize> Log_FIFO; // 16K buffer for SD-log
@ -80,11 +80,22 @@ static int WriteLog(size_t MaxBlock=FIFOsize/2) // process th
const char *IGC_Path = "/sdcard/IGC";
const int IGC_PathLen = 11;
const uint32_t IGC_SavePeriod = 20;
// constexpr int IGC_PathLen = strlen(IGC_Path);
const char *IGC_Serial = "XXX";
char IGC_Serial[4] = { 0, 0, 0, 0 };
char IGC_FileName[32];
static FILE *IGC_File=0;
uint8_t IGC_FlightNum=0;
static uint32_t IGC_SaveTime=0;
uint16_t IGC_FlightNum=0;
static void IGC_TimeStamp(void)
{ struct stat FileStat;
struct utimbuf FileTime;
if(stat(IGC_FileName, &FileStat)>=0) // get file attributes (maybe not needed really ?
{ FileTime.actime = IGC_SaveTime; // set access and modification tim$
FileTime.modtime = IGC_SaveTime;
utime(IGC_FileName, &FileTime); } // write to the FAT
}
static void IGC_Close(void)
{ if(IGC_File) // if a file open, then close it and increment the flight number
@ -93,16 +104,19 @@ static void IGC_Close(void)
Format_String(CONS_UART_Write, IGC_FileName);
Format_String(CONS_UART_Write, "\n");
xSemaphoreGive(CONS_Mutex);
fclose(IGC_File); IGC_File=0; IGC_FlightNum++;
uint32_t Time = TimeSync_Time();
fclose(IGC_File); IGC_File=0; IGC_FlightNum++; }
}
/*
IGC_SaveTime = TimeSync_Time();
struct stat FileStat;
struct utimbuf FileTime;
if(stat(IGC_FileName, &FileStat)>=0) // get file attributes (maybe not needed really ?
{ FileTime.actime = Time; // set access and modification tim$
FileTime.modtime = Time;
{ FileTime.actime = IGC_SaveTime; // set access and modification tim$
FileTime.modtime = IGC_SaveTime;
utime(IGC_FileName, &FileTime); } // write to the FAT
}
}
*/
static int IGC_Open(void)
{ IGC_Close(); // close the previous file, if open
@ -117,17 +131,58 @@ static int IGC_Open(void)
{ if(mkdir(IGC_Path, 0777)<0) return -3; // -3 => can't create sub-dir
IGC_File=fopen(IGC_FileName, "wt"); } // retry to open for write
if(IGC_File)
{ xSemaphoreTake(CONS_Mutex, portMAX_DELAY);
{ IGC_SaveTime = TimeSync_Time();
xSemaphoreTake(CONS_Mutex, portMAX_DELAY);
Format_String(CONS_UART_Write, "IGC_Open: ");
Format_String(CONS_UART_Write, IGC_FileName);
Format_String(CONS_UART_Write, "\n");
xSemaphoreGive(CONS_Mutex); }
return IGC_File ? 0:-4; } // -4 => can't open for write
static void IGC_Reopen(void)
{ if(IGC_File)
{ fclose(IGC_File);
IGC_SaveTime = TimeSync_Time();
IGC_TimeStamp();
IGC_File=fopen(IGC_FileName, "at"); }
}
static char Line[192];
static int IGC_Header(void) // write the top of the IGC file
{
static int IGC_HeadParm(const char *Name, const char *Parm)
{ int Len=Format_String(Line, Name);
Len+=Format_String(Line+Len, Parm);
Line[Len++]='\n'; Line[Len]=0;
fputs(Line, IGC_File);
return 0; }
static int IGC_Header(const GPS_Position &Pos) // write the top of the IGC file
{ fputs("AGNE001Tracker\n", IGC_File);
{ int Len=Format_String(Line, "HFDTEDate:"); // date
Len+=Format_UnsDec(Line+Len, (uint16_t)Pos.Day , 2);
Len+=Format_UnsDec(Line+Len, (uint16_t)Pos.Month, 2);
Len+=Format_UnsDec(Line+Len, (uint16_t)Pos.Year , 2);
Line[Len++]=',';
Len+=Format_UnsDec(Line+Len, (uint16_t)IGC_FlightNum, 2);
Line[Len++]='\n'; Line[Len]=0;
fputs(Line, IGC_File); }
IGC_HeadParm("HFPLTPilotincharge:", Parameters.Pilot);
IGC_HeadParm("HFGTYGliderType:", Parameters.Type);
IGC_HeadParm("HFGIDGliderID:", Parameters.Reg);
IGC_HeadParm("HFCM2Crew2:", Parameters.Crew);
IGC_HeadParm("HFCCLCompetitionClass:", Parameters.Class);
IGC_HeadParm("HFCIDCompetitionID:", Parameters.ID);
{ int Len=Format_String(Line, "HFGIDGliderid:"); // unique ID
uint64_t ID = getUniqueID(); // 48-bit ID
Len+=Format_Hex(Line+Len, (uint16_t)(ID>>32));
Len+=Format_Hex(Line+Len, (uint32_t)ID);
Line[Len++]=',';
Len+=Format_Hex(Line+Len, Parameters.AcftID); // stealth, no-track, aircraft-type, address-type, address
Line[Len++]='\n'; Line[Len]=0;
fputs(Line, IGC_File); }
fputs("HFRFWFirmwareVersion:" __DATE__ " " __TIME__ "\n", IGC_File);
fputs("HFGPSReceiver:L80\n", IGC_File); // GPS sensor
fputs("HFPRSPressAltSensor:BMP280\n", IGC_File); // pressure sensor
return 0; }
static int IGC_Log(const GPS_Position &Pos) // log GPS position as B-record
@ -161,13 +216,18 @@ static void IGC_Check(void) // check if
if(IGC_File) // if IGC file already open
{ IGC_Log(GPS_Pos[PosIdx]); // log position
if(!inFlight) // if no longer in flight
{ IGC_Close(); } // then close the IGC file
{ IGC_Close(); IGC_TimeStamp(); } // then close the IGC file
else
{ uint32_t Time=TimeSync_Time();
if(Time-IGC_SaveTime>=IGC_SavePeriod)
{ IGC_Reopen(); }
}
}
else // if IGC file is not open
{ if(inFlight) // and in-flight
{ for(int Try=0; Try<8; Try++)
{ int Err=IGC_Open(); if(Err!=(-2)) break; } // try to open a new IGC file but don't overwrite the old ones
if(IGC_File) { IGC_Header(); IGC_Log(GPS_Pos[PosIdx]); } // if open succesfully then write header and first B-record
if(IGC_File) { IGC_Header(GPS_Pos[PosIdx]); IGC_Log(GPS_Pos[PosIdx]); } // if open succesfully then write header and first B-record
}
}
}
@ -178,7 +238,12 @@ static void IGC_Check(void) // check if
extern "C"
void vTaskSDLOG(void* pvParameters)
{ Log_FIFO.Clear();
{ uint32_t ID = getUniqueAddress();
IGC_Serial[2] = Flight.Code36(ID%36); ID/=36;
IGC_Serial[1] = Flight.Code36(ID%36); ID/=36;
IGC_Serial[0] = Flight.Code36(ID%36);
Log_FIFO.Clear();
for( ; ; )
{ if(!SD_isMounted()) // if SD ia not mounted: