kopia lustrzana https://github.com/pjalocha/esp32-ogn-tracker
Support for AERO protocol
rodzic
6fb70d356e
commit
0878e8378d
|
@ -0,0 +1,115 @@
|
|||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "hal.h"
|
||||
#include "aero.h"
|
||||
|
||||
class AEROmsg
|
||||
{ public:
|
||||
|
||||
static const uint8_t MaxLen=96; // maximum length
|
||||
static const uint8_t MaxParms=16; // maximum number of parameters (commas)
|
||||
|
||||
uint8_t Data[MaxLen]; // the message itself
|
||||
uint8_t Len; // number of bytes
|
||||
uint8_t Parms; // number of commas
|
||||
uint8_t Parm[MaxParms]; // offset to each comma
|
||||
uint8_t State; // bits: 0:loading, 1:complete, 2:locked,
|
||||
|
||||
public:
|
||||
void Clear(void) // Clear the frame: discard all data, ready for next message
|
||||
{ State=0; Len=0; Parms=0; }
|
||||
|
||||
void ProcessByte(uint8_t Byte) // pass all bytes through this call and it will build the frame
|
||||
{
|
||||
if(isComplete()) return; // if already a complete frame, ignore extra bytes
|
||||
if(Len==0) // if data is empty
|
||||
{ if(Byte!='#') return; // then ignore all bytes but '#'
|
||||
Data[Len++]=Byte; // start storing the frame
|
||||
setLoading(); Parms=0; // set state to "isLoading", clear checksum
|
||||
} else // if not empty (being loaded)
|
||||
{ if((Byte=='\r')||(Byte=='\n')) // if CR (or NL ?) then frame is complete
|
||||
{ setComplete(); if(Len<MaxLen) Data[Len]=0;
|
||||
return; }
|
||||
else if(Byte<=' ') // other control bytes treat as errors
|
||||
{ Clear(); return; } // and drop the frame
|
||||
else if(Byte==',') // save comma positions to later get back to the fields
|
||||
{ if(Parms<MaxParms) Parm[Parms++]=Len+1; }
|
||||
if(Len<MaxLen) { Data[Len++]=Byte; } // store data but if too much then treat as an error
|
||||
else Clear(); // if too long, then drop the frame completely
|
||||
}
|
||||
return; }
|
||||
|
||||
uint8_t isLoading(void) const { return State &0x01; }
|
||||
void setLoading(void) { State|=0x01; }
|
||||
|
||||
uint8_t isComplete(void) const { return State &0x02; }
|
||||
void setComplete(void) { State|=0x02; }
|
||||
|
||||
uint8_t isLocked(void) const { return State&0x04; }
|
||||
|
||||
uint8_t isEmpty(void) const { return Len==0; }
|
||||
|
||||
uint8_t isChecked(void) const // is the AERO checksum OK ?
|
||||
{ if(Data[Len-5]!=',') return 0;
|
||||
uint16_t CRC; if(Read_Hex(CRC, (const char *)(Data+(Len-4)))!=4) return 0;
|
||||
return CRC == CRC16(Data, Len-5); }
|
||||
|
||||
static uint16_t CRC16(uint16_t CRC, uint8_t Byte)
|
||||
{ uint8_t X = (CRC>>8) ^ Byte; X ^= X>>4;
|
||||
CRC = (CRC<<8) ^ ((uint16_t)(X<<12)) ^ ((uint16_t)(X <<5)) ^ ((uint16_t)X);
|
||||
return CRC; }
|
||||
|
||||
static uint16_t CRC16(const uint8_t *Data, uint8_t Len)
|
||||
{ uint16_t CRC = 0xFFFF;
|
||||
while(Len--)
|
||||
{ CRC = CRC16(CRC, *Data++); }
|
||||
return (CRC>>8) | (CRC<<8); }
|
||||
|
||||
} ;
|
||||
|
||||
static AEROmsg AERO;
|
||||
|
||||
static void ADSB_AERO(bool GoodCRC)
|
||||
{
|
||||
// #ifdef DEBUG_PRINT
|
||||
xSemaphoreTake(CONS_Mutex, portMAX_DELAY);
|
||||
// Format_UnsDec(CONS_UART_Write, TimeSync_Time()%60);
|
||||
// CONS_UART_Write('.');
|
||||
// Format_UnsDec(CONS_UART_Write, TimeSync_msTime(),3);
|
||||
// Format_String(CONS_UART_Write, " -> ");
|
||||
Format_String(CONS_UART_Write, (const char *)AERO.Data, AERO.Len, 0);
|
||||
if(!GoodCRC) Format_String(CONS_UART_Write, " <- bad !");
|
||||
Format_String(CONS_UART_Write, "\n");
|
||||
xSemaphoreGive(CONS_Mutex);
|
||||
// #endif
|
||||
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
#endif
|
||||
void vTaskAERO(void* pvParameters)
|
||||
{
|
||||
|
||||
vTaskDelay(5); // put some initial delay for lighter startup load
|
||||
|
||||
xSemaphoreTake(CONS_Mutex, portMAX_DELAY);
|
||||
Format_String(CONS_UART_Write, "TaskAERO:");
|
||||
Format_String(CONS_UART_Write, "\n");
|
||||
xSemaphoreGive(CONS_Mutex);
|
||||
|
||||
for( ; ; ) // main task loop: every milisecond (RTOS time tick)
|
||||
{ vTaskDelay(1); //
|
||||
for( ; ; ) // loop over bytes in the AERO UART buffer
|
||||
{ uint8_t Byte; int Err=AERO_UART_Read(Byte); if(Err<=0) break; // get Byte from serial port, if no bytes then break this l$
|
||||
AERO.ProcessByte(Byte); // process through the AERO interpreter
|
||||
if(AERO.isComplete()) // AERO completely received ?
|
||||
{ ADSB_AERO(AERO.isChecked());
|
||||
AERO.Clear(); break; }
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
#include "hal.h"
|
||||
|
||||
#include "timesync.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
#endif
|
||||
void vTaskAERO(void* pvParameters);
|
||||
|
24
main/hal.cpp
24
main/hal.cpp
|
@ -248,9 +248,9 @@ GPIO HELTEC TTGO JACEK T-Beam FollowMe Restrictions
|
|||
#define I2C_BUS I2C_NUM_1 // use bus #1 to talk to OLED and Baro sensor
|
||||
|
||||
#ifdef WITH_FollowMe
|
||||
#define ADSB_UART UART_NUM_2 // UART2
|
||||
#define PIN_ADSB_TXD GPIO_NUM_25
|
||||
#define PIN_ADSB_RXD GPIO_NUM_27
|
||||
#define AERO_UART UART_NUM_2 // UART2
|
||||
#define PIN_AERO_TXD GPIO_NUM_25
|
||||
#define PIN_AERO_RXD GPIO_NUM_27
|
||||
#endif
|
||||
|
||||
#if defined(WITH_HELTEC) || defined(WITH_TTGO)
|
||||
|
@ -585,10 +585,10 @@ int CONS_UART_Read (uint8_t &Byte) { int Ret=getchar(); if(Ret>=0) { Byte=Ret
|
|||
//--------------------------------------------------------------------------------------------------------
|
||||
// ADS-B UART
|
||||
|
||||
#ifdef ADSB_UART
|
||||
int ADSB_UART_Read (uint8_t &Byte) { return uart_read_bytes (ADSB_UART, &Byte, 1, 0); } // should be buffered and non-blocking
|
||||
void ADSB_UART_Write (char Byte) { uart_write_bytes (ADSB_UART, &Byte, 1); } // should be buffered and blocking
|
||||
void ADSB_UART_SetBaudrate(int BaudRate) { uart_set_baudrate(ADSB_UART, BaudRate); }
|
||||
#ifdef AERO_UART
|
||||
int AERO_UART_Read (uint8_t &Byte) { return uart_read_bytes (AERO_UART, &Byte, 1, 0); } // should be buffered and non-blocking
|
||||
void AERO_UART_Write (char Byte) { uart_write_bytes (AERO_UART, &Byte, 1); } // should be buffered and blocking
|
||||
void AERO_UART_SetBaudrate(int BaudRate) { uart_set_baudrate(AERO_UART, BaudRate); }
|
||||
#endif
|
||||
|
||||
//--------------------------------------------------------------------------------------------------------
|
||||
|
@ -1269,8 +1269,8 @@ void IO_Configuration(void)
|
|||
uart_driver_install(GPS_UART, 256, 256, 0, 0, 0);
|
||||
#endif
|
||||
|
||||
#ifdef ADSB_UART
|
||||
uart_config_t ADSB_UART_Config = // ADSB UART
|
||||
#ifdef AERO_UART
|
||||
uart_config_t AERO_UART_Config = // AERO UART
|
||||
{ baud_rate : 115200,
|
||||
data_bits : UART_DATA_8_BITS,
|
||||
parity : UART_PARITY_DISABLE,
|
||||
|
@ -1279,9 +1279,9 @@ void IO_Configuration(void)
|
|||
rx_flow_ctrl_thresh: 0,
|
||||
use_ref_tick: 0
|
||||
};
|
||||
uart_param_config (ADSB_UART, &ADSB_UART_Config);
|
||||
uart_set_pin (ADSB_UART, PIN_ADSB_TXD, PIN_ADSB_RXD, UART_PIN_NO_CHANGE, UART_PIN_NO_CHANGE);
|
||||
uart_driver_install(ADSB_UART, 256, 256, 0, 0, 0);
|
||||
uart_param_config (AERO_UART, &AERO_UART_Config);
|
||||
uart_set_pin (AERO_UART, PIN_AERO_TXD, PIN_AERO_RXD, UART_PIN_NO_CHANGE, UART_PIN_NO_CHANGE);
|
||||
uart_driver_install(AERO_UART, 256, 256, 0, 0, 0);
|
||||
#endif
|
||||
|
||||
#if defined(WITH_OLED) || defined(WITH_U8G2)
|
||||
|
|
|
@ -64,10 +64,10 @@ void GPS_ENABLE(void);
|
|||
void GPS_DISABLE(void);
|
||||
#endif
|
||||
|
||||
// #ifdef WITH_ADSB
|
||||
int ADSB_UART_Read (uint8_t &Byte); // non-blocking
|
||||
void ADSB_UART_Write (char Byte); // blocking
|
||||
void ADSB_UART_SetBaudrate(int BaudRate);
|
||||
// #ifdef WITH_AERO
|
||||
int AERO_UART_Read (uint8_t &Byte); // non-blocking
|
||||
void AERO_UART_Write (char Byte); // blocking
|
||||
void AERO_UART_SetBaudrate(int BaudRate);
|
||||
// #endif
|
||||
|
||||
void RFM_TransferBlock(uint8_t *Data, uint8_t Len);
|
||||
|
|
|
@ -12,6 +12,10 @@
|
|||
#include "ctrl.h" // Control task
|
||||
#include "log.h" // Data logging task
|
||||
|
||||
#ifdef WITH_AERO
|
||||
#include "aero.h"
|
||||
#endif
|
||||
|
||||
#ifdef WITH_WIFI
|
||||
#include "wifi.h" // WIFI task
|
||||
#endif
|
||||
|
@ -55,6 +59,9 @@ void app_main(void)
|
|||
#if defined(WITH_BMP180) || defined(WITH_BMP280) || defined(WITH_BME280) || defined(WITH_MS5607)
|
||||
xTaskCreate(vTaskSENS, "SENS", 2048, 0, tskIDLE_PRIORITY+4, 0);
|
||||
#endif
|
||||
#ifdef WITH_AERO
|
||||
xTaskCreate(vTaskAERO, "AERO", 2048, 0, tskIDLE_PRIORITY+4, 0);
|
||||
#endif
|
||||
#ifdef WITH_WIFI
|
||||
xTaskCreate(vTaskWIFI, "WIFI", 4096, 0, tskIDLE_PRIORITY+2, 0);
|
||||
#endif
|
||||
|
|
Ładowanie…
Reference in New Issue