diff --git a/AX25RX.cpp b/AX25RX.cpp new file mode 100644 index 0000000..8305407 --- /dev/null +++ b/AX25RX.cpp @@ -0,0 +1,33 @@ +/* + * Copyright (C) 2020 by Jonathan Naylor G4KLX + * + * 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 2 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, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include "Config.h" +#include "Globals.h" +#include "AX25RX.h" + +CAX25RX::CAX25RX() +{ +} + +void CAX25RX::samples(const q15_t* samples, uint8_t length) +{ + for (uint8_t i = 0U; i < length; i++) { + q15_t sample = samples[i]; + } +} + diff --git a/AX25RX.h b/AX25RX.h new file mode 100644 index 0000000..bbb2779 --- /dev/null +++ b/AX25RX.h @@ -0,0 +1,34 @@ +/* + * Copyright (C) 2020 by Jonathan Naylor G4KLX + * + * 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 2 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, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#if !defined(AX25RX_H) +#define AX25RX_H + +#include "Config.h" + +class CAX25RX { +public: + CAX25RX(); + + void samples(const q15_t* samples, uint8_t length); + +private: +}; + +#endif + diff --git a/Config.h b/Config.h index 73e716b..cdebe56 100644 --- a/Config.h +++ b/Config.h @@ -39,7 +39,7 @@ // #define USE_COS_AS_LOCKOUT // Use pins to output the current mode via LEDs -// #define MODE_LEDS +#define MODE_LEDS // For the original Arduino Due pin layout // #define ARDUINO_DUE_PAPA diff --git a/Globals.h b/Globals.h index 5cb147a..4d25617 100644 --- a/Globals.h +++ b/Globals.h @@ -51,6 +51,7 @@ enum MMDVM_STATE { STATE_NXDN = 5, STATE_POCSAG = 6, STATE_FM = 10, + STATE_AX25 = 11, // Dummy states start at 90 STATE_NXDNCAL1K = 91, @@ -96,6 +97,7 @@ enum MMDVM_STATE { #include "CalPOCSAG.h" #include "CalRSSI.h" #include "CWIdTX.h" +#include "AX25RX.h" #include "Debug.h" #include "IO.h" #include "FM.h" @@ -124,6 +126,7 @@ extern bool m_p25Enable; extern bool m_nxdnEnable; extern bool m_pocsagEnable; extern bool m_fmEnable; +extern bool m_ax25Enable; extern bool m_duplex; @@ -154,7 +157,8 @@ extern CNXDNTX nxdnTX; extern CPOCSAGTX pocsagTX; -extern CFM fm; +extern CFM fm; +extern CAX25RX ax25RX; extern CCalDStarRX calDStarRX; extern CCalDStarTX calDStarTX; @@ -168,3 +172,4 @@ extern CCalRSSI calRSSI; extern CCWIdTX cwIdTX; #endif + diff --git a/IO.cpp b/IO.cpp index a737693..6962f08 100644 --- a/IO.cpp +++ b/IO.cpp @@ -362,6 +362,14 @@ void CIO::process() fm.samples(cos, dcSamples, RX_BLOCK_SIZE); #else fm.samples(cos, samples, RX_BLOCK_SIZE); +#endif + } + + if (m_ax25Enable) { +#if defined(USE_DCBLOCKER) + ax25RX.samples(dcSamples, RX_BLOCK_SIZE); +#else + ax25RX.samples(samples, RX_BLOCK_SIZE); #endif } } else if (m_modemState == STATE_DSTAR) { @@ -426,8 +434,12 @@ void CIO::process() bool cos = getCOSInt(); #if defined(USE_DCBLOCKER) fm.samples(cos, dcSamples, RX_BLOCK_SIZE); + if (m_ax25Enable) + ax25RX.samples(dcSamples, RX_BLOCK_SIZE); #else fm.samples(cos, samples, RX_BLOCK_SIZE); + if (m_ax25Enable) + ax25RX.samples(samples, RX_BLOCK_SIZE); #endif } else if (m_modemState == STATE_DSTARCAL) { q15_t GMSKVals[RX_BLOCK_SIZE]; diff --git a/MMDVM.cpp b/MMDVM.cpp index a6d4577..5b5bc4b 100644 --- a/MMDVM.cpp +++ b/MMDVM.cpp @@ -33,6 +33,7 @@ bool m_p25Enable = true; bool m_nxdnEnable = true; bool m_pocsagEnable = true; bool m_fmEnable = true; +bool m_ax25Enable = true; bool m_duplex = true; @@ -61,6 +62,7 @@ CNXDNTX nxdnTX; CPOCSAGTX pocsagTX; CFM fm; +CAX25RX ax25RX; CCalDStarRX calDStarRX; CCalDStarTX calDStarTX; diff --git a/MMDVM.ino b/MMDVM.ino index 17c4ad8..f1073dd 100644 --- a/MMDVM.ino +++ b/MMDVM.ino @@ -30,6 +30,7 @@ bool m_p25Enable = true; bool m_nxdnEnable = true; bool m_pocsagEnable = true; bool m_fmEnable = true; +bool m_ax25Enable = true; bool m_duplex = true; @@ -58,6 +59,7 @@ CNXDNTX nxdnTX; CPOCSAGTX pocsagTX; CFM fm; +CAX25RX ax25RX; CCalDStarRX calDStarRX; CCalDStarTX calDStarTX; diff --git a/SerialPort.cpp b/SerialPort.cpp index 338f5f9..f906bc0 100644 --- a/SerialPort.cpp +++ b/SerialPort.cpp @@ -65,6 +65,8 @@ const uint8_t MMDVM_NXDN_LOST = 0x41U; const uint8_t MMDVM_POCSAG_DATA = 0x50U; +const uint8_t MMDVM_AX25_DATA = 0x55U; + const uint8_t MMDVM_FM_PARAMS1 = 0x60U; const uint8_t MMDVM_FM_PARAMS2 = 0x61U; const uint8_t MMDVM_FM_PARAMS3 = 0x62U; @@ -103,7 +105,7 @@ const uint8_t MMDVM_DEBUG5 = 0xF5U; #define HW_TYPE "MMDVM" #endif -#define DESCRIPTION "20200520 (D-Star/DMR/System Fusion/P25/NXDN/POCSAG/FM)" +#define DESCRIPTION "20200608 (D-Star/DMR/System Fusion/P25/NXDN/POCSAG/FM/AX.25)" #if defined(GITVERSION) #define concat(h, a, b, c) h " " a " " b " GitID #" c "" @@ -176,6 +178,8 @@ void CSerialPort::getStatus() reply[3U] |= 0x20U; if (m_fmEnable) reply[3U] |= 0x40U; + if (m_ax25Enable) + reply[3U] |= 0x80U; reply[4U] = uint8_t(m_modemState); @@ -282,6 +286,7 @@ uint8_t CSerialPort::setConfig(const uint8_t* data, uint8_t length) bool nxdnEnable = (data[1U] & 0x10U) == 0x10U; bool pocsagEnable = (data[1U] & 0x20U) == 0x20U; bool fmEnable = (data[1U] & 0x40U) == 0x40U; + bool ax25Enable = (data[1U] & 0x80U) == 0x80U; uint8_t txDelay = data[2U]; if (txDelay > 50U) @@ -344,6 +349,7 @@ uint8_t CSerialPort::setConfig(const uint8_t* data, uint8_t length) m_nxdnEnable = nxdnEnable; m_pocsagEnable = pocsagEnable; m_fmEnable = fmEnable; + m_ax25Enable = ax25Enable; m_duplex = !simplex; dstarTX.setTXDelay(txDelay); @@ -1197,6 +1203,29 @@ void CSerialPort::writeNXDNLost() writeInt(1U, reply, 3); } +void CSerialPort::writeAX25Data(const uint8_t* data, uint8_t length) +{ + if (m_modemState != STATE_FM && m_modemState != STATE_IDLE) + return; + + if (!m_ax25Enable) + return; + + uint8_t reply[300U]; + + reply[0U] = MMDVM_FRAME_START; + reply[1U] = 0U; + reply[2U] = MMDVM_AX25_DATA; + + uint8_t count = 3U; + for (uint8_t i = 0U; i < length; i++, count++) + reply[count] = data[i]; + + reply[1U] = count; + + writeInt(1U, reply, count); +} + void CSerialPort::writeCalData(const uint8_t* data, uint8_t length) { if (m_modemState != STATE_DSTARCAL) diff --git a/SerialPort.h b/SerialPort.h index cd09bbe..e8b9d58 100644 --- a/SerialPort.h +++ b/SerialPort.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2015,2016,2017,2018 by Jonathan Naylor G4KLX + * Copyright (C) 2015,2016,2017,2018,2020 by Jonathan Naylor G4KLX * * 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 @@ -50,6 +50,8 @@ public: void writeNXDNData(const uint8_t* data, uint8_t length); void writeNXDNLost(); + void writeAX25Data(const uint8_t* data, uint8_t length); + void writeCalData(const uint8_t* data, uint8_t length); void writeRSSIData(const uint8_t* data, uint8_t length);