From b34d3c3dbd6e0d2ecae8aca5102fb2d749e4e39c Mon Sep 17 00:00:00 2001 From: Jonathan Naylor Date: Wed, 7 Feb 2018 18:07:51 +0000 Subject: [PATCH] Revert "Start work on 4800 baud NXDN support." This reverts commit a6b6219c6d10bcc15e9bbaed4a60d5a03f920ee7. --- NXDN48Defines.h | 50 ----- NXDN96Defines.h | 50 ----- NXDN96RX.cpp | 398 ------------------------------------- NXDN96RX.h | 69 ------- NXDN96TX.cpp | 153 -------------- NXDN96TX.h | 51 ----- NXDN48RX.cpp => NXDNRX.cpp | 0 NXDN48RX.h => NXDNRX.h | 0 NXDN48TX.cpp => NXDNTX.cpp | 0 NXDN48TX.h => NXDNTX.h | 0 10 files changed, 771 deletions(-) delete mode 100644 NXDN48Defines.h delete mode 100644 NXDN96Defines.h delete mode 100644 NXDN96RX.cpp delete mode 100644 NXDN96RX.h delete mode 100644 NXDN96TX.cpp delete mode 100644 NXDN96TX.h rename NXDN48RX.cpp => NXDNRX.cpp (100%) rename NXDN48RX.h => NXDNRX.h (100%) rename NXDN48TX.cpp => NXDNTX.cpp (100%) rename NXDN48TX.h => NXDNTX.h (100%) diff --git a/NXDN48Defines.h b/NXDN48Defines.h deleted file mode 100644 index cbb7731..0000000 --- a/NXDN48Defines.h +++ /dev/null @@ -1,50 +0,0 @@ -/* - * Copyright (C) 2016,2017,2018 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(NXDNDEFINES_H) -#define NXDNDEFINES_H - -const unsigned int NXDN_RADIO_SYMBOL_LENGTH = 5U; // At 24 kHz sample rate - -const unsigned int NXDN_FRAME_LENGTH_BITS = 384U; -const unsigned int NXDN_FRAME_LENGTH_BYTES = NXDN_FRAME_LENGTH_BITS / 8U; -const unsigned int NXDN_FRAME_LENGTH_SYMBOLS = NXDN_FRAME_LENGTH_BITS / 2U; -const unsigned int NXDN_FRAME_LENGTH_SAMPLES = NXDN_FRAME_LENGTH_SYMBOLS * NXDN_RADIO_SYMBOL_LENGTH; - -const unsigned int NXDN_FSW_LENGTH_BITS = 20U; -const unsigned int NXDN_FSW_LENGTH_SYMBOLS = NXDN_FSW_LENGTH_BITS / 2U; -const unsigned int NXDN_FSW_LENGTH_SAMPLES = NXDN_FSW_LENGTH_SYMBOLS * NXDN_RADIO_SYMBOL_LENGTH; - -const uint8_t NXDN_FSW_BYTES[] = {0xCDU, 0xF5U, 0x90U}; -const uint8_t NXDN_FSW_BYTES_MASK[] = {0xFFU, 0xFFU, 0xF0U}; -const uint8_t NXDN_FSW_BYTES_LENGTH = 3U; - -const uint32_t NXDN_FSW_BITS = 0x000CDF59U; -const uint32_t NXDN_FSW_BITS_MASK = 0x000FFFFFU; - -// C D F 5 9 -// 11 00 11 01 11 11 01 01 10 01 -// -3 +1 -3 +3 -3 -3 +3 +3 -1 +3 - -const int8_t NXDN_FSW_SYMBOLS_VALUES[] = {-3, +1, -3, +3, -3, -3, +3, +3, -1, +3}; - -const uint16_t NXDN_FSW_SYMBOLS = 0x014DU; -const uint16_t NXDN_FSW_SYMBOLS_MASK = 0x03FFU; - -#endif - diff --git a/NXDN96Defines.h b/NXDN96Defines.h deleted file mode 100644 index cbb7731..0000000 --- a/NXDN96Defines.h +++ /dev/null @@ -1,50 +0,0 @@ -/* - * Copyright (C) 2016,2017,2018 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(NXDNDEFINES_H) -#define NXDNDEFINES_H - -const unsigned int NXDN_RADIO_SYMBOL_LENGTH = 5U; // At 24 kHz sample rate - -const unsigned int NXDN_FRAME_LENGTH_BITS = 384U; -const unsigned int NXDN_FRAME_LENGTH_BYTES = NXDN_FRAME_LENGTH_BITS / 8U; -const unsigned int NXDN_FRAME_LENGTH_SYMBOLS = NXDN_FRAME_LENGTH_BITS / 2U; -const unsigned int NXDN_FRAME_LENGTH_SAMPLES = NXDN_FRAME_LENGTH_SYMBOLS * NXDN_RADIO_SYMBOL_LENGTH; - -const unsigned int NXDN_FSW_LENGTH_BITS = 20U; -const unsigned int NXDN_FSW_LENGTH_SYMBOLS = NXDN_FSW_LENGTH_BITS / 2U; -const unsigned int NXDN_FSW_LENGTH_SAMPLES = NXDN_FSW_LENGTH_SYMBOLS * NXDN_RADIO_SYMBOL_LENGTH; - -const uint8_t NXDN_FSW_BYTES[] = {0xCDU, 0xF5U, 0x90U}; -const uint8_t NXDN_FSW_BYTES_MASK[] = {0xFFU, 0xFFU, 0xF0U}; -const uint8_t NXDN_FSW_BYTES_LENGTH = 3U; - -const uint32_t NXDN_FSW_BITS = 0x000CDF59U; -const uint32_t NXDN_FSW_BITS_MASK = 0x000FFFFFU; - -// C D F 5 9 -// 11 00 11 01 11 11 01 01 10 01 -// -3 +1 -3 +3 -3 -3 +3 +3 -1 +3 - -const int8_t NXDN_FSW_SYMBOLS_VALUES[] = {-3, +1, -3, +3, -3, -3, +3, +3, -1, +3}; - -const uint16_t NXDN_FSW_SYMBOLS = 0x014DU; -const uint16_t NXDN_FSW_SYMBOLS_MASK = 0x03FFU; - -#endif - diff --git a/NXDN96RX.cpp b/NXDN96RX.cpp deleted file mode 100644 index eab67dd..0000000 --- a/NXDN96RX.cpp +++ /dev/null @@ -1,398 +0,0 @@ -/* - * Copyright (C) 2009-2018 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 "NXDNRX.h" -#include "Utils.h" - -const q15_t SCALING_FACTOR = 18750; // Q15(0.55) - -const uint8_t MAX_FSW_BIT_ERRS = 1U; - -const uint8_t MAX_FSW_SYMBOLS_ERRS = 1U; - -const uint8_t BIT_MASK_TABLE[] = {0x80U, 0x40U, 0x20U, 0x10U, 0x08U, 0x04U, 0x02U, 0x01U}; - -#define WRITE_BIT1(p,i,b) p[(i)>>3] = (b) ? (p[(i)>>3] | BIT_MASK_TABLE[(i)&7]) : (p[(i)>>3] & ~BIT_MASK_TABLE[(i)&7]) - -const uint8_t NOAVEPTR = 99U; - -const uint16_t NOENDPTR = 9999U; - -const unsigned int MAX_FSW_FRAMES = 5U + 1U; - -CNXDNRX::CNXDNRX() : -m_state(NXDNRXS_NONE), -m_bitBuffer(), -m_buffer(), -m_bitPtr(0U), -m_dataPtr(0U), -m_startPtr(NOENDPTR), -m_endPtr(NOENDPTR), -m_fswPtr(NOENDPTR), -m_minFSWPtr(NOENDPTR), -m_maxFSWPtr(NOENDPTR), -m_maxCorr(0), -m_lostCount(0U), -m_countdown(0U), -m_centre(), -m_centreVal(0), -m_threshold(), -m_thresholdVal(0), -m_averagePtr(NOAVEPTR), -m_rssiAccum(0U), -m_rssiCount(0U) -{ -} - -void CNXDNRX::reset() -{ - m_state = NXDNRXS_NONE; - m_dataPtr = 0U; - m_bitPtr = 0U; - m_maxCorr = 0; - m_averagePtr = NOAVEPTR; - m_startPtr = NOENDPTR; - m_endPtr = NOENDPTR; - m_fswPtr = NOENDPTR; - m_minFSWPtr = NOENDPTR; - m_maxFSWPtr = NOENDPTR; - m_centreVal = 0; - m_thresholdVal = 0; - m_lostCount = 0U; - m_countdown = 0U; - m_rssiAccum = 0U; - m_rssiCount = 0U; -} - -void CNXDNRX::samples(const q15_t* samples, uint16_t* rssi, uint8_t length) -{ - for (uint8_t i = 0U; i < length; i++) { - q15_t sample = samples[i]; - - m_rssiAccum += rssi[i]; - m_rssiCount++; - - m_bitBuffer[m_bitPtr] <<= 1; - if (sample < 0) - m_bitBuffer[m_bitPtr] |= 0x01U; - - m_buffer[m_dataPtr] = sample; - - switch (m_state) { - case NXDNRXS_DATA: - processData(sample); - break; - default: - processNone(sample); - break; - } - - m_dataPtr++; - if (m_dataPtr >= NXDN_FRAME_LENGTH_SAMPLES) - m_dataPtr = 0U; - - m_bitPtr++; - if (m_bitPtr >= NXDN_RADIO_SYMBOL_LENGTH) - m_bitPtr = 0U; - } -} - -void CNXDNRX::processNone(q15_t sample) -{ - bool ret = correlateFSW(); - if (ret) { - // On the first sync, start the countdown to the state change - if (m_countdown == 0U) { - m_rssiAccum = 0U; - m_rssiCount = 0U; - - io.setDecode(true); - io.setADCDetection(true); - - m_averagePtr = NOAVEPTR; - - m_countdown = 5U; - } - } - - if (m_countdown > 0U) - m_countdown--; - - if (m_countdown == 1U) { - m_minFSWPtr = m_fswPtr + NXDN_FRAME_LENGTH_SAMPLES - 1U; - if (m_minFSWPtr >= NXDN_FRAME_LENGTH_SAMPLES) - m_minFSWPtr -= NXDN_FRAME_LENGTH_SAMPLES; - - m_maxFSWPtr = m_fswPtr + 1U; - if (m_maxFSWPtr >= NXDN_FRAME_LENGTH_SAMPLES) - m_maxFSWPtr -= NXDN_FRAME_LENGTH_SAMPLES; - - m_state = NXDNRXS_DATA; - m_countdown = 0U; - } -} - -void CNXDNRX::processData(q15_t sample) -{ - if (m_minFSWPtr < m_maxFSWPtr) { - if (m_dataPtr >= m_minFSWPtr && m_dataPtr <= m_maxFSWPtr) - correlateFSW(); - } else { - if (m_dataPtr >= m_minFSWPtr || m_dataPtr <= m_maxFSWPtr) - correlateFSW(); - } - - if (m_dataPtr == m_endPtr) { - // Only update the centre and threshold if they are from a good sync - if (m_lostCount == MAX_FSW_FRAMES) { - m_minFSWPtr = m_fswPtr + NXDN_FRAME_LENGTH_SAMPLES - 1U; - if (m_minFSWPtr >= NXDN_FRAME_LENGTH_SAMPLES) - m_minFSWPtr -= NXDN_FRAME_LENGTH_SAMPLES; - - m_maxFSWPtr = m_fswPtr + 1U; - if (m_maxFSWPtr >= NXDN_FRAME_LENGTH_SAMPLES) - m_maxFSWPtr -= NXDN_FRAME_LENGTH_SAMPLES; - } - - calculateLevels(m_startPtr, NXDN_FRAME_LENGTH_SYMBOLS); - - DEBUG4("NXDNRX: sync found pos/centre/threshold", m_fswPtr, m_centreVal, m_thresholdVal); - - uint8_t frame[NXDN_FRAME_LENGTH_BYTES + 3U]; - samplesToBits(m_startPtr, NXDN_FRAME_LENGTH_SYMBOLS, frame, 8U, m_centreVal, m_thresholdVal); - - // We've not seen a data sync for too long, signal RXLOST and change to RX_NONE - m_lostCount--; - if (m_lostCount == 0U) { - DEBUG1("NXDNRX: sync timed out, lost lock"); - - io.setDecode(false); - io.setADCDetection(false); - - serial.writeNXDNLost(); - - m_state = NXDNRXS_NONE; - m_endPtr = NOENDPTR; - m_averagePtr = NOAVEPTR; - m_countdown = 0U; - m_maxCorr = 0; - } else { - frame[0U] = m_lostCount == (MAX_FSW_FRAMES - 1U) ? 0x01U : 0x00U; - writeRSSIData(frame); - m_maxCorr = 0; - } - } -} - -bool CNXDNRX::correlateFSW() -{ - if (countBits32((m_bitBuffer[m_bitPtr] & NXDN_FSW_SYMBOLS_MASK) ^ NXDN_FSW_SYMBOLS) <= MAX_FSW_SYMBOLS_ERRS) { - uint16_t ptr = m_dataPtr + NXDN_FRAME_LENGTH_SAMPLES - NXDN_FSW_LENGTH_SAMPLES + NXDN_RADIO_SYMBOL_LENGTH; - if (ptr >= NXDN_FRAME_LENGTH_SAMPLES) - ptr -= NXDN_FRAME_LENGTH_SAMPLES; - - q31_t corr = 0; - q15_t min = 16000; - q15_t max = -16000; - - for (uint8_t i = 0U; i < NXDN_FSW_LENGTH_SYMBOLS; i++) { - q15_t val = m_buffer[ptr]; - - if (val > max) - max = val; - if (val < min) - min = val; - - switch (NXDN_FSW_SYMBOLS_VALUES[i]) { - case +3: - corr -= (val + val + val); - break; - case +1: - corr -= val; - break; - case -1: - corr += val; - break; - default: // -3 - corr += (val + val + val); - break; - } - - ptr += NXDN_RADIO_SYMBOL_LENGTH; - if (ptr >= NXDN_FRAME_LENGTH_SAMPLES) - ptr -= NXDN_FRAME_LENGTH_SAMPLES; - } - - if (corr > m_maxCorr) { - if (m_averagePtr == NOAVEPTR) { - m_centreVal = (max + min) >> 1; - - q31_t v1 = (max - m_centreVal) * SCALING_FACTOR; - m_thresholdVal = q15_t(v1 >> 15); - } - - uint16_t startPtr = m_dataPtr + NXDN_FRAME_LENGTH_SAMPLES - NXDN_FSW_LENGTH_SAMPLES + NXDN_RADIO_SYMBOL_LENGTH; - if (startPtr >= NXDN_FRAME_LENGTH_SAMPLES) - startPtr -= NXDN_FRAME_LENGTH_SAMPLES; - - uint8_t sync[NXDN_FSW_BYTES_LENGTH]; - samplesToBits(startPtr, NXDN_FSW_LENGTH_SYMBOLS, sync, 0U, m_centreVal, m_thresholdVal); - - uint8_t errs = 0U; - for (uint8_t i = 0U; i < NXDN_FSW_BYTES_LENGTH; i++) - errs += countBits8((sync[i] & NXDN_FSW_BYTES_MASK[i]) ^ NXDN_FSW_BYTES[i]); - - if (errs <= MAX_FSW_BIT_ERRS) { - m_maxCorr = corr; - m_lostCount = MAX_FSW_FRAMES; - m_fswPtr = m_dataPtr; - - m_startPtr = startPtr; - - m_endPtr = m_dataPtr + NXDN_FRAME_LENGTH_SAMPLES - NXDN_FSW_LENGTH_SAMPLES - 1U; - if (m_endPtr >= NXDN_FRAME_LENGTH_SAMPLES) - m_endPtr -= NXDN_FRAME_LENGTH_SAMPLES; - - return true; - } - } - } - - return false; -} - -void CNXDNRX::calculateLevels(uint16_t start, uint16_t count) -{ - q15_t maxPos = -16000; - q15_t minPos = 16000; - q15_t maxNeg = 16000; - q15_t minNeg = -16000; - - for (uint16_t i = 0U; i < count; i++) { - q15_t sample = m_buffer[start]; - - if (sample > 0) { - if (sample > maxPos) - maxPos = sample; - if (sample < minPos) - minPos = sample; - } else { - if (sample < maxNeg) - maxNeg = sample; - if (sample > minNeg) - minNeg = sample; - } - - start += NXDN_RADIO_SYMBOL_LENGTH; - if (start >= NXDN_FRAME_LENGTH_SAMPLES) - start -= NXDN_FRAME_LENGTH_SAMPLES; - } - - q15_t posThresh = (maxPos + minPos) >> 1; - q15_t negThresh = (maxNeg + minNeg) >> 1; - - q15_t centre = (posThresh + negThresh) >> 1; - - q15_t threshold = posThresh - centre; - - DEBUG5("NXDNRX: pos/neg/centre/threshold", posThresh, negThresh, centre, threshold); - - if (m_averagePtr == NOAVEPTR) { - for (uint8_t i = 0U; i < 16U; i++) { - m_centre[i] = centre; - m_threshold[i] = threshold; - } - - m_averagePtr = 0U; - } else { - m_centre[m_averagePtr] = centre; - m_threshold[m_averagePtr] = threshold; - - m_averagePtr++; - if (m_averagePtr >= 16U) - m_averagePtr = 0U; - } - - m_centreVal = 0; - m_thresholdVal = 0; - - for (uint8_t i = 0U; i < 16U; i++) { - m_centreVal += m_centre[i]; - m_thresholdVal += m_threshold[i]; - } - - m_centreVal >>= 4; - m_thresholdVal >>= 4; -} - -void CNXDNRX::samplesToBits(uint16_t start, uint16_t count, uint8_t* buffer, uint16_t offset, q15_t centre, q15_t threshold) -{ - for (uint16_t i = 0U; i < count; i++) { - q15_t sample = m_buffer[start] - centre; - - if (sample < -threshold) { - WRITE_BIT1(buffer, offset, false); - offset++; - WRITE_BIT1(buffer, offset, true); - offset++; - } else if (sample < 0) { - WRITE_BIT1(buffer, offset, false); - offset++; - WRITE_BIT1(buffer, offset, false); - offset++; - } else if (sample < threshold) { - WRITE_BIT1(buffer, offset, true); - offset++; - WRITE_BIT1(buffer, offset, false); - offset++; - } else { - WRITE_BIT1(buffer, offset, true); - offset++; - WRITE_BIT1(buffer, offset, true); - offset++; - } - - start += NXDN_RADIO_SYMBOL_LENGTH; - if (start >= NXDN_FRAME_LENGTH_SAMPLES) - start -= NXDN_FRAME_LENGTH_SAMPLES; - } -} - -void CNXDNRX::writeRSSIData(uint8_t* data) -{ -#if defined(SEND_RSSI_DATA) - if (m_rssiCount > 0U) { - uint16_t rssi = m_rssiAccum / m_rssiCount; - - data[49U] = (rssi >> 8) & 0xFFU; - data[50U] = (rssi >> 0) & 0xFFU; - - serial.writeNXDNData(data, NXDN_FRAME_LENGTH_BYTES + 3U); - } else { - serial.writeNXDNData(data, NXDN_FRAME_LENGTH_BYTES + 1U); - } -#else - serial.writeNXDNData(data, NXDN_FRAME_LENGTH_BYTES + 1U); -#endif - - m_rssiAccum = 0U; - m_rssiCount = 0U; -} - diff --git a/NXDN96RX.h b/NXDN96RX.h deleted file mode 100644 index 1bff2ac..0000000 --- a/NXDN96RX.h +++ /dev/null @@ -1,69 +0,0 @@ -/* - * Copyright (C) 2015,2016,2017,2018 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(NXDNRX_H) -#define NXDNRX_H - -#include "Config.h" -#include "NXDNDefines.h" - -enum NXDNRX_STATE { - NXDNRXS_NONE, - NXDNRXS_DATA -}; - -class CNXDNRX { -public: - CNXDNRX(); - - void samples(const q15_t* samples, uint16_t* rssi, uint8_t length); - - void reset(); - -private: - NXDNRX_STATE m_state; - uint16_t m_bitBuffer[NXDN_RADIO_SYMBOL_LENGTH]; - q15_t m_buffer[NXDN_FRAME_LENGTH_SAMPLES]; - uint16_t m_bitPtr; - uint16_t m_dataPtr; - uint16_t m_startPtr; - uint16_t m_endPtr; - uint16_t m_fswPtr; - uint16_t m_minFSWPtr; - uint16_t m_maxFSWPtr; - q31_t m_maxCorr; - uint16_t m_lostCount; - uint8_t m_countdown; - q15_t m_centre[16U]; - q15_t m_centreVal; - q15_t m_threshold[16U]; - q15_t m_thresholdVal; - uint8_t m_averagePtr; - uint32_t m_rssiAccum; - uint16_t m_rssiCount; - - void processNone(q15_t sample); - void processData(q15_t sample); - bool correlateFSW(); - void calculateLevels(uint16_t start, uint16_t count); - void samplesToBits(uint16_t start, uint16_t count, uint8_t* buffer, uint16_t offset, q15_t centre, q15_t threshold); - void writeRSSIData(uint8_t* data); -}; - -#endif - diff --git a/NXDN96TX.cpp b/NXDN96TX.cpp deleted file mode 100644 index 16e6d55..0000000 --- a/NXDN96TX.cpp +++ /dev/null @@ -1,153 +0,0 @@ -/* - * Copyright (C) 2009-2018 by Jonathan Naylor G4KLX - * Copyright (C) 2017 by Andy Uribe CA6JAU - * - * 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 "NXDNTX.h" - -#include "NXDNDefines.h" - -// Generated using rcosdesign(0.2, 8, 5, 'sqrt') in MATLAB -static q15_t RRC_0_2_FILTER[] = {0, 0, 0, 0, 850, 219, -720, -1548, -1795, -1172, 237, 1927, 3120, 3073, 1447, -1431, -4544, -6442, - -5735, -1633, 5651, 14822, 23810, 30367, 32767, 30367, 23810, 14822, 5651, -1633, -5735, -6442, - -4544, -1431, 1447, 3073, 3120, 1927, 237, -1172, -1795, -1548, -720, 219, 850}; // numTaps = 45, L = 5 -const uint16_t RRC_0_2_FILTER_PHASE_LEN = 9U; // phaseLength = numTaps/L - -const q15_t NXDN_LEVELA = 1680; -const q15_t NXDN_LEVELB = 560; -const q15_t NXDN_LEVELC = -560; -const q15_t NXDN_LEVELD = -1680; - -const uint8_t NXDN_PREAMBLE[] = {0x57U, 0x75U, 0xFDU}; -const uint8_t NXDN_SYNC = 0x5FU; - -CNXDNTX::CNXDNTX() : -m_buffer(1500U), -m_modFilter(), -m_modState(), -m_poBuffer(), -m_poLen(0U), -m_poPtr(0U), -m_txDelay(240U) // 200ms -{ - ::memset(m_modState, 0x00U, 16U * sizeof(q15_t)); - - m_modFilter.L = NXDN_RADIO_SYMBOL_LENGTH; - m_modFilter.phaseLength = RRC_0_2_FILTER_PHASE_LEN; - m_modFilter.pCoeffs = RRC_0_2_FILTER; - m_modFilter.pState = m_modState; -} - -void CNXDNTX::process() -{ - if (m_buffer.getData() == 0U && m_poLen == 0U) - return; - - if (m_poLen == 0U) { - if (!m_tx) { - for (uint16_t i = 0U; i < m_txDelay; i++) - m_poBuffer[m_poLen++] = NXDN_SYNC; - m_poBuffer[m_poLen++] = NXDN_PREAMBLE[0U]; - m_poBuffer[m_poLen++] = NXDN_PREAMBLE[1U]; - m_poBuffer[m_poLen++] = NXDN_PREAMBLE[2U]; - } else { - for (uint8_t i = 0U; i < NXDN_FRAME_LENGTH_BYTES; i++) { - uint8_t c = m_buffer.get(); - m_poBuffer[m_poLen++] = c; - } - } - - m_poPtr = 0U; - } - - if (m_poLen > 0U) { - uint16_t space = io.getSpace(); - - while (space > (4U * NXDN_RADIO_SYMBOL_LENGTH)) { - uint8_t c = m_poBuffer[m_poPtr++]; - writeByte(c); - - space -= 4U * NXDN_RADIO_SYMBOL_LENGTH; - - if (m_poPtr >= m_poLen) { - m_poPtr = 0U; - m_poLen = 0U; - return; - } - } - } -} - -uint8_t CNXDNTX::writeData(const uint8_t* data, uint8_t length) -{ - if (length != (NXDN_FRAME_LENGTH_BYTES + 1U)) - return 4U; - - uint16_t space = m_buffer.getSpace(); - if (space < NXDN_FRAME_LENGTH_BYTES) - return 5U; - - for (uint8_t i = 0U; i < NXDN_FRAME_LENGTH_BYTES; i++) - m_buffer.put(data[i + 1U]); - - return 0U; -} - -void CNXDNTX::writeByte(uint8_t c) -{ - q15_t inBuffer[4U]; - q15_t outBuffer[NXDN_RADIO_SYMBOL_LENGTH * 4U]; - - const uint8_t MASK = 0xC0U; - - for (uint8_t i = 0U; i < 4U; i++, c <<= 2) { - switch (c & MASK) { - case 0xC0U: - inBuffer[i] = NXDN_LEVELA; - break; - case 0x80U: - inBuffer[i] = NXDN_LEVELB; - break; - case 0x00U: - inBuffer[i] = NXDN_LEVELC; - break; - default: - inBuffer[i] = NXDN_LEVELD; - break; - } - } - - ::arm_fir_interpolate_q15(&m_modFilter, inBuffer, outBuffer, 4U); - - io.write(STATE_NXDN, outBuffer, NXDN_RADIO_SYMBOL_LENGTH * 4U); -} - -void CNXDNTX::setTXDelay(uint8_t delay) -{ - m_txDelay = 600U + uint16_t(delay) * 12U; // 500ms + tx delay - - if (m_txDelay > 1200U) - m_txDelay = 1200U; -} - -uint8_t CNXDNTX::getSpace() const -{ - return m_buffer.getSpace() / YSF_FRAME_LENGTH_BYTES; -} - diff --git a/NXDN96TX.h b/NXDN96TX.h deleted file mode 100644 index f98cf48..0000000 --- a/NXDN96TX.h +++ /dev/null @@ -1,51 +0,0 @@ -/* - * Copyright (C) 2015,2016,2017,2018 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(NXDNTX_H) -#define NXDNTX_H - -#include "Config.h" - -#include "SerialRB.h" - -class CNXDNTX { -public: - CNXDNTX(); - - uint8_t writeData(const uint8_t* data, uint8_t length); - - void process(); - - void setTXDelay(uint8_t delay); - - uint8_t getSpace() const; - -private: - CSerialRB m_buffer; - arm_fir_interpolate_instance_q15 m_modFilter; - q15_t m_modState[16U]; // blockSize + phaseLength - 1, 4 + 9 - 1 plus some spare - uint8_t m_poBuffer[1200U]; - uint16_t m_poLen; - uint16_t m_poPtr; - uint16_t m_txDelay; - - void writeByte(uint8_t c); -}; - -#endif - diff --git a/NXDN48RX.cpp b/NXDNRX.cpp similarity index 100% rename from NXDN48RX.cpp rename to NXDNRX.cpp diff --git a/NXDN48RX.h b/NXDNRX.h similarity index 100% rename from NXDN48RX.h rename to NXDNRX.h diff --git a/NXDN48TX.cpp b/NXDNTX.cpp similarity index 100% rename from NXDN48TX.cpp rename to NXDNTX.cpp diff --git a/NXDN48TX.h b/NXDNTX.h similarity index 100% rename from NXDN48TX.h rename to NXDNTX.h