From d0e118e85c23776081e542d9181016e538131d97 Mon Sep 17 00:00:00 2001 From: Jonathan Naylor Date: Thu, 7 Jul 2016 20:23:30 +0100 Subject: [PATCH] Start on DMR rate 3/4 data. --- DMRSlot.cpp | 11 ++- DMRTrellis.cpp | 156 ++++++++++++++++++++++++++++++++++++++ DMRTrellis.h | 31 ++++++++ MMDVMHost.vcxproj | 2 + MMDVMHost.vcxproj.filters | 6 ++ Makefile | 4 +- Makefile.Pi.Adafruit | 6 +- Makefile.Pi.HD44780 | 6 +- Makefile.Pi.OLED | 6 +- Makefile.Pi.PCF8574 | 6 +- 10 files changed, 218 insertions(+), 16 deletions(-) create mode 100644 DMRTrellis.cpp create mode 100644 DMRTrellis.h diff --git a/DMRSlot.cpp b/DMRSlot.cpp index 801ea18..162ebc9 100644 --- a/DMRSlot.cpp +++ b/DMRSlot.cpp @@ -13,6 +13,7 @@ #include "DMRSlotType.h" #include "DMRShortLC.h" +#include "DMRTrellis.h" #include "DMRFullLC.h" #include "BPTC19696.h" #include "DMRSlot.h" @@ -411,7 +412,10 @@ void CDMRSlot::writeModem(unsigned char *data) bptc.encode(payload, data + 2U); } else if (dataType == DT_RATE_34_DATA) { LogDebug("DMR Slot %u, received RF rate 3/4 data", m_slotNo); - CUtils::dump(1U, "Payload", data + 2U, DMR_FRAME_LENGTH_BYTES); + CDMRTrellis trellis; + unsigned char payload[18U]; + trellis.decode(data + 2U, payload); + // trellis.encode(payload, data + 2U); } // Regenerate the Slot Type @@ -1283,7 +1287,10 @@ void CDMRSlot::writeNetwork(const CDMRData& dmrData) bptc.encode(payload, data + 2U); } else if (dataType == DT_RATE_34_DATA) { LogDebug("DMR Slot %u, received network rate 3/4 data", m_slotNo); - CUtils::dump(1U, "Payload", data + 2U, DMR_FRAME_LENGTH_BYTES); + CDMRTrellis trellis; + unsigned char payload[18U]; + trellis.decode(data + 2U, payload); + // trellis.encode(payload, data + 2U); } // Regenerate the Slot Type diff --git a/DMRTrellis.cpp b/DMRTrellis.cpp new file mode 100644 index 0000000..b8ee592 --- /dev/null +++ b/DMRTrellis.cpp @@ -0,0 +1,156 @@ +/* +* Copyright (C) 2016 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 +* the Free Software Foundation; version 2 of the License. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +*/ + +#include "DMRTrellis.h" +#include "DMRDefines.h" +#include "Utils.h" +#include "Log.h" + +#include +#include + +const unsigned int INTERLEAVE_TABLE[] = { + 0U, 4U, 8U, 12U, 16U, 20U, 24U, 28U, 32U, 36U, 40U, 44U, 48U, + 1U, 5U, 9U, 13U, 17U, 21U, 25U, 29U, 33U, 37U, 41U, 45U, + 2U, 6U, 10U, 14U, 18U, 22U, 26U, 30U, 34U, 38U, 42U, 46U, + 3U, 7U, 11U, 15U, 19U, 23U, 27U, 31U, 35U, 39U, 43U, 47U}; + +const unsigned char DIBITS_TO_POINT[] = { 11U, 12U, 0U, 7U, 14U, 9U, 5U, 2U, 10U, 13U, 1U, 6U, 15U, 8U, 4U, 3U}; +const unsigned char POINT_TO_DIBITS[] = {0x2U, 0xAU, 0x7U, 0xFU, 0xEU, 0x6U, 0xBU, 0x3U, 0xDU, 0x5U, 0x8U, 0x0U, 0x1U, 0x9U, 0x4U, 0xCU}; + +const unsigned char ENCODE_TABLE[] = { + 0U, 8U, 4U, 12U, 2U, 10U, 6U, 14U, + 4U, 12U, 2U, 10U, 6U, 14U, 0U, 8U, + 1U, 9U, 5U, 13U, 3U, 11U, 7U, 15U, + 5U, 13U, 3U, 11U, 7U, 15U, 1U, 9U, + 3U, 11U, 7U, 15U, 1U, 9U, 5U, 13U, + 7U, 15U, 1U, 9U, 5U, 13U, 3U, 11U, + 2U, 10U, 6U, 14U, 0U, 8U, 4U, 12U, + 6U, 14U, 0U, 8U, 4U, 12U, 2U, 10U +}; + +const unsigned char BIT_MASK_TABLE[] = {0x80U, 0x40U, 0x20U, 0x10U, 0x08U, 0x04U, 0x02U, 0x01U}; + +#define WRITE_BIT(p,i,b) p[(i)>>3] = (b) ? (p[(i)>>3] | BIT_MASK_TABLE[(i)&7]) : (p[(i)>>3] & ~BIT_MASK_TABLE[(i)&7]) +#define READ_BIT(p,i) (p[(i)>>3] & BIT_MASK_TABLE[(i)&7]) + +CDMRTrellis::CDMRTrellis() +{ +} + +CDMRTrellis::~CDMRTrellis() +{ +} + +void CDMRTrellis::decode(const unsigned char* data, unsigned char* payload) +{ + assert(data != NULL); + assert(payload != NULL); + + CUtils::dump(1U, "Payload", data, DMR_FRAME_LENGTH_BYTES); + + // unsigned char points[49U]; + // deinterleave(data, points); +} + +void CDMRTrellis::encode(const unsigned char* payload, unsigned char* data) +{ + assert(payload != NULL); + assert(data != NULL); + + unsigned char tribits[49U]; + totribits(payload, tribits); + + unsigned char points[49U]; + unsigned char state = 0U; + + for (unsigned int i = 0U; i < 49U; i++) { + unsigned char tribit = tribits[i]; + + points[i] = ENCODE_TABLE[state * 8U + tribit]; + + state = tribit; + } + + interleave(points, data); +} + +void CDMRTrellis::deinterleave(const unsigned char* data, unsigned char* points) const +{ + for (unsigned int i = 0U; i < 49U; i++) { + unsigned int n = INTERLEAVE_TABLE[i] * 4U; + if (n > 108U) n += 48U; + + bool b1 = READ_BIT(data, n) != 0x00U; + n++; + bool b2 = READ_BIT(data, n) != 0x00U; + n++; + bool b3 = READ_BIT(data, n) != 0x00U; + n++; + bool b4 = READ_BIT(data, n) != 0x00U; + + unsigned int dibits = 0U; + dibits |= b1 ? 8U : 0U; + dibits |= b2 ? 4U : 0U; + dibits |= b3 ? 2U : 0U; + dibits |= b4 ? 1U : 0U; + + points[i] = DIBITS_TO_POINT[dibits]; + } +} + +void CDMRTrellis::interleave(const unsigned char* points, unsigned char* data) const +{ + for (unsigned int i = 0U; i < 49U; i++) { + unsigned char point = points[i]; + unsigned char dibits = POINT_TO_DIBITS[point]; + + bool b1 = (dibits & 0x08U) == 0x08U; + bool b2 = (dibits & 0x04U) == 0x04U; + bool b3 = (dibits & 0x02U) == 0x02U; + bool b4 = (dibits & 0x01U) == 0x01U; + + unsigned int n = INTERLEAVE_TABLE[i] * 4U; + if (n > 108U) n += 48U; + + WRITE_BIT(data, n, b1); + n++; + WRITE_BIT(data, n, b2); + n++; + WRITE_BIT(data, n, b3); + n++; + WRITE_BIT(data, n, b4); + } +} + +void CDMRTrellis::totribits(const unsigned char* payload, unsigned char* tribits) const +{ + for (unsigned int i = 0U; i < 48U; i++) { + unsigned int n = 143U - i * 3U; + + bool b1 = READ_BIT(payload, n) != 0x00U; + n--; + bool b2 = READ_BIT(payload, n) != 0x00U; + n--; + bool b3 = READ_BIT(payload, n) != 0x00U; + + unsigned char tribit = 0U; + tribit |= b1 ? 4U : 0U; + tribit |= b2 ? 2U : 0U; + tribit |= b3 ? 1U : 0U; + + tribits[i] = tribit; + } + + tribits[48U] = 0U; +} diff --git a/DMRTrellis.h b/DMRTrellis.h new file mode 100644 index 0000000..c3b852b --- /dev/null +++ b/DMRTrellis.h @@ -0,0 +1,31 @@ +/* +* Copyright (C) 2016 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 +* the Free Software Foundation; version 2 of the License. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +*/ + +#ifndef DMRTrellis_H +#define DMRTrellis_H + +class CDMRTrellis { +public: + CDMRTrellis(); + ~CDMRTrellis(); + + void decode(const unsigned char* data, unsigned char* payload); + void encode(const unsigned char* payload, unsigned char* data); + +private: + void deinterleave(const unsigned char* in, unsigned char* points) const; + void interleave(const unsigned char* points, unsigned char* out) const; + void totribits(const unsigned char* payload, unsigned char* tribits) const; +}; + +#endif diff --git a/MMDVMHost.vcxproj b/MMDVMHost.vcxproj index 1fc5912..6442ecb 100644 --- a/MMDVMHost.vcxproj +++ b/MMDVMHost.vcxproj @@ -165,6 +165,7 @@ + @@ -218,6 +219,7 @@ + diff --git a/MMDVMHost.vcxproj.filters b/MMDVMHost.vcxproj.filters index cf774a7..ad76229 100644 --- a/MMDVMHost.vcxproj.filters +++ b/MMDVMHost.vcxproj.filters @@ -167,6 +167,9 @@ Header Files + + Header Files + @@ -307,5 +310,8 @@ Source Files + + Source Files + \ No newline at end of file diff --git a/Makefile b/Makefile index d464064..64fa332 100644 --- a/Makefile +++ b/Makefile @@ -8,8 +8,8 @@ LDFLAGS = -g OBJECTS = \ AMBEFEC.o BPTC19696.o Conf.o CRC.o Display.o DMRControl.o DMRCSBK.o DMRData.o DMRDataHeader.o DMREMB.o DMREmbeddedLC.o DMRFullLC.o DMRIPSC.o DMRLookup.o DMRLC.o \ - DMRShortLC.o DMRSlot.o DMRSlotType.o DStarControl.o DStarHeader.o DStarNetwork.o DStarSlowData.o Golay2087.o Golay24128.o Hamming.o Log.o MMDVMHost.o Modem.o \ - Nextion.o NullDisplay.o QR1676.o RS129.o SerialController.o SHA256.o StopWatch.o Sync.o TFTSerial.o Thread.o Timer.o UDPSocket.o Utils.o YSFControl.o \ + DMRShortLC.o DMRSlot.o DMRSlotType.o DMRTrellis.o DStarControl.o DStarHeader.o DStarNetwork.o DStarSlowData.o Golay2087.o Golay24128.o Hamming.o Log.o MMDVMHost.o \ + Modem.o Nextion.o NullDisplay.o QR1676.o RS129.o SerialController.o SHA256.o StopWatch.o Sync.o TFTSerial.o Thread.o Timer.o UDPSocket.o Utils.o YSFControl.o \ YSFConvolution.o YSFFICH.o YSFNetwork.o YSFPayload.o all: MMDVMHost diff --git a/Makefile.Pi.Adafruit b/Makefile.Pi.Adafruit index 7e5a9a5..e336fbb 100644 --- a/Makefile.Pi.Adafruit +++ b/Makefile.Pi.Adafruit @@ -8,9 +8,9 @@ LDFLAGS = -g -L/usr/local/lib OBJECTS = \ AMBEFEC.o BPTC19696.o Conf.o CRC.o Display.o DMRControl.o DMRCSBK.o DMRData.o DMRDataHeader.o DMREMB.o DMREmbeddedLC.o DMRFullLC.o DMRIPSC.o DMRLookup.o DMRLC.o \ - DMRShortLC.o DMRSlot.o DMRSlotType.o DStarControl.o DStarHeader.o DStarNetwork.o DStarSlowData.o Golay2087.o Golay24128.o Hamming.o HD44780.o Log.o MMDVMHost.o \ - Modem.o Nextion.o NullDisplay.o QR1676.o RS129.o SerialController.o SHA256.o StopWatch.o Sync.o TFTSerial.o Thread.o Timer.o UDPSocket.o Utils.o YSFControl.o \ - YSFConvolution.o YSFFICH.o YSFNetwork.o YSFPayload.o + DMRShortLC.o DMRSlot.o DMRSlotType.o DMRTrellis.o DStarControl.o DStarHeader.o DStarNetwork.o DStarSlowData.o Golay2087.o Golay24128.o Hamming.o HD44780.o Log.o \ + MMDVMHost.o Modem.o Nextion.o NullDisplay.o QR1676.o RS129.o SerialController.o SHA256.o StopWatch.o Sync.o TFTSerial.o Thread.o Timer.o UDPSocket.o Utils.o \ + YSFControl.o YSFConvolution.o YSFFICH.o YSFNetwork.o YSFPayload.o all: MMDVMHost diff --git a/Makefile.Pi.HD44780 b/Makefile.Pi.HD44780 index e44d606..fa04657 100644 --- a/Makefile.Pi.HD44780 +++ b/Makefile.Pi.HD44780 @@ -8,9 +8,9 @@ LDFLAGS = -g -L/usr/local/lib OBJECTS = \ AMBEFEC.o BPTC19696.o Conf.o CRC.o Display.o DMRControl.o DMRCSBK.o DMRData.o DMRDataHeader.o DMREMB.o DMREmbeddedLC.o DMRFullLC.o DMRIPSC.o DMRLookup.o DMRLC.o \ - DMRShortLC.o DMRSlot.o DMRSlotType.o DStarControl.o DStarHeader.o DStarNetwork.o DStarSlowData.o Golay2087.o Golay24128.o Hamming.o HD44780.o Log.o MMDVMHost.o \ - Modem.o Nextion.o NullDisplay.o QR1676.o RS129.o SerialController.o SHA256.o StopWatch.o Sync.o TFTSerial.o Thread.o Timer.o UDPSocket.o Utils.o YSFControl.o \ - YSFConvolution.o YSFFICH.o YSFNetwork.o YSFPayload.o + DMRShortLC.o DMRSlot.o DMRSlotType.o DMRTrellis.o DStarControl.o DStarHeader.o DStarNetwork.o DStarSlowData.o Golay2087.o Golay24128.o Hamming.o HD44780.o Log.o \ + MMDVMHost.o Modem.o Nextion.o NullDisplay.o QR1676.o RS129.o SerialController.o SHA256.o StopWatch.o Sync.o TFTSerial.o Thread.o Timer.o UDPSocket.o Utils.o \ + YSFControl.o YSFConvolution.o YSFFICH.o YSFNetwork.o YSFPayload.o all: MMDVMHost diff --git a/Makefile.Pi.OLED b/Makefile.Pi.OLED index 7af4bed..37103d9 100644 --- a/Makefile.Pi.OLED +++ b/Makefile.Pi.OLED @@ -8,9 +8,9 @@ LDFLAGS = -g -L/usr/local/lib OBJECTS = \ AMBEFEC.o BPTC19696.o Conf.o CRC.o Display.o DMRControl.o DMRCSBK.o DMRData.o DMRDataHeader.o DMREMB.o DMREmbeddedLC.o DMRFullLC.o DMRIPSC.o DMRLookup.o DMRLC.o \ - DMRShortLC.o DMRSlot.o DMRSlotType.o DStarControl.o DStarHeader.o DStarNetwork.o DStarSlowData.o Golay2087.o Golay24128.o Hamming.o OLED.o Log.o MMDVMHost.o \ - Modem.o Nextion.o NullDisplay.o QR1676.o RS129.o SerialController.o SHA256.o StopWatch.o Sync.o TFTSerial.o Thread.o Timer.o UDPSocket.o Utils.o YSFControl.o \ - YSFConvolution.o YSFFICH.o YSFNetwork.o YSFPayload.o + DMRShortLC.o DMRSlot.o DMRSlotType.o DMRTrellis.o DStarControl.o DStarHeader.o DStarNetwork.o DStarSlowData.o Golay2087.o Golay24128.o Hamming.o OLED.o Log.o \ + MMDVMHost.o Modem.o Nextion.o NullDisplay.o QR1676.o RS129.o SerialController.o SHA256.o StopWatch.o Sync.o TFTSerial.o Thread.o Timer.o UDPSocket.o Utils.o \ + YSFControl.o YSFConvolution.o YSFFICH.o YSFNetwork.o YSFPayload.o all: MMDVMHost diff --git a/Makefile.Pi.PCF8574 b/Makefile.Pi.PCF8574 index 9cdc7c3..b47dd3c 100644 --- a/Makefile.Pi.PCF8574 +++ b/Makefile.Pi.PCF8574 @@ -8,9 +8,9 @@ LDFLAGS = -g -L/usr/local/lib OBJECTS = \ AMBEFEC.o BPTC19696.o Conf.o CRC.o Display.o DMRControl.o DMRCSBK.o DMRData.o DMRDataHeader.o DMREMB.o DMREmbeddedLC.o DMRFullLC.o DMRIPSC.o DMRLookup.o DMRLC.o \ - DMRShortLC.o DMRSlot.o DMRSlotType.o DStarControl.o DStarHeader.o DStarNetwork.o DStarSlowData.o Golay2087.o Golay24128.o Hamming.o HD44780.o Log.o MMDVMHost.o \ - Modem.o Nextion.o NullDisplay.o QR1676.o RS129.o SerialController.o SHA256.o StopWatch.o Sync.o TFTSerial.o Thread.o Timer.o UDPSocket.o Utils.o YSFControl.o \ - YSFConvolution.o YSFFICH.o YSFNetwork.o YSFPayload.o + DMRShortLC.o DMRSlot.o DMRSlotType.o DMRTrellis.o DStarControl.o DStarHeader.o DStarNetwork.o DStarSlowData.o Golay2087.o Golay24128.o Hamming.o HD44780.o Log.o \ + MMDVMHost.o Modem.o Nextion.o NullDisplay.o QR1676.o RS129.o SerialController.o SHA256.o StopWatch.o Sync.o TFTSerial.o Thread.o Timer.o UDPSocket.o Utils.o \ + YSFControl.o YSFConvolution.o YSFFICH.o YSFNetwork.o YSFPayload.o all: MMDVMHost