diff --git a/.gitignore b/.gitignore index 46b5953..64deba0 100644 --- a/.gitignore +++ b/.gitignore @@ -2,3 +2,5 @@ obj/ bin/ STM32F4XX_Lib/ +GitVersion.h +build/ diff --git a/CWIdTX.cpp b/CWIdTX.cpp index 0613772..189e774 100644 --- a/CWIdTX.cpp +++ b/CWIdTX.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2009-2015 by Jonathan Naylor G4KLX + * Copyright (C) 2009-2017 by Jonathan Naylor G4KLX * Copyright (C) 2016 by Colin Durbridge G4EML * * This program is free software; you can redistribute it and/or modify @@ -17,8 +17,6 @@ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -// #define WANT_DEBUG - #include "Config.h" #include "Globals.h" #include "CWIdTX.h" @@ -77,6 +75,8 @@ const struct { {'/', 0xEAE80000U, 16U}, {'?', 0xAEEA0000U, 18U}, {',', 0xEEAEE000U, 22U}, + {'-', 0xEAAE0000U, 18U}, + {'=', 0xEAB80000U, 16U}, {' ', 0x00000000U, 4U}, {0U, 0x00000000U, 0U} }; diff --git a/Config.h b/Config.h index 78ef5d8..c7fb2b8 100644 --- a/Config.h +++ b/Config.h @@ -60,11 +60,6 @@ // Use separate mode pins to switch external filters/bandwidth for example // #define STM32F4_NUCLEO_MODE_PINS -// To use wider C4FSK filters for DMR, System Fusion and P25 on transmit -// #define WIDE_C4FSK_FILTERS_TX -// To use wider C4FSK filters for DMR, System Fusion and P25 on receive -// #define WIDE_C4FSK_FILTERS_RX - // Pass RSSI information to the host // #define SEND_RSSI_DATA diff --git a/DMRDMORX.cpp b/DMRDMORX.cpp index dffda63..2c3bdef 100644 --- a/DMRDMORX.cpp +++ b/DMRDMORX.cpp @@ -16,10 +16,6 @@ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -#define WANT_DEBUG - -// #define DUMP_SAMPLES - #include "Config.h" #include "Globals.h" #include "DMRDMORX.h" @@ -147,9 +143,6 @@ bool CDMRDMORX::processSample(q15_t sample, uint16_t rssi) case DT_DATA_HEADER: DEBUG4("DMRDMORX: data header found pos/centre/threshold", m_syncPtr, centre, threshold); writeRSSIData(frame); -#if defined(DUMP_SAMPLES) - writeSamples(ptr, frame[0U]); -#endif m_state = DMORXS_DATA; m_type = 0x00U; break; @@ -159,27 +152,18 @@ bool CDMRDMORX::processSample(q15_t sample, uint16_t rssi) if (m_state == DMORXS_DATA) { DEBUG4("DMRDMORX: data payload found pos/centre/threshold", m_syncPtr, centre, threshold); writeRSSIData(frame); -#if defined(DUMP_SAMPLES) - writeSamples(ptr, frame[0U]); -#endif m_type = dataType; } break; case DT_VOICE_LC_HEADER: DEBUG4("DMRDMORX: voice header found pos/centre/threshold", m_syncPtr, centre, threshold); writeRSSIData(frame); -#if defined(DUMP_SAMPLES) - writeSamples(ptr, frame[0U]); -#endif m_state = DMORXS_VOICE; break; case DT_VOICE_PI_HEADER: if (m_state == DMORXS_VOICE) { DEBUG4("DMRDMORX: voice pi header found pos/centre/threshold", m_syncPtr, centre, threshold); writeRSSIData(frame); -#if defined(DUMP_SAMPLES) - writeSamples(ptr, frame[0U]); -#endif } m_state = DMORXS_VOICE; break; @@ -187,18 +171,12 @@ bool CDMRDMORX::processSample(q15_t sample, uint16_t rssi) if (m_state == DMORXS_VOICE) { DEBUG4("DMRDMORX: voice terminator found pos/centre/threshold", m_syncPtr, centre, threshold); writeRSSIData(frame); -#if defined(DUMP_SAMPLES) - writeSamples(ptr, frame[0U]); -#endif reset(); } break; default: // DT_CSBK DEBUG4("DMRDMORX: csbk found pos/centre/threshold", m_syncPtr, centre, threshold); writeRSSIData(frame); -#if defined(DUMP_SAMPLES) - writeSamples(ptr, frame[0U]); -#endif reset(); break; } @@ -207,9 +185,6 @@ bool CDMRDMORX::processSample(q15_t sample, uint16_t rssi) // Voice sync DEBUG4("DMRDMORX: voice sync found pos/centre/threshold", m_syncPtr, centre, threshold); writeRSSIData(frame); -#if defined(DUMP_SAMPLES) - writeSamples(ptr, frame[0U]); -#endif m_state = DMORXS_VOICE; m_syncCount = 0U; m_n = 0U; @@ -231,16 +206,10 @@ bool CDMRDMORX::processSample(q15_t sample, uint16_t rssi) } serial.writeDMRData(true, frame, DMR_FRAME_LENGTH_BYTES + 1U); -#if defined(DUMP_SAMPLES) - writeSamples(ptr, frame[0U]); -#endif } else if (m_state == DMORXS_DATA) { if (m_type != 0x00U) { frame[0U] = CONTROL_DATA | m_type; writeRSSIData(frame); -#if defined(DUMP_SAMPLES) - writeSamples(ptr, frame[0U]); -#endif } } } @@ -454,20 +423,3 @@ void CDMRDMORX::writeRSSIData(uint8_t* frame) serial.writeDMRData(true, frame, DMR_FRAME_LENGTH_BYTES + 1U); #endif } - -#if defined(DUMP_SAMPLES) -void CDMRDMORX::writeSamples(uint16_t start, uint8_t control) -{ - q15_t samples[DMR_FRAME_LENGTH_SYMBOLS]; - - for (uint16_t i = 0U; i < DMR_FRAME_LENGTH_SYMBOLS; i++) { - samples[i] = m_buffer[start]; - - start += DMR_RADIO_SYMBOL_LENGTH; - if (start >= DMO_BUFFER_LENGTH_SAMPLES) - start -= DMO_BUFFER_LENGTH_SAMPLES; - } - - serial.writeSamples(STATE_DMR, control, samples, DMR_FRAME_LENGTH_SYMBOLS); -} -#endif diff --git a/DMRDMORX.h b/DMRDMORX.h index 0b20764..6952fd4 100644 --- a/DMRDMORX.h +++ b/DMRDMORX.h @@ -64,7 +64,6 @@ private: void correlateSync(bool first); void samplesToBits(uint16_t start, uint8_t count, uint8_t* buffer, uint16_t offset, q15_t centre, q15_t threshold); void writeRSSIData(uint8_t* frame); - void writeSamples(uint16_t start, uint8_t control); }; #endif diff --git a/DMRDMOTX.cpp b/DMRDMOTX.cpp index 476fd42..fe64db6 100644 --- a/DMRDMOTX.cpp +++ b/DMRDMOTX.cpp @@ -1,6 +1,7 @@ /* * Copyright (C) 2009-2017 by Jonathan Naylor G4KLX * Copyright (C) 2016 by Colin Durbridge G4EML + * 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 @@ -17,31 +18,22 @@ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -// #define WANT_DEBUG - #include "Config.h" #include "Globals.h" #include "DMRSlotType.h" -#if defined(WIDE_C4FSK_FILTERS_TX) -// Generated using rcosdesign(0.2, 4, 5, 'sqrt') in MATLAB -static q15_t DMR_C4FSK_FILTER[] = {0, 0, 0, 0, 688, -680, -2158, -3060, -2724, -775, 2684, 7041, 11310, 14425, 15565, 14425, - 11310, 7041, 2684, -775, -2724, -3060, -2158, -680, 688}; // numTaps = 25, L = 5 -const uint16_t DMR_C4FSK_FILTER_PHASE_LEN = 5U; // phaseLength = numTaps/L -#else // Generated using rcosdesign(0.2, 8, 5, 'sqrt') in MATLAB -static q15_t DMR_C4FSK_FILTER[] = {0, 0, 0, 0, 401, 104, -340, -731, -847, -553, 112, 909, 1472, 1450, 683, -675, -2144, -3040, -2706, -770, 2667, 6995, +static q15_t RRC_0_2_FILTER[] = {0, 0, 0, 0, 401, 104, -340, -731, -847, -553, 112, 909, 1472, 1450, 683, -675, -2144, -3040, -2706, -770, 2667, 6995, 11237, 14331, 15464, 14331, 11237, 6995, 2667, -770, -2706, -3040, -2144, -675, 683, 1450, 1472, 909, 112, -553, -847, -731, -340, 104, 401}; // numTaps = 45, L = 5 -const uint16_t DMR_C4FSK_FILTER_PHASE_LEN = 9U; // phaseLength = numTaps/L -#endif +const uint16_t RRC_0_2_FILTER_PHASE_LEN = 9U; // phaseLength = numTaps/L const q15_t DMR_LEVELA = 2889; const q15_t DMR_LEVELB = 963; const q15_t DMR_LEVELC = -963; const q15_t DMR_LEVELD = -2889; -// The PR FILL and Data Sync pattern. +// The PR FILL and BS Data Sync pattern. const uint8_t IDLE_DATA[] = {0x53U, 0xC2U, 0x5EU, 0xABU, 0xA8U, 0x67U, 0x1DU, 0xC7U, 0x38U, 0x3BU, 0xD9U, 0x36U, 0x00U, 0x0DU, 0xFFU, 0x57U, 0xD7U, 0x5DU, 0xF5U, 0xD0U, 0x03U, 0xF6U, @@ -76,10 +68,10 @@ m_cachPtr(0U) { ::memset(m_modState, 0x00U, 16U * sizeof(q15_t)); - m_modFilter.L = DMR_RADIO_SYMBOL_LENGTH; - m_modFilter.phaseLength = DMR_C4FSK_FILTER_PHASE_LEN; - m_modFilter.pCoeffs = DMR_C4FSK_FILTER; - m_modFilter.pState = m_modState; + m_modFilter.L = DMR_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 CDMRDMOTX::process() diff --git a/DMRIdleRX.cpp b/DMRIdleRX.cpp index 8296c03..3d2b5f5 100644 --- a/DMRIdleRX.cpp +++ b/DMRIdleRX.cpp @@ -16,10 +16,6 @@ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -#define WANT_DEBUG - -// #define DUMP_SAMPLES - #include "Config.h" #include "Globals.h" #include "DMRIdleRX.h" @@ -161,9 +157,6 @@ void CDMRIdleRX::processSample(q15_t sample) if (colorCode == m_colorCode && dataType == DT_CSBK) { frame[0U] = CONTROL_IDLE | CONTROL_DATA | DT_CSBK; serial.writeDMRData(false, frame, DMR_FRAME_LENGTH_BYTES + 1U); -#if defined(DUMP_SAMPLES) - writeSamples(ptr, frame[0U]); -#endif } m_endPtr = NOENDPTR; @@ -216,20 +209,3 @@ void CDMRIdleRX::setColorCode(uint8_t colorCode) { m_colorCode = colorCode; } - -#if defined(DUMP_SAMPLES) -void CDMRIdleRX::writeSamples(uint16_t start, uint8_t control) -{ - q15_t samples[DMR_FRAME_LENGTH_SYMBOLS]; - - for (uint16_t i = 0U; i < DMR_FRAME_LENGTH_SYMBOLS; i++) { - samples[i] = m_buffer[start]; - - start += DMR_RADIO_SYMBOL_LENGTH; - if (start >= DMR_FRAME_LENGTH_SAMPLES) - start -= DMR_FRAME_LENGTH_SAMPLES; - } - - serial.writeSamples(STATE_DMR, control, samples, DMR_FRAME_LENGTH_SYMBOLS); -} -#endif diff --git a/DMRIdleRX.h b/DMRIdleRX.h index 79be1b7..922ea85 100644 --- a/DMRIdleRX.h +++ b/DMRIdleRX.h @@ -45,7 +45,6 @@ private: void processSample(q15_t sample); void samplesToBits(uint16_t start, uint8_t count, uint8_t* buffer, uint16_t offset, q15_t centre, q15_t threshold); - void writeSamples(uint16_t start, uint8_t control); }; #endif diff --git a/DMRSlotRX.cpp b/DMRSlotRX.cpp index a86f9b9..0d34560 100644 --- a/DMRSlotRX.cpp +++ b/DMRSlotRX.cpp @@ -16,10 +16,6 @@ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -#define WANT_DEBUG - -// #define DUMP_SAMPLES - #include "Config.h" #include "Globals.h" #include "DMRSlotRX.h" @@ -150,9 +146,6 @@ bool CDMRSlotRX::processSample(q15_t sample, uint16_t rssi) case DT_DATA_HEADER: DEBUG5("DMRSlotRX: data header found slot/pos/centre/threshold", m_slot ? 2U : 1U, m_syncPtr, centre, threshold); writeRSSIData(frame); -#if defined(DUMP_SAMPLES) - writeSamples(ptr, frame[0U]); -#endif m_state = DMRRXS_DATA; m_type = 0x00U; break; @@ -162,27 +155,18 @@ bool CDMRSlotRX::processSample(q15_t sample, uint16_t rssi) if (m_state == DMRRXS_DATA) { DEBUG5("DMRSlotRX: data payload found slot/pos/centre/threshold", m_slot ? 2U : 1U, m_syncPtr, centre, threshold); writeRSSIData(frame); -#if defined(DUMP_SAMPLES) - writeSamples(ptr, frame[0U]); -#endif m_type = dataType; } break; case DT_VOICE_LC_HEADER: DEBUG5("DMRSlotRX: voice header found slot/pos/centre/threshold", m_slot ? 2U : 1U, m_syncPtr, centre, threshold); writeRSSIData(frame); -#if defined(DUMP_SAMPLES) - writeSamples(ptr, frame[0U]); -#endif m_state = DMRRXS_VOICE; break; case DT_VOICE_PI_HEADER: if (m_state == DMRRXS_VOICE) { DEBUG5("DMRSlotRX: voice pi header found slot/pos/centre/threshold", m_slot ? 2U : 1U, m_syncPtr, centre, threshold); writeRSSIData(frame); -#if defined(DUMP_SAMPLES) - writeSamples(ptr, frame[0U]); -#endif } m_state = DMRRXS_VOICE; break; @@ -190,9 +174,6 @@ bool CDMRSlotRX::processSample(q15_t sample, uint16_t rssi) if (m_state == DMRRXS_VOICE) { DEBUG5("DMRSlotRX: voice terminator found slot/pos/centre/threshold", m_slot ? 2U : 1U, m_syncPtr, centre, threshold); writeRSSIData(frame); -#if defined(DUMP_SAMPLES) - writeSamples(ptr, frame[0U]); -#endif m_state = DMRRXS_NONE; m_endPtr = NOENDPTR; } @@ -200,9 +181,6 @@ bool CDMRSlotRX::processSample(q15_t sample, uint16_t rssi) default: // DT_CSBK DEBUG5("DMRSlotRX: csbk found slot/pos/centre/threshold", m_slot ? 2U : 1U, m_syncPtr, centre, threshold); writeRSSIData(frame); -#if defined(DUMP_SAMPLES) - writeSamples(ptr, frame[0U]); -#endif m_state = DMRRXS_NONE; m_endPtr = NOENDPTR; break; @@ -212,9 +190,6 @@ bool CDMRSlotRX::processSample(q15_t sample, uint16_t rssi) // Voice sync DEBUG5("DMRSlotRX: voice sync found slot/pos/centre/threshold", m_slot ? 2U : 1U, m_syncPtr, centre, threshold); writeRSSIData(frame); -#if defined(DUMP_SAMPLES) - writeSamples(ptr, frame[0U]); -#endif m_state = DMRRXS_VOICE; m_syncCount = 0U; m_n = 0U; @@ -237,16 +212,10 @@ bool CDMRSlotRX::processSample(q15_t sample, uint16_t rssi) } serial.writeDMRData(m_slot, frame, DMR_FRAME_LENGTH_BYTES + 1U); -#if defined(DUMP_SAMPLES) - writeSamples(ptr, frame[0U]); -#endif } else if (m_state == DMRRXS_DATA) { if (m_type != 0x00U) { frame[0U] = CONTROL_DATA | m_type; writeRSSIData(frame); -#if defined(DUMP_SAMPLES) - writeSamples(ptr, frame[0U]); -#endif } } } @@ -431,17 +400,3 @@ void CDMRSlotRX::writeRSSIData(uint8_t* frame) serial.writeDMRData(m_slot, frame, DMR_FRAME_LENGTH_BYTES + 1U); #endif } - -#if defined(DUMP_SAMPLES) -void CDMRSlotRX::writeSamples(uint16_t start, uint8_t control) -{ - q15_t samples[DMR_FRAME_LENGTH_SYMBOLS]; - - for (uint16_t i = 0U; i < DMR_FRAME_LENGTH_SYMBOLS; i++) { - samples[i] = m_buffer[start]; - start += DMR_RADIO_SYMBOL_LENGTH; - } - - serial.writeSamples(STATE_DMR, control, samples, DMR_FRAME_LENGTH_SYMBOLS); -} -#endif diff --git a/DMRSlotRX.h b/DMRSlotRX.h index 858f223..a47cc73 100644 --- a/DMRSlotRX.h +++ b/DMRSlotRX.h @@ -67,7 +67,6 @@ private: void correlateSync(bool first); void samplesToBits(uint16_t start, uint8_t count, uint8_t* buffer, uint16_t offset, q15_t centre, q15_t threshold); void writeRSSIData(uint8_t* frame); - void writeSamples(uint16_t start, uint8_t control); }; #endif diff --git a/DMRTX.cpp b/DMRTX.cpp index e3568e4..e202a3f 100644 --- a/DMRTX.cpp +++ b/DMRTX.cpp @@ -1,6 +1,7 @@ /* * Copyright (C) 2009-2017 by Jonathan Naylor G4KLX * Copyright (C) 2016 by Colin Durbridge G4EML + * 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 @@ -17,31 +18,22 @@ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -// #define WANT_DEBUG - #include "Config.h" #include "Globals.h" #include "DMRSlotType.h" -#if defined(WIDE_C4FSK_FILTERS_TX) -// Generated using rcosdesign(0.2, 4, 5, 'sqrt') in MATLAB -static q15_t DMR_C4FSK_FILTER[] = {0, 0, 0, 0, 688, -680, -2158, -3060, -2724, -775, 2684, 7041, 11310, 14425, 15565, 14425, - 11310, 7041, 2684, -775, -2724, -3060, -2158, -680, 688}; // numTaps = 25, L = 5 -const uint16_t DMR_C4FSK_FILTER_PHASE_LEN = 5U; // phaseLength = numTaps/L -#else // Generated using rcosdesign(0.2, 8, 5, 'sqrt') in MATLAB -static q15_t DMR_C4FSK_FILTER[] = {0, 0, 0, 0, 401, 104, -340, -731, -847, -553, 112, 909, 1472, 1450, 683, -675, -2144, -3040, -2706, -770, 2667, 6995, +static q15_t RRC_0_2_FILTER[] = {0, 0, 0, 0, 401, 104, -340, -731, -847, -553, 112, 909, 1472, 1450, 683, -675, -2144, -3040, -2706, -770, 2667, 6995, 11237, 14331, 15464, 14331, 11237, 6995, 2667, -770, -2706, -3040, -2144, -675, 683, 1450, 1472, 909, 112, -553, -847, -731, -340, 104, 401}; // numTaps = 45, L = 5 -const uint16_t DMR_C4FSK_FILTER_PHASE_LEN = 9U; // phaseLength = numTaps/L -#endif +const uint16_t RRC_0_2_FILTER_PHASE_LEN = 9U; // phaseLength = numTaps/L const q15_t DMR_LEVELA = 2889; const q15_t DMR_LEVELB = 963; const q15_t DMR_LEVELC = -963; const q15_t DMR_LEVELD = -2889; -// The PR FILL and Data Sync pattern. +// The PR FILL and BS Data Sync pattern. const uint8_t IDLE_DATA[] = {0x53U, 0xC2U, 0x5EU, 0xABU, 0xA8U, 0x67U, 0x1DU, 0xC7U, 0x38U, 0x3BU, 0xD9U, 0x36U, 0x00U, 0x0DU, 0xFFU, 0x57U, 0xD7U, 0x5DU, 0xF5U, 0xD0U, 0x03U, 0xF6U, @@ -81,10 +73,10 @@ m_abort() { ::memset(m_modState, 0x00U, 16U * sizeof(q15_t)); - m_modFilter.L = DMR_RADIO_SYMBOL_LENGTH; - m_modFilter.phaseLength = DMR_C4FSK_FILTER_PHASE_LEN; - m_modFilter.pCoeffs = DMR_C4FSK_FILTER; - m_modFilter.pState = m_modState; + m_modFilter.L = DMR_RADIO_SYMBOL_LENGTH; + m_modFilter.phaseLength = RRC_0_2_FILTER_PHASE_LEN; + m_modFilter.pCoeffs = RRC_0_2_FILTER; + m_modFilter.pState = m_modState; ::memcpy(m_newShortLC, EMPTY_SHORT_LC, 12U); ::memcpy(m_shortLC, EMPTY_SHORT_LC, 12U); diff --git a/DStarRX.cpp b/DStarRX.cpp index d4178c0..6c4f342 100644 --- a/DStarRX.cpp +++ b/DStarRX.cpp @@ -1,5 +1,6 @@ /* * Copyright (C) 2009-2017 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 @@ -16,8 +17,6 @@ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -// #define WANT_DEBUG - #include "Config.h" #include "Globals.h" #include "DStarRX.h" @@ -35,9 +34,9 @@ const unsigned int SYNC_POS = 21U * DSTAR_DATA_LENGTH_BITS; const unsigned int SYNC_SCAN_START = SYNC_POS - 3U; const unsigned int SYNC_SCAN_END = SYNC_POS + 3U; -// Generated using [b, a] = butter(1, 0.002) in MATLAB -static q15_t DC_FILTER[] = {103, 0, 103, 0, 32563, 0}; // {b0, 0, b1, b2, -a1, -a2} -const uint16_t DC_FILTER_STAGES = 1U; // One Biquad stage +// Generated using [b, a] = butter(1, 0.001) in MATLAB +static q31_t DC_FILTER[] = {3367972, 0, 3367972, 0, 2140747704, 0}; // {b0, 0, b1, b2, -a1, -a2} +const uint32_t DC_FILTER_STAGES = 1U; // One Biquad stage // D-Star bit order version of 0x55 0x55 0x6E 0x0A const uint32_t FRAME_SYNC_DATA = 0x00557650U; @@ -262,14 +261,16 @@ m_pathMemory2(), m_pathMemory3(), m_fecOutput(), m_rssiAccum(0U), -m_rssiCount(0U) +m_rssiCount(0U), +m_dcFilter(), +m_dcState() { - ::memset(m_DCState, 0x00U, 4U * sizeof(q15_t)); + ::memset(m_dcState, 0x00U, 4U * sizeof(q31_t)); - m_DCFilter.numStages = DC_FILTER_STAGES; - m_DCFilter.pState = m_DCState; - m_DCFilter.pCoeffs = DC_FILTER; - m_DCFilter.postShift = 0; + m_dcFilter.numStages = DC_FILTER_STAGES; + m_dcFilter.pState = m_dcState; + m_dcFilter.pCoeffs = DC_FILTER; + m_dcFilter.postShift = 0; } void CDStarRX::reset() @@ -287,12 +288,14 @@ void CDStarRX::reset() void CDStarRX::samples(const q15_t* samples, const uint16_t* rssi, uint8_t length) { q31_t dc_level = 0; - q15_t DCVals[20]; + q31_t dcVals[20]; + q31_t intSamp[20]; - ::arm_biquad_cascade_df1_q15(&m_DCFilter, (q15_t*)samples, DCVals, length); + ::arm_q15_to_q31((q15_t*)samples, intSamp, length); + ::arm_biquad_cascade_df1_q31(&m_dcFilter, intSamp, dcVals, length); for (uint8_t i = 0U; i < length; i++) - dc_level += (q31_t)DCVals[i]; + dc_level += dcVals[i]; dc_level /= length; @@ -300,7 +303,7 @@ void CDStarRX::samples(const q15_t* samples, const uint16_t* rssi, uint8_t lengt m_rssiAccum += rssi[i]; m_rssiCount++; - bool bit = samples[i] < (q15_t)dc_level; + bool bit = samples[i] < (q15_t) (dc_level >> 16); if (bit != m_prev) { if (m_pll < (PLLMAX / 2U)) @@ -434,12 +437,11 @@ void CDStarRX::processData(bool bit) bool syncSeen = false; if (m_dataBits >= SYNC_SCAN_START && m_dataBits <= (SYNC_POS + 1U)) { if (countBits32((m_patternBuffer & DATA_SYNC_MASK) ^ DATA_SYNC_DATA) <= DATA_SYNC_ERRS) { -#if defined(WANT_DEBUG) if (m_dataBits < SYNC_POS) DEBUG2("DStarRX: found data sync in Data, early", SYNC_POS - m_dataBits); else DEBUG1("DStarRX: found data sync in Data"); -#endif + m_rxBufferBits = DSTAR_DATA_LENGTH_BITS; m_dataBits = 0U; syncSeen = true; diff --git a/DStarRX.h b/DStarRX.h index b374b44..157fb41 100644 --- a/DStarRX.h +++ b/DStarRX.h @@ -53,9 +53,8 @@ private: uint8_t m_fecOutput[42U]; uint32_t m_rssiAccum; uint16_t m_rssiCount; - - arm_biquad_casd_df1_inst_q15 m_DCFilter; - q15_t m_DCState[4]; + arm_biquad_casd_df1_inst_q31 m_dcFilter; + q31_t m_dcState[4]; void processNone(bool bit); void processHeader(bool bit); diff --git a/DStarTX.cpp b/DStarTX.cpp index 5ba86cb..4ed0bf6 100644 --- a/DStarTX.cpp +++ b/DStarTX.cpp @@ -1,5 +1,6 @@ /* * Copyright (C) 2009-2017 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 @@ -16,8 +17,6 @@ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -#define WANT_DEBUG - #include "Config.h" #include "Globals.h" #include "DStarTX.h" @@ -29,8 +28,8 @@ const uint8_t BIT_SYNC = 0xAAU; const uint8_t FRAME_SYNC[] = {0xEAU, 0xA6U, 0x00U}; // Generated using gaussfir(0.35, 1, 5) in MATLAB -static q15_t DSTAR_GMSK_FILTER[] = {0, 0, 0, 0, 212, 743, 1974, 3965, 6026, 6929, 6026, 3965, 1974, 743, 212}; // numTaps = 15, L = 5 -const uint16_t DSTAR_GMSK_FILTER_PHASE_LEN = 3U; // phaseLength = numTaps/L +static q15_t GAUSSIAN_0_35_FILTER[] = {0, 0, 0, 0, 212, 743, 1974, 3965, 6026, 6929, 6026, 3965, 1974, 743, 212}; // numTaps = 15, L = 5 +const uint16_t GAUSSIAN_0_35_FILTER_PHASE_LEN = 3U; // phaseLength = numTaps/L const q15_t DSTAR_LEVEL0 = -4000; const q15_t DSTAR_LEVEL1 = 4000; @@ -199,10 +198,10 @@ m_txDelay(60U) // 100ms { ::memset(m_modState, 0x00U, 20U * sizeof(q15_t)); - m_modFilter.L = DSTAR_RADIO_BIT_LENGTH; - m_modFilter.phaseLength = DSTAR_GMSK_FILTER_PHASE_LEN; - m_modFilter.pCoeffs = DSTAR_GMSK_FILTER; - m_modFilter.pState = m_modState; + m_modFilter.L = DSTAR_RADIO_BIT_LENGTH; + m_modFilter.phaseLength = GAUSSIAN_0_35_FILTER_PHASE_LEN; + m_modFilter.pCoeffs = GAUSSIAN_0_35_FILTER; + m_modFilter.pState = m_modState; } void CDStarTX::process() diff --git a/Debug.h b/Debug.h index 667856d..e8be149 100644 --- a/Debug.h +++ b/Debug.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2015,2016 by Jonathan Naylor G4KLX + * Copyright (C) 2015,2016,2017 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 @@ -20,9 +20,6 @@ #define DEBUG_H #include "Config.h" - -#if defined(WANT_DEBUG) - #include "Globals.h" #define DEBUG1(a) serial.writeDebug((a)) @@ -32,16 +29,5 @@ #define DEBUG5(a,b,c,d,e) serial.writeDebug((a),(b),(c),(d),(e)) #define ASSERT(a) serial.writeAssert((a),#a,__FILE__,__LINE__) -#else - -#define DEBUG1(a) -#define DEBUG2(a,b) -#define DEBUG3(a,b,c) -#define DEBUG4(a,b,c,d) -#define DEBUG5(a,b,c,d,e) -#define ASSERT(a) - -#endif - #endif diff --git a/IO.cpp b/IO.cpp index 22163d9..f6e73a8 100644 --- a/IO.cpp +++ b/IO.cpp @@ -18,32 +18,28 @@ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -// #define WANT_DEBUG - #include "Config.h" #include "Globals.h" #include "IO.h" -#if defined(WIDE_C4FSK_FILTERS_RX) -// Generated using rcosdesign(0.2, 4, 5, 'sqrt') in MATLAB -static q15_t C4FSK_FILTER[] = {688, -680, -2158, -3060, -2724, -775, 2684, 7041, 11310, 14425, 15565, 14425, - 11310, 7041, 2684, -775, -2724, -3060, -2158, -680, 688, 0}; -const uint16_t C4FSK_FILTER_LEN = 22U; -#else // Generated using rcosdesign(0.2, 8, 5, 'sqrt') in MATLAB -static q15_t C4FSK_FILTER[] = {401, 104, -340, -731, -847, -553, 112, 909, 1472, 1450, 683, -675, -2144, -3040, -2706, -770, 2667, 6995, +static q15_t RRC_0_2_FILTER[] = {401, 104, -340, -731, -847, -553, 112, 909, 1472, 1450, 683, -675, -2144, -3040, -2706, -770, 2667, 6995, 11237, 14331, 15464, 14331, 11237, 6995, 2667, -770, -2706, -3040, -2144, -675, 683, 1450, 1472, 909, 112, -553, -847, -731, -340, 104, 401, 0}; -const uint16_t C4FSK_FILTER_LEN = 42U; -#endif +const uint16_t RRC_0_2_FILTER_LEN = 42U; + +// Generated using rcosdesign(0.2, 8, 5, 'normal') in MATLAB +static q15_t RC_0_2_FILTER[] = {0, -413, -750, -845, -587, 0, 741, 1347, 1520, 1062, 0, -1383, -2582, -3021, -2222, 0, 3434, 7487, 11318, 14054, 15044, 14054, + 11318, 7487, 3434, 0, -2222, -3021, -2582, -1383, 0, 1062, 1520, 1347, 741, 0, -587, -845, -750, -413}; +const uint16_t RC_0_2_FILTER_LEN = 40U; // Generated using gaussfir(0.5, 4, 5) in MATLAB -static q15_t GMSK_FILTER[] = {8, 104, 760, 3158, 7421, 9866, 7421, 3158, 760, 104, 8, 0}; -const uint16_t GMSK_FILTER_LEN = 12U; +static q15_t GAUSSIAN_0_5_FILTER[] = {8, 104, 760, 3158, 7421, 9866, 7421, 3158, 760, 104, 8, 0}; +const uint16_t GAUSSIAN_0_5_FILTER_LEN = 12U; // One symbol boxcar filter -static q15_t P25_FILTER[] = {3000, 3000, 3000, 3000, 3000, 0}; -const uint16_t P25_FILTER_LEN = 6U; +static q15_t BOXCAR_FILTER[] = {3000, 3000, 3000, 3000, 3000, 0}; +const uint16_t BOXCAR_FILTER_LEN = 6U; const uint16_t DC_OFFSET = 2048U; @@ -52,12 +48,14 @@ m_started(false), m_rxBuffer(RX_RINGBUFFER_SIZE), m_txBuffer(TX_RINGBUFFER_SIZE), m_rssiBuffer(RX_RINGBUFFER_SIZE), -m_C4FSKFilter(), -m_GMSKFilter(), -m_P25Filter(), -m_C4FSKState(), -m_GMSKState(), -m_P25State(), +m_rrcFilter(), +m_rcFilter(), +m_gaussianFilter(), +m_boxcarFilter(), +m_rrcState(), +m_rcState(), +m_gaussianState(), +m_boxcarState(), m_pttInvert(false), m_rxLevel(128 * 128), m_cwIdTXLevel(128 * 128), @@ -73,21 +71,26 @@ m_dacOverflow(0U), m_watchdog(0U), m_lockout(false) { - ::memset(m_C4FSKState, 0x00U, 70U * sizeof(q15_t)); - ::memset(m_GMSKState, 0x00U, 40U * sizeof(q15_t)); - ::memset(m_P25State, 0x00U, 30U * sizeof(q15_t)); + ::memset(m_rrcState, 0x00U, 70U * sizeof(q15_t)); + ::memset(m_rcState, 0x00U, 70U * sizeof(q15_t)); + ::memset(m_gaussianState, 0x00U, 40U * sizeof(q15_t)); + ::memset(m_boxcarState, 0x00U, 30U * sizeof(q15_t)); - m_C4FSKFilter.numTaps = C4FSK_FILTER_LEN; - m_C4FSKFilter.pState = m_C4FSKState; - m_C4FSKFilter.pCoeffs = C4FSK_FILTER; + m_rrcFilter.numTaps = RRC_0_2_FILTER_LEN; + m_rrcFilter.pState = m_rrcState; + m_rrcFilter.pCoeffs = RRC_0_2_FILTER; - m_GMSKFilter.numTaps = GMSK_FILTER_LEN; - m_GMSKFilter.pState = m_GMSKState; - m_GMSKFilter.pCoeffs = GMSK_FILTER; + m_rcFilter.numTaps = RC_0_2_FILTER_LEN; + m_rcFilter.pState = m_rcState; + m_rcFilter.pCoeffs = RC_0_2_FILTER; - m_P25Filter.numTaps = P25_FILTER_LEN; - m_P25Filter.pState = m_P25State; - m_P25Filter.pCoeffs = P25_FILTER; + m_gaussianFilter.numTaps = GAUSSIAN_0_5_FILTER_LEN; + m_gaussianFilter.pState = m_gaussianState; + m_gaussianFilter.pCoeffs = GAUSSIAN_0_5_FILTER; + + m_boxcarFilter.numTaps = BOXCAR_FILTER_LEN; + m_boxcarFilter.pState = m_boxcarState; + m_boxcarFilter.pCoeffs = BOXCAR_FILTER; initInt(); } @@ -169,21 +172,21 @@ void CIO::process() if (m_modemState == STATE_IDLE) { if (m_dstarEnable) { q15_t GMSKVals[RX_BLOCK_SIZE]; - ::arm_fir_fast_q15(&m_GMSKFilter, samples, GMSKVals, RX_BLOCK_SIZE); + ::arm_fir_fast_q15(&m_gaussianFilter, samples, GMSKVals, RX_BLOCK_SIZE); dstarRX.samples(GMSKVals, rssi, RX_BLOCK_SIZE); } if (m_p25Enable) { q15_t P25Vals[RX_BLOCK_SIZE]; - ::arm_fir_fast_q15(&m_P25Filter, samples, P25Vals, RX_BLOCK_SIZE); + ::arm_fir_fast_q15(&m_boxcarFilter, samples, P25Vals, RX_BLOCK_SIZE); p25RX.samples(P25Vals, rssi, RX_BLOCK_SIZE); } if (m_dmrEnable || m_ysfEnable) { q15_t C4FSKVals[RX_BLOCK_SIZE]; - ::arm_fir_fast_q15(&m_C4FSKFilter, samples, C4FSKVals, RX_BLOCK_SIZE); + ::arm_fir_fast_q15(&m_rrcFilter, samples, C4FSKVals, RX_BLOCK_SIZE); if (m_dmrEnable) { if (m_duplex) @@ -198,14 +201,14 @@ void CIO::process() } else if (m_modemState == STATE_DSTAR) { if (m_dstarEnable) { q15_t GMSKVals[RX_BLOCK_SIZE]; - ::arm_fir_fast_q15(&m_GMSKFilter, samples, GMSKVals, RX_BLOCK_SIZE); + ::arm_fir_fast_q15(&m_gaussianFilter, samples, GMSKVals, RX_BLOCK_SIZE); dstarRX.samples(GMSKVals, rssi, RX_BLOCK_SIZE); } } else if (m_modemState == STATE_DMR) { if (m_dmrEnable) { q15_t C4FSKVals[RX_BLOCK_SIZE]; - ::arm_fir_fast_q15(&m_C4FSKFilter, samples, C4FSKVals, RX_BLOCK_SIZE); + ::arm_fir_fast_q15(&m_rrcFilter, samples, C4FSKVals, RX_BLOCK_SIZE); if (m_duplex) { // If the transmitter isn't on, use the DMR idle RX to detect the wakeup CSBKs @@ -220,20 +223,23 @@ void CIO::process() } else if (m_modemState == STATE_YSF) { if (m_ysfEnable) { q15_t C4FSKVals[RX_BLOCK_SIZE]; - ::arm_fir_fast_q15(&m_C4FSKFilter, samples, C4FSKVals, RX_BLOCK_SIZE); + ::arm_fir_fast_q15(&m_rrcFilter, samples, C4FSKVals, RX_BLOCK_SIZE); ysfRX.samples(C4FSKVals, rssi, RX_BLOCK_SIZE); } } else if (m_modemState == STATE_P25) { if (m_p25Enable) { - q15_t P25Vals[RX_BLOCK_SIZE]; - ::arm_fir_fast_q15(&m_P25Filter, samples, P25Vals, RX_BLOCK_SIZE); + q15_t P25Vals1[RX_BLOCK_SIZE]; + ::arm_fir_fast_q15(&m_boxcarFilter, samples, P25Vals1, RX_BLOCK_SIZE); - p25RX.samples(P25Vals, rssi, RX_BLOCK_SIZE); + q15_t P25Vals2[RX_BLOCK_SIZE]; + ::arm_fir_fast_q15(&m_rcFilter, P25Vals1, P25Vals2, RX_BLOCK_SIZE); + + p25RX.samples(P25Vals2, rssi, RX_BLOCK_SIZE); } } else if (m_modemState == STATE_DSTARCAL) { q15_t GMSKVals[RX_BLOCK_SIZE]; - ::arm_fir_fast_q15(&m_GMSKFilter, samples, GMSKVals, RX_BLOCK_SIZE); + ::arm_fir_fast_q15(&m_gaussianFilter, samples, GMSKVals, RX_BLOCK_SIZE); calDStarRX.samples(GMSKVals, RX_BLOCK_SIZE); } else if (m_modemState == STATE_RSSICAL) { @@ -346,11 +352,6 @@ void CIO::getOverflow(bool& adcOverflow, bool& dacOverflow) adcOverflow = m_adcOverflow > 0U; dacOverflow = m_dacOverflow > 0U; -#if defined(WANT_DEBUG) - if (m_adcOverflow > 0U || m_dacOverflow > 0U) - DEBUG3("IO: adc/dac", m_adcOverflow, m_dacOverflow); -#endif - m_adcOverflow = 0U; m_dacOverflow = 0U; } diff --git a/IO.h b/IO.h index 25559c7..339b4ac 100644 --- a/IO.h +++ b/IO.h @@ -60,12 +60,14 @@ private: CSampleRB m_txBuffer; CRSSIRB m_rssiBuffer; - arm_fir_instance_q15 m_C4FSKFilter; - arm_fir_instance_q15 m_GMSKFilter; - arm_fir_instance_q15 m_P25Filter; - q15_t m_C4FSKState[70U]; // NoTaps + BlockSize - 1, 42 + 20 - 1 plus some spare - q15_t m_GMSKState[40U]; // NoTaps + BlockSize - 1, 12 + 20 - 1 plus some spare - q15_t m_P25State[30U]; // NoTaps + BlockSize - 1, 6 + 20 - 1 plus some spare + arm_fir_instance_q15 m_rrcFilter; + arm_fir_instance_q15 m_rcFilter; + arm_fir_instance_q15 m_gaussianFilter; + arm_fir_instance_q15 m_boxcarFilter; + q15_t m_rrcState[70U]; // NoTaps + BlockSize - 1, 42 + 20 - 1 plus some spare + q15_t m_rcState[70U]; // NoTaps + BlockSize - 1, 42 + 20 - 1 plus some spare + q15_t m_gaussianState[40U]; // NoTaps + BlockSize - 1, 12 + 20 - 1 plus some spare + q15_t m_boxcarState[30U]; // NoTaps + BlockSize - 1, 6 + 20 - 1 plus some spare bool m_pttInvert; q15_t m_rxLevel; diff --git a/Makefile b/Makefile index a97316d..3b1e789 100644 --- a/Makefile +++ b/Makefile @@ -36,19 +36,19 @@ ifdef SYSTEMROOT ASOURCES=$(shell dir /S /B *.s) CSOURCES=$(shell dir /S /B *.c) CXXSOURCES=$(shell dir /S /B *.cpp) - CLEANCMD=del /S *.o *.hex *.bin *.elf + CLEANCMD=del /S *.o *.hex *.bin *.elf GitVersion.h MDBIN=md $@ else ifdef SystemRoot ASOURCES=$(shell dir /S /B *.s) CSOURCES=$(shell dir /S /B *.c) CXXSOURCES=$(shell dir /S /B *.cpp) - CLEANCMD=del /S *.o *.hex *.bin *.elf + CLEANCMD=del /S *.o *.hex *.bin *.elf GitVersion.h MDBIN=md $@ else ASOURCES=$(shell find . -name '*.s') CSOURCES=$(shell find . -name '*.c') CXXSOURCES=$(shell find . -name '*.cpp') - CLEANCMD=rm -f $(OBJECTS) $(BINDIR)/$(BINELF) $(BINDIR)/$(BINHEX) $(BINDIR)/$(BINBIN) + CLEANCMD=rm -f $(OBJECTS) $(BINDIR)/$(BINELF) $(BINDIR)/$(BINHEX) $(BINDIR)/$(BINBIN) GitVersion.h MDBIN=mkdir $@ endif @@ -85,11 +85,11 @@ MCFLAGS=-mcpu=cortex-m4 -mthumb -mlittle-endian \ # COMPILE FLAGS # STM32F4 Discovery board: -DEFS_DIS=-DUSE_STDPERIPH_DRIVER -DSTM32F4XX -DSTM32F40_41xxx -DSTM32F4_DISCOVERY -DHSE_VALUE=$(OSC) +DEFS_DIS=-DUSE_STDPERIPH_DRIVER -DSTM32F4XX -DSTM32F40_41xxx -DSTM32F4_DISCOVERY -DHSE_VALUE=$(OSC) -DMADEBYMAKEFILE # Pi board: -DEFS_PI=-DUSE_STDPERIPH_DRIVER -DSTM32F4XX -DSTM32F446xx -DSTM32F4_PI -DARDUINO_MODE_PINS -DSEND_RSSI_DATA -DSERIAL_REPEATER -DHSE_VALUE=$(OSC) +DEFS_PI=-DUSE_STDPERIPH_DRIVER -DSTM32F4XX -DSTM32F446xx -DSTM32F4_PI -DARDUINO_MODE_PINS -DSEND_RSSI_DATA -DSERIAL_REPEATER -DHSE_VALUE=$(OSC) -DMADEBYMAKEFILE # STM32F4 Nucleo 446 board: -DEFS_NUCLEO=-DUSE_STDPERIPH_DRIVER -DSTM32F4XX -DSTM32F446xx -DSTM32F4_NUCLEO -DHSE_VALUE=$(OSC) +DEFS_NUCLEO=-DUSE_STDPERIPH_DRIVER -DSTM32F4XX -DSTM32F446xx -DSTM32F4_NUCLEO -DHSE_VALUE=$(OSC) -DMADEBYMAKEFILE CFLAGS=-c $(MCFLAGS) $(INCLUDES) CXXFLAGS=-c $(MCFLAGS) $(INCLUDES) @@ -109,6 +109,7 @@ pi: CXXFLAGS+=$(DEFS_PI) -Os -fno-exceptions -ffunction-sections -fdata-sections pi: LDFLAGS+=-Os --specs=nano.specs pi: release +nucleo: GitVersion.h nucleo: CFLAGS+=$(DEFS_NUCLEO) -Os -ffunction-sections -fdata-sections -fno-builtin -Wno-implicit -DCUSTOM_NEW -DNO_EXCEPTIONS nucleo: CXXFLAGS+=$(DEFS_NUCLEO) -Os -fno-exceptions -ffunction-sections -fdata-sections -fno-builtin -fno-rtti -DCUSTOM_NEW -DNO_EXCEPTIONS nucleo: LDFLAGS+=-Os --specs=nano.specs @@ -171,3 +172,11 @@ endif ifneq ($(wildcard /opt/openocd/bin/openocd),) /opt/openocd/bin/openocd -f /opt/openocd/share/openocd/scripts/board/stm32f4discovery.cfg -c "program bin/$(BINELF) verify reset exit" endif + +# Export the current git version if the index file exists, else 000... +GitVersion.h: +ifneq ("$(wildcard .git/index)","") + echo "#define GITVERSION \"$(shell git rev-parse --short HEAD)\"" > $@ +else + echo "#define GITVERSION \"0000000\"" > $@ +endif diff --git a/Makefile.Arduino b/Makefile.Arduino new file mode 100644 index 0000000..36c3dd4 --- /dev/null +++ b/Makefile.Arduino @@ -0,0 +1,190 @@ +#!/usr/bin/make +# makefile for the arduino due (works with arduino IDE 1.6.11) +# +# The original file can be found at https://github.com/pauldreik/arduino-due-makefile +# +# USAGE: put this file in the same dir as your .ino file is. +# configure the PORT variable and ADIR at the top of the file +# to match your local configuration. +# Type make upload to compile and upload. +# + +#user specific settings: +#where to find the IDE +ADIR:=$(HOME)/.arduino15 +#which serial port to use (add a file with SUBSYSTEMS=="usb", +#ATTRS{product}=="Arduino Due Prog. Port", ATTRS{idProduct}=="003d", +#ATTRS{idVendor}=="2341", SYMLINK+="arduino_due" in /etc/udev/rules.d/ +#to get this working). Do not prefix the port with /dev/, just take +#the basename. +PORT:=ttyACM0 +#if you want to verify the bossac upload, define this to -v +VERIFY:=-v + + +#end of user configuration. + + +#then some general settings. They should not be necessary to modify. +#CXX:=$(ADIR)/tools/g++_arm_none_eabi/bin/arm-none-eabi-g++ +CXX:=$(ADIR)/packages/arduino/tools/arm-none-eabi-gcc/4.8.3-2014q1/bin/arm-none-eabi-g++ +#CC:=$(ADIR)/tools/g++_arm_none_eabi/bin/arm-none-eabi-gcc +CC:=$(ADIR)/packages/arduino/tools/arm-none-eabi-gcc/4.8.3-2014q1/bin/arm-none-eabi-gcc +OBJCOPY:=$(ADIR)/packages/arduino/tools/arm-none-eabi-gcc/4.8.3-2014q1/bin/arm-none-eabi-objcopy + +C:=$(CC) +#SAM:=arduino/sam/ +SAM:=$(ADIR)/packages/arduino/hardware/sam/1.6.11 +#CMSIS:=arduino/sam/system/CMSIS/ +#LIBSAM:=arduino/sam/system/libsam +TMPDIR:=$(PWD)/build +AR:=$(ADIR)/tools/g++_arm_none_eabi/bin/arm-none-eabi-ar +AR:=$(ADIR)/packages/arduino/tools/arm-none-eabi-gcc/4.8.3-2014q1/bin/arm-none-eabi-ar + + +#all these values are hard coded and should maybe be configured somehow else, +#like olikraus does in his makefile. +DEFINES:=-Dprintf=iprintf -DF_CPU=84000000 -DARDUINO=10611 -D__SAM3X8E__ -DUSB_PID=0x003e -DUSB_VID=0x2341 -DUSBCON \ + -DARDUINO_SAM_DUE -DARDUINO_ARCH_SAM '-DUSB_MANUFACTURER="Arduino LLC"' '-DUSB_PRODUCT="Arduino Due"' \ + -DMADEBYMAKEFILE + +INCLUDES:=-I$(SAM)/system/libsam -I$(SAM)/system/CMSIS/CMSIS/Include/ \ + -I$(SAM)/system/CMSIS/Device/ATMEL/ -I$(SAM)/cores/arduino \ + -I$(SAM)/variants/arduino_due_x + +#also include the current dir for convenience +INCLUDES += -I. + +#compilation flags common to both c and c++ +COMMON_FLAGS:=-g -Os -w -ffunction-sections -fdata-sections -nostdlib \ + --param max-inline-insns-single=500 -mcpu=cortex-m3 -mthumb \ + -fno-threadsafe-statics +#for compiling c (do not warn, this is not our code) +CFLAGS:=$(COMMON_FLAGS) -std=gnu11 +#for compiling c++ +CXXFLAGS:=$(COMMON_FLAGS) -fno-rtti -fno-exceptions -std=gnu++11 -Wall -Wextra + +#let the results be named after the project +PROJNAME:=$(shell basename *.ino .ino) + +#we will make a new mainfile from the ino file. +NEWMAINFILE:=$(TMPDIR)/$(PROJNAME).ino.cpp + +#our own sourcefiles is the (converted) ino file and any local cpp files +MYSRCFILES:=$(NEWMAINFILE) $(shell ls *.cpp 2>/dev/null) +MYOBJFILES:=$(addsuffix .o,$(addprefix $(TMPDIR)/,$(notdir $(MYSRCFILES)))) + +#These source files are the ones forming core.a +CORESRCXX:=$(shell ls ${SAM}/cores/arduino/*.cpp ${SAM}/cores/arduino/USB/*.cpp ${SAM}/variants/arduino_due_x/variant.cpp) +CORESRC:=$(shell ls ${SAM}/cores/arduino/*.c) + +#hey this one is needed too: $(SAM)/cores/arduino/wiring_pulse_asm.S" add -x assembler-with-cpp +#and this one: /1.6.11/cores/arduino/avr/dtostrf.c but it seems to work +#anyway, probably because I do not use that functionality. + +#convert the core source files to object files. assume no clashes. +COREOBJSXX:=$(addprefix $(TMPDIR)/core/,$(notdir $(CORESRCXX)) ) +COREOBJSXX:=$(addsuffix .o,$(COREOBJSXX)) +COREOBJS:=$(addprefix $(TMPDIR)/core/,$(notdir $(CORESRC)) ) +COREOBJS:=$(addsuffix .o,$(COREOBJS)) + +default: + @echo default rule, does nothing. Try make compile or make upload. + +#This rule is good to just make sure stuff compiles, without having to wait +#for bossac. +compile: GitVersion.h +compile: $(TMPDIR)/$(PROJNAME).elf + +#This is a make rule template to create object files from the source files. +# arg 1=src file +# arg 2=object file +# arg 3= XX if c++, empty if c +define OBJ_template +$(2): $(1) + $(C$(3)) -MD -c $(C$(3)FLAGS) $(DEFINES) $(INCLUDES) $(1) -o $(2) +endef +#now invoke the template both for c++ sources +$(foreach src,$(CORESRCXX), $(eval $(call OBJ_template,$(src),$(addsuffix .o,$(addprefix $(TMPDIR)/core/,$(notdir $(src)))),XX) ) ) +#...and for c sources: +$(foreach src,$(CORESRC), $(eval $(call OBJ_template,$(src),$(addsuffix .o,$(addprefix $(TMPDIR)/core/,$(notdir $(src)))),) ) ) + +#and our own c++ sources +$(foreach src,$(MYSRCFILES), $(eval $(call OBJ_template,$(src),$(addsuffix .o,$(addprefix $(TMPDIR)/,$(notdir $(src)))),XX) ) ) + + +clean: + test ! -d $(TMPDIR) || rm -rf $(TMPDIR) + $(RM) GitVersion.h + +.PHONY: .FORCE upload default + +$(TMPDIR): + mkdir -p $(TMPDIR) + +$(TMPDIR)/core: + mkdir -p $(TMPDIR)/core + +#creates the cpp file from the .ino file +$(NEWMAINFILE): $(PROJNAME).ino + cat $(SAM)/cores/arduino/main.cpp > $(NEWMAINFILE) + cat $(PROJNAME).ino >> $(NEWMAINFILE) + echo 'extern "C" void __cxa_pure_virtual() {while (true);}' >> $(NEWMAINFILE) + +#include the dependencies for our own files +-include $(MYOBJFILES:.o=.d) + +#create the core library from the core objects. Do this EXACTLY as the +#arduino IDE does it, seems *really* picky about this. +#Sorry for the hard coding. +$(TMPDIR)/core.a: $(TMPDIR)/core $(COREOBJS) $(COREOBJSXX) + $(AR) rcs $(TMPDIR)/core.a $(TMPDIR)/core/wiring_shift.c.o + $(AR) rcs $(TMPDIR)/core.a $(TMPDIR)/core/wiring_analog.c.o + $(AR) rcs $(TMPDIR)/core.a $(TMPDIR)/core/itoa.c.o + $(AR) rcs $(TMPDIR)/core.a $(TMPDIR)/core/cortex_handlers.c.o + $(AR) rcs $(TMPDIR)/core.a $(TMPDIR)/core/hooks.c.o + $(AR) rcs $(TMPDIR)/core.a $(TMPDIR)/core/wiring.c.o + $(AR) rcs $(TMPDIR)/core.a $(TMPDIR)/core/WInterrupts.c.o + $(AR) rcs $(TMPDIR)/core.a $(TMPDIR)/core/syscalls_sam3.c.o + $(AR) rcs $(TMPDIR)/core.a $(TMPDIR)/core/iar_calls_sam3.c.o + $(AR) rcs $(TMPDIR)/core.a $(TMPDIR)/core/wiring_digital.c.o + $(AR) rcs $(TMPDIR)/core.a $(TMPDIR)/core/Print.cpp.o + $(AR) rcs $(TMPDIR)/core.a $(TMPDIR)/core/USARTClass.cpp.o + $(AR) rcs $(TMPDIR)/core.a $(TMPDIR)/core/WString.cpp.o + $(AR) rcs $(TMPDIR)/core.a $(TMPDIR)/core/PluggableUSB.cpp.o + $(AR) rcs $(TMPDIR)/core.a $(TMPDIR)/core/USBCore.cpp.o + $(AR) rcs $(TMPDIR)/core.a $(TMPDIR)/core/CDC.cpp.o + $(AR) rcs $(TMPDIR)/core.a $(TMPDIR)/core/wiring_pulse.cpp.o + $(AR) rcs $(TMPDIR)/core.a $(TMPDIR)/core/UARTClass.cpp.o + $(AR) rcs $(TMPDIR)/core.a $(TMPDIR)/core/main.cpp.o + $(AR) rcs $(TMPDIR)/core.a $(TMPDIR)/core/new.cpp.o + $(AR) rcs $(TMPDIR)/core.a $(TMPDIR)/core/watchdog.cpp.o + $(AR) rcs $(TMPDIR)/core.a $(TMPDIR)/core/Stream.cpp.o + $(AR) rcs $(TMPDIR)/core.a $(TMPDIR)/core/RingBuffer.cpp.o + $(AR) rcs $(TMPDIR)/core.a $(TMPDIR)/core/IPAddress.cpp.o + $(AR) rcs $(TMPDIR)/core.a $(TMPDIR)/core/Reset.cpp.o + $(AR) rcs $(TMPDIR)/core.a $(TMPDIR)/core/WMath.cpp.o + $(AR) rcs $(TMPDIR)/core.a $(TMPDIR)/core/variant.cpp.o + +#link our own object files with core to form the elf file +$(TMPDIR)/$(PROJNAME).elf: $(TMPDIR)/core.a $(TMPDIR)/core/syscalls_sam3.c.o $(MYOBJFILES) + $(CC) -mcpu=cortex-m3 -mthumb -Os -Wl,--gc-sections -T$(SAM)/variants/arduino_due_x/linker_scripts/gcc/flash.ld -Wl,-Map,$(NEWMAINFILE).map -o $@ -L$(TMPDIR) -Wl,--cref -Wl,--check-sections -Wl,--gc-sections -Wl,--entry=Reset_Handler -Wl,--unresolved-symbols=report-all -Wl,--warn-common -Wl,--warn-section-align -Wl,--start-group -u _sbrk -u link -u _close -u _fstat -u _isatty -u _lseek -u _read -u _write -u _exit -u kill -u _getpid $(MYOBJFILES) $(TMPDIR)/core/variant.cpp.o $(SAM)/variants/arduino_due_x/libsam_sam3x8e_gcc_rel.a $(SAM)/system/CMSIS/CMSIS/Lib/GCC/libarm_cortexM3l_math.a $(TMPDIR)/core.a -Wl,--end-group -lm -gcc + +#copy from the hex to our bin file (why?) +$(TMPDIR)/$(PROJNAME).bin: $(TMPDIR)/$(PROJNAME).elf + $(OBJCOPY) -O binary $< $@ + +#upload to the arduino by first resetting it (stty) and the running bossac +upload: $(TMPDIR)/$(PROJNAME).bin + stty -F /dev/$(PORT) cs8 1200 hupcl + $(ADIR)/packages/arduino/tools/bossac/1.6.1-arduino/bossac -i --port=$(PORT) -U false -e -w $(VERIFY) -b $(TMPDIR)/$(PROJNAME).bin -R + +# Export the current git version if the index file exists, else 000... +GitVersion.h: .FORCE +ifneq ("$(wildcard .git/index)","") + echo "#define GITVERSION \"$(shell git rev-parse --short HEAD)\"" > $@ +else + echo "#define GITVERSION \"0000000\"" > $@ +endif + +.FORCE: diff --git a/P25RX.cpp b/P25RX.cpp index a01f2a2..9228c5b 100644 --- a/P25RX.cpp +++ b/P25RX.cpp @@ -16,10 +16,6 @@ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -#define WANT_DEBUG - -// #define DUMP_SAMPLES - #include "Config.h" #include "Globals.h" #include "P25RX.h" @@ -245,9 +241,6 @@ void CP25RX::processLdu(q15_t sample) } else { frame[0U] = m_lostCount == (MAX_SYNC_FRAMES - 1U) ? 0x01U : 0x00U; writeRSSILdu(frame); -#if defined(DUMP_SAMPLES) - writeSamples(m_lduStartPtr, frame[0U]); -#endif m_maxCorr = 0; } } @@ -471,20 +464,3 @@ void CP25RX::writeRSSILdu(uint8_t* ldu) m_rssiAccum = 0U; m_rssiCount = 0U; } - -#if defined(DUMP_SAMPLES) -void CP25RX::writeSamples(uint16_t start, uint8_t control) -{ - q15_t samples[P25_LDU_FRAME_LENGTH_SYMBOLS]; - - for (uint16_t i = 0U; i < P25_LDU_FRAME_LENGTH_SYMBOLS; i++) { - samples[i] = m_buffer[start]; - - start += P25_RADIO_SYMBOL_LENGTH; - if (start >= P25_LDU_FRAME_LENGTH_SAMPLES) - start -= P25_LDU_FRAME_LENGTH_SAMPLES; - } - - serial.writeSamples(STATE_P25, control, samples, P25_LDU_FRAME_LENGTH_SYMBOLS); -} -#endif diff --git a/P25RX.h b/P25RX.h index 904d5a6..0bdf3c5 100644 --- a/P25RX.h +++ b/P25RX.h @@ -67,7 +67,6 @@ private: 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 writeRSSILdu(uint8_t* ldu); - void writeSamples(uint16_t start, uint8_t control); }; #endif diff --git a/P25TX.cpp b/P25TX.cpp index bf0f8e9..a6147ba 100644 --- a/P25TX.cpp +++ b/P25TX.cpp @@ -1,5 +1,6 @@ /* * Copyright (C) 2016,2017 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 @@ -16,35 +17,26 @@ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -// #define WANT_DEBUG - #include "Config.h" #include "Globals.h" #include "P25TX.h" #include "P25Defines.h" -#if defined(WIDE_C4FSK_FILTERS_TX) -// Generated using rcosdesign(0.2, 4, 5, 'normal') in MATLAB -// numTaps = 20, L = 5 -static q15_t P25_C4FSK_FILTER[] = {-1392, -2602, -3043, -2238, 0, 3460, 7543, 11400, 14153, 15152, 14153, 11400, 7543, 3460, 0, -2238, -3043, -2602, -1392, 0}; -const uint16_t P25_C4FSK_FILTER_PHASE_LEN = 4U; // phaseLength = numTaps/L -#else // Generated using rcosdesign(0.2, 8, 5, 'normal') in MATLAB // numTaps = 40, L = 5 -static q15_t P25_C4FSK_FILTER[] = {-413, -751, -845, -587, 0, 740, 1348, 1520, 1063, 0, -1383, -2583, -3021, -2222, 0, 3435, 7488, 11318, 14053, 15044, 14053, +static q15_t RC_0_2_FILTER[] = {-413, -751, -845, -587, 0, 740, 1348, 1520, 1063, 0, -1383, -2583, -3021, -2222, 0, 3435, 7488, 11318, 14053, 15044, 14053, 11318, 7488, 3435, 0, -2222, -3021, -2583, -1383, 0, 1063, 1520, 1348, 740, 0, -587, -845, -751, -413, 0}; -const uint16_t P25_C4FSK_FILTER_PHASE_LEN = 8U; // phaseLength = numTaps/L -#endif +const uint16_t RC_0_2_FILTER_PHASE_LEN = 8U; // phaseLength = numTaps/L // Generated in MATLAB using the following commands, and then normalised for unity gain // shape2 = 'Inverse-sinc Lowpass'; // d2 = fdesign.interpolator(2, shape2); // h2 = design(d2, 'SystemObject', true); -static q15_t P25_LP_FILTER[] = {170, 401, 340, -203, -715, -478, 281, 419, -440, -1002, -103, 1114, 528, -1389, -1520, 1108, 2674, -388, -4662, +static q15_t LOWPASS_FILTER[] = {170, 401, 340, -203, -715, -478, 281, 419, -440, -1002, -103, 1114, 528, -1389, -1520, 1108, 2674, -388, -4662, -2132, 9168, 20241, 20241, 9168, -2132, -4662, -388, 2674, 1108, -1520, -1389, 528, 1114, -103, -1002, -440, 419, 281, -478, -715, -203, 340, 401, 170}; -const uint16_t P25_LP_FILTER_LEN = 44U; +const uint16_t LOWPASS_FILTER_LEN = 44U; const q15_t P25_LEVELA = 1698; const q15_t P25_LEVELB = 566; @@ -67,14 +59,14 @@ m_txDelay(240U) // 200ms ::memset(m_modState, 0x00U, 16U * sizeof(q15_t)); ::memset(m_lpState, 0x00U, 70U * sizeof(q15_t)); - m_modFilter.L = P25_RADIO_SYMBOL_LENGTH; - m_modFilter.phaseLength = P25_C4FSK_FILTER_PHASE_LEN; - m_modFilter.pCoeffs = P25_C4FSK_FILTER; - m_modFilter.pState = m_modState; + m_modFilter.L = P25_RADIO_SYMBOL_LENGTH; + m_modFilter.phaseLength = RC_0_2_FILTER_PHASE_LEN; + m_modFilter.pCoeffs = RC_0_2_FILTER; + m_modFilter.pState = m_modState; - m_lpFilter.numTaps = P25_LP_FILTER_LEN; + m_lpFilter.numTaps = LOWPASS_FILTER_LEN; m_lpFilter.pState = m_lpState; - m_lpFilter.pCoeffs = P25_LP_FILTER; + m_lpFilter.pCoeffs = LOWPASS_FILTER; } void CP25TX::process() diff --git a/SerialPort.cpp b/SerialPort.cpp index 1746492..c54b646 100644 --- a/SerialPort.cpp +++ b/SerialPort.cpp @@ -17,11 +17,14 @@ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -// #define WANT_DEBUG - #include "Config.h" #include "Globals.h" +#if defined(MADEBYMAKEFILE) +#include "GitVersion.h" +#endif + + #include "SerialPort.h" const uint8_t MMDVM_FRAME_START = 0xE0U; @@ -62,8 +65,6 @@ const uint8_t MMDVM_NAK = 0x7FU; const uint8_t MMDVM_SERIAL = 0x80U; -const uint8_t MMDVM_SAMPLES = 0xF0U; - const uint8_t MMDVM_DEBUG1 = 0xF1U; const uint8_t MMDVM_DEBUG2 = 0xF2U; const uint8_t MMDVM_DEBUG3 = 0xF3U; @@ -76,8 +77,14 @@ const uint8_t MMDVM_DEBUG5 = 0xF5U; #else #define DESCRIPTION "MMDVM 20170406 (D-Star/DMR/System Fusion/P25/RSSI/CW Id)" #endif + +#if defined(GITVERSION) +#define concat(a, b) a " GitID #" b "" +const char HARDWARE[] = concat(DESCRIPTION, GITVERSION); +#else #define concat(a, b, c) a " (Build: " b " " c ")" const char HARDWARE[] = concat(DESCRIPTION, __TIME__, __DATE__); +#endif const uint8_t PROTOCOL_VERSION = 1U; @@ -85,7 +92,8 @@ const uint8_t PROTOCOL_VERSION = 1U; CSerialPort::CSerialPort() : m_buffer(), m_ptr(0U), -m_len(0U) +m_len(0U), +m_debug(false) { } @@ -221,6 +229,8 @@ uint8_t CSerialPort::setConfig(const uint8_t* data, uint8_t length) bool ysfLoDev = (data[0U] & 0x08U) == 0x08U; bool simplex = (data[0U] & 0x80U) == 0x80U; + m_debug = (data[0U] & 0x10U) == 0x10U; + bool dstarEnable = (data[1U] & 0x01U) == 0x01U; bool dmrEnable = (data[1U] & 0x02U) == 0x02U; bool ysfEnable = (data[1U] & 0x04U) == 0x04U; @@ -920,33 +930,11 @@ void CSerialPort::writeRSSIData(const uint8_t* data, uint8_t length) writeInt(1U, reply, count); } -void CSerialPort::writeSamples(uint8_t mode, uint8_t control, const q15_t* samples, uint16_t nSamples) -{ - uint8_t reply[1800U]; - - reply[0U] = MMDVM_FRAME_START; - reply[1U] = 0U; - reply[2U] = MMDVM_SAMPLES; - - reply[5U] = mode; - reply[6U] = control; - - uint16_t count = 7U; - for (uint16_t i = 0U; i < nSamples; i++) { - uint16_t val = uint16_t(samples[i] + 2048); - - reply[count++] = (val >> 8) & 0xFF; - reply[count++] = (val >> 0) & 0xFF; - } - - reply[3U] = (count >> 8) & 0xFFU; - reply[4U] = (count >> 0) & 0xFFU; - - writeInt(1U, reply, count, true); -} - void CSerialPort::writeDebug(const char* text) { + if (!m_debug) + return; + uint8_t reply[130U]; reply[0U] = MMDVM_FRAME_START; @@ -964,6 +952,9 @@ void CSerialPort::writeDebug(const char* text) void CSerialPort::writeDebug(const char* text, int16_t n1) { + if (!m_debug) + return; + uint8_t reply[130U]; reply[0U] = MMDVM_FRAME_START; @@ -984,6 +975,9 @@ void CSerialPort::writeDebug(const char* text, int16_t n1) void CSerialPort::writeDebug(const char* text, int16_t n1, int16_t n2) { + if (!m_debug) + return; + uint8_t reply[130U]; reply[0U] = MMDVM_FRAME_START; @@ -1007,6 +1001,9 @@ void CSerialPort::writeDebug(const char* text, int16_t n1, int16_t n2) void CSerialPort::writeDebug(const char* text, int16_t n1, int16_t n2, int16_t n3) { + if (!m_debug) + return; + uint8_t reply[130U]; reply[0U] = MMDVM_FRAME_START; @@ -1033,6 +1030,9 @@ void CSerialPort::writeDebug(const char* text, int16_t n1, int16_t n2, int16_t n void CSerialPort::writeDebug(const char* text, int16_t n1, int16_t n2, int16_t n3, int16_t n4) { + if (!m_debug) + return; + uint8_t reply[130U]; reply[0U] = MMDVM_FRAME_START; diff --git a/SerialPort.h b/SerialPort.h index 2a3522f..8dc7658 100644 --- a/SerialPort.h +++ b/SerialPort.h @@ -49,8 +49,6 @@ public: void writeCalData(const uint8_t* data, uint8_t length); void writeRSSIData(const uint8_t* data, uint8_t length); - void writeSamples(uint8_t mode, uint8_t control, const q15_t* samples, uint16_t nSamples); - void writeDebug(const char* text); void writeDebug(const char* text, int16_t n1); void writeDebug(const char* text, int16_t n1, int16_t n2); @@ -63,6 +61,7 @@ private: uint8_t m_buffer[256U]; uint8_t m_ptr; uint8_t m_len; + bool m_debug; void sendACK(); void sendNAK(uint8_t err); diff --git a/YSFRX.cpp b/YSFRX.cpp index bc7483b..88c6f83 100644 --- a/YSFRX.cpp +++ b/YSFRX.cpp @@ -16,10 +16,6 @@ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -#define WANT_DEBUG - -// #define DUMP_SAMPLES - #include "Config.h" #include "Globals.h" #include "YSFRX.h" @@ -201,9 +197,6 @@ void CYSFRX::processData(q15_t sample) } else { frame[0U] = m_lostCount == (MAX_SYNC_FRAMES - 1U) ? 0x01U : 0x00U; writeRSSIData(frame); -#if defined(DUMP_SAMPLES) - writeSamples(m_startPtr, frame[0U]); -#endif m_maxCorr = 0; } } @@ -409,20 +402,3 @@ void CYSFRX::writeRSSIData(uint8_t* data) m_rssiAccum = 0U; m_rssiCount = 0U; } - -#if defined(DUMP_SAMPLES) -void CYSFRX::writeSamples(uint16_t start, uint8_t control) -{ - q15_t samples[YSF_FRAME_LENGTH_SYMBOLS]; - - for (uint16_t i = 0U; i < YSF_FRAME_LENGTH_SYMBOLS; i++) { - samples[i] = m_buffer[start]; - - start += YSF_RADIO_SYMBOL_LENGTH; - if (start >= YSF_FRAME_LENGTH_SAMPLES) - start -= YSF_FRAME_LENGTH_SAMPLES; - } - - serial.writeSamples(STATE_YSF, control, samples, YSF_FRAME_LENGTH_SYMBOLS); -} -#endif diff --git a/YSFRX.h b/YSFRX.h index e8e7edc..556280a 100644 --- a/YSFRX.h +++ b/YSFRX.h @@ -63,7 +63,6 @@ private: 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); - void writeSamples(uint16_t start, uint8_t control); }; #endif diff --git a/YSFTX.cpp b/YSFTX.cpp index a5a8b92..e6010b9 100644 --- a/YSFTX.cpp +++ b/YSFTX.cpp @@ -1,5 +1,6 @@ /* * Copyright (C) 2009-2017 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 @@ -16,26 +17,17 @@ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -// #define WANT_DEBUG - #include "Config.h" #include "Globals.h" #include "YSFTX.h" #include "YSFDefines.h" -#if defined(WIDE_C4FSK_FILTERS_TX) -// Generated using rcosdesign(0.2, 4, 5, 'sqrt') in MATLAB -static q15_t YSF_C4FSK_FILTER[] = {0, 0, 0, 0, 688, -680, -2158, -3060, -2724, -775, 2684, 7041, 11310, 14425, 15565, 14425, - 11310, 7041, 2684, -775, -2724, -3060, -2158, -680, 688}; // numTaps = 25, L = 5 -const uint16_t YSF_C4FSK_FILTER_PHASE_LEN = 5U; // phaseLength = numTaps/L -#else // Generated using rcosdesign(0.2, 8, 5, 'sqrt') in MATLAB -static q15_t YSF_C4FSK_FILTER[] = {0, 0, 0, 0, 401, 104, -340, -731, -847, -553, 112, 909, 1472, 1450, 683, -675, -2144, -3040, -2706, -770, 2667, 6995, +static q15_t RRC_0_2_FILTER[] = {0, 0, 0, 0, 401, 104, -340, -731, -847, -553, 112, 909, 1472, 1450, 683, -675, -2144, -3040, -2706, -770, 2667, 6995, 11237, 14331, 15464, 14331, 11237, 6995, 2667, -770, -2706, -3040, -2144, -675, 683, 1450, 1472, 909, 112, -553, -847, -731, -340, 104, 401}; // numTaps = 45, L = 5 -const uint16_t YSF_C4FSK_FILTER_PHASE_LEN = 9U; // phaseLength = numTaps/L -#endif +const uint16_t RRC_0_2_FILTER_PHASE_LEN = 9U; // phaseLength = numTaps/L const q15_t YSF_LEVELA_HI = 3900; const q15_t YSF_LEVELB_HI = 1300; @@ -62,10 +54,10 @@ m_loDev(false) { ::memset(m_modState, 0x00U, 16U * sizeof(q15_t)); - m_modFilter.L = YSF_RADIO_SYMBOL_LENGTH; - m_modFilter.phaseLength = YSF_C4FSK_FILTER_PHASE_LEN; - m_modFilter.pCoeffs = YSF_C4FSK_FILTER; - m_modFilter.pState = m_modState; + m_modFilter.L = YSF_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 CYSFTX::process()