Support for AERO protocol

pull/5/head
Pawel Jalocha 2019-05-08 17:03:54 +00:00
rodzic 6fb70d356e
commit 0878e8378d
5 zmienionych plików z 147 dodań i 16 usunięć

115
main/aero.cpp 100644
Wyświetl plik

@ -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; }
}
}
}

9
main/aero.h 100644
Wyświetl plik

@ -0,0 +1,9 @@
#include "hal.h"
#include "timesync.h"
#ifdef __cplusplus
extern "C"
#endif
void vTaskAERO(void* pvParameters);

Wyświetl plik

@ -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)

Wyświetl plik

@ -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);

Wyświetl plik

@ -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