diff --git a/Config.h b/Config.h index f594cf0..27f7290 100644 --- a/Config.h +++ b/Config.h @@ -48,5 +48,8 @@ // To use wider C4FSK filters for DMR and System Fusion on receive // #define WIDE_C4FSK_FILTERS_RX +// Pass RSSI information to the host +// #define SEND_RSSI_DATA + #endif diff --git a/DMRSlotRX.cpp b/DMRSlotRX.cpp index 05af4b5..5ad4070 100644 --- a/DMRSlotRX.cpp +++ b/DMRSlotRX.cpp @@ -64,7 +64,9 @@ m_colorCode(0U), m_delay(0U), m_state(DMRRXS_NONE), m_n(0U), -m_type(0U) +m_type(0U), +m_rssiCount(0U), +m_rssi(0U) { } @@ -89,6 +91,7 @@ void CDMRSlotRX::reset() m_state = DMRRXS_NONE; m_startPtr = 0U; m_endPtr = NOENDPTR; + m_rssiCount = 0U; } bool CDMRSlotRX::processSample(q15_t sample) @@ -120,6 +123,11 @@ bool CDMRSlotRX::processSample(q15_t sample) if (m_dataPtr >= SCAN_START && m_dataPtr <= SCAN_END) correlateSync(true); } else { +#if defined(SEND_RSSI_DATA) + // Grab the RSSI data near the centre of the frame + if (m_state == DMRRXS_VOICE && m_dataPtr == m_syncPtr && m_rssiCount == 0U) + m_rssi = io.getRSSIValue(); +#endif uint16_t min = m_syncPtr - 1U; uint16_t max = m_syncPtr + 1U; if (m_dataPtr >= min && m_dataPtr <= max) @@ -131,7 +139,7 @@ bool CDMRSlotRX::processSample(q15_t sample) q15_t centre = (m_centre[0U] + m_centre[1U] + m_centre[2U] + m_centre[3U]) >> 2; q15_t threshold = (m_threshold[0U] + m_threshold[1U] + m_threshold[2U] + m_threshold[3U]) >> 2; - uint8_t frame[DMR_FRAME_LENGTH_BYTES + 1U]; + uint8_t frame[DMR_FRAME_LENGTH_BYTES + 3U]; frame[0U] = m_control; uint16_t ptr = m_endPtr - DMR_FRAME_LENGTH_SAMPLES + DMR_RADIO_SYMBOL_LENGTH + 1U; @@ -197,7 +205,22 @@ bool CDMRSlotRX::processSample(q15_t sample) } 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 0.5 seconds + if (m_rssiCount == 0U) { + frame[34U] = (m_rssi >> 8) & 0xFFU; + frame[35U] = (m_rssi >> 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 >= 8U) + m_rssiCount = 0U; +#else serial.writeDMRData(m_slot, frame, DMR_FRAME_LENGTH_BYTES + 1U); +#endif m_state = DMRRXS_VOICE; m_syncCount = 0U; m_n = 0U; @@ -214,12 +237,26 @@ bool CDMRSlotRX::processSample(q15_t sample) if (m_state == DMRRXS_VOICE) { if (m_n >= 5U) { frame[0U] = CONTROL_VOICE; - serial.writeDMRData(m_slot, frame, DMR_FRAME_LENGTH_BYTES + 1U); m_n = 0U; } else { frame[0U] = ++m_n; + } +#if defined(SEND_RSSI_DATA) + // Send RSSI data approximately every 0.5 seconds + if (m_rssiCount == 0U) { + frame[34U] = (m_rssi >> 8) & 0xFFU; + frame[35U] = (m_rssi >> 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 >= 8U) + 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; @@ -290,6 +327,7 @@ 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; @@ -315,6 +353,7 @@ 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; diff --git a/DMRSlotRX.h b/DMRSlotRX.h index 994839f..12482d0 100644 --- a/DMRSlotRX.h +++ b/DMRSlotRX.h @@ -62,6 +62,8 @@ private: DMRRX_STATE m_state; uint8_t m_n; uint8_t m_type; + uint16_t m_rssiCount; + uint16_t m_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); diff --git a/DStarRX.cpp b/DStarRX.cpp index 15edfcc..9a2eb61 100644 --- a/DStarRX.cpp +++ b/DStarRX.cpp @@ -260,7 +260,8 @@ m_pathMemory2(), m_pathMemory3(), m_fecOutput(), m_samples(), -m_samplesPtr(0U) +m_samplesPtr(0U), +m_rssiCount(0U) { } @@ -273,6 +274,7 @@ void CDStarRX::reset() m_rxBufferBits = 0U; m_dataBits = 0U; m_samplesPtr = 0U; + m_rssiCount = 0U; } void CDStarRX::samples(const q15_t* samples, uint8_t length) @@ -343,11 +345,12 @@ void CDStarRX::processNone(bool bit) serial.writeDStarData(DSTAR_DATA_SYNC_BYTES, DSTAR_DATA_LENGTH_BYTES); - ::memset(m_rxBuffer, 0x00U, DSTAR_DATA_LENGTH_BYTES); + ::memset(m_rxBuffer, 0x00U, DSTAR_DATA_LENGTH_BYTES + 2U); m_rxBufferBits = 0U; - m_dataBits = 0U; - m_rxState = DSRXS_DATA; + m_dataBits = 0U; + m_rssiCount = 0U; + m_rxState = DSRXS_DATA; return; } } @@ -372,11 +375,12 @@ void CDStarRX::processHeader(bool bit) serial.writeDStarHeader(header, DSTAR_HEADER_LENGTH_BYTES); - ::memset(m_rxBuffer, 0x00U, DSTAR_DATA_LENGTH_BYTES); + ::memset(m_rxBuffer, 0x00U, DSTAR_DATA_LENGTH_BYTES + 2U); m_rxBufferBits = 0U; - m_rxState = DSRXS_DATA; - m_dataBits = SYNC_POS - DSTAR_DATA_LENGTH_BITS + 1U; + m_rxState = DSRXS_DATA; + m_rssiCount = 0U; + m_dataBits = SYNC_POS - DSTAR_DATA_LENGTH_BITS + 1U; } else { // The checksum failed, return to looking for syncs m_rxState = DSRXS_NONE; @@ -459,10 +463,26 @@ void CDStarRX::processData(bool bit) m_rxBuffer[11U] = DSTAR_DATA_SYNC_BYTES[11U]; } +#if defined(SEND_RSSI_DATA) + // Send RSSI data every 0.5 seconds + if (m_rssiCount == 0U) { + uint16_t rssi = io.getRSSIValue(); + m_rxBuffer[12U] = (rssi >> 8) & 0xFFU; + m_rxBuffer[13U] = (rssi >> 0) & 0xFFU; + serial.writeDStarData(m_rxBuffer, DSTAR_DATA_LENGTH_BYTES + 2U); + } else { + serial.writeDStarData(m_rxBuffer, DSTAR_DATA_LENGTH_BYTES); + } + + m_rssiCount++; + if (m_rssiCount >= 25U) + m_rssiCount = 0U; +#else serial.writeDStarData(m_rxBuffer, DSTAR_DATA_LENGTH_BYTES); +#endif // Start the next frame - ::memset(m_rxBuffer, 0x00U, DSTAR_DATA_LENGTH_BYTES); + ::memset(m_rxBuffer, 0x00U, DSTAR_DATA_LENGTH_BYTES + 2U); m_rxBufferBits = 0U; } } diff --git a/DStarRX.h b/DStarRX.h index dd63ed3..a9252a8 100644 --- a/DStarRX.h +++ b/DStarRX.h @@ -53,6 +53,7 @@ private: uint8_t m_fecOutput[42U]; q15_t m_samples[DSTAR_DATA_SYNC_LENGTH_BITS]; uint8_t m_samplesPtr; + uint16_t m_rssiCount; void processNone(bool bit); void processHeader(bool bit); diff --git a/IO.cpp b/IO.cpp index ce98e1b..1b79b47 100644 --- a/IO.cpp +++ b/IO.cpp @@ -61,6 +61,7 @@ const uint16_t DC_OFFSET = 2048U; #define PIN_DSTAR 9 #define PIN_DMR 8 #define PIN_YSF 7 +#define PIN_RSSI 88 // ADC on Due pin A8 - Due AD10 #define ADC_CHER_Chan (1<<13) // ADC on Due pin A11 - Due AD13 - (1 << 13) (PB20) #define ADC_ISR_EOC_Chan ADC_ISR_EOC13 #define ADC_CDR_Chan 13 @@ -158,6 +159,11 @@ m_lockout(false) pinMode(PIN_DMR, OUTPUT); pinMode(PIN_YSF, OUTPUT); #endif + +#if defined(SEND_RSSI_DATA) + pinMode(PIN_RSSI, INPUT); + analogReadResolution(12); +#endif #endif } @@ -544,3 +550,10 @@ bool CIO::hasLockout() const return m_lockout; } +#if defined(SEND_RSSI_DATA) +uint16_t CIO::getRSSIValue() +{ + return analogRead(PIN_RSSI); +} +#endif + diff --git a/IO.h b/IO.h index bf047e2..5fa529d 100644 --- a/IO.h +++ b/IO.h @@ -52,6 +52,10 @@ public: void resetWatchdog(); +#if defined(SEND_RSSI_DATA) + uint16_t getRSSIValue(); +#endif + private: #if defined(__MBED__) DigitalOut m_pinPTT; diff --git a/YSFRX.cpp b/YSFRX.cpp index 37826af..579334a 100644 --- a/YSFRX.cpp +++ b/YSFRX.cpp @@ -54,6 +54,7 @@ m_buffer(NULL), m_bufferPtr(0U), m_symbolPtr(0U), m_lostCount(0U), +m_rssiCount(0U), m_centre(0), m_threshold(0) { @@ -69,6 +70,7 @@ void CYSFRX::reset() m_bufferPtr = 0U; m_symbolPtr = 0U; m_lostCount = 0U; + m_rssiCount = 0U; m_centre = 0; m_threshold = 0; } @@ -162,6 +164,7 @@ void CYSFRX::processNone(q15_t sample) m_lostCount = MAX_SYNC_FRAMES; m_bufferPtr = YSF_SYNC_LENGTH_BITS; m_state = YSFRXS_DATA; + m_rssiCount = 0U; io.setDecode(true); io.setADCDetection(true); @@ -233,10 +236,26 @@ void CYSFRX::processData(q15_t sample) } else { m_outBuffer[0U] = m_lostCount == (MAX_SYNC_FRAMES - 1U) ? 0x01U : 0x00U; +#if defined(SEND_RSSI_DATA) + // Send RSSI data every 0.5 seconds + if (m_rssiCount == 0U) { + uint16_t rssi = io.getRSSIValue(); + m_outBuffer[121U] = (rssi >> 8) & 0xFFU; + m_outBuffer[122U] = (rssi >> 0) & 0xFFU; + serial.writeYSFData(m_outBuffer, YSF_FRAME_LENGTH_BYTES + 3U); + } else { + serial.writeYSFData(m_outBuffer, YSF_FRAME_LENGTH_BYTES + 1U); + } + + m_rssiCount++; + if (m_rssiCount >= 5U) + m_rssiCount = 0U; +#else serial.writeYSFData(m_outBuffer, YSF_FRAME_LENGTH_BYTES + 1U); +#endif // Start the next frame - ::memset(m_outBuffer, 0x00U, YSF_FRAME_LENGTH_BYTES + 1U); + ::memset(m_outBuffer, 0x00U, YSF_FRAME_LENGTH_BYTES + 3U); m_bufferPtr = 0U; } } diff --git a/YSFRX.h b/YSFRX.h index 22228ce..41a8b71 100644 --- a/YSFRX.h +++ b/YSFRX.h @@ -42,11 +42,12 @@ private: uint32_t m_symbolBuffer; uint64_t m_bitBuffer; q15_t m_symbols[YSF_SYNC_LENGTH_SYMBOLS]; - uint8_t m_outBuffer[YSF_FRAME_LENGTH_BYTES + 1U]; + uint8_t m_outBuffer[YSF_FRAME_LENGTH_BYTES + 3U]; uint8_t* m_buffer; uint16_t m_bufferPtr; uint16_t m_symbolPtr; uint16_t m_lostCount; + uint16_t m_rssiCount; q15_t m_centre; q15_t m_threshold;