- symbol map bugfix
pull/25/head
Wojciech Kaczmarski 2024-01-08 14:32:08 +01:00
rodzic b1c4b62f27
commit 33c381ab9b
8 zmienionych plików z 645 dodań i 24 usunięć

Wyświetl plik

@ -106,6 +106,7 @@ extern const float rrc_taps_5[8*5+1];
// M17 C library - lib/encode/symbols.c
// dibits-symbols map (TX)
extern const int8_t symbol_map[4];
extern const int8_t symbol_list[4];
// M17 C library - lib/phy/sync.c
//syncwords
@ -125,10 +126,6 @@ void viterbi_decode_bit(uint16_t s0, uint16_t s1, size_t pos);
uint32_t viterbi_chainback(uint8_t* out, size_t pos, const uint16_t len);
void viterbi_reset(void);
// M17 C library - encode/symbols.c
// dibits-symbols map (TX)
extern const int8_t symbol_map[4];
//End of Transmission symbol pattern
extern const float eot_symbols[8];

Wyświetl plik

@ -15,6 +15,12 @@ clean:
fclean:
rm -f $(TARGET)
test:
$(CC) $(CFLAGS) ../tests/unit_tests.c -o ../tests/unit_tests -lm -lunity -lm17
testrun:
./../tests/unit_tests
install:
sudo install $(TARGET) /usr/local/lib

Wyświetl plik

@ -2,12 +2,15 @@
// M17 C library - encode/symbols.c
//
// Wojciech Kaczmarski, SP5WWP
// M17 Project, 5 January 2024
// M17 Project, 8 January 2024
//--------------------------------------------------------------------
#include <m17/m17.h>
//dibits-symbols map (TX)
const int8_t symbol_map[4]={+1, +3, -1, -3};
//symbol list (RX)
const int8_t symbol_list[4]={-3, -1, +1, +3};
//End of Transmission symbol pattern
const float eot_symbols[8]={+3, +3, +3, +3, +3, +3, -3, +3};

Wyświetl plik

@ -51,7 +51,7 @@ uint32_t golay24_encode(const uint16_t data)
}
}
return (data<<12) | checksum;
return ((uint32_t)data<<12) | checksum;
}
/**

Wyświetl plik

@ -82,21 +82,21 @@ int main(void)
for(uint8_t i=0; i<SYM_PER_PLD; i++)
{
//bit 0
if(pld[i]>=symbol_map[3])
if(pld[i]>=symbol_list[3])
{
soft_bit[i*2+1]=0xFFFF;
}
else if(pld[i]>=symbol_map[2])
else if(pld[i]>=symbol_list[2])
{
soft_bit[i*2+1]=-(float)0xFFFF/(symbol_map[3]-symbol_map[2])*symbol_map[2]+pld[i]*(float)0xFFFF/(symbol_map[3]-symbol_map[2]);
soft_bit[i*2+1]=-(float)0xFFFF/(symbol_list[3]-symbol_list[2])*symbol_list[2]+pld[i]*(float)0xFFFF/(symbol_list[3]-symbol_list[2]);
}
else if(pld[i]>=symbol_map[1])
else if(pld[i]>=symbol_list[1])
{
soft_bit[i*2+1]=0x0000;
}
else if(pld[i]>=symbol_map[0])
else if(pld[i]>=symbol_list[0])
{
soft_bit[i*2+1]=(float)0xFFFF/(symbol_map[1]-symbol_map[0])*symbol_map[1]-pld[i]*(float)0xFFFF/(symbol_map[1]-symbol_map[0]);
soft_bit[i*2+1]=(float)0xFFFF/(symbol_list[1]-symbol_list[0])*symbol_list[1]-pld[i]*(float)0xFFFF/(symbol_list[1]-symbol_list[0]);
}
else
{
@ -104,13 +104,13 @@ int main(void)
}
//bit 1
if(pld[i]>=symbol_map[2])
if(pld[i]>=symbol_list[2])
{
soft_bit[i*2]=0x0000;
}
else if(pld[i]>=symbol_map[1])
else if(pld[i]>=symbol_list[1])
{
soft_bit[i*2]=0x7FFF-pld[i]*(float)0xFFFF/(symbol_map[2]-symbol_map[1]);
soft_bit[i*2]=0x7FFF-pld[i]*(float)0xFFFF/(symbol_list[2]-symbol_list[1]);
}
else
{

Wyświetl plik

@ -124,21 +124,21 @@ int main(int argc, char* argv[])
for(uint8_t i=0; i<SYM_PER_PLD; i++)
{
//bit 0
if(pld[i]>=symbol_map[3])
if(pld[i]>=symbol_list[3])
{
soft_bit[i*2+1]=0xFFFF;
}
else if(pld[i]>=symbol_map[2])
else if(pld[i]>=symbol_list[2])
{
soft_bit[i*2+1]=-(float)0xFFFF/(symbol_map[3]-symbol_map[2])*symbol_map[2]+pld[i]*(float)0xFFFF/(symbol_map[3]-symbol_map[2]);
soft_bit[i*2+1]=-(float)0xFFFF/(symbol_list[3]-symbol_list[2])*symbol_list[2]+pld[i]*(float)0xFFFF/(symbol_list[3]-symbol_list[2]);
}
else if(pld[i]>=symbol_map[1])
else if(pld[i]>=symbol_list[1])
{
soft_bit[i*2+1]=0x0000;
}
else if(pld[i]>=symbol_map[0])
else if(pld[i]>=symbol_list[0])
{
soft_bit[i*2+1]=(float)0xFFFF/(symbol_map[1]-symbol_map[0])*symbol_map[1]-pld[i]*(float)0xFFFF/(symbol_map[1]-symbol_map[0]);
soft_bit[i*2+1]=(float)0xFFFF/(symbol_list[1]-symbol_list[0])*symbol_list[1]-pld[i]*(float)0xFFFF/(symbol_list[1]-symbol_list[0]);
}
else
{
@ -146,13 +146,13 @@ int main(int argc, char* argv[])
}
//bit 1
if(pld[i]>=symbol_map[2])
if(pld[i]>=symbol_list[2])
{
soft_bit[i*2]=0x0000;
}
else if(pld[i]>=symbol_map[1])
else if(pld[i]>=symbol_list[1])
{
soft_bit[i*2]=0x7FFF-pld[i]*(float)0xFFFF/(symbol_map[2]-symbol_map[1]);
soft_bit[i*2]=0x7FFF-pld[i]*(float)0xFFFF/(symbol_list[2]-symbol_list[1]);
}
else
{

1
SP5WWP/tests/.gitignore vendored 100644
Wyświetl plik

@ -0,0 +1 @@
unit_tests

Wyświetl plik

@ -0,0 +1,614 @@
#include <stdio.h>
#include <string.h>
#include <inttypes.h>
#include <stdlib.h>
#include <math.h>
#include <time.h>
#include <unity/unity.h>
#include <m17/m17.h>
//this is run before every test
void setUp(void)
{
return;
}
//this is run after every test
void tearDown(void)
{
return;
}
void soft_logic_xor(void)
{
TEST_ASSERT_EQUAL(0x0000, soft_bit_XOR(0x0000, 0x0000));
TEST_ASSERT_EQUAL(0x7FFE, soft_bit_XOR(0x0000, 0x7FFF)); //off by 1 is acceptable
TEST_ASSERT_EQUAL(0xFFFE, soft_bit_XOR(0x0000, 0xFFFF)); //off by 1 is acceptable
TEST_ASSERT_EQUAL(0x7FFE, soft_bit_XOR(0x7FFF, 0x0000)); //off by 1 is acceptable
TEST_ASSERT_EQUAL(0x7FFE, soft_bit_XOR(0x7FFF, 0x7FFF));
TEST_ASSERT_EQUAL(0x7FFF, soft_bit_XOR(0x7FFF, 0xFFFF));
TEST_ASSERT_EQUAL(0xFFFE, soft_bit_XOR(0xFFFF, 0x0000)); //off by 1 is acceptable
TEST_ASSERT_EQUAL(0x7FFF, soft_bit_XOR(0xFFFF, 0x7FFF));
TEST_ASSERT_EQUAL(0x0000, soft_bit_XOR(0xFFFF, 0xFFFF));
}
void symbol_to_soft_dibit(uint16_t dibit[2], float symb_in)
{
//bit 0
if(symb_in>=symbol_list[3])
{
dibit[1]=0xFFFF;
}
else if(symb_in>=symbol_list[2])
{
dibit[1]=-(float)0xFFFF/(symbol_list[3]-symbol_list[2])*symbol_list[2]+symb_in*(float)0xFFFF/(symbol_list[3]-symbol_list[2]);
}
else if(symb_in>=symbol_list[1])
{
dibit[1]=0x0000;
}
else if(symb_in>=symbol_list[0])
{
dibit[1]=(float)0xFFFF/(symbol_list[1]-symbol_list[0])*symbol_list[1]-symb_in*(float)0xFFFF/(symbol_list[1]-symbol_list[0]);
}
else
{
dibit[1]=0xFFFF;
}
//bit 1
if(symb_in>=symbol_list[2])
{
dibit[0]=0x0000;
}
else if(symb_in>=symbol_list[1])
{
dibit[0]=0x7FFF-symb_in*(float)0xFFFF/(symbol_list[2]-symbol_list[1]);
}
else
{
dibit[0]=0xFFFF;
}
}
void symbol_to_dibit(void)
{
uint16_t dibit[2];
symbol_to_soft_dibit(dibit, +30.0);
TEST_ASSERT_EQUAL(0x0000, dibit[0]);
TEST_ASSERT_EQUAL(0xFFFF, dibit[1]); //this is the LSB...
symbol_to_soft_dibit(dibit, +4.0);
TEST_ASSERT_EQUAL(0x0000, dibit[0]);
TEST_ASSERT_EQUAL(0xFFFF, dibit[1]);
symbol_to_soft_dibit(dibit, +3.0);
TEST_ASSERT_EQUAL(0x0000, dibit[0]);
TEST_ASSERT_EQUAL(0xFFFF, dibit[1]);
symbol_to_soft_dibit(dibit, +2.0);
TEST_ASSERT_EQUAL(0x0000, dibit[0]);
TEST_ASSERT_EQUAL(0x7FFF, dibit[1]);
symbol_to_soft_dibit(dibit, +1.0);
TEST_ASSERT_EQUAL(0x0000, dibit[0]);
TEST_ASSERT_EQUAL(0x0000, dibit[1]);
symbol_to_soft_dibit(dibit, 0.0);
TEST_ASSERT_EQUAL(0x7FFF, dibit[0]);
TEST_ASSERT_EQUAL(0x0000, dibit[1]);
symbol_to_soft_dibit(dibit, -1.0);
TEST_ASSERT_EQUAL(0xFFFE, dibit[0]); //off by one is acceptable
TEST_ASSERT_EQUAL(0x0000, dibit[1]);
symbol_to_soft_dibit(dibit, -2.0);
TEST_ASSERT_EQUAL(0xFFFF, dibit[0]);
TEST_ASSERT_EQUAL(0x7FFF, dibit[1]);
symbol_to_soft_dibit(dibit, -3.0);
TEST_ASSERT_EQUAL(0xFFFF, dibit[0]);
TEST_ASSERT_EQUAL(0xFFFF, dibit[1]);
symbol_to_soft_dibit(dibit, -4.0);
TEST_ASSERT_EQUAL(0xFFFF, dibit[0]);
TEST_ASSERT_EQUAL(0xFFFF, dibit[1]);
symbol_to_soft_dibit(dibit, -30.0);
TEST_ASSERT_EQUAL(0xFFFF, dibit[0]);
TEST_ASSERT_EQUAL(0xFFFF, dibit[1]);
}
/**
* @brief Apply errors to a soft-valued 24-bit logic vector.
* Errors are spread out evenly among num_errs bits.
* @param vect Input vector.
* @param start_pos
* @param end_pos
* @param num_errs Number of bits to apply errors to.
* @param sum_errs Sum of all errors (total).
*/
void apply_errors(uint16_t vect[24], uint8_t start_pos, uint8_t end_pos, uint8_t num_errs, float sum_errs)
{
if(end_pos<start_pos)
{
printf("ERROR: Invalid bit range.\nExiting.\n");
exit(1);
}
uint8_t bit_pos;
uint8_t num_bits=end_pos-start_pos+1;
if(num_errs>num_bits || num_bits>24 || num_errs>24 || sum_errs>num_errs) //too many errors or too wide range
{
printf("ERROR: Impossible combination of error value and number of bits.\nExiting.\n");
exit(1);
}
uint16_t val=roundf((float)0xFFFF*sum_errs/num_errs);
uint32_t err_loc=0;
for(uint8_t i=0; i<num_errs; i++)
{
//assure we didnt select the same bit more than once
do
{
bit_pos=start_pos+(rand()%num_bits);
}
while(err_loc&(1<<bit_pos));
vect[bit_pos]^=val; //apply error
err_loc|=(1<<bit_pos);
}
}
void golay_encode(void)
{
uint16_t data=0x0800;
//single-bit data
for(uint8_t i=sizeof(encode_matrix)/sizeof(uint16_t)-1; i>0; i--)
{
TEST_ASSERT_EQUAL(((uint32_t)data<<12)|encode_matrix[i], golay24_encode(data));
data>>=1;
}
//test data vector
data=0x0D78;
TEST_ASSERT_EQUAL(0x0D7880FU, golay24_encode(data));
}
/**
* @brief Golay soft-decode one known codeword.
*
*/
void golay_soft_decode_clean(void)
{
uint16_t vector[24];
//clean D78|80F
for(uint8_t i=0; i<24; i++)
vector[23-i]=((0x0D7880F>>i)&1)*0xFFFF;
TEST_ASSERT_EQUAL(0x0D78, golay24_sdecode(vector));
}
void golay_soft_decode_flipped_parity_1(void)
{
uint16_t vector[24]; //soft-logic 24-bit vector
//clean D78|80F to soft-logic data
for(uint8_t i=0; i<24; i++)
vector[23-i]=((0x0D7880F>>i)&1)*0xFFFF;
for(uint16_t j=0; j<1000; j++)
{
apply_errors(vector, 0, 11, 1, 1.0);
TEST_ASSERT_EQUAL(0x0D78, golay24_sdecode(vector));
for(uint8_t i=0; i<24; i++)
vector[23-i]=((0x0D7880F>>i)&1)*0xFFFF;
}
}
void golay_soft_decode_erased_parity_1(void)
{
uint16_t vector[24]; //soft-logic 24-bit vector
//clean D78|80F to soft-logic data
for(uint8_t i=0; i<24; i++)
vector[23-i]=((0x0D7880F>>i)&1)*0xFFFF;
for(uint16_t j=0; j<1000; j++)
{
apply_errors(vector, 0, 11, 1, 0.5);
TEST_ASSERT_EQUAL(0x0D78, golay24_sdecode(vector));
for(uint8_t i=0; i<24; i++)
vector[23-i]=((0x0D7880F>>i)&1)*0xFFFF;
}
}
void golay_soft_decode_flipped_parity_2(void)
{
uint16_t vector[24]; //soft-logic 24-bit vector
//clean D78|80F to soft-logic data
for(uint8_t i=0; i<24; i++)
vector[23-i]=((0x0D7880F>>i)&1)*0xFFFF;
for(uint16_t j=0; j<1000; j++)
{
apply_errors(vector, 0, 11, 2, 2.0);
TEST_ASSERT_EQUAL(0x0D78, golay24_sdecode(vector));
for(uint8_t i=0; i<24; i++)
vector[23-i]=((0x0D7880F>>i)&1)*0xFFFF;
}
}
void golay_soft_decode_erased_parity_2(void)
{
uint16_t vector[24]; //soft-logic 24-bit vector
//clean D78|80F to soft-logic data
for(uint8_t i=0; i<24; i++)
vector[23-i]=((0x0D7880F>>i)&1)*0xFFFF;
for(uint16_t j=0; j<1000; j++)
{
apply_errors(vector, 0, 11, 2, 1.0);
TEST_ASSERT_EQUAL(0x0D78, golay24_sdecode(vector));
for(uint8_t i=0; i<24; i++)
vector[23-i]=((0x0D7880F>>i)&1)*0xFFFF;
}
}
void golay_soft_decode_flipped_parity_3(void)
{
uint16_t vector[24]; //soft-logic 24-bit vector
//clean D78|80F to soft-logic data
for(uint8_t i=0; i<24; i++)
vector[23-i]=((0x0D7880F>>i)&1)*0xFFFF;
for(uint16_t j=0; j<1000; j++)
{
apply_errors(vector, 0, 11, 3, 3.0);
TEST_ASSERT_EQUAL(0x0D78, golay24_sdecode(vector));
for(uint8_t i=0; i<24; i++)
vector[23-i]=((0x0D7880F>>i)&1)*0xFFFF;
}
}
void golay_soft_decode_erased_parity_3(void)
{
uint16_t vector[24]; //soft-logic 24-bit vector
//clean D78|80F to soft-logic data
for(uint8_t i=0; i<24; i++)
vector[23-i]=((0x0D7880F>>i)&1)*0xFFFF;
for(uint16_t j=0; j<1000; j++)
{
apply_errors(vector, 0, 11, 3, 1.5);
TEST_ASSERT_EQUAL(0x0D78, golay24_sdecode(vector));
for(uint8_t i=0; i<24; i++)
vector[23-i]=((0x0D7880F>>i)&1)*0xFFFF;
}
}
void golay_soft_decode_erased_parity_3_5(void)
{
uint16_t vector[24]; //soft-logic 24-bit vector
//clean D78|80F to soft-logic data
for(uint8_t i=0; i<24; i++)
vector[23-i]=((0x0D7880F>>i)&1)*0xFFFF;
for(uint16_t j=0; j<1000; j++)
{
apply_errors(vector, 0, 11, 7, 3.5);
TEST_ASSERT_NOT_EQUAL(0x0D78, golay24_sdecode(vector));
for(uint8_t i=0; i<24; i++)
vector[23-i]=((0x0D7880F>>i)&1)*0xFFFF;
}
}
//4 errors is exactly half the hamming distance, so due to rounding etc., results may vary
//therefore we run 2 tests here to prove that
void golay_soft_decode_flipped_parity_4(void)
{
uint16_t vector[24]; //soft-logic 24-bit vector
//clean D78|80F to soft-logic data
for(uint8_t i=0; i<24; i++)
vector[23-i]=((0x0D7880F>>i)&1)*0xFFFF;
vector[6]^=0xFFFF;
vector[7]^=0xFFFF;
vector[8]^=0xFFFF;
vector[11]^=0xFFFF;
TEST_ASSERT_NOT_EQUAL(0x0D78, golay24_sdecode(vector));
for(uint8_t i=0; i<24; i++)
vector[23-i]=((0x0D7880F>>i)&1)*0xFFFF;
vector[6]^=0xFFFF;
vector[7]^=0xFFFF;
vector[8]^=0xFFFF;
vector[9]^=0xFFFF;
TEST_ASSERT_EQUAL(0x0D78, golay24_sdecode(vector));
for(uint8_t i=0; i<24; i++)
vector[23-i]=((0x0D7880F>>i)&1)*0xFFFF;
}
void golay_soft_decode_erased_parity_5(void)
{
uint16_t vector[24]; //soft-logic 24-bit vector
//clean D78|80F to soft-logic data
for(uint8_t i=0; i<24; i++)
vector[23-i]=((0x0D7880F>>i)&1)*0xFFFF;
for(uint16_t j=0; j<1000; j++)
{
apply_errors(vector, 0, 11, 5, 2.5);
TEST_ASSERT_NOT_EQUAL(0x0D78, golay24_sdecode(vector));
for(uint8_t i=0; i<24; i++)
vector[23-i]=((0x0D7880F>>i)&1)*0xFFFF;
}
}
void golay_soft_decode_flipped_parity_5(void)
{
uint16_t vector[24]; //soft-logic 24-bit vector
//clean D78|80F to soft-logic data
for(uint8_t i=0; i<24; i++)
vector[23-i]=((0x0D7880F>>i)&1)*0xFFFF;
for(uint16_t j=0; j<1000; j++)
{
apply_errors(vector, 0, 11, 5, 5.0);
TEST_ASSERT_NOT_EQUAL(0x0D78, golay24_sdecode(vector));
for(uint8_t i=0; i<24; i++)
vector[23-i]=((0x0D7880F>>i)&1)*0xFFFF;
}
}
void golay_soft_decode_flipped_data_1(void)
{
uint16_t vector[24]; //soft-logic 24-bit vector
//clean D78|80F to soft-logic data
for(uint8_t i=0; i<24; i++)
vector[23-i]=((0x0D7880F>>i)&1)*0xFFFF;
for(uint16_t j=0; j<1000; j++)
{
apply_errors(vector, 12, 23, 1, 1.0);
TEST_ASSERT_EQUAL(0x0D78, golay24_sdecode(vector));
for(uint8_t i=0; i<24; i++)
vector[23-i]=((0x0D7880F>>i)&1)*0xFFFF;
}
}
void golay_soft_decode_erased_data_1(void)
{
uint16_t vector[24]; //soft-logic 24-bit vector
//clean D78|80F to soft-logic data
for(uint8_t i=0; i<24; i++)
vector[23-i]=((0x0D7880F>>i)&1)*0xFFFF;
for(uint16_t j=0; j<1000; j++)
{
apply_errors(vector, 12, 23, 1, 0.5);
TEST_ASSERT_EQUAL(0x0D78, golay24_sdecode(vector));
for(uint8_t i=0; i<24; i++)
vector[23-i]=((0x0D7880F>>i)&1)*0xFFFF;
}
}
void golay_soft_decode_flipped_data_2(void)
{
uint16_t vector[24]; //soft-logic 24-bit vector
//clean D78|80F to soft-logic data
for(uint8_t i=0; i<24; i++)
vector[23-i]=((0x0D7880F>>i)&1)*0xFFFF;
for(uint16_t j=0; j<1000; j++)
{
apply_errors(vector, 12, 23, 2, 2.0);
TEST_ASSERT_EQUAL(0x0D78, golay24_sdecode(vector));
for(uint8_t i=0; i<24; i++)
vector[23-i]=((0x0D7880F>>i)&1)*0xFFFF;
}
}
void golay_soft_decode_erased_data_2(void)
{
uint16_t vector[24]; //soft-logic 24-bit vector
//clean D78|80F to soft-logic data
for(uint8_t i=0; i<24; i++)
vector[23-i]=((0x0D7880F>>i)&1)*0xFFFF;
for(uint16_t j=0; j<1000; j++)
{
apply_errors(vector, 12, 23, 2, 1.0);
TEST_ASSERT_EQUAL(0x0D78, golay24_sdecode(vector));
for(uint8_t i=0; i<24; i++)
vector[23-i]=((0x0D7880F>>i)&1)*0xFFFF;
}
}
void golay_soft_decode_flipped_data_3(void)
{
uint16_t vector[24]; //soft-logic 24-bit vector
//clean D78|80F to soft-logic data
for(uint8_t i=0; i<24; i++)
vector[23-i]=((0x0D7880F>>i)&1)*0xFFFF;
for(uint16_t j=0; j<1000; j++)
{
apply_errors(vector, 12, 23, 3, 3.0);
TEST_ASSERT_EQUAL(0x0D78, golay24_sdecode(vector));
for(uint8_t i=0; i<24; i++)
vector[23-i]=((0x0D7880F>>i)&1)*0xFFFF;
}
}
void golay_soft_decode_erased_data_3(void)
{
uint16_t vector[24]; //soft-logic 24-bit vector
//clean D78|80F to soft-logic data
for(uint8_t i=0; i<24; i++)
vector[23-i]=((0x0D7880F>>i)&1)*0xFFFF;
for(uint16_t j=0; j<1000; j++)
{
apply_errors(vector, 12, 23, 3, 1.5);
TEST_ASSERT_EQUAL(0x0D78, golay24_sdecode(vector));
for(uint8_t i=0; i<24; i++)
vector[23-i]=((0x0D7880F>>i)&1)*0xFFFF;
}
}
void golay_soft_decode_erased_data_3_5(void)
{
uint16_t vector[24]; //soft-logic 24-bit vector
//clean D78|80F to soft-logic data
for(uint8_t i=0; i<24; i++)
vector[23-i]=((0x0D7880F>>i)&1)*0xFFFF;
for(uint16_t j=0; j<1000; j++)
{
apply_errors(vector, 12, 23, 7, 3.5);
TEST_ASSERT_EQUAL(0x0D78, golay24_sdecode(vector));
for(uint8_t i=0; i<24; i++)
vector[23-i]=((0x0D7880F>>i)&1)*0xFFFF;
}
}
//4 errors is exactly half the hamming distance, so due to rounding etc., results may vary
//therefore we run 2 tests here to prove that
void golay_soft_decode_flipped_data_4(void)
{
uint16_t vector[24]; //soft-logic 24-bit vector
//clean D78|80F to soft-logic data
for(uint8_t i=0; i<24; i++)
vector[23-i]=((0x0D7880F>>i)&1)*0xFFFF;
vector[12]^=0xFFFF;
vector[13]^=0xFFFF;
vector[16]^=0xFFFF;
vector[22]^=0xFFFF;
TEST_ASSERT_NOT_EQUAL(0x0D78, golay24_sdecode(vector));
for(uint8_t i=0; i<24; i++)
vector[23-i]=((0x0D7880F>>i)&1)*0xFFFF;
vector[14]^=0xFFFF;
vector[16]^=0xFFFF;
vector[17]^=0xFFFF;
vector[20]^=0xFFFF;
TEST_ASSERT_EQUAL(0x0D78, golay24_sdecode(vector));
for(uint8_t i=0; i<24; i++)
vector[23-i]=((0x0D7880F>>i)&1)*0xFFFF;
}
void golay_soft_decode_corrupt_data_4_5(void)
{
uint16_t vector[24]; //soft-logic 24-bit vector
//clean D78|80F to soft-logic data
for(uint8_t i=0; i<24; i++)
vector[23-i]=((0x0D7880F>>i)&1)*0xFFFF;
//4.5 errors - should be uncorrectable - WTF?
apply_errors(vector, 12, 23, 12, 4.5);
TEST_ASSERT_EQUAL(0x0D78, golay24_sdecode(vector));
for(uint8_t i=0; i<24; i++)
vector[23-i]=((0x0D7880F>>i)&1)*0xFFFF;
}
void golay_soft_decode_erased_data_5(void)
{
uint16_t vector[24]; //soft-logic 24-bit vector
//clean D78|80F to soft-logic data
for(uint8_t i=0; i<24; i++)
vector[23-i]=((0x0D7880F>>i)&1)*0xFFFF;
for(uint16_t j=0; j<1000; j++)
{
apply_errors(vector, 12, 23, 5, 2.5);
TEST_ASSERT_EQUAL(0x0D78, golay24_sdecode(vector));
for(uint8_t i=0; i<24; i++)
vector[23-i]=((0x0D7880F>>i)&1)*0xFFFF;
}
}
void golay_soft_decode_flipped_data_5(void)
{
uint16_t vector[24]; //soft-logic 24-bit vector
//clean D78|80F to soft-logic data
for(uint8_t i=0; i<24; i++)
vector[23-i]=((0x0D7880F>>i)&1)*0xFFFF;
for(uint16_t j=0; j<1000; j++)
{
apply_errors(vector, 12, 23, 5, 5.0);
TEST_ASSERT_NOT_EQUAL(0x0D78, golay24_sdecode(vector));
for(uint8_t i=0; i<24; i++)
vector[23-i]=((0x0D7880F>>i)&1)*0xFFFF;
}
}
int main(void)
{
srand(time(NULL));
UNITY_BEGIN();
//soft logic arithmetic
RUN_TEST(soft_logic_xor);
//symbol to dibit
RUN_TEST(symbol_to_dibit);
//soft Golay
RUN_TEST(golay_encode);
RUN_TEST(golay_soft_decode_clean);
RUN_TEST(golay_soft_decode_erased_parity_1);
RUN_TEST(golay_soft_decode_flipped_parity_1);
RUN_TEST(golay_soft_decode_erased_parity_2);
RUN_TEST(golay_soft_decode_flipped_parity_2);
RUN_TEST(golay_soft_decode_erased_parity_3);
RUN_TEST(golay_soft_decode_flipped_parity_3);
RUN_TEST(golay_soft_decode_erased_parity_3_5);
RUN_TEST(golay_soft_decode_flipped_parity_4);
RUN_TEST(golay_soft_decode_erased_parity_5);
RUN_TEST(golay_soft_decode_flipped_parity_5);
RUN_TEST(golay_soft_decode_erased_data_1);
RUN_TEST(golay_soft_decode_flipped_data_1);
RUN_TEST(golay_soft_decode_erased_data_2);
RUN_TEST(golay_soft_decode_flipped_data_2);
RUN_TEST(golay_soft_decode_erased_data_3);
RUN_TEST(golay_soft_decode_flipped_data_3);
RUN_TEST(golay_soft_decode_erased_data_3_5);
RUN_TEST(golay_soft_decode_flipped_data_4);
RUN_TEST(golay_soft_decode_corrupt_data_4_5);
RUN_TEST(golay_soft_decode_erased_data_5);
RUN_TEST(golay_soft_decode_flipped_data_5);
return UNITY_END();
}