diff --git a/DMRDMORX.cpp b/DMRDMORX.cpp index df9e717..35028b8 100644 --- a/DMRDMORX.cpp +++ b/DMRDMORX.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2009-2016 by Jonathan Naylor G4KLX + * Copyright (C) 2009-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 @@ -59,7 +59,6 @@ m_colorCode(0U), m_state(DMORXS_NONE), m_n(0U), m_type(0U), -m_rssiCount(0U), m_rssi() { } @@ -73,7 +72,6 @@ void CDMRDMORX::reset() m_state = DMORXS_NONE; m_startPtr = 0U; m_endPtr = NOENDPTR; - m_rssiCount = 0U; } void CDMRDMORX::samples(const q15_t* samples, const uint16_t* rssi, uint8_t length) @@ -146,7 +144,7 @@ bool CDMRDMORX::processSample(q15_t sample, uint16_t rssi) switch (dataType) { case DT_DATA_HEADER: DEBUG4("DMRDMORX: data header found pos/centre/threshold", m_syncPtr, centre, threshold); - serial.writeDMRData(true, frame, DMR_FRAME_LENGTH_BYTES + 1U); + writeRSSIData(frame); m_state = DMORXS_DATA; m_type = 0x00U; break; @@ -155,32 +153,32 @@ bool CDMRDMORX::processSample(q15_t sample, uint16_t rssi) case DT_RATE_1_DATA: if (m_state == DMORXS_DATA) { DEBUG4("DMRDMORX: data payload found pos/centre/threshold", m_syncPtr, centre, threshold); - serial.writeDMRData(true, frame, DMR_FRAME_LENGTH_BYTES + 1U); + writeRSSIData(frame); m_type = dataType; } break; case DT_VOICE_LC_HEADER: DEBUG4("DMRDMORX: voice header found pos/centre/threshold", m_syncPtr, centre, threshold); - serial.writeDMRData(true, frame, DMR_FRAME_LENGTH_BYTES + 1U); + writeRSSIData(frame); 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); - serial.writeDMRData(true, frame, DMR_FRAME_LENGTH_BYTES + 1U); + writeRSSIData(frame); } m_state = DMORXS_VOICE; break; case DT_TERMINATOR_WITH_LC: if (m_state == DMORXS_VOICE) { DEBUG4("DMRDMORX: voice terminator found pos/centre/threshold", m_syncPtr, centre, threshold); - serial.writeDMRData(true, frame, DMR_FRAME_LENGTH_BYTES + 1U); + writeRSSIData(frame); reset(); } break; default: // DT_CSBK DEBUG4("DMRDMORX: csbk found pos/centre/threshold", m_syncPtr, centre, threshold); - serial.writeDMRData(true, frame, DMR_FRAME_LENGTH_BYTES + 1U); + writeRSSIData(frame); reset(); break; } @@ -188,24 +186,7 @@ bool CDMRDMORX::processSample(q15_t sample, uint16_t rssi) } else if (m_control == CONTROL_VOICE) { // Voice sync DEBUG4("DMRDMORX: voice sync found pos/centre/threshold", m_syncPtr, centre, threshold); -#if defined(SEND_RSSI_DATA) - // Send RSSI data approximately every second - if (m_rssiCount == 2U) { - // Calculate RSSI average over a burst period. We don't take into account 2.5 ms at the beginning and 2.5 ms at the end - uint16_t rssi_avg = avgRSSI(m_startPtr + DMR_SYNC_LENGTH_SAMPLES / 2U, DMR_FRAME_LENGTH_SAMPLES - DMR_SYNC_LENGTH_SAMPLES); - frame[34U] = (rssi_avg >> 8) & 0xFFU; - frame[35U] = (rssi_avg >> 0) & 0xFFU; - serial.writeDMRData(true, frame, DMR_FRAME_LENGTH_BYTES + 3U); - } else { - serial.writeDMRData(true, frame, DMR_FRAME_LENGTH_BYTES + 1U); - } - - m_rssiCount++; - if (m_rssiCount >= 16U) - m_rssiCount = 0U; -#else - serial.writeDMRData(true, frame, DMR_FRAME_LENGTH_BYTES + 1U); -#endif + writeRSSIData(frame); m_state = DMORXS_VOICE; m_syncCount = 0U; m_n = 0U; @@ -225,28 +206,12 @@ bool CDMRDMORX::processSample(q15_t sample, uint16_t rssi) } else { frame[0U] = ++m_n; } -#if defined(SEND_RSSI_DATA) - // Send RSSI data approximately every second - if (m_rssiCount == 2U) { - // Calculate RSSI average over a burst period. We don't take into account 2.5 ms at the beginning and 2.5 ms at the end - uint16_t rssi_avg = avgRSSI(m_startPtr + DMR_SYNC_LENGTH_SAMPLES / 2U, DMR_FRAME_LENGTH_SAMPLES - DMR_SYNC_LENGTH_SAMPLES); - frame[34U] = (rssi_avg >> 8) & 0xFFU; - frame[35U] = (rssi_avg >> 0) & 0xFFU; - serial.writeDMRData(true, frame, DMR_FRAME_LENGTH_BYTES + 3U); - } else { - serial.writeDMRData(true, frame, DMR_FRAME_LENGTH_BYTES + 1U); - } - - m_rssiCount++; - if (m_rssiCount >= 16U) - m_rssiCount = 0U; -#else + serial.writeDMRData(true, frame, DMR_FRAME_LENGTH_BYTES + 1U); -#endif } else if (m_state == DMORXS_DATA) { if (m_type != 0x00U) { frame[0U] = CONTROL_DATA | m_type; - serial.writeDMRData(true, frame, DMR_FRAME_LENGTH_BYTES + 1U); + writeRSSIData(frame); } } } @@ -337,7 +302,6 @@ void CDMRDMORX::correlateSync(bool first) m_threshold[0U] = m_threshold[1U] = m_threshold[2U] = m_threshold[3U] = threshold; m_centre[0U] = m_centre[1U] = m_centre[2U] = m_centre[3U] = centre; m_averagePtr = 0U; - m_rssiCount = 0U; } else { m_threshold[m_averagePtr] = threshold; m_centre[m_averagePtr] = centre; @@ -373,7 +337,6 @@ void CDMRDMORX::correlateSync(bool first) m_threshold[0U] = m_threshold[1U] = m_threshold[2U] = m_threshold[3U] = threshold; m_centre[0U] = m_centre[1U] = m_centre[2U] = m_centre[3U] = centre; m_averagePtr = 0U; - m_rssiCount = 0U; } else { m_threshold[m_averagePtr] = threshold; m_centre[m_averagePtr] = centre; @@ -400,21 +363,6 @@ void CDMRDMORX::correlateSync(bool first) } } -uint16_t CDMRDMORX::avgRSSI(uint16_t start, uint16_t count) -{ - float rssi_tmp = 0.0F; - - for (uint16_t i = 0U; i < count; i++) { - rssi_tmp += float(m_rssi[start]); - - start++; - if (start >= DMO_BUFFER_LENGTH_SAMPLES) - start -= DMO_BUFFER_LENGTH_SAMPLES; - } - - return uint16_t(rssi_tmp / count); -} - void CDMRDMORX::samplesToBits(uint16_t start, uint8_t count, uint8_t* buffer, uint16_t offset, q15_t centre, q15_t threshold) { for (uint8_t i = 0U; i < count; i++) { @@ -453,3 +401,27 @@ void CDMRDMORX::setColorCode(uint8_t colorCode) m_colorCode = colorCode; } +void CDMRDMORX::writeRSSIData(uint8_t* frame) +{ +#if defined(SEND_RSSI_DATA) + // Calculate RSSI average over a burst period. We don't take into account 2.5 ms at the beginning and 2.5 ms at the end + uint16_t start = m_startPtr + DMR_SYNC_LENGTH_SAMPLES / 2U; + + uint32_t accum = 0U; + for (uint16_t i = 0U; i < (DMR_FRAME_LENGTH_SAMPLES - DMR_SYNC_LENGTH_SAMPLES); i++) { + accum += m_rssi[start]; + + start++; + if (start >= DMO_BUFFER_LENGTH_SAMPLES) + start -= DMO_BUFFER_LENGTH_SAMPLES; + } + + uint16_t avg = accum / (DMR_FRAME_LENGTH_SAMPLES - DMR_SYNC_LENGTH_SAMPLES); + frame[34U] = (avg >> 8) & 0xFFU; + frame[35U] = (avg >> 0) & 0xFFU; + + serial.writeDMRData(true, frame, DMR_FRAME_LENGTH_BYTES + 3U); +#else + serial.writeDMRData(true, frame, DMR_FRAME_LENGTH_BYTES + 1U); +#endif +} diff --git a/DMRDMORX.h b/DMRDMORX.h index e342348..21de2cc 100644 --- a/DMRDMORX.h +++ b/DMRDMORX.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 @@ -58,13 +58,12 @@ private: DMORX_STATE m_state; uint8_t m_n; uint8_t m_type; - uint16_t m_rssiCount; uint16_t m_rssi[DMO_BUFFER_LENGTH_SAMPLES]; bool processSample(q15_t sample, uint16_t rssi); void correlateSync(bool first); void samplesToBits(uint16_t start, uint8_t count, uint8_t* buffer, uint16_t offset, q15_t centre, q15_t threshold); - uint16_t avgRSSI(uint16_t start, uint16_t count); + void writeRSSIData(uint8_t* frame); }; #endif diff --git a/DMRSlotRX.cpp b/DMRSlotRX.cpp index 708d008..e8d7052 100644 --- a/DMRSlotRX.cpp +++ b/DMRSlotRX.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2009-2016 by Jonathan Naylor G4KLX + * Copyright (C) 2009-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 @@ -65,7 +65,6 @@ m_delay(0U), m_state(DMRRXS_NONE), m_n(0U), m_type(0U), -m_rssiCount(0U), m_rssi() { } @@ -91,7 +90,6 @@ void CDMRSlotRX::reset() m_state = DMRRXS_NONE; m_startPtr = 0U; m_endPtr = NOENDPTR; - m_rssiCount = 0U; } bool CDMRSlotRX::processSample(q15_t sample, uint16_t rssi) @@ -149,7 +147,7 @@ bool CDMRSlotRX::processSample(q15_t sample, uint16_t rssi) switch (dataType) { case DT_DATA_HEADER: DEBUG5("DMRSlotRX: data header found slot/pos/centre/threshold", m_slot ? 2U : 1U, m_syncPtr, centre, threshold); - serial.writeDMRData(m_slot, frame, DMR_FRAME_LENGTH_BYTES + 1U); + writeRSSIData(frame); m_state = DMRRXS_DATA; m_type = 0x00U; break; @@ -158,33 +156,33 @@ bool CDMRSlotRX::processSample(q15_t sample, uint16_t rssi) case DT_RATE_1_DATA: if (m_state == DMRRXS_DATA) { DEBUG5("DMRSlotRX: data payload found slot/pos/centre/threshold", m_slot ? 2U : 1U, m_syncPtr, centre, threshold); - serial.writeDMRData(m_slot, frame, DMR_FRAME_LENGTH_BYTES + 1U); + writeRSSIData(frame); 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); - serial.writeDMRData(m_slot, frame, DMR_FRAME_LENGTH_BYTES + 1U); + writeRSSIData(frame); 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); - serial.writeDMRData(m_slot, frame, DMR_FRAME_LENGTH_BYTES + 1U); + writeRSSIData(frame); } m_state = DMRRXS_VOICE; break; case DT_TERMINATOR_WITH_LC: if (m_state == DMRRXS_VOICE) { DEBUG5("DMRSlotRX: voice terminator found slot/pos/centre/threshold", m_slot ? 2U : 1U, m_syncPtr, centre, threshold); - serial.writeDMRData(m_slot, frame, DMR_FRAME_LENGTH_BYTES + 1U); + writeRSSIData(frame); m_state = DMRRXS_NONE; m_endPtr = NOENDPTR; } break; default: // DT_CSBK DEBUG5("DMRSlotRX: csbk found slot/pos/centre/threshold", m_slot ? 2U : 1U, m_syncPtr, centre, threshold); - serial.writeDMRData(m_slot, frame, DMR_FRAME_LENGTH_BYTES + 1U); + writeRSSIData(frame); m_state = DMRRXS_NONE; m_endPtr = NOENDPTR; break; @@ -193,24 +191,7 @@ bool CDMRSlotRX::processSample(q15_t sample, uint16_t rssi) } else if (m_control == CONTROL_VOICE) { // Voice sync DEBUG5("DMRSlotRX: voice sync found slot/pos/centre/threshold", m_slot ? 2U : 1U, m_syncPtr, centre, threshold); -#if defined(SEND_RSSI_DATA) - // Send RSSI data approximately every second - if (m_rssiCount == 2U) { - // Calculate RSSI average over a burst period. We don't take into account 2.5 ms at the beginning and 2.5 ms at the end - uint16_t rssi_avg = avgRSSI(m_startPtr + DMR_SYNC_LENGTH_SAMPLES / 2U, DMR_FRAME_LENGTH_SAMPLES - DMR_SYNC_LENGTH_SAMPLES); - frame[34U] = (rssi_avg >> 8) & 0xFFU; - frame[35U] = (rssi_avg >> 0) & 0xFFU; - serial.writeDMRData(m_slot, frame, DMR_FRAME_LENGTH_BYTES + 3U); - } else { - serial.writeDMRData(m_slot, frame, DMR_FRAME_LENGTH_BYTES + 1U); - } - - m_rssiCount++; - if (m_rssiCount >= 16U) - m_rssiCount = 0U; -#else - serial.writeDMRData(m_slot, frame, DMR_FRAME_LENGTH_BYTES + 1U); -#endif + writeRSSIData(frame); m_state = DMRRXS_VOICE; m_syncCount = 0U; m_n = 0U; @@ -231,28 +212,12 @@ bool CDMRSlotRX::processSample(q15_t sample, uint16_t rssi) } else { frame[0U] = ++m_n; } -#if defined(SEND_RSSI_DATA) - // Send RSSI data approximately every second - if (m_rssiCount == 2U) { - // Calculate RSSI average over a burst period. We don't take into account 2.5 ms at the beginning and 2.5 ms at the end - uint16_t rssi_avg = avgRSSI(m_startPtr + DMR_SYNC_LENGTH_SAMPLES / 2U, DMR_FRAME_LENGTH_SAMPLES - DMR_SYNC_LENGTH_SAMPLES); - frame[34U] = (rssi_avg >> 8) & 0xFFU; - frame[35U] = (rssi_avg >> 0) & 0xFFU; - serial.writeDMRData(m_slot, frame, DMR_FRAME_LENGTH_BYTES + 3U); - } else { - serial.writeDMRData(m_slot, frame, DMR_FRAME_LENGTH_BYTES + 1U); - } - m_rssiCount++; - if (m_rssiCount >= 16U) - m_rssiCount = 0U; -#else serial.writeDMRData(m_slot, frame, DMR_FRAME_LENGTH_BYTES + 1U); -#endif } else if (m_state == DMRRXS_DATA) { if (m_type != 0x00U) { frame[0U] = CONTROL_DATA | m_type; - serial.writeDMRData(m_slot, frame, DMR_FRAME_LENGTH_BYTES + 1U); + writeRSSIData(frame); } } } @@ -319,7 +284,6 @@ void CDMRSlotRX::correlateSync(bool first) m_threshold[0U] = m_threshold[1U] = m_threshold[2U] = m_threshold[3U] = threshold; m_centre[0U] = m_centre[1U] = m_centre[2U] = m_centre[3U] = centre; m_averagePtr = 0U; - m_rssiCount = 0U; } else { m_threshold[m_averagePtr] = threshold; m_centre[m_averagePtr] = centre; @@ -345,7 +309,6 @@ void CDMRSlotRX::correlateSync(bool first) m_threshold[0U] = m_threshold[1U] = m_threshold[2U] = m_threshold[3U] = threshold; m_centre[0U] = m_centre[1U] = m_centre[2U] = m_centre[3U] = centre; m_averagePtr = 0U; - m_rssiCount = 0U; } else { m_threshold[m_averagePtr] = threshold; m_centre[m_averagePtr] = centre; @@ -366,21 +329,6 @@ void CDMRSlotRX::correlateSync(bool first) } } -uint16_t CDMRSlotRX::avgRSSI(uint16_t start, uint16_t count) -{ - float rssi_tmp = 0.0F; - - for (uint16_t i = 0U; i < count; i++) { - rssi_tmp += float(m_rssi[start]); - - start++; - if (start >= 900U) - start -= 900U; - } - - return uint16_t(rssi_tmp / count); -} - void CDMRSlotRX::samplesToBits(uint16_t start, uint8_t count, uint8_t* buffer, uint16_t offset, q15_t centre, q15_t threshold) { for (uint8_t i = 0U; i < count; i++, start += DMR_RADIO_SYMBOL_LENGTH) { @@ -420,3 +368,22 @@ void CDMRSlotRX::setDelay(uint8_t delay) m_delay = delay; } +void CDMRSlotRX::writeRSSIData(uint8_t* frame) +{ +#if defined(SEND_RSSI_DATA) + // Calculate RSSI average over a burst period. We don't take into account 2.5 ms at the beginning and 2.5 ms at the end + uint16_t start = m_startPtr + DMR_SYNC_LENGTH_SAMPLES / 2U; + + uint32_t accum = 0U; + for (uint16_t i = 0U; i < (DMR_FRAME_LENGTH_SAMPLES - DMR_SYNC_LENGTH_SAMPLES); i++) + accum += m_rssi[start++]; + + uint16_t avg = accum / (DMR_FRAME_LENGTH_SAMPLES - DMR_SYNC_LENGTH_SAMPLES); + frame[34U] = (avg >> 8) & 0xFFU; + frame[35U] = (avg >> 0) & 0xFFU; + + serial.writeDMRData(m_slot, frame, DMR_FRAME_LENGTH_BYTES + 3U); +#else + serial.writeDMRData(m_slot, frame, DMR_FRAME_LENGTH_BYTES + 1U); +#endif +} diff --git a/DMRSlotRX.h b/DMRSlotRX.h index 1a4376b..aab79ff 100644 --- a/DMRSlotRX.h +++ b/DMRSlotRX.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 @@ -62,12 +62,11 @@ private: DMRRX_STATE m_state; uint8_t m_n; uint8_t m_type; - uint16_t m_rssiCount; uint16_t m_rssi[900U]; void correlateSync(bool first); void samplesToBits(uint16_t start, uint8_t count, uint8_t* buffer, uint16_t offset, q15_t centre, q15_t threshold); - uint16_t avgRSSI(uint16_t start, uint16_t count); + void writeRSSIData(uint8_t* frame); }; #endif diff --git a/DStarRX.cpp b/DStarRX.cpp index 81268cb..c606c79 100644 --- a/DStarRX.cpp +++ b/DStarRX.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2009-2016 by Jonathan Naylor G4KLX + * Copyright (C) 2009-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 @@ -275,7 +275,7 @@ void CDStarRX::reset() m_samplesPtr = 0U; } -void CDStarRX::samples(const q15_t* samples, uint8_t length) +void CDStarRX::samples(const q15_t* samples, const uint16_t* rssi, uint8_t length) { for (uint16_t i = 0U; i < length; i++) { m_samples[m_samplesPtr] = samples[i]; @@ -298,13 +298,13 @@ void CDStarRX::samples(const q15_t* samples, uint8_t length) switch (m_rxState) { case DSRXS_NONE: - processNone(bit); + processNone(bit, rssi[i]); break; case DSRXS_HEADER: - processHeader(bit); + processHeader(bit, rssi[i]); break; case DSRXS_DATA: - processData(bit); + processData(bit, rssi[i]); break; default: break; @@ -317,7 +317,7 @@ void CDStarRX::samples(const q15_t* samples, uint8_t length) } } -void CDStarRX::processNone(bool bit) +void CDStarRX::processNone(bool bit, uint16_t rssi) { m_patternBuffer <<= 1; if (bit) @@ -341,7 +341,8 @@ void CDStarRX::processNone(bool bit) io.setDecode(true); io.setADCDetection(true); - serial.writeDStarData(DSTAR_DATA_SYNC_BYTES, DSTAR_DATA_LENGTH_BYTES); + ::memcpy(m_rxBuffer, DSTAR_DATA_SYNC_BYTES, DSTAR_DATA_LENGTH_BYTES); + writeRSSIData(m_rxBuffer, rssi); ::memset(m_rxBuffer, 0x00U, DSTAR_DATA_LENGTH_BYTES + 2U); m_rxBufferBits = 0U; @@ -352,7 +353,7 @@ void CDStarRX::processNone(bool bit) } } -void CDStarRX::processHeader(bool bit) +void CDStarRX::processHeader(bool bit, uint16_t rssi) { m_patternBuffer <<= 1; if (bit) @@ -370,7 +371,7 @@ void CDStarRX::processHeader(bool bit) io.setDecode(true); io.setADCDetection(true); - serial.writeDStarHeader(header, DSTAR_HEADER_LENGTH_BYTES); + writeRSSIHeader(header, rssi); ::memset(m_rxBuffer, 0x00U, DSTAR_DATA_LENGTH_BYTES + 2U); m_rxBufferBits = 0U; @@ -384,7 +385,7 @@ void CDStarRX::processHeader(bool bit) } } -void CDStarRX::processData(bool bit) +void CDStarRX::processData(bool bit, uint16_t rssi) { m_patternBuffer <<= 1; if (bit) @@ -457,9 +458,10 @@ void CDStarRX::processData(bool bit) m_rxBuffer[9U] = DSTAR_DATA_SYNC_BYTES[9U]; m_rxBuffer[10U] = DSTAR_DATA_SYNC_BYTES[10U]; m_rxBuffer[11U] = DSTAR_DATA_SYNC_BYTES[11U]; - } - - serial.writeDStarData(m_rxBuffer, DSTAR_DATA_LENGTH_BYTES); + writeRSSIData(m_rxBuffer, rssi); + } else { + serial.writeDStarData(m_rxBuffer, DSTAR_DATA_LENGTH_BYTES); + } // Start the next frame ::memset(m_rxBuffer, 0x00U, DSTAR_DATA_LENGTH_BYTES + 2U); @@ -467,6 +469,30 @@ void CDStarRX::processData(bool bit) } } +void CDStarRX::writeRSSIHeader(unsigned char* header, uint16_t rssi) +{ +#if defined(SEND_RSSI_DATA) + header[41U] = (rssi >> 8) & 0xFFU; + header[42U] = (rssi >> 0) & 0xFFU; + + serial.writeDStarHeader(header, DSTAR_HEADER_LENGTH_BYTES + 2U); +#else + serial.writeDStarHeader(header, DSTAR_HEADER_LENGTH_BYTES + 0U); +#endif +} + +void CDStarRX::writeRSSIData(unsigned char* data, uint16_t rssi) +{ +#if defined(SEND_RSSI_DATA) + data[12U] = (rssi >> 8) & 0xFFU; + data[13U] = (rssi >> 0) & 0xFFU; + + serial.writeDStarData(data, DSTAR_DATA_LENGTH_BYTES + 2U); +#else + serial.writeDStarData(data, DSTAR_DATA_LENGTH_BYTES + 0U); +#endif +} + bool CDStarRX::rxHeader(uint8_t* in, uint8_t* out) { int i; @@ -682,4 +708,3 @@ bool CDStarRX::checksum(const uint8_t* header) const return crc8[0U] == header[DSTAR_HEADER_LENGTH_BYTES - 2U] && crc8[1U] == header[DSTAR_HEADER_LENGTH_BYTES - 1U]; } - diff --git a/DStarRX.h b/DStarRX.h index dd63ed3..5154be7 100644 --- a/DStarRX.h +++ b/DStarRX.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 @@ -32,7 +32,7 @@ class CDStarRX { public: CDStarRX(); - void samples(const q15_t* samples, uint8_t length); + void samples(const q15_t* samples, const uint16_t* rssi, uint8_t length); void reset(); @@ -54,9 +54,11 @@ private: q15_t m_samples[DSTAR_DATA_SYNC_LENGTH_BITS]; uint8_t m_samplesPtr; - void processNone(bool bit); - void processHeader(bool bit); - void processData(bool bit); + void processNone(bool bit, uint16_t rssi); + void processHeader(bool bit, uint16_t rssi); + void processData(bool bit, uint16_t rssi); + void writeRSSIHeader(unsigned char* header, uint16_t rssi); + void writeRSSIData(unsigned char* data, uint16_t rssi); bool rxHeader(uint8_t* in, uint8_t* out); void acs(int* metric); void viterbiDecode(int* data); diff --git a/DStarTX.cpp b/DStarTX.cpp index 03caa31..3e08aa9 100644 --- a/DStarTX.cpp +++ b/DStarTX.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2009-2016 by Jonathan Naylor G4KLX + * Copyright (C) 2009-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 @@ -457,7 +457,7 @@ void CDStarTX::writeByte(uint8_t c) void CDStarTX::setTXDelay(uint8_t delay) { - m_txDelay = 150U + uint16_t(delay) * 6U; // 250ms + tx delay + m_txDelay = 300U + uint16_t(delay) * 6U; // 250ms + tx delay } uint16_t CDStarTX::getSpace() const diff --git a/DStarTX.h b/DStarTX.h index 828974c..24bb7af 100644 --- a/DStarTX.h +++ b/DStarTX.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 @@ -41,7 +41,7 @@ private: CSerialRB m_buffer; arm_fir_instance_q15 m_modFilter; q15_t m_modState[60U]; // NoTaps + BlockSize - 1, 12 + 40 - 1 plus some spare - uint8_t m_poBuffer[500U]; + uint8_t m_poBuffer[600U]; uint16_t m_poLen; uint16_t m_poPtr; uint16_t m_txDelay; // In bytes diff --git a/IO.cpp b/IO.cpp index 5da8eb1..61f4bd8 100644 --- a/IO.cpp +++ b/IO.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2015,2016 by Jonathan Naylor G4KLX + * Copyright (C) 2015,2016,2017 by Jonathan Naylor G4KLX * Copyright (C) 2015 by Jim Mclaughlin KI6ZUM * Copyright (C) 2016 by Colin Durbridge G4EML * @@ -184,7 +184,7 @@ void CIO::process() q15_t GMSKVals[RX_BLOCK_SIZE + 1U]; ::arm_fir_fast_q15(&m_GMSKFilter, samples, GMSKVals, blockSize); - dstarRX.samples(GMSKVals, blockSize); + dstarRX.samples(GMSKVals, rssi, blockSize); } if (m_dmrEnable || m_ysfEnable || m_p25Enable) { @@ -199,17 +199,17 @@ void CIO::process() } if (m_ysfEnable) - ysfRX.samples(C4FSKVals, blockSize); + ysfRX.samples(C4FSKVals, rssi, blockSize); if (m_p25Enable) - p25RX.samples(C4FSKVals, blockSize); + p25RX.samples(C4FSKVals, rssi, blockSize); } } else if (m_modemState == STATE_DSTAR) { if (m_dstarEnable) { q15_t GMSKVals[RX_BLOCK_SIZE + 1U]; ::arm_fir_fast_q15(&m_GMSKFilter, samples, GMSKVals, blockSize); - dstarRX.samples(GMSKVals, blockSize); + dstarRX.samples(GMSKVals, rssi, blockSize); } } else if (m_modemState == STATE_DMR) { if (m_dmrEnable) { @@ -231,14 +231,14 @@ void CIO::process() q15_t C4FSKVals[RX_BLOCK_SIZE + 1U]; ::arm_fir_fast_q15(&m_C4FSKFilter, samples, C4FSKVals, blockSize); - ysfRX.samples(C4FSKVals, blockSize); + ysfRX.samples(C4FSKVals, rssi, blockSize); } } else if (m_modemState == STATE_P25) { if (m_p25Enable) { q15_t C4FSKVals[RX_BLOCK_SIZE + 1U]; ::arm_fir_fast_q15(&m_C4FSKFilter, samples, C4FSKVals, blockSize); - p25RX.samples(C4FSKVals, blockSize); + p25RX.samples(C4FSKVals, rssi, blockSize); } } else if (m_modemState == STATE_DSTARCAL) { q15_t GMSKVals[RX_BLOCK_SIZE + 1U]; diff --git a/IO.h b/IO.h index 357c04e..d1ec266 100644 --- a/IO.h +++ b/IO.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 @@ -40,7 +40,7 @@ public: void setADCDetection(bool detect); void setMode(); - void interrupt(uint8_t source); + void interrupt(); void setParameters(bool rxInvert, bool txInvert, bool pttInvert, uint8_t rxLevel, uint8_t cwIdTXLevel, uint8_t dstarTXLevel, uint8_t dmrTXLevel, uint8_t ysfTXLevel, uint8_t p25TXLevel); diff --git a/IODue.cpp b/IODue.cpp index ab71d46..8d1e034 100644 --- a/IODue.cpp +++ b/IODue.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2015,2016 by Jonathan Naylor G4KLX + * Copyright (C) 2015,2016,2017 by Jonathan Naylor G4KLX * Copyright (C) 2015 by Jim Mclaughlin KI6ZUM * Copyright (C) 2016 by Colin Durbridge G4EML * @@ -77,7 +77,7 @@ const uint16_t DC_OFFSET = 2048U; extern "C" { void ADC_Handler() { - io.interrupt(0U); + io.interrupt(); } } @@ -101,7 +101,7 @@ void CIO::initInt() void CIO::startInt() { if (ADC->ADC_ISR & ADC_ISR_EOC_Chan) // Ensure there was an End-of-Conversion and we read the ISR reg - io.interrupt(0U); + io.interrupt(); // Set up the ADC NVIC_EnableIRQ(ADC_IRQn); // Enable ADC interrupt vector @@ -164,7 +164,7 @@ void CIO::startInt() digitalWrite(PIN_LED, HIGH); } -void CIO::interrupt(uint8_t source) +void CIO::interrupt() { if ((ADC->ADC_ISR & ADC_ISR_EOC_Chan) == ADC_ISR_EOC_Chan) { // Ensure there was an End-of-Conversion and we read the ISR reg uint8_t control = MARK_NONE; diff --git a/IOSTM.cpp b/IOSTM.cpp index bb27e20..b1bfad4 100644 --- a/IOSTM.cpp +++ b/IOSTM.cpp @@ -1,6 +1,7 @@ /* * Copyright (C) 2016 by Jim McLaughlin KI6ZUM * Copyright (C) 2016 by Andy Uribe CA6JAU + * Copyright (C) 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 @@ -213,7 +214,7 @@ extern "C" { void TIM2_IRQHandler() { if (TIM_GetITStatus(TIM2, TIM_IT_Update) != RESET) { TIM_ClearITPendingBit(TIM2, TIM_IT_Update); - io.interrupt(0U); + io.interrupt(); } } } @@ -280,7 +281,7 @@ void CIO::initInt() void CIO::startInt() { if ((ADC_GetFlagStatus(ADC1, ADC_FLAG_EOC) != RESET)) - io.interrupt(0U); + io.interrupt(); // Init the ADC GPIO_InitTypeDef GPIO_InitStruct; @@ -421,7 +422,7 @@ void CIO::startInt() GPIO_SetBits(PORT_LED, PIN_LED); } -void CIO::interrupt(uint8_t source) +void CIO::interrupt() { uint8_t control = MARK_NONE; uint16_t sample = DC_OFFSET; diff --git a/IOTeensy.cpp b/IOTeensy.cpp index 8c22c77..3f4d9b9 100644 --- a/IOTeensy.cpp +++ b/IOTeensy.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2016 by Jonathan Naylor G4KLX + * Copyright (C) 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 @@ -45,15 +45,8 @@ const uint16_t DC_OFFSET = 2048U; extern "C" { void adc0_isr() { - io.interrupt(0U); + io.interrupt(); } - -#if defined(SEND_RSSI_DATA) - void adc1_isr() - { - io.interrupt(1U); - } -#endif } void CIO::initInt() @@ -116,7 +109,6 @@ void CIO::startInt() ADC1_CLP2 + ADC1_CLP1 + ADC1_CLP0; sum1 = (sum1 / 2U) | 0x8000U; ADC1_PG = sum1; - #endif #if defined(EXTERNAL_OSC) @@ -149,42 +141,33 @@ void CIO::startInt() digitalWrite(PIN_LED, HIGH); } -void CIO::interrupt(uint8_t source) +void CIO::interrupt() { - if (source == 0U) { // ADC0 - uint8_t control = MARK_NONE; - uint16_t sample = DC_OFFSET; + uint8_t control = MARK_NONE; + uint16_t sample = DC_OFFSET; - m_txBuffer.get(sample, control); - *(int16_t *)&(DAC0_DAT0L) = sample; + m_txBuffer.get(sample, control); + *(int16_t *)&(DAC0_DAT0L) = sample; - if ((ADC0_SC1A & ADC_SC1_COCO) == ADC_SC1_COCO) { - sample = ADC0_RA; - m_rxBuffer.put(sample, control); - } + if ((ADC0_SC1A & ADC_SC1_COCO) == ADC_SC1_COCO) { + sample = ADC0_RA; + m_rxBuffer.put(sample, control); + } #if defined(SEND_RSSI_DATA) - - if ((ADC1_SC1A & ADC_SC1_COCO) == ADC_SC1_COCO) { - uint16_t rssi = ADC1_RA; - m_rssiBuffer.put(rssi); - } - else { - m_rssiBuffer.put(0U); - } - ADC1_SC1A = ADC_SC1_AIEN | PIN_RSSI; //start the next RSSI conversion - -#else - m_rssiBuffer.put(0U); -#endif - - - m_watchdog++; + if ((ADC1_SC1A & ADC_SC1_COCO) == ADC_SC1_COCO) { + uint16_t rssi = ADC1_RA; + m_rssiBuffer.put(rssi); + } else { + m_rssiBuffer.put(0U); } + ADC1_SC1A = PIN_RSSI; // Start the next RSSI conversion +#else + m_rssiBuffer.put(0U); +#endif - - + m_watchdog++; } bool CIO::getCOSInt() diff --git a/P25RX.cpp b/P25RX.cpp index bb7ad25..071910a 100644 --- a/P25RX.cpp +++ b/P25RX.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2016 by Jonathan Naylor G4KLX + * Copyright (C) 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 @@ -73,7 +73,7 @@ void CP25RX::reset() m_threshold = 0; } -void CP25RX::samples(const q15_t* samples, uint8_t length) +void CP25RX::samples(const q15_t* samples, const uint16_t* rssi, uint8_t length) { for (uint16_t i = 0U; i < length; i++) { bool bit = samples[i] < 0; @@ -95,7 +95,7 @@ void CP25RX::samples(const q15_t* samples, uint8_t length) if (m_state == P25RXS_NONE) processNone(samples[i]); else - processData(samples[i]); + processData(samples[i], rssi[i]); } } } @@ -173,7 +173,7 @@ void CP25RX::processNone(q15_t sample) m_symbolPtr = 0U; } -void CP25RX::processData(q15_t sample) +void CP25RX::processData(q15_t sample, uint16_t rssi) { sample -= m_centre; @@ -251,7 +251,7 @@ void CP25RX::processData(q15_t sample) } else { m_outBuffer[0U] = m_lostCount == (MAX_SYNC_FRAMES - 1U) ? 0x01U : 0x00U; - serial.writeP25Ldu(m_outBuffer, P25_LDU_FRAME_LENGTH_BYTES + 1U); + writeRSSILdu(m_outBuffer, rssi); // Start the next frame ::memset(m_outBuffer, 0x00U, P25_LDU_FRAME_LENGTH_BYTES + 3U); @@ -260,3 +260,14 @@ void CP25RX::processData(q15_t sample) } } +void CP25RX::writeRSSILdu(uint8_t* ldu, uint16_t rssi) +{ +#if defined(SEND_RSSI_DATA) + ldu[216U] = (rssi >> 8) & 0xFFU; + ldu[217U] = (rssi >> 0) & 0xFFU; + + serial.writeP25Ldu(ldu, P25_LDU_FRAME_LENGTH_BYTES + 3U); +#else + serial.writeP25Ldu(ldu, P25_LDU_FRAME_LENGTH_BYTES + 1U); +#endif +} diff --git a/P25RX.h b/P25RX.h index 691763d..f68fe93 100644 --- a/P25RX.h +++ b/P25RX.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 @@ -31,7 +31,7 @@ class CP25RX { public: CP25RX(); - void samples(const q15_t* samples, uint8_t length); + void samples(const q15_t* samples, const uint16_t* rssi, uint8_t length); void reset(); @@ -51,7 +51,8 @@ private: q15_t m_threshold; void processNone(q15_t sample); - void processData(q15_t sample); + void processData(q15_t sample, uint16_t rssi); + void writeRSSILdu(uint8_t* data, uint16_t rssi); }; #endif diff --git a/P25TX.h b/P25TX.h index bbe6393..4340d35 100644 --- a/P25TX.h +++ b/P25TX.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2016 by Jonathan Naylor G4KLX + * Copyright (C) 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 @@ -41,7 +41,7 @@ private: arm_fir_instance_q15 m_lpFilter; q15_t m_modState[70U]; // NoTaps + BlockSize - 1, 42 + 20 - 1 plus some spare q15_t m_lpState[70U]; // NoTaps + BlockSize - 1, 44 + 20 - 1 plus some spare - uint8_t m_poBuffer[920U]; + uint8_t m_poBuffer[1200U]; uint16_t m_poLen; uint16_t m_poPtr; uint16_t m_txDelay; diff --git a/YSFRX.cpp b/YSFRX.cpp index cfe4fab..cb54e23 100644 --- a/YSFRX.cpp +++ b/YSFRX.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2009-2016 by Jonathan Naylor G4KLX + * Copyright (C) 2009-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 @@ -73,7 +73,7 @@ void CYSFRX::reset() m_threshold = 0; } -void CYSFRX::samples(const q15_t* samples, uint8_t length) +void CYSFRX::samples(const q15_t* samples, const uint16_t* rssi, uint8_t length) { for (uint16_t i = 0U; i < length; i++) { bool bit = samples[i] < 0; @@ -95,7 +95,7 @@ void CYSFRX::samples(const q15_t* samples, uint8_t length) if (m_state == YSFRXS_NONE) processNone(samples[i]); else - processData(samples[i]); + processData(samples[i], rssi[i]); } } } @@ -173,7 +173,7 @@ void CYSFRX::processNone(q15_t sample) m_symbolPtr = 0U; } -void CYSFRX::processData(q15_t sample) +void CYSFRX::processData(q15_t sample, uint16_t rssi) { sample -= m_centre; @@ -233,7 +233,7 @@ void CYSFRX::processData(q15_t sample) } else { m_outBuffer[0U] = m_lostCount == (MAX_SYNC_FRAMES - 1U) ? 0x01U : 0x00U; - serial.writeYSFData(m_outBuffer, YSF_FRAME_LENGTH_BYTES + 1U); + writeRSSIData(m_outBuffer, rssi); // Start the next frame ::memset(m_outBuffer, 0x00U, YSF_FRAME_LENGTH_BYTES + 3U); @@ -242,3 +242,14 @@ void CYSFRX::processData(q15_t sample) } } +void CYSFRX::writeRSSIData(uint8_t* data, uint16_t rssi) +{ +#if defined(SEND_RSSI_DATA) + data[120U] = (rssi >> 8) & 0xFFU; + data[121U] = (rssi >> 0) & 0xFFU; + + serial.writeYSFData(data, YSF_FRAME_LENGTH_BYTES + 3U); +#else + serial.writeYSFData(data, YSF_FRAME_LENGTH_BYTES + 1U); +#endif +} diff --git a/YSFRX.h b/YSFRX.h index 8f8f770..5f18993 100644 --- a/YSFRX.h +++ b/YSFRX.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 @@ -31,7 +31,7 @@ class CYSFRX { public: CYSFRX(); - void samples(const q15_t* samples, uint8_t length); + void samples(const q15_t* samples, const uint16_t* rssi, uint8_t length); void reset(); @@ -51,7 +51,8 @@ private: q15_t m_threshold; void processNone(q15_t sample); - void processData(q15_t sample); + void processData(q15_t sample, uint16_t rssi); + void writeRSSIData(unsigned char* data, uint16_t rssi); }; #endif diff --git a/YSFTX.h b/YSFTX.h index 309cacc..21fcabc 100644 --- a/YSFTX.h +++ b/YSFTX.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 @@ -39,7 +39,7 @@ private: CSerialRB m_buffer; arm_fir_instance_q15 m_modFilter; q15_t m_modState[70U]; // NoTaps + BlockSize - 1, 42 + 20 - 1 plus some spare - uint8_t m_poBuffer[920U]; + uint8_t m_poBuffer[1200U]; uint16_t m_poLen; uint16_t m_poPtr; uint16_t m_txDelay;