mirror of https://github.com/markqvist/MMDVM.git
Add an optional RSSI input.
parent
b96413c5af
commit
eafc329cc9
3
Config.h
3
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
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
36
DStarRX.cpp
36
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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
13
IO.cpp
13
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
|
||||
|
||||
|
|
4
IO.h
4
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;
|
||||
|
|
21
YSFRX.cpp
21
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;
|
||||
}
|
||||
}
|
||||
|
|
3
YSFRX.h
3
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;
|
||||
|
||||
|
|
Loading…
Reference in New Issue