Skip to content

Commit 75c5b94

Browse files
authored
Merge pull request #61 from srcejon/fix_golay20
Fix Golay_20_8 parity correction
2 parents 64e7590 + cdfa2af commit 75c5b94

4 files changed

Lines changed: 95 additions & 13 deletions

File tree

dmr.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -993,7 +993,7 @@ void DSDDMR::processSlotTypePDU()
993993

994994
unsigned int dataType = (slotTypeBits[4] << 3) + (slotTypeBits[5] << 2) + (slotTypeBits[6] << 1) + slotTypeBits[7];
995995

996-
if (dataType > DMR_TYPES_COUNT)
996+
if (dataType >= DMR_TYPES_COUNT)
997997
{
998998
m_dataType = DSDDMRDataReserved;
999999
memcpy(&m_slotText[4], "RES", 3);

fec.cpp

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -650,7 +650,7 @@ void Golay_20_8::init()
650650
int syndromeIP = syndromeI ^ (1 << (11-ip));
651651
m_corr[syndromeIP][0] = i1;
652652
m_corr[syndromeIP][1] = i2;
653-
m_corr[syndromeIP][2] = 12 + ip;
653+
m_corr[syndromeIP][2] = 8 + ip;
654654
}
655655
}
656656

@@ -669,14 +669,14 @@ void Golay_20_8::init()
669669
{
670670
int syndromeIP1 = syndromeI ^ (1 << (11-ip1));
671671
m_corr[syndromeIP1][0] = i1;
672-
m_corr[syndromeIP1][1] = 12 + ip1;
672+
m_corr[syndromeIP1][1] = 8 + ip1;
673673

674674
for (int ip2 = ip1+1; ip2 < 12; ip2++) // 1 more bit flip in parity
675675
{
676676
int syndromeIP2 = syndromeIP1 ^ (1 << (11-ip2));
677677
m_corr[syndromeIP2][0] = i1;
678-
m_corr[syndromeIP2][1] = 12 + ip1;
679-
m_corr[syndromeIP2][2] = 12 + ip2;
678+
m_corr[syndromeIP2][1] = 8 + ip1;
679+
m_corr[syndromeIP2][2] = 8 + ip2;
680680
}
681681
}
682682
}
@@ -685,20 +685,20 @@ void Golay_20_8::init()
685685
for (int ip1 = 0; ip1 < 12; ip1++) // 1 bit flip in parity
686686
{
687687
int syndromeIP1 = (1 << (11-ip1));
688-
m_corr[syndromeIP1][0] = 12 + ip1;
688+
m_corr[syndromeIP1][0] = 8 + ip1;
689689

690690
for (int ip2 = ip1+1; ip2 < 12; ip2++) // 1 more bit flip in parity
691691
{
692692
int syndromeIP2 = syndromeIP1 ^ (1 << (11-ip2));
693-
m_corr[syndromeIP2][0] = 12 + ip1;
694-
m_corr[syndromeIP2][1] = 12 + ip2;
693+
m_corr[syndromeIP2][0] = 8 + ip1;
694+
m_corr[syndromeIP2][1] = 8 + ip2;
695695

696696
for (int ip3 = ip2+1; ip3 < 12; ip3++) // 1 more bit flip in parity
697697
{
698698
int syndromeIP3 = syndromeIP2 ^ (1 << (11-ip3));
699-
m_corr[syndromeIP3][0] = 12 + ip1;
700-
m_corr[syndromeIP3][1] = 12 + ip2;
701-
m_corr[syndromeIP3][2] = 12 + ip3;
699+
m_corr[syndromeIP3][0] = 8 + ip1;
700+
m_corr[syndromeIP3][1] = 8 + ip2;
701+
m_corr[syndromeIP3][2] = 8 + ip3;
702702
}
703703
}
704704
}

testfec/Makefile

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ hamming16: fec.o hamming16.cpp
2828
g++ -o hamming16 fec.o hamming16.cpp
2929

3030
golay20: fec.o golay20.cpp
31-
g++ -o golay20 fec.o golay20.cpp
31+
g++ $(CXXLFAGS) -o golay20 fec.o golay20.cpp
3232

3333
golay23: fec.o golay23.cpp
3434
g++ -o golay23 fec.o golay23.cpp
@@ -65,4 +65,3 @@ descramble.o: ../descramble.h ../descramble.cpp
6565

6666
clean:
6767
rm -f *.o qr golay20 golay23 golay24 hamming7 hamming12 hamming15 hamming16 viterbi viterbi35 crc
68-

testfec/golay20.cpp

Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,87 @@ void decode(DSDcc::Golay_20_8& Golay_20_8, unsigned char *codeword)
4141
}
4242
}
4343

44+
void rand_test()
45+
{
46+
unsigned char msg[8];
47+
unsigned char codeword[20], xcodeword[20];
48+
int idx1, idx2, idx3;
49+
int dataIn, dataOut;
50+
int passCount = 0, failCount = 0, parityFailCount = 0;
51+
DSDcc::Golay_20_8 golay_20_8;
52+
53+
// Run multiple times, to randomly corrupt different bits
54+
// Takes about 10 seconds on a fast PC
55+
for (int repeat = 0; repeat < 100000; repeat++)
56+
{
57+
// Exhaustively test all 8-bit inputs
58+
for (int dataIn = 0; dataIn < 256; dataIn++)
59+
{
60+
// Convert to array of bits
61+
for (int j = 0; j < 8; j++) {
62+
msg[j] = (dataIn >> j) & 1;
63+
}
64+
65+
// Encode
66+
golay_20_8.encode(msg, codeword);
67+
68+
// Save copy of uncorrupted codeword
69+
std::copy(codeword, codeword + 20, xcodeword);
70+
71+
// Randomly corrupt up to 3 bits
72+
idx1 = rand() % 20;
73+
idx2 = rand() % 20;
74+
idx3 = rand() % 20;
75+
codeword[idx1] ^= codeword[idx1];
76+
codeword[idx2] ^= codeword[idx2];
77+
codeword[idx3] ^= codeword[idx3];
78+
79+
bool fail = false;
80+
// Decode and correct errors
81+
dataOut = 0;
82+
if (golay_20_8.decode(codeword))
83+
{
84+
// Check data is corrected
85+
for (int j = 0; j < 8; j++) {
86+
dataOut |= codeword[j] << j;
87+
}
88+
if (dataIn != dataOut) {
89+
fail = true;
90+
}
91+
92+
// Check also that parity has been corrected, as we previously had a bug with this
93+
if (memcmp(codeword, xcodeword, 20)) {
94+
parityFailCount++;
95+
}
96+
}
97+
else
98+
{
99+
fail = true;
100+
}
101+
if (fail)
102+
{
103+
std::cout << "Decode failed:"
104+
<< " dataIn=" << dataIn
105+
<< " dataOut=" << dataOut
106+
<< " idx1=" << idx1
107+
<< " idx2=" << idx2
108+
<< " idx3=" << idx3
109+
<< "\n";
110+
failCount++;
111+
}
112+
else
113+
{
114+
passCount++;
115+
}
116+
}
117+
}
118+
119+
std::cout << "rand_test:"
120+
<< " Passcount=" << passCount
121+
<< " Failcount=" << failCount
122+
<< " parityFailCount=" << parityFailCount << "\n";
123+
}
124+
44125
int main(int argc, char *argv[])
45126
{
46127
unsigned char msg[8] = {1, 0, 0, 1, 0, 1, 0, 0};
@@ -106,6 +187,8 @@ int main(int argc, char *argv[])
106187
xcodeword[19] ^= 1;
107188
decode(golay_20_8, xcodeword);
108189

190+
rand_test();
191+
109192
return 0;
110193
}
111194

0 commit comments

Comments
 (0)