Simple minded rate 3/4 FEC decoding.

This commit is contained in:
Jonathan Naylor
2016-07-14 18:58:03 +01:00
parent 767c30ebf5
commit 9e83d23c48
3 changed files with 58 additions and 22 deletions

View File

@@ -365,11 +365,11 @@ void CDMRSlot::writeModem(unsigned char *data)
bptc.decode(data + 2U, payload); bptc.decode(data + 2U, payload);
bptc.encode(payload, data + 2U); bptc.encode(payload, data + 2U);
} else if (dataType == DT_RATE_34_DATA) { } else if (dataType == DT_RATE_34_DATA) {
LogDebug("DMR Slot %u, received RF rate 3/4 data", m_slotNo);
CDMRTrellis trellis; CDMRTrellis trellis;
unsigned char payload[18U]; unsigned char payload[18U];
trellis.decode(data + 2U, payload); bool ret = trellis.decode(data + 2U, payload);
// trellis.encode(payload, data + 2U); if (ret)
trellis.encode(payload, data + 2U);
} }
// Regenerate the Slot Type // Regenerate the Slot Type
@@ -1164,11 +1164,11 @@ void CDMRSlot::writeNetwork(const CDMRData& dmrData)
bptc.decode(data + 2U, payload); bptc.decode(data + 2U, payload);
bptc.encode(payload, data + 2U); bptc.encode(payload, data + 2U);
} else if (dataType == DT_RATE_34_DATA) { } else if (dataType == DT_RATE_34_DATA) {
LogDebug("DMR Slot %u, received network rate 3/4 data", m_slotNo);
CDMRTrellis trellis; CDMRTrellis trellis;
unsigned char payload[18U]; unsigned char payload[18U];
trellis.decode(data + 2U, payload); bool ret = trellis.decode(data + 2U, payload);
// trellis.encode(payload, data + 2U); if (ret)
trellis.encode(payload, data + 2U);
} }
// Regenerate the Slot Type // Regenerate the Slot Type

View File

@@ -59,29 +59,38 @@ bool CDMRTrellis::decode(const unsigned char* data, unsigned char* payload)
dibitsToPoints(dibits, points); dibitsToPoints(dibits, points);
unsigned char tribits[49U]; unsigned char tribits[49U];
unsigned char state = 0U;
for (unsigned int i = 0U; i < 49U; i++) { // Check the original code
tribits[i] = 9U; unsigned int failPos = checkCode(points, tribits);
if (failPos == 999U) {
tribitsToBits(tribits, payload);
return true;
}
for (unsigned int j = 0U; j < 8U; j++) { for (unsigned j = 0U; j < 20U; j++) {
if (points[i] == ENCODE_TABLE[state * 8U + j]) { unsigned int bestPos = 0U;
tribits[i] = j; unsigned int bestVal = 0U;
break;
for (unsigned int i = 0U; i < 16U; i++) {
points[failPos] = i;
unsigned int pos = checkCode(points, tribits);
if (pos == 999U) {
tribitsToBits(tribits, payload);
return true;
}
if (pos > bestPos) {
bestPos = pos;
bestVal = i;
} }
} }
if (tribits[i] == 9U) { points[failPos] = bestVal;
LogDebug("Decoding failure at position %u", i); failPos = bestPos;
return false;
}
state = tribits[i];
} }
tribitsToBits(tribits, payload); return false;
return true;
} }
void CDMRTrellis::encode(const unsigned char* payload, unsigned char* data) void CDMRTrellis::encode(const unsigned char* payload, unsigned char* data)
@@ -320,3 +329,29 @@ void CDMRTrellis::tribitsToBits(const unsigned char* tribits, unsigned char* pay
WRITE_BIT(payload, n, b3); WRITE_BIT(payload, n, b3);
} }
} }
unsigned int CDMRTrellis::checkCode(const unsigned char* points, unsigned char* tribits) const
{
unsigned char state = 0U;
for (unsigned int i = 0U; i < 49U; i++) {
tribits[i] = 9U;
for (unsigned int j = 0U; j < 8U; j++) {
if (points[i] == ENCODE_TABLE[state * 8U + j]) {
tribits[i] = j;
break;
}
}
if (tribits[i] == 9U)
return i;
state = tribits[i];
}
if (tribits[48U] != 0U)
return 48U;
return 999U;
}

View File

@@ -29,6 +29,7 @@ private:
void pointsToDibits(const unsigned char* points, signed char* dibits) const; void pointsToDibits(const unsigned char* points, signed char* dibits) const;
void bitsToTribits(const unsigned char* payload, unsigned char* tribits) const; void bitsToTribits(const unsigned char* payload, unsigned char* tribits) const;
void tribitsToBits(const unsigned char* tribits, unsigned char* payload) const; void tribitsToBits(const unsigned char* tribits, unsigned char* payload) const;
unsigned int checkCode(const unsigned char* points, unsigned char* tribits) const;
}; };
#endif #endif