mirror of https://github.com/markqvist/MMDVM.git
Add RSSI reporting for all modes.
parent
8777c2b29c
commit
57fde3afcc
96
DMRDMORX.cpp
96
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
|
* 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
|
* 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_state(DMORXS_NONE),
|
||||||
m_n(0U),
|
m_n(0U),
|
||||||
m_type(0U),
|
m_type(0U),
|
||||||
m_rssiCount(0U),
|
|
||||||
m_rssi()
|
m_rssi()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
@ -73,7 +72,6 @@ void CDMRDMORX::reset()
|
||||||
m_state = DMORXS_NONE;
|
m_state = DMORXS_NONE;
|
||||||
m_startPtr = 0U;
|
m_startPtr = 0U;
|
||||||
m_endPtr = NOENDPTR;
|
m_endPtr = NOENDPTR;
|
||||||
m_rssiCount = 0U;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void CDMRDMORX::samples(const q15_t* samples, const uint16_t* rssi, uint8_t length)
|
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) {
|
switch (dataType) {
|
||||||
case DT_DATA_HEADER:
|
case DT_DATA_HEADER:
|
||||||
DEBUG4("DMRDMORX: data header found pos/centre/threshold", m_syncPtr, centre, threshold);
|
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_state = DMORXS_DATA;
|
||||||
m_type = 0x00U;
|
m_type = 0x00U;
|
||||||
break;
|
break;
|
||||||
|
@ -155,32 +153,32 @@ bool CDMRDMORX::processSample(q15_t sample, uint16_t rssi)
|
||||||
case DT_RATE_1_DATA:
|
case DT_RATE_1_DATA:
|
||||||
if (m_state == DMORXS_DATA) {
|
if (m_state == DMORXS_DATA) {
|
||||||
DEBUG4("DMRDMORX: data payload found pos/centre/threshold", m_syncPtr, centre, threshold);
|
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;
|
m_type = dataType;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case DT_VOICE_LC_HEADER:
|
case DT_VOICE_LC_HEADER:
|
||||||
DEBUG4("DMRDMORX: voice header found pos/centre/threshold", m_syncPtr, centre, threshold);
|
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;
|
m_state = DMORXS_VOICE;
|
||||||
break;
|
break;
|
||||||
case DT_VOICE_PI_HEADER:
|
case DT_VOICE_PI_HEADER:
|
||||||
if (m_state == DMORXS_VOICE) {
|
if (m_state == DMORXS_VOICE) {
|
||||||
DEBUG4("DMRDMORX: voice pi header found pos/centre/threshold", m_syncPtr, centre, threshold);
|
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;
|
m_state = DMORXS_VOICE;
|
||||||
break;
|
break;
|
||||||
case DT_TERMINATOR_WITH_LC:
|
case DT_TERMINATOR_WITH_LC:
|
||||||
if (m_state == DMORXS_VOICE) {
|
if (m_state == DMORXS_VOICE) {
|
||||||
DEBUG4("DMRDMORX: voice terminator found pos/centre/threshold", m_syncPtr, centre, threshold);
|
DEBUG4("DMRDMORX: voice terminator found pos/centre/threshold", m_syncPtr, centre, threshold);
|
||||||
serial.writeDMRData(true, frame, DMR_FRAME_LENGTH_BYTES + 1U);
|
writeRSSIData(frame);
|
||||||
reset();
|
reset();
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
default: // DT_CSBK
|
default: // DT_CSBK
|
||||||
DEBUG4("DMRDMORX: csbk found pos/centre/threshold", m_syncPtr, centre, threshold);
|
DEBUG4("DMRDMORX: csbk found pos/centre/threshold", m_syncPtr, centre, threshold);
|
||||||
serial.writeDMRData(true, frame, DMR_FRAME_LENGTH_BYTES + 1U);
|
writeRSSIData(frame);
|
||||||
reset();
|
reset();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -188,24 +186,7 @@ bool CDMRDMORX::processSample(q15_t sample, uint16_t rssi)
|
||||||
} else if (m_control == CONTROL_VOICE) {
|
} else if (m_control == CONTROL_VOICE) {
|
||||||
// Voice sync
|
// Voice sync
|
||||||
DEBUG4("DMRDMORX: voice sync found pos/centre/threshold", m_syncPtr, centre, threshold);
|
DEBUG4("DMRDMORX: voice sync found pos/centre/threshold", m_syncPtr, centre, threshold);
|
||||||
#if defined(SEND_RSSI_DATA)
|
writeRSSIData(frame);
|
||||||
// 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
|
|
||||||
m_state = DMORXS_VOICE;
|
m_state = DMORXS_VOICE;
|
||||||
m_syncCount = 0U;
|
m_syncCount = 0U;
|
||||||
m_n = 0U;
|
m_n = 0U;
|
||||||
|
@ -225,28 +206,12 @@ bool CDMRDMORX::processSample(q15_t sample, uint16_t rssi)
|
||||||
} else {
|
} else {
|
||||||
frame[0U] = ++m_n;
|
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);
|
serial.writeDMRData(true, frame, DMR_FRAME_LENGTH_BYTES + 1U);
|
||||||
#endif
|
|
||||||
} else if (m_state == DMORXS_DATA) {
|
} else if (m_state == DMORXS_DATA) {
|
||||||
if (m_type != 0x00U) {
|
if (m_type != 0x00U) {
|
||||||
frame[0U] = CONTROL_DATA | m_type;
|
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_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_centre[0U] = m_centre[1U] = m_centre[2U] = m_centre[3U] = centre;
|
||||||
m_averagePtr = 0U;
|
m_averagePtr = 0U;
|
||||||
m_rssiCount = 0U;
|
|
||||||
} else {
|
} else {
|
||||||
m_threshold[m_averagePtr] = threshold;
|
m_threshold[m_averagePtr] = threshold;
|
||||||
m_centre[m_averagePtr] = centre;
|
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_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_centre[0U] = m_centre[1U] = m_centre[2U] = m_centre[3U] = centre;
|
||||||
m_averagePtr = 0U;
|
m_averagePtr = 0U;
|
||||||
m_rssiCount = 0U;
|
|
||||||
} else {
|
} else {
|
||||||
m_threshold[m_averagePtr] = threshold;
|
m_threshold[m_averagePtr] = threshold;
|
||||||
m_centre[m_averagePtr] = centre;
|
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)
|
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++) {
|
for (uint8_t i = 0U; i < count; i++) {
|
||||||
|
@ -453,3 +401,27 @@ void CDMRDMORX::setColorCode(uint8_t colorCode)
|
||||||
m_colorCode = 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
|
||||||
|
}
|
||||||
|
|
|
@ -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
|
* 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
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
@ -58,13 +58,12 @@ private:
|
||||||
DMORX_STATE m_state;
|
DMORX_STATE m_state;
|
||||||
uint8_t m_n;
|
uint8_t m_n;
|
||||||
uint8_t m_type;
|
uint8_t m_type;
|
||||||
uint16_t m_rssiCount;
|
|
||||||
uint16_t m_rssi[DMO_BUFFER_LENGTH_SAMPLES];
|
uint16_t m_rssi[DMO_BUFFER_LENGTH_SAMPLES];
|
||||||
|
|
||||||
bool processSample(q15_t sample, uint16_t rssi);
|
bool processSample(q15_t sample, uint16_t rssi);
|
||||||
void correlateSync(bool first);
|
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 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
|
#endif
|
||||||
|
|
|
@ -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
|
* 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
|
* 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_state(DMRRXS_NONE),
|
||||||
m_n(0U),
|
m_n(0U),
|
||||||
m_type(0U),
|
m_type(0U),
|
||||||
m_rssiCount(0U),
|
|
||||||
m_rssi()
|
m_rssi()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
@ -91,7 +90,6 @@ void CDMRSlotRX::reset()
|
||||||
m_state = DMRRXS_NONE;
|
m_state = DMRRXS_NONE;
|
||||||
m_startPtr = 0U;
|
m_startPtr = 0U;
|
||||||
m_endPtr = NOENDPTR;
|
m_endPtr = NOENDPTR;
|
||||||
m_rssiCount = 0U;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CDMRSlotRX::processSample(q15_t sample, uint16_t rssi)
|
bool CDMRSlotRX::processSample(q15_t sample, uint16_t rssi)
|
||||||
|
@ -149,7 +147,7 @@ bool CDMRSlotRX::processSample(q15_t sample, uint16_t rssi)
|
||||||
switch (dataType) {
|
switch (dataType) {
|
||||||
case DT_DATA_HEADER:
|
case DT_DATA_HEADER:
|
||||||
DEBUG5("DMRSlotRX: data header found slot/pos/centre/threshold", m_slot ? 2U : 1U, m_syncPtr, centre, threshold);
|
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_state = DMRRXS_DATA;
|
||||||
m_type = 0x00U;
|
m_type = 0x00U;
|
||||||
break;
|
break;
|
||||||
|
@ -158,33 +156,33 @@ bool CDMRSlotRX::processSample(q15_t sample, uint16_t rssi)
|
||||||
case DT_RATE_1_DATA:
|
case DT_RATE_1_DATA:
|
||||||
if (m_state == DMRRXS_DATA) {
|
if (m_state == DMRRXS_DATA) {
|
||||||
DEBUG5("DMRSlotRX: data payload found slot/pos/centre/threshold", m_slot ? 2U : 1U, m_syncPtr, centre, threshold);
|
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;
|
m_type = dataType;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case DT_VOICE_LC_HEADER:
|
case DT_VOICE_LC_HEADER:
|
||||||
DEBUG5("DMRSlotRX: voice header found slot/pos/centre/threshold", m_slot ? 2U : 1U, m_syncPtr, centre, threshold);
|
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;
|
m_state = DMRRXS_VOICE;
|
||||||
break;
|
break;
|
||||||
case DT_VOICE_PI_HEADER:
|
case DT_VOICE_PI_HEADER:
|
||||||
if (m_state == DMRRXS_VOICE) {
|
if (m_state == DMRRXS_VOICE) {
|
||||||
DEBUG5("DMRSlotRX: voice pi header found slot/pos/centre/threshold", m_slot ? 2U : 1U, m_syncPtr, centre, threshold);
|
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;
|
m_state = DMRRXS_VOICE;
|
||||||
break;
|
break;
|
||||||
case DT_TERMINATOR_WITH_LC:
|
case DT_TERMINATOR_WITH_LC:
|
||||||
if (m_state == DMRRXS_VOICE) {
|
if (m_state == DMRRXS_VOICE) {
|
||||||
DEBUG5("DMRSlotRX: voice terminator found slot/pos/centre/threshold", m_slot ? 2U : 1U, m_syncPtr, centre, threshold);
|
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_state = DMRRXS_NONE;
|
||||||
m_endPtr = NOENDPTR;
|
m_endPtr = NOENDPTR;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
default: // DT_CSBK
|
default: // DT_CSBK
|
||||||
DEBUG5("DMRSlotRX: csbk found slot/pos/centre/threshold", m_slot ? 2U : 1U, m_syncPtr, centre, threshold);
|
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_state = DMRRXS_NONE;
|
||||||
m_endPtr = NOENDPTR;
|
m_endPtr = NOENDPTR;
|
||||||
break;
|
break;
|
||||||
|
@ -193,24 +191,7 @@ bool CDMRSlotRX::processSample(q15_t sample, uint16_t rssi)
|
||||||
} else if (m_control == CONTROL_VOICE) {
|
} else if (m_control == CONTROL_VOICE) {
|
||||||
// Voice sync
|
// Voice sync
|
||||||
DEBUG5("DMRSlotRX: voice sync found slot/pos/centre/threshold", m_slot ? 2U : 1U, m_syncPtr, centre, threshold);
|
DEBUG5("DMRSlotRX: voice sync found slot/pos/centre/threshold", m_slot ? 2U : 1U, m_syncPtr, centre, threshold);
|
||||||
#if defined(SEND_RSSI_DATA)
|
writeRSSIData(frame);
|
||||||
// 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
|
|
||||||
m_state = DMRRXS_VOICE;
|
m_state = DMRRXS_VOICE;
|
||||||
m_syncCount = 0U;
|
m_syncCount = 0U;
|
||||||
m_n = 0U;
|
m_n = 0U;
|
||||||
|
@ -231,28 +212,12 @@ bool CDMRSlotRX::processSample(q15_t sample, uint16_t rssi)
|
||||||
} else {
|
} else {
|
||||||
frame[0U] = ++m_n;
|
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);
|
serial.writeDMRData(m_slot, frame, DMR_FRAME_LENGTH_BYTES + 1U);
|
||||||
#endif
|
|
||||||
} else if (m_state == DMRRXS_DATA) {
|
} else if (m_state == DMRRXS_DATA) {
|
||||||
if (m_type != 0x00U) {
|
if (m_type != 0x00U) {
|
||||||
frame[0U] = CONTROL_DATA | m_type;
|
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_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_centre[0U] = m_centre[1U] = m_centre[2U] = m_centre[3U] = centre;
|
||||||
m_averagePtr = 0U;
|
m_averagePtr = 0U;
|
||||||
m_rssiCount = 0U;
|
|
||||||
} else {
|
} else {
|
||||||
m_threshold[m_averagePtr] = threshold;
|
m_threshold[m_averagePtr] = threshold;
|
||||||
m_centre[m_averagePtr] = centre;
|
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_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_centre[0U] = m_centre[1U] = m_centre[2U] = m_centre[3U] = centre;
|
||||||
m_averagePtr = 0U;
|
m_averagePtr = 0U;
|
||||||
m_rssiCount = 0U;
|
|
||||||
} else {
|
} else {
|
||||||
m_threshold[m_averagePtr] = threshold;
|
m_threshold[m_averagePtr] = threshold;
|
||||||
m_centre[m_averagePtr] = centre;
|
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)
|
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) {
|
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;
|
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
|
||||||
|
}
|
||||||
|
|
|
@ -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
|
* 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
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
@ -62,12 +62,11 @@ private:
|
||||||
DMRRX_STATE m_state;
|
DMRRX_STATE m_state;
|
||||||
uint8_t m_n;
|
uint8_t m_n;
|
||||||
uint8_t m_type;
|
uint8_t m_type;
|
||||||
uint16_t m_rssiCount;
|
|
||||||
uint16_t m_rssi[900U];
|
uint16_t m_rssi[900U];
|
||||||
|
|
||||||
void correlateSync(bool first);
|
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 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
|
#endif
|
||||||
|
|
53
DStarRX.cpp
53
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
|
* 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
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
@ -275,7 +275,7 @@ void CDStarRX::reset()
|
||||||
m_samplesPtr = 0U;
|
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++) {
|
for (uint16_t i = 0U; i < length; i++) {
|
||||||
m_samples[m_samplesPtr] = samples[i];
|
m_samples[m_samplesPtr] = samples[i];
|
||||||
|
@ -298,13 +298,13 @@ void CDStarRX::samples(const q15_t* samples, uint8_t length)
|
||||||
|
|
||||||
switch (m_rxState) {
|
switch (m_rxState) {
|
||||||
case DSRXS_NONE:
|
case DSRXS_NONE:
|
||||||
processNone(bit);
|
processNone(bit, rssi[i]);
|
||||||
break;
|
break;
|
||||||
case DSRXS_HEADER:
|
case DSRXS_HEADER:
|
||||||
processHeader(bit);
|
processHeader(bit, rssi[i]);
|
||||||
break;
|
break;
|
||||||
case DSRXS_DATA:
|
case DSRXS_DATA:
|
||||||
processData(bit);
|
processData(bit, rssi[i]);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
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;
|
m_patternBuffer <<= 1;
|
||||||
if (bit)
|
if (bit)
|
||||||
|
@ -341,7 +341,8 @@ void CDStarRX::processNone(bool bit)
|
||||||
io.setDecode(true);
|
io.setDecode(true);
|
||||||
io.setADCDetection(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);
|
::memset(m_rxBuffer, 0x00U, DSTAR_DATA_LENGTH_BYTES + 2U);
|
||||||
m_rxBufferBits = 0U;
|
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;
|
m_patternBuffer <<= 1;
|
||||||
if (bit)
|
if (bit)
|
||||||
|
@ -370,7 +371,7 @@ void CDStarRX::processHeader(bool bit)
|
||||||
io.setDecode(true);
|
io.setDecode(true);
|
||||||
io.setADCDetection(true);
|
io.setADCDetection(true);
|
||||||
|
|
||||||
serial.writeDStarHeader(header, DSTAR_HEADER_LENGTH_BYTES);
|
writeRSSIHeader(header, rssi);
|
||||||
|
|
||||||
::memset(m_rxBuffer, 0x00U, DSTAR_DATA_LENGTH_BYTES + 2U);
|
::memset(m_rxBuffer, 0x00U, DSTAR_DATA_LENGTH_BYTES + 2U);
|
||||||
m_rxBufferBits = 0U;
|
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;
|
m_patternBuffer <<= 1;
|
||||||
if (bit)
|
if (bit)
|
||||||
|
@ -457,9 +458,10 @@ void CDStarRX::processData(bool bit)
|
||||||
m_rxBuffer[9U] = DSTAR_DATA_SYNC_BYTES[9U];
|
m_rxBuffer[9U] = DSTAR_DATA_SYNC_BYTES[9U];
|
||||||
m_rxBuffer[10U] = DSTAR_DATA_SYNC_BYTES[10U];
|
m_rxBuffer[10U] = DSTAR_DATA_SYNC_BYTES[10U];
|
||||||
m_rxBuffer[11U] = DSTAR_DATA_SYNC_BYTES[11U];
|
m_rxBuffer[11U] = DSTAR_DATA_SYNC_BYTES[11U];
|
||||||
}
|
writeRSSIData(m_rxBuffer, rssi);
|
||||||
|
} else {
|
||||||
serial.writeDStarData(m_rxBuffer, DSTAR_DATA_LENGTH_BYTES);
|
serial.writeDStarData(m_rxBuffer, DSTAR_DATA_LENGTH_BYTES);
|
||||||
|
}
|
||||||
|
|
||||||
// Start the next frame
|
// Start the next frame
|
||||||
::memset(m_rxBuffer, 0x00U, DSTAR_DATA_LENGTH_BYTES + 2U);
|
::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)
|
bool CDStarRX::rxHeader(uint8_t* in, uint8_t* out)
|
||||||
{
|
{
|
||||||
int i;
|
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];
|
return crc8[0U] == header[DSTAR_HEADER_LENGTH_BYTES - 2U] && crc8[1U] == header[DSTAR_HEADER_LENGTH_BYTES - 1U];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
12
DStarRX.h
12
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
|
* 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
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
@ -32,7 +32,7 @@ class CDStarRX {
|
||||||
public:
|
public:
|
||||||
CDStarRX();
|
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();
|
void reset();
|
||||||
|
|
||||||
|
@ -54,9 +54,11 @@ private:
|
||||||
q15_t m_samples[DSTAR_DATA_SYNC_LENGTH_BITS];
|
q15_t m_samples[DSTAR_DATA_SYNC_LENGTH_BITS];
|
||||||
uint8_t m_samplesPtr;
|
uint8_t m_samplesPtr;
|
||||||
|
|
||||||
void processNone(bool bit);
|
void processNone(bool bit, uint16_t rssi);
|
||||||
void processHeader(bool bit);
|
void processHeader(bool bit, uint16_t rssi);
|
||||||
void processData(bool bit);
|
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);
|
bool rxHeader(uint8_t* in, uint8_t* out);
|
||||||
void acs(int* metric);
|
void acs(int* metric);
|
||||||
void viterbiDecode(int* data);
|
void viterbiDecode(int* data);
|
||||||
|
|
|
@ -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
|
* 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
|
* 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)
|
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
|
uint16_t CDStarTX::getSpace() const
|
||||||
|
|
|
@ -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
|
* 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
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
@ -41,7 +41,7 @@ private:
|
||||||
CSerialRB m_buffer;
|
CSerialRB m_buffer;
|
||||||
arm_fir_instance_q15 m_modFilter;
|
arm_fir_instance_q15 m_modFilter;
|
||||||
q15_t m_modState[60U]; // NoTaps + BlockSize - 1, 12 + 40 - 1 plus some spare
|
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_poLen;
|
||||||
uint16_t m_poPtr;
|
uint16_t m_poPtr;
|
||||||
uint16_t m_txDelay; // In bytes
|
uint16_t m_txDelay; // In bytes
|
||||||
|
|
14
IO.cpp
14
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) 2015 by Jim Mclaughlin KI6ZUM
|
||||||
* Copyright (C) 2016 by Colin Durbridge G4EML
|
* Copyright (C) 2016 by Colin Durbridge G4EML
|
||||||
*
|
*
|
||||||
|
@ -184,7 +184,7 @@ void CIO::process()
|
||||||
q15_t GMSKVals[RX_BLOCK_SIZE + 1U];
|
q15_t GMSKVals[RX_BLOCK_SIZE + 1U];
|
||||||
::arm_fir_fast_q15(&m_GMSKFilter, samples, GMSKVals, blockSize);
|
::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) {
|
if (m_dmrEnable || m_ysfEnable || m_p25Enable) {
|
||||||
|
@ -199,17 +199,17 @@ void CIO::process()
|
||||||
}
|
}
|
||||||
|
|
||||||
if (m_ysfEnable)
|
if (m_ysfEnable)
|
||||||
ysfRX.samples(C4FSKVals, blockSize);
|
ysfRX.samples(C4FSKVals, rssi, blockSize);
|
||||||
|
|
||||||
if (m_p25Enable)
|
if (m_p25Enable)
|
||||||
p25RX.samples(C4FSKVals, blockSize);
|
p25RX.samples(C4FSKVals, rssi, blockSize);
|
||||||
}
|
}
|
||||||
} else if (m_modemState == STATE_DSTAR) {
|
} else if (m_modemState == STATE_DSTAR) {
|
||||||
if (m_dstarEnable) {
|
if (m_dstarEnable) {
|
||||||
q15_t GMSKVals[RX_BLOCK_SIZE + 1U];
|
q15_t GMSKVals[RX_BLOCK_SIZE + 1U];
|
||||||
::arm_fir_fast_q15(&m_GMSKFilter, samples, GMSKVals, blockSize);
|
::arm_fir_fast_q15(&m_GMSKFilter, samples, GMSKVals, blockSize);
|
||||||
|
|
||||||
dstarRX.samples(GMSKVals, blockSize);
|
dstarRX.samples(GMSKVals, rssi, blockSize);
|
||||||
}
|
}
|
||||||
} else if (m_modemState == STATE_DMR) {
|
} else if (m_modemState == STATE_DMR) {
|
||||||
if (m_dmrEnable) {
|
if (m_dmrEnable) {
|
||||||
|
@ -231,14 +231,14 @@ void CIO::process()
|
||||||
q15_t C4FSKVals[RX_BLOCK_SIZE + 1U];
|
q15_t C4FSKVals[RX_BLOCK_SIZE + 1U];
|
||||||
::arm_fir_fast_q15(&m_C4FSKFilter, samples, C4FSKVals, blockSize);
|
::arm_fir_fast_q15(&m_C4FSKFilter, samples, C4FSKVals, blockSize);
|
||||||
|
|
||||||
ysfRX.samples(C4FSKVals, blockSize);
|
ysfRX.samples(C4FSKVals, rssi, blockSize);
|
||||||
}
|
}
|
||||||
} else if (m_modemState == STATE_P25) {
|
} else if (m_modemState == STATE_P25) {
|
||||||
if (m_p25Enable) {
|
if (m_p25Enable) {
|
||||||
q15_t C4FSKVals[RX_BLOCK_SIZE + 1U];
|
q15_t C4FSKVals[RX_BLOCK_SIZE + 1U];
|
||||||
::arm_fir_fast_q15(&m_C4FSKFilter, samples, C4FSKVals, blockSize);
|
::arm_fir_fast_q15(&m_C4FSKFilter, samples, C4FSKVals, blockSize);
|
||||||
|
|
||||||
p25RX.samples(C4FSKVals, blockSize);
|
p25RX.samples(C4FSKVals, rssi, blockSize);
|
||||||
}
|
}
|
||||||
} else if (m_modemState == STATE_DSTARCAL) {
|
} else if (m_modemState == STATE_DSTARCAL) {
|
||||||
q15_t GMSKVals[RX_BLOCK_SIZE + 1U];
|
q15_t GMSKVals[RX_BLOCK_SIZE + 1U];
|
||||||
|
|
4
IO.h
4
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
|
* 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
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
@ -40,7 +40,7 @@ public:
|
||||||
void setADCDetection(bool detect);
|
void setADCDetection(bool detect);
|
||||||
void setMode();
|
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);
|
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);
|
||||||
|
|
||||||
|
|
|
@ -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) 2015 by Jim Mclaughlin KI6ZUM
|
||||||
* Copyright (C) 2016 by Colin Durbridge G4EML
|
* Copyright (C) 2016 by Colin Durbridge G4EML
|
||||||
*
|
*
|
||||||
|
@ -77,7 +77,7 @@ const uint16_t DC_OFFSET = 2048U;
|
||||||
extern "C" {
|
extern "C" {
|
||||||
void ADC_Handler()
|
void ADC_Handler()
|
||||||
{
|
{
|
||||||
io.interrupt(0U);
|
io.interrupt();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -101,7 +101,7 @@ void CIO::initInt()
|
||||||
void CIO::startInt()
|
void CIO::startInt()
|
||||||
{
|
{
|
||||||
if (ADC->ADC_ISR & ADC_ISR_EOC_Chan) // Ensure there was an End-of-Conversion and we read the ISR reg
|
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
|
// Set up the ADC
|
||||||
NVIC_EnableIRQ(ADC_IRQn); // Enable ADC interrupt vector
|
NVIC_EnableIRQ(ADC_IRQn); // Enable ADC interrupt vector
|
||||||
|
@ -164,7 +164,7 @@ void CIO::startInt()
|
||||||
digitalWrite(PIN_LED, HIGH);
|
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
|
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;
|
uint8_t control = MARK_NONE;
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 2016 by Jim McLaughlin KI6ZUM
|
* Copyright (C) 2016 by Jim McLaughlin KI6ZUM
|
||||||
* Copyright (C) 2016 by Andy Uribe CA6JAU
|
* 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
|
* 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
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
@ -213,7 +214,7 @@ extern "C" {
|
||||||
void TIM2_IRQHandler() {
|
void TIM2_IRQHandler() {
|
||||||
if (TIM_GetITStatus(TIM2, TIM_IT_Update) != RESET) {
|
if (TIM_GetITStatus(TIM2, TIM_IT_Update) != RESET) {
|
||||||
TIM_ClearITPendingBit(TIM2, TIM_IT_Update);
|
TIM_ClearITPendingBit(TIM2, TIM_IT_Update);
|
||||||
io.interrupt(0U);
|
io.interrupt();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -280,7 +281,7 @@ void CIO::initInt()
|
||||||
void CIO::startInt()
|
void CIO::startInt()
|
||||||
{
|
{
|
||||||
if ((ADC_GetFlagStatus(ADC1, ADC_FLAG_EOC) != RESET))
|
if ((ADC_GetFlagStatus(ADC1, ADC_FLAG_EOC) != RESET))
|
||||||
io.interrupt(0U);
|
io.interrupt();
|
||||||
|
|
||||||
// Init the ADC
|
// Init the ADC
|
||||||
GPIO_InitTypeDef GPIO_InitStruct;
|
GPIO_InitTypeDef GPIO_InitStruct;
|
||||||
|
@ -421,7 +422,7 @@ void CIO::startInt()
|
||||||
GPIO_SetBits(PORT_LED, PIN_LED);
|
GPIO_SetBits(PORT_LED, PIN_LED);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CIO::interrupt(uint8_t source)
|
void CIO::interrupt()
|
||||||
{
|
{
|
||||||
uint8_t control = MARK_NONE;
|
uint8_t control = MARK_NONE;
|
||||||
uint16_t sample = DC_OFFSET;
|
uint16_t sample = DC_OFFSET;
|
||||||
|
|
59
IOTeensy.cpp
59
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
|
* 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
|
* 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" {
|
extern "C" {
|
||||||
void adc0_isr()
|
void adc0_isr()
|
||||||
{
|
{
|
||||||
io.interrupt(0U);
|
io.interrupt();
|
||||||
}
|
}
|
||||||
|
|
||||||
#if defined(SEND_RSSI_DATA)
|
|
||||||
void adc1_isr()
|
|
||||||
{
|
|
||||||
io.interrupt(1U);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void CIO::initInt()
|
void CIO::initInt()
|
||||||
|
@ -116,7 +109,6 @@ void CIO::startInt()
|
||||||
ADC1_CLP2 + ADC1_CLP1 + ADC1_CLP0;
|
ADC1_CLP2 + ADC1_CLP1 + ADC1_CLP0;
|
||||||
sum1 = (sum1 / 2U) | 0x8000U;
|
sum1 = (sum1 / 2U) | 0x8000U;
|
||||||
ADC1_PG = sum1;
|
ADC1_PG = sum1;
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(EXTERNAL_OSC)
|
#if defined(EXTERNAL_OSC)
|
||||||
|
@ -149,42 +141,33 @@ void CIO::startInt()
|
||||||
digitalWrite(PIN_LED, HIGH);
|
digitalWrite(PIN_LED, HIGH);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CIO::interrupt(uint8_t source)
|
void CIO::interrupt()
|
||||||
{
|
{
|
||||||
if (source == 0U) { // ADC0
|
uint8_t control = MARK_NONE;
|
||||||
uint8_t control = MARK_NONE;
|
uint16_t sample = DC_OFFSET;
|
||||||
uint16_t sample = DC_OFFSET;
|
|
||||||
|
|
||||||
m_txBuffer.get(sample, control);
|
m_txBuffer.get(sample, control);
|
||||||
*(int16_t *)&(DAC0_DAT0L) = sample;
|
*(int16_t *)&(DAC0_DAT0L) = sample;
|
||||||
|
|
||||||
if ((ADC0_SC1A & ADC_SC1_COCO) == ADC_SC1_COCO) {
|
if ((ADC0_SC1A & ADC_SC1_COCO) == ADC_SC1_COCO) {
|
||||||
sample = ADC0_RA;
|
sample = ADC0_RA;
|
||||||
m_rxBuffer.put(sample, control);
|
m_rxBuffer.put(sample, control);
|
||||||
}
|
}
|
||||||
|
|
||||||
#if defined(SEND_RSSI_DATA)
|
#if defined(SEND_RSSI_DATA)
|
||||||
|
if ((ADC1_SC1A & ADC_SC1_COCO) == ADC_SC1_COCO) {
|
||||||
if ((ADC1_SC1A & ADC_SC1_COCO) == ADC_SC1_COCO) {
|
uint16_t rssi = ADC1_RA;
|
||||||
uint16_t rssi = ADC1_RA;
|
m_rssiBuffer.put(rssi);
|
||||||
m_rssiBuffer.put(rssi);
|
} else {
|
||||||
}
|
m_rssiBuffer.put(0U);
|
||||||
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++;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ADC1_SC1A = PIN_RSSI; // Start the next RSSI conversion
|
||||||
|
#else
|
||||||
|
m_rssiBuffer.put(0U);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
m_watchdog++;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CIO::getCOSInt()
|
bool CIO::getCOSInt()
|
||||||
|
|
21
P25RX.cpp
21
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
|
* 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
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
@ -73,7 +73,7 @@ void CP25RX::reset()
|
||||||
m_threshold = 0;
|
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++) {
|
for (uint16_t i = 0U; i < length; i++) {
|
||||||
bool bit = samples[i] < 0;
|
bool bit = samples[i] < 0;
|
||||||
|
@ -95,7 +95,7 @@ void CP25RX::samples(const q15_t* samples, uint8_t length)
|
||||||
if (m_state == P25RXS_NONE)
|
if (m_state == P25RXS_NONE)
|
||||||
processNone(samples[i]);
|
processNone(samples[i]);
|
||||||
else
|
else
|
||||||
processData(samples[i]);
|
processData(samples[i], rssi[i]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -173,7 +173,7 @@ void CP25RX::processNone(q15_t sample)
|
||||||
m_symbolPtr = 0U;
|
m_symbolPtr = 0U;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CP25RX::processData(q15_t sample)
|
void CP25RX::processData(q15_t sample, uint16_t rssi)
|
||||||
{
|
{
|
||||||
sample -= m_centre;
|
sample -= m_centre;
|
||||||
|
|
||||||
|
@ -251,7 +251,7 @@ void CP25RX::processData(q15_t sample)
|
||||||
} else {
|
} else {
|
||||||
m_outBuffer[0U] = m_lostCount == (MAX_SYNC_FRAMES - 1U) ? 0x01U : 0x00U;
|
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
|
// Start the next frame
|
||||||
::memset(m_outBuffer, 0x00U, P25_LDU_FRAME_LENGTH_BYTES + 3U);
|
::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
|
||||||
|
}
|
||||||
|
|
7
P25RX.h
7
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
|
* 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
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
@ -31,7 +31,7 @@ class CP25RX {
|
||||||
public:
|
public:
|
||||||
CP25RX();
|
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();
|
void reset();
|
||||||
|
|
||||||
|
@ -51,7 +51,8 @@ private:
|
||||||
q15_t m_threshold;
|
q15_t m_threshold;
|
||||||
|
|
||||||
void processNone(q15_t sample);
|
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
|
#endif
|
||||||
|
|
4
P25TX.h
4
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
|
* 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
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
@ -41,7 +41,7 @@ private:
|
||||||
arm_fir_instance_q15 m_lpFilter;
|
arm_fir_instance_q15 m_lpFilter;
|
||||||
q15_t m_modState[70U]; // NoTaps + BlockSize - 1, 42 + 20 - 1 plus some spare
|
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
|
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_poLen;
|
||||||
uint16_t m_poPtr;
|
uint16_t m_poPtr;
|
||||||
uint16_t m_txDelay;
|
uint16_t m_txDelay;
|
||||||
|
|
21
YSFRX.cpp
21
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
|
* 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
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
@ -73,7 +73,7 @@ void CYSFRX::reset()
|
||||||
m_threshold = 0;
|
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++) {
|
for (uint16_t i = 0U; i < length; i++) {
|
||||||
bool bit = samples[i] < 0;
|
bool bit = samples[i] < 0;
|
||||||
|
@ -95,7 +95,7 @@ void CYSFRX::samples(const q15_t* samples, uint8_t length)
|
||||||
if (m_state == YSFRXS_NONE)
|
if (m_state == YSFRXS_NONE)
|
||||||
processNone(samples[i]);
|
processNone(samples[i]);
|
||||||
else
|
else
|
||||||
processData(samples[i]);
|
processData(samples[i], rssi[i]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -173,7 +173,7 @@ void CYSFRX::processNone(q15_t sample)
|
||||||
m_symbolPtr = 0U;
|
m_symbolPtr = 0U;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CYSFRX::processData(q15_t sample)
|
void CYSFRX::processData(q15_t sample, uint16_t rssi)
|
||||||
{
|
{
|
||||||
sample -= m_centre;
|
sample -= m_centre;
|
||||||
|
|
||||||
|
@ -233,7 +233,7 @@ void CYSFRX::processData(q15_t sample)
|
||||||
} else {
|
} else {
|
||||||
m_outBuffer[0U] = m_lostCount == (MAX_SYNC_FRAMES - 1U) ? 0x01U : 0x00U;
|
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
|
// Start the next frame
|
||||||
::memset(m_outBuffer, 0x00U, YSF_FRAME_LENGTH_BYTES + 3U);
|
::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
|
||||||
|
}
|
||||||
|
|
7
YSFRX.h
7
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
|
* 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
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
@ -31,7 +31,7 @@ class CYSFRX {
|
||||||
public:
|
public:
|
||||||
CYSFRX();
|
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();
|
void reset();
|
||||||
|
|
||||||
|
@ -51,7 +51,8 @@ private:
|
||||||
q15_t m_threshold;
|
q15_t m_threshold;
|
||||||
|
|
||||||
void processNone(q15_t sample);
|
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
|
#endif
|
||||||
|
|
4
YSFTX.h
4
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
|
* 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
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
@ -39,7 +39,7 @@ private:
|
||||||
CSerialRB m_buffer;
|
CSerialRB m_buffer;
|
||||||
arm_fir_instance_q15 m_modFilter;
|
arm_fir_instance_q15 m_modFilter;
|
||||||
q15_t m_modState[70U]; // NoTaps + BlockSize - 1, 42 + 20 - 1 plus some spare
|
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_poLen;
|
||||||
uint16_t m_poPtr;
|
uint16_t m_poPtr;
|
||||||
uint16_t m_txDelay;
|
uint16_t m_txDelay;
|
||||||
|
|
Loading…
Reference in New Issue