diff --git a/software/firmware/source/SoftRF/Makefile b/software/firmware/source/SoftRF/Makefile index 96f0c3dbc..7cdf9ddd7 100644 --- a/software/firmware/source/SoftRF/Makefile +++ b/software/firmware/source/SoftRF/Makefile @@ -146,6 +146,7 @@ PLAT_CPPS := $(PLATFORM_PATH)/ESP8266.cpp \ DRV_CPPS := $(DRIVER_PATH)/RF.cpp \ $(DRIVER_PATH)/radio/nordic.cpp \ $(DRIVER_PATH)/radio/almic.cpp \ + $(DRIVER_PATH)/radio/uatm.cpp \ $(DRIVER_PATH)/radio/easylink.cpp \ $(DRIVER_PATH)/radio/ogn.cpp \ $(DRIVER_PATH)/radio/nicerf.cpp \ diff --git a/software/firmware/source/SoftRF/src/driver/RF.cpp b/software/firmware/source/SoftRF/src/driver/RF.cpp index a17fe0eea..adc9478ee 100644 --- a/software/firmware/source/SoftRF/src/driver/RF.cpp +++ b/software/firmware/source/SoftRF/src/driver/RF.cpp @@ -19,11 +19,10 @@ #include "RF.h" #include "EEPROM.h" //#include "Battery.h" -#include "../ui/Web.h" +//#include "../ui/Web.h" #if !defined(EXCLUDE_MAVLINK) #include "../protocol/data/MAVLink.h" #endif /* EXCLUDE_MAVLINK */ -#include byte RxBuffer[MAX_PKT_SIZE] __attribute__((aligned(sizeof(uint32_t)))); @@ -61,26 +60,6 @@ static uint8_t RF_timing = RF_TIMING_INTERVAL; extern const gnss_chip_ops_t *gnss_chip; -static bool uatm_probe(void); -static void uatm_setup(void); -static void uatm_channel(int8_t); -static bool uatm_receive(void); -static bool uatm_transmit(void); -static void uatm_shutdown(void); - -#if !defined(EXCLUDE_UATM) -const rfchip_ops_t uatm_ops = { - RF_IC_UATM, - "UATM", - uatm_probe, - uatm_setup, - uatm_channel, - uatm_receive, - uatm_transmit, - uatm_shutdown -}; -#endif /* EXCLUDE_UATM */ - String Bin2Hex(byte *buffer, size_t size) { String str = ""; @@ -432,171 +411,3 @@ uint8_t RF_Payload_Size(uint8_t protocol) default: return 0; } } - -#if !defined(EXCLUDE_UATM) -/* - * UATM-specific code - * - * - */ - -#include - -#define UAT_RINGBUF_SIZE (sizeof(Stratux_frame_t) * 2) - -static unsigned char uat_ringbuf[UAT_RINGBUF_SIZE]; -static unsigned int uatbuf_head = 0; -Stratux_frame_t uatradio_frame; - -const char UAT_ident[] PROGMEM = SOFTRF_IDENT; - -static bool uatm_probe() -{ - bool success = false; - unsigned long startTime; - unsigned int uatbuf_tail; - u1_t keylen = strlen_P(UAT_ident); - u1_t i=0; - - /* Do not probe on itself and ESP8266 */ - if (SoC->id == SOC_CC13X0 || - SoC->id == SOC_CC13X2 || - SoC->id == SOC_ESP8266) { - return success; - } - - SoC->UATSerial_begin(UAT_RECEIVER_BR); - - SoC->UATModule_restart(); - - startTime = millis(); - - // Timeout if no valid response in 1 second - while (millis() - startTime < 1000) { - - if (UATSerial.available() > 0) { - unsigned char c = UATSerial.read(); -#if DEBUG - Serial.println(c, HEX); -#endif - uat_ringbuf[uatbuf_head % UAT_RINGBUF_SIZE] = c; - - uatbuf_tail = uatbuf_head - keylen; - uatbuf_head++; - - for (i=0; i < keylen; i++) { - if (pgm_read_byte(&UAT_ident[i]) != uat_ringbuf[(uatbuf_tail + i) % UAT_RINGBUF_SIZE]) { - break; - } - } - - if (i >= keylen) { - success = true; - break; - } - } - } - - /* cleanup UAT data buffer */ - uatbuf_head = 0; - memset(uat_ringbuf, 0, sizeof(uat_ringbuf)); - - /* Current ESP32 Core has a bug with Serial2.end()+Serial2.begin() cycle */ - if (SoC->id != SOC_ESP32) { - UATSerial.end(); - } - - return success; -} - -static void uatm_channel(int8_t channel) -{ - /* Nothing to do */ -} - -static void uatm_setup() -{ - /* Current ESP32 Core has a bug with Serial2.end()+Serial2.begin() cycle */ - if (SoC->id != SOC_ESP32) { - SoC->UATSerial_begin(UAT_RECEIVER_BR); - } - - init_fec(); - - /* Enforce radio settings to follow UAT978 protocol's RF specs */ - settings->rf_protocol = RF_PROTOCOL_ADSB_UAT; - - RF_FreqPlan.setPlan(settings->band, settings->rf_protocol); - - protocol_encode = &uat978_encode; - protocol_decode = &uat978_decode; -} - -static bool uatm_receive() -{ - bool success = false; - unsigned int uatbuf_tail; - int rs_errors; - - while (UATSerial.available()) { - unsigned char c = UATSerial.read(); - - uat_ringbuf[uatbuf_head % UAT_RINGBUF_SIZE] = c; - - uatbuf_tail = uatbuf_head - sizeof(Stratux_frame_t); - uatbuf_head++; - - if (uat_ringbuf[ uatbuf_tail % UAT_RINGBUF_SIZE] == STRATUX_UATRADIO_MAGIC_1 && - uat_ringbuf[(uatbuf_tail + 1) % UAT_RINGBUF_SIZE] == STRATUX_UATRADIO_MAGIC_2 && - uat_ringbuf[(uatbuf_tail + 2) % UAT_RINGBUF_SIZE] == STRATUX_UATRADIO_MAGIC_3 && - uat_ringbuf[(uatbuf_tail + 3) % UAT_RINGBUF_SIZE] == STRATUX_UATRADIO_MAGIC_4) { - - unsigned char *pre_fec_buf = (unsigned char *) &uatradio_frame; - for (u1_t i=0; i < sizeof(Stratux_frame_t); i++) { - pre_fec_buf[i] = uat_ringbuf[(uatbuf_tail + i) % UAT_RINGBUF_SIZE]; - } - - int frame_type = correct_adsb_frame(uatradio_frame.data, &rs_errors); - - if (frame_type == -1) { - continue; - } - - u1_t size = 0; - - if (frame_type == 1) { - size = SHORT_FRAME_DATA_BYTES; - } else if (frame_type == 2) { - size = LONG_FRAME_DATA_BYTES; - } - - if (size > sizeof(RxBuffer)) { - size = sizeof(RxBuffer); - } - - if (size > 0) { - memcpy(RxBuffer, uatradio_frame.data, size); - - RF_last_rssi = uatradio_frame.rssi; - rx_packets_counter++; - success = true; - - break; - } - } - } - - return success; -} - -static bool uatm_transmit() -{ - /* Nothing to do */ - return false; -} - -static void uatm_shutdown() -{ - /* Nothing to do */ -} -#endif /* EXCLUDE_UATM */ diff --git a/software/firmware/source/SoftRF/src/driver/RF.h b/software/firmware/source/SoftRF/src/driver/RF.h index 12b98f0a4..59550ca20 100644 --- a/software/firmware/source/SoftRF/src/driver/RF.h +++ b/software/firmware/source/SoftRF/src/driver/RF.h @@ -154,7 +154,9 @@ extern const rfchip_ops_t sx1262_ops; #endif /* USE_BASICMAC */ #endif /*EXCLUDE_SX12XX */ -/* PLACEHOLDER */ +#if !defined(EXCLUDE_UATM) +extern const rfchip_ops_t uatm_ops; +#endif /* EXCLUDE_UATM */ #if !defined(EXCLUDE_CC13XX) extern const rfchip_ops_t cc13xx_ops; diff --git a/software/firmware/source/SoftRF/src/driver/radio/uatm.cpp b/software/firmware/source/SoftRF/src/driver/radio/uatm.cpp new file mode 100644 index 000000000..b15827ce6 --- /dev/null +++ b/software/firmware/source/SoftRF/src/driver/radio/uatm.cpp @@ -0,0 +1,208 @@ +/* + * uatm.cpp + * Copyright (C) 2019-2024 Linar Yusupov + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include "../RF.h" + +#if !defined(EXCLUDE_UATM) +/* + * UATM-specific code + * + * + */ + +#include +#include + +#include "../EEPROM.h" + +#define UAT_RINGBUF_SIZE (sizeof(Stratux_frame_t) * 2) + +static bool uatm_probe(void); +static void uatm_setup(void); +static void uatm_channel(int8_t); +static bool uatm_receive(void); +static bool uatm_transmit(void); +static void uatm_shutdown(void); + +const rfchip_ops_t uatm_ops = { + RF_IC_UATM, + "UATM", + uatm_probe, + uatm_setup, + uatm_channel, + uatm_receive, + uatm_transmit, + uatm_shutdown +}; + +static unsigned char uat_ringbuf[UAT_RINGBUF_SIZE]; +static unsigned int uatbuf_head = 0; +Stratux_frame_t uatradio_frame; + +const char UAT_ident[] PROGMEM = SOFTRF_IDENT; + +static bool uatm_probe() +{ + bool success = false; + unsigned long startTime; + unsigned int uatbuf_tail; + u1_t keylen = strlen_P(UAT_ident); + u1_t i=0; + + /* Do not probe on itself and ESP8266 */ + if (SoC->id == SOC_CC13X0 || + SoC->id == SOC_CC13X2 || + SoC->id == SOC_ESP8266) { + return success; + } + + SoC->UATSerial_begin(UAT_RECEIVER_BR); + + SoC->UATModule_restart(); + + startTime = millis(); + + // Timeout if no valid response in 1 second + while (millis() - startTime < 1000) { + + if (UATSerial.available() > 0) { + unsigned char c = UATSerial.read(); +#if DEBUG + Serial.println(c, HEX); +#endif + uat_ringbuf[uatbuf_head % UAT_RINGBUF_SIZE] = c; + + uatbuf_tail = uatbuf_head - keylen; + uatbuf_head++; + + for (i=0; i < keylen; i++) { + if (pgm_read_byte(&UAT_ident[i]) != uat_ringbuf[(uatbuf_tail + i) % UAT_RINGBUF_SIZE]) { + break; + } + } + + if (i >= keylen) { + success = true; + break; + } + } + } + + /* cleanup UAT data buffer */ + uatbuf_head = 0; + memset(uat_ringbuf, 0, sizeof(uat_ringbuf)); + + /* Current ESP32 Core has a bug with Serial2.end()+Serial2.begin() cycle */ + if (SoC->id != SOC_ESP32) { + UATSerial.end(); + } + + return success; +} + +static void uatm_channel(int8_t channel) +{ + /* Nothing to do */ +} + +static void uatm_setup() +{ + /* Current ESP32 Core has a bug with Serial2.end()+Serial2.begin() cycle */ + if (SoC->id != SOC_ESP32) { + SoC->UATSerial_begin(UAT_RECEIVER_BR); + } + + init_fec(); + + /* Enforce radio settings to follow UAT978 protocol's RF specs */ + settings->rf_protocol = RF_PROTOCOL_ADSB_UAT; + + RF_FreqPlan.setPlan(settings->band, settings->rf_protocol); + + protocol_encode = &uat978_encode; + protocol_decode = &uat978_decode; +} + +static bool uatm_receive() +{ + bool success = false; + unsigned int uatbuf_tail; + int rs_errors; + + while (UATSerial.available()) { + unsigned char c = UATSerial.read(); + + uat_ringbuf[uatbuf_head % UAT_RINGBUF_SIZE] = c; + + uatbuf_tail = uatbuf_head - sizeof(Stratux_frame_t); + uatbuf_head++; + + if (uat_ringbuf[ uatbuf_tail % UAT_RINGBUF_SIZE] == STRATUX_UATRADIO_MAGIC_1 && + uat_ringbuf[(uatbuf_tail + 1) % UAT_RINGBUF_SIZE] == STRATUX_UATRADIO_MAGIC_2 && + uat_ringbuf[(uatbuf_tail + 2) % UAT_RINGBUF_SIZE] == STRATUX_UATRADIO_MAGIC_3 && + uat_ringbuf[(uatbuf_tail + 3) % UAT_RINGBUF_SIZE] == STRATUX_UATRADIO_MAGIC_4) { + + unsigned char *pre_fec_buf = (unsigned char *) &uatradio_frame; + for (u1_t i=0; i < sizeof(Stratux_frame_t); i++) { + pre_fec_buf[i] = uat_ringbuf[(uatbuf_tail + i) % UAT_RINGBUF_SIZE]; + } + + int frame_type = correct_adsb_frame(uatradio_frame.data, &rs_errors); + + if (frame_type == -1) { + continue; + } + + u1_t size = 0; + + if (frame_type == 1) { + size = SHORT_FRAME_DATA_BYTES; + } else if (frame_type == 2) { + size = LONG_FRAME_DATA_BYTES; + } + + if (size > sizeof(RxBuffer)) { + size = sizeof(RxBuffer); + } + + if (size > 0) { + memcpy(RxBuffer, uatradio_frame.data, size); + + RF_last_rssi = uatradio_frame.rssi; + rx_packets_counter++; + success = true; + + break; + } + } + } + + return success; +} + +static bool uatm_transmit() +{ + /* Nothing to do */ + return false; +} + +static void uatm_shutdown() +{ + /* Nothing to do */ +} +#endif /* EXCLUDE_UATM */ diff --git a/software/firmware/source/SoftRF/src/ui/Web.h b/software/firmware/source/SoftRF/src/ui/Web.h index 4270b28e2..9f1270906 100644 --- a/software/firmware/source/SoftRF/src/ui/Web.h +++ b/software/firmware/source/SoftRF/src/ui/Web.h @@ -25,7 +25,7 @@ #include #endif /* ARDUINO */ -#include +//#include #include "../driver/EEPROM.h" #include "../driver/RF.h" @@ -51,6 +51,6 @@ extern String TxDataTemplate; extern WiFiClient client; #endif /* ARDUINO */ -extern TinyGPSPlus gps; +//extern TinyGPSPlus gps; #endif /* WEBHELPER_H */