From 3ceff08654a76753d7f3b507c15b670e0f97c50a Mon Sep 17 00:00:00 2001 From: Wojciech Kaczmarski Date: Wed, 24 Jan 2024 12:39:09 +0100 Subject: [PATCH] migrated to libm17 --- .gitmodules | 3 + SP5WWP/include/m17/m17.h | 158 ------- SP5WWP/lib/.gitignore | 3 - SP5WWP/lib/Makefile | 30 -- SP5WWP/lib/README.md | 5 - SP5WWP/lib/decode/symbols.c | 16 - SP5WWP/lib/decode/viterbi.c | 202 --------- SP5WWP/lib/encode/convol.c | 237 ---------- SP5WWP/lib/encode/symbols.c | 16 - SP5WWP/lib/lib.c | 80 ---- SP5WWP/lib/math/golay.c | 284 ------------ SP5WWP/lib/math/math.c | 179 -------- SP5WWP/lib/math/rrc.c | 67 --- SP5WWP/lib/payload/call.c | 173 -------- SP5WWP/lib/payload/crc.c | 57 --- SP5WWP/lib/payload/lich.c | 93 ---- SP5WWP/lib/phy/interleave.c | 60 --- SP5WWP/lib/phy/randomize.c | 49 -- SP5WWP/lib/phy/slice.c | 57 --- SP5WWP/lib/phy/sync.c | 14 - SP5WWP/m17-coder/Makefile | 2 +- SP5WWP/m17-coder/m17-coder-sym.c | 2 +- SP5WWP/m17-decoder/Makefile | 2 +- SP5WWP/m17-decoder/m17-decoder-sym.c | 2 +- SP5WWP/m17-packet/Makefile | 4 +- SP5WWP/m17-packet/m17-packet-decode.c | 2 +- SP5WWP/m17-packet/m17-packet-encode.c | 2 +- SP5WWP/tests/unit_tests.c | 614 -------------------------- libm17 | 1 + 29 files changed, 12 insertions(+), 2402 deletions(-) create mode 100644 .gitmodules delete mode 100644 SP5WWP/include/m17/m17.h delete mode 100644 SP5WWP/lib/.gitignore delete mode 100644 SP5WWP/lib/Makefile delete mode 100644 SP5WWP/lib/README.md delete mode 100644 SP5WWP/lib/decode/symbols.c delete mode 100644 SP5WWP/lib/decode/viterbi.c delete mode 100644 SP5WWP/lib/encode/convol.c delete mode 100644 SP5WWP/lib/encode/symbols.c delete mode 100644 SP5WWP/lib/lib.c delete mode 100644 SP5WWP/lib/math/golay.c delete mode 100644 SP5WWP/lib/math/math.c delete mode 100644 SP5WWP/lib/math/rrc.c delete mode 100644 SP5WWP/lib/payload/call.c delete mode 100644 SP5WWP/lib/payload/crc.c delete mode 100644 SP5WWP/lib/payload/lich.c delete mode 100644 SP5WWP/lib/phy/interleave.c delete mode 100644 SP5WWP/lib/phy/randomize.c delete mode 100644 SP5WWP/lib/phy/slice.c delete mode 100644 SP5WWP/lib/phy/sync.c delete mode 100644 SP5WWP/tests/unit_tests.c create mode 160000 libm17 diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 0000000..ae11332 --- /dev/null +++ b/.gitmodules @@ -0,0 +1,3 @@ +[submodule "libm17"] + path = libm17 + url = https://github.com/M17-Project/libm17 diff --git a/SP5WWP/include/m17/m17.h b/SP5WWP/include/m17/m17.h deleted file mode 100644 index 3a4a189..0000000 --- a/SP5WWP/include/m17/m17.h +++ /dev/null @@ -1,158 +0,0 @@ -//-------------------------------------------------------------------- -// M17 C library - m17.h -// -// Wojciech Kaczmarski, SP5WWP -// M17 Project, 29 December 2023 -//-------------------------------------------------------------------- -#pragma once - -#ifdef __cplusplus -extern "C" { -#endif -#include -#include - -// M17 C library - lib/lib.c -#define BSB_SPS 10 //samples per symbol -#define FLT_SPAN 8 //baseband RRC filter span in symbols -#define SYM_PER_SWD 8 //symbols per syncword -#define SW_LEN (BSB_SPS*SYM_PER_SWD) //syncword detector length -#define SYM_PER_PLD 184 //symbols per payload in a frame -#define SYM_PER_FRA 192 //symbols per whole 40 ms frame -#define RRC_DEV 7168.0f //.rrc file deviation for +1.0 symbol - -//L2 metric threshold -#define DIST_THRESH 2.0f //threshold for distance (syncword detection) - -void send_preamble(float out[SYM_PER_FRA], uint32_t *cnt, const uint8_t type); -void send_syncword(float out[SYM_PER_SWD], uint32_t *cnt, const uint16_t syncword); -void send_data(float out[SYM_PER_PLD], uint32_t *cnt, const uint8_t* in); -void send_eot(float out[SYM_PER_FRA], uint32_t *cnt); - -// M17 C library - lib/payload/call.c -#define CHAR_MAP " ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-/." - -void decode_callsign_bytes(uint8_t *outp, const uint8_t inp[6]); -void decode_callsign_value(uint8_t *outp, const uint64_t inp); -int8_t encode_callsign_bytes(uint8_t out[6], const uint8_t *inp); -int8_t encode_callsign_value(uint64_t *out, const uint8_t *inp); - -// M17 C library - payload -/** - * @brief Structure holding Link Setup Frame data. - * - */ -struct LSF -{ - uint8_t dst[6]; - uint8_t src[6]; - uint8_t type[2]; - uint8_t meta[112/8]; - uint8_t crc[2]; -}; - -// M17 C library - lib/encode/convol.c -extern const uint8_t puncture_pattern_1[61]; -extern const uint8_t puncture_pattern_2[12]; -extern const uint8_t puncture_pattern_3[8]; - -void conv_encode_stream_frame(uint8_t* out, const uint8_t* in, const uint16_t fn); -void conv_encode_packet_frame(uint8_t* out, const uint8_t* in); -void conv_encode_LSF(uint8_t* out, const struct LSF *in); - -// M17 C library - lib/payload/crc.c -//M17 CRC polynomial -extern const uint16_t M17_CRC_POLY; - -uint16_t CRC_M17(const uint8_t *in, const uint16_t len); -uint16_t LSF_CRC(const struct LSF *in); - -// M17 C library - lib/payload/lich.c -void extract_LICH(uint8_t outp[6], const uint8_t cnt, const struct LSF *inp); -void unpack_LICH(uint8_t *out, const uint8_t in[12]); - -// M17 C library - lib/math/golay.c -extern const uint16_t encode_matrix[12]; -extern const uint16_t decode_matrix[12]; - -uint32_t golay24_encode(const uint16_t data); -uint16_t golay24_sdecode(const uint16_t codeword[24]); -void decode_LICH(uint8_t outp[6], const uint16_t inp[96]); -void encode_LICH(uint8_t outp[12], const uint8_t inp[6]); - -// M17 C library - lib/phy/interleave.c -//interleaver pattern -extern const uint16_t intrl_seq[SYM_PER_PLD*2]; - -void reorder_bits(uint8_t outp[SYM_PER_PLD*2], const uint8_t inp[SYM_PER_PLD*2]); -void reorder_soft_bits(uint16_t outp[SYM_PER_PLD*2], const uint16_t inp[SYM_PER_PLD*2]); - -// M17 C library - lib/math/math.c -uint16_t q_abs_diff(const uint16_t v1, const uint16_t v2); -float eucl_norm(const float* in1, const int8_t* in2, const uint8_t n); -void int_to_soft(uint16_t* out, const uint16_t in, const uint8_t len); -uint16_t soft_to_int(const uint16_t* in, const uint8_t len); -uint16_t div16(const uint16_t a, const uint16_t b); -uint16_t mul16(const uint16_t a, const uint16_t b); -uint16_t soft_bit_XOR(const uint16_t a, const uint16_t b); -uint16_t soft_bit_NOT(const uint16_t a); -void soft_XOR(uint16_t* out, const uint16_t* a, const uint16_t* b, const uint8_t len); - -// M17 C library - lib/phy/randomize.c -//randomizing pattern -extern const uint8_t rand_seq[46]; - -void randomize_bits(uint8_t inp[SYM_PER_PLD*2]); -void randomize_soft_bits(uint16_t inp[SYM_PER_PLD*2]); - -// M17 C library - lib/phy/slice.c -void slice_symbols(uint16_t out[2*SYM_PER_PLD], const float inp[SYM_PER_PLD]); - -// M17 C library - lib/math/rrc.c -//sample RRC filter for 48kHz sample rate -//alpha=0.5, span=8, sps=10, gain=sqrt(sps) -extern const float rrc_taps_10[8*10+1]; - -//sample RRC filter for 24kHz sample rate -//alpha=0.5, span=8, sps=5, gain=sqrt(sps) -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 -extern const uint16_t SYNC_LSF; -extern const uint16_t SYNC_STR; -extern const uint16_t SYNC_PKT; -extern const uint16_t SYNC_BER; -extern const uint16_t EOT_MRKR; - -// M17 C library - lib/decode/viterbi.c -#define K 5 //constraint length -#define NUM_STATES (1 << (K - 1)) //number of states - -uint32_t viterbi_decode(uint8_t* out, const uint16_t* in, const uint16_t len); -uint32_t viterbi_decode_punctured(uint8_t* out, const uint16_t* in, const uint8_t* punct, const uint16_t in_len, const uint16_t p_len); -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); - -//End of Transmission symbol pattern -extern const float eot_symbols[8]; - -// M17 C library - decode/symbols.c -// syncword patterns (RX) -// TODO: Compute those at runtime from the consts below -extern const int8_t lsf_sync_symbols[8]; -extern const int8_t str_sync_symbols[8]; -extern const int8_t pkt_sync_symbols[8]; - -// symbol levels (RX) -extern const float symbol_levels[4]; - -#ifdef __cplusplus -} -#endif diff --git a/SP5WWP/lib/.gitignore b/SP5WWP/lib/.gitignore deleted file mode 100644 index 33ec174..0000000 --- a/SP5WWP/lib/.gitignore +++ /dev/null @@ -1,3 +0,0 @@ -*.o -*.so -*.a diff --git a/SP5WWP/lib/Makefile b/SP5WWP/lib/Makefile deleted file mode 100644 index 6f2db6d..0000000 --- a/SP5WWP/lib/Makefile +++ /dev/null @@ -1,30 +0,0 @@ -INC = -I ../include - -TARGET = libm17.so - -CFLAGS = $(INC) -fPIC -Wall -Wextra -LDFLAGS = -shared -lm -SRCS = $(wildcard *.c) $(wildcard */*.c) -OBJS = $(SRCS:.c=.o) - -all: $(TARGET) clean - -clean: - rm -f $(OBJS) - -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 - -$(TARGET): $(OBJS) - $(CC) $(CFLAGS) $(OBJS) -o $@ $(LDFLAGS) - -.PHONY: all clean fclean diff --git a/SP5WWP/lib/README.md b/SP5WWP/lib/README.md deleted file mode 100644 index 8706c36..0000000 --- a/SP5WWP/lib/README.md +++ /dev/null @@ -1,5 +0,0 @@ -# libm17 - -### Compiling - -To compile, simply run `make`. This will generate a shared library `libm17.so`. diff --git a/SP5WWP/lib/decode/symbols.c b/SP5WWP/lib/decode/symbols.c deleted file mode 100644 index d0d914a..0000000 --- a/SP5WWP/lib/decode/symbols.c +++ /dev/null @@ -1,16 +0,0 @@ -//-------------------------------------------------------------------- -// M17 C library - decode/symbols.c -// -// Wojciech Kaczmarski, SP5WWP -// M17 Project, 29 December 2023 -//-------------------------------------------------------------------- -#include - -// syncword patterns (RX) -// TODO: Compute those at runtime from the consts below -const int8_t lsf_sync_symbols[8]={+3, +3, +3, +3, -3, -3, +3, -3}; -const int8_t str_sync_symbols[8]={-3, -3, -3, -3, +3, +3, -3, +3}; -const int8_t pkt_sync_symbols[8]={+3, -3, +3, +3, -3, -3, -3, -3}; - -// symbol levels (RX) -const float symbol_levels[4]={-3.0, -1.0, +1.0, +3.0}; diff --git a/SP5WWP/lib/decode/viterbi.c b/SP5WWP/lib/decode/viterbi.c deleted file mode 100644 index ee15898..0000000 --- a/SP5WWP/lib/decode/viterbi.c +++ /dev/null @@ -1,202 +0,0 @@ -//-------------------------------------------------------------------- -// M17 C library - decode/viterbi.c -// -// This file contains: -// - the Viterbi decoder -// -// Wojciech Kaczmarski, SP5WWP -// M17 Project, 29 December 2023 -//-------------------------------------------------------------------- -#include -#include - -#include - -static uint32_t prevMetrics[NUM_STATES]; -static uint32_t currMetrics[NUM_STATES]; -static uint32_t prevMetricsData[NUM_STATES]; -static uint32_t currMetricsData[NUM_STATES]; -static uint16_t viterbi_history[244]; - -/** - * @brief Decode unpunctured convolutionally encoded data. - * - * @param out Destination array where decoded data is written. - * @param in Input data. - * @param len Input length in bits. - * @return Number of bit errors corrected. - */ -uint32_t viterbi_decode(uint8_t* out, const uint16_t* in, const uint16_t len) -{ - if(len > 244*2) - fprintf(stderr, "Input size exceeds max history\n"); - - viterbi_reset(); - - size_t pos = 0; - for(size_t i = 0; i < len; i += 2) - { - uint16_t s0 = in[i]; - uint16_t s1 = in[i + 1]; - - viterbi_decode_bit(s0, s1, pos); - pos++; - } - - return viterbi_chainback(out, pos, len/2); -} - -/** - * @brief Decode punctured convolutionally encoded data. - * - * @param out Destination array where decoded data is written. - * @param in Input data. - * @param punct Puncturing matrix. - * @param in_len Input data length. - * @param p_len Puncturing matrix length (entries). - * @return Number of bit errors corrected. - */ -uint32_t viterbi_decode_punctured(uint8_t* out, const uint16_t* in, const uint8_t* punct, const uint16_t in_len, const uint16_t p_len) -{ - if(in_len > 244*2) - fprintf(stderr, "Input size exceeds max history\n"); - - uint16_t umsg[244*2]; //unpunctured message - uint8_t p=0; //puncturer matrix entry - uint16_t u=0; //bits count - unpunctured message - uint16_t i=0; //bits read from the input message - - while(i= m1) - { - viterbi_history[pos]|=(1<= m3) - { - viterbi_history[pos]|=(1< 0) - { - bitPos--; - pos--; - uint16_t bit = viterbi_history[pos]&((1<<(state>>4))); - state >>= 1; - if(bit) - { - state |= 0x80; - out[bitPos/8]|=1<<(7-(bitPos%8)); - } - } - - uint32_t cost = prevMetrics[0]; - - for(size_t i = 0; i < NUM_STATES; i++) - { - uint32_t m = prevMetrics[i]; - if(m < cost) cost = m; - } - - return cost; -} - -/** - * @brief Reset the decoder state. No args. - * - */ -void viterbi_reset(void) -{ - memset((uint8_t*)viterbi_history, 0, 2*244); - memset((uint8_t*)currMetrics, 0, 4*NUM_STATES); - memset((uint8_t*)prevMetrics, 0, 4*NUM_STATES); - memset((uint8_t*)currMetricsData, 0, 4*NUM_STATES); - memset((uint8_t*)prevMetricsData, 0, 4*NUM_STATES); -} diff --git a/SP5WWP/lib/encode/convol.c b/SP5WWP/lib/encode/convol.c deleted file mode 100644 index daf1f0e..0000000 --- a/SP5WWP/lib/encode/convol.c +++ /dev/null @@ -1,237 +0,0 @@ -//-------------------------------------------------------------------- -// M17 C library - encode/convol.c -// -// This file contains: -// - convolutional encoders for the LSF, stream, and packet frames -// -// Wojciech Kaczmarski, SP5WWP -// M17 Project, 29 December 2023 -//-------------------------------------------------------------------- -#include -#include - -const uint8_t puncture_pattern_1[61] = { - 1,1,0,1,1,1,0,1,1,1,0,1,1,1,0,1,1, - 1,0,1,1,1,0,1,1,1,0,1,1,1,0,1,1, - 1,0,1,1,1,0,1,1,1,0,1,1,1,0,1,1, - 1,0,1,1,1,0,1,1,1,0,1,1 -}; - -const uint8_t puncture_pattern_2[12]={1,1,1,1,1,1,1,1,1,1,1,0}; -const uint8_t puncture_pattern_3[8]={1,1,1,1,1,1,1,0}; - -/** - * @brief Encode M17 stream frame using convolutional encoder with puncturing. - * - * @param out Output array, unpacked. - * @param in Input - packed array of uint8_t, 144 type-1 bits. - * @param fn Input - 16-bit frame number. - */ -void conv_encode_stream_frame(uint8_t* out, const uint8_t* in, const uint16_t fn) -{ - uint8_t pp_len = sizeof(puncture_pattern_2); - uint8_t p=0; //puncturing pattern index - uint16_t pb=0; //pushed punctured bits - uint8_t ud[144+4+4]; //unpacked data - - memset(ud, 0, 144+4+4); - - //unpack frame number - for(uint8_t i=0; i<16; i++) - { - ud[4+i]=(fn>>(15-i))&1; - } - - //unpack data - for(uint8_t i=0; i<16; i++) - { - for(uint8_t j=0; j<8; j++) - { - ud[4+16+i*8+j]=(in[i]>>(7-j))&1; - } - } - - //encode - for(uint8_t i=0; i<144+4; i++) - { - uint8_t G1=(ud[i+4] +ud[i+1]+ud[i+0])%2; - uint8_t G2=(ud[i+4]+ud[i+3]+ud[i+2] +ud[i+0])%2; - - //printf("%d%d", G1, G2); - - if(puncture_pattern_2[p]) - { - out[pb]=G1; - pb++; - } - - p++; - p%=pp_len; - - if(puncture_pattern_2[p]) - { - out[pb]=G2; - pb++; - } - - p++; - p%=pp_len; - } - - //printf("pb=%d\n", pb); -} - -/** - * @brief Encode M17 packet frame using convolutional encoder with puncturing. - * - * @param out Output array, unpacked. - * @param in Input - packed array of uint8_t, 206 type-1 bits. - */ -void conv_encode_packet_frame(uint8_t* out, const uint8_t* in) -{ - uint8_t pp_len = sizeof(puncture_pattern_3); - uint8_t p=0; //puncturing pattern index - uint16_t pb=0; //pushed punctured bits - uint8_t ud[206+4+4]; //unpacked data - - memset(ud, 0, 206+4+4); - - //unpack data - for(uint8_t i=0; i<26; i++) - { - for(uint8_t j=0; j<8; j++) - { - if(i<=24 || j<=5) - ud[4+i*8+j]=(in[i]>>(7-j))&1; - } - } - - //encode - for(uint8_t i=0; i<206+4; i++) - { - uint8_t G1=(ud[i+4] +ud[i+1]+ud[i+0])%2; - uint8_t G2=(ud[i+4]+ud[i+3]+ud[i+2] +ud[i+0])%2; - - //fprintf(stderr, "%d%d", G1, G2); - - if(puncture_pattern_3[p]) - { - out[pb]=G1; - pb++; - } - - p++; - p%=pp_len; - - if(puncture_pattern_3[p]) - { - out[pb]=G2; - pb++; - } - - p++; - p%=pp_len; - } - - //fprintf(stderr, "pb=%d\n", pb); -} - -/** - * @brief Encode M17 stream frame using convolutional encoder with puncturing. - * - * @param out Output array, unpacked. - * @param in Input - pointer to a struct holding the Link Setup Frame. - */ -void conv_encode_LSF(uint8_t* out, const struct LSF *in) -{ - uint8_t pp_len = sizeof(puncture_pattern_1); - uint8_t p=0; //puncturing pattern index - uint16_t pb=0; //pushed punctured bits - uint8_t ud[240+4+4]; //unpacked data - - memset(ud, 0, 240+4+4); - - //unpack DST - for(uint8_t i=0; i<8; i++) - { - ud[4+i] =((in->dst[0])>>(7-i))&1; - ud[4+i+8] =((in->dst[1])>>(7-i))&1; - ud[4+i+16]=((in->dst[2])>>(7-i))&1; - ud[4+i+24]=((in->dst[3])>>(7-i))&1; - ud[4+i+32]=((in->dst[4])>>(7-i))&1; - ud[4+i+40]=((in->dst[5])>>(7-i))&1; - } - - //unpack SRC - for(uint8_t i=0; i<8; i++) - { - ud[4+i+48]=((in->src[0])>>(7-i))&1; - ud[4+i+56]=((in->src[1])>>(7-i))&1; - ud[4+i+64]=((in->src[2])>>(7-i))&1; - ud[4+i+72]=((in->src[3])>>(7-i))&1; - ud[4+i+80]=((in->src[4])>>(7-i))&1; - ud[4+i+88]=((in->src[5])>>(7-i))&1; - } - - //unpack TYPE - for(uint8_t i=0; i<8; i++) - { - ud[4+i+96] =((in->type[0])>>(7-i))&1; - ud[4+i+104]=((in->type[1])>>(7-i))&1; - } - - //unpack META - for(uint8_t i=0; i<8; i++) - { - ud[4+i+112]=((in->meta[0])>>(7-i))&1; - ud[4+i+120]=((in->meta[1])>>(7-i))&1; - ud[4+i+128]=((in->meta[2])>>(7-i))&1; - ud[4+i+136]=((in->meta[3])>>(7-i))&1; - ud[4+i+144]=((in->meta[4])>>(7-i))&1; - ud[4+i+152]=((in->meta[5])>>(7-i))&1; - ud[4+i+160]=((in->meta[6])>>(7-i))&1; - ud[4+i+168]=((in->meta[7])>>(7-i))&1; - ud[4+i+176]=((in->meta[8])>>(7-i))&1; - ud[4+i+184]=((in->meta[9])>>(7-i))&1; - ud[4+i+192]=((in->meta[10])>>(7-i))&1; - ud[4+i+200]=((in->meta[11])>>(7-i))&1; - ud[4+i+208]=((in->meta[12])>>(7-i))&1; - ud[4+i+216]=((in->meta[13])>>(7-i))&1; - } - - //unpack CRC - for(uint8_t i=0; i<8; i++) - { - ud[4+i+224]=((in->crc[0])>>(7-i))&1; - ud[4+i+232]=((in->crc[1])>>(7-i))&1; - } - - //encode - for(uint8_t i=0; i<240+4; i++) - { - uint8_t G1=(ud[i+4] +ud[i+1]+ud[i+0])%2; - uint8_t G2=(ud[i+4]+ud[i+3]+ud[i+2] +ud[i+0])%2; - - //printf("%d%d", G1, G2); - - if(puncture_pattern_1[p]) - { - out[pb]=G1; - pb++; - } - - p++; - p%=pp_len; - - if(puncture_pattern_1[p]) - { - out[pb]=G2; - pb++; - } - - p++; - p%=pp_len; - } - - //printf("pb=%d\n", pb); -} diff --git a/SP5WWP/lib/encode/symbols.c b/SP5WWP/lib/encode/symbols.c deleted file mode 100644 index 7c01968..0000000 --- a/SP5WWP/lib/encode/symbols.c +++ /dev/null @@ -1,16 +0,0 @@ -//-------------------------------------------------------------------- -// M17 C library - encode/symbols.c -// -// Wojciech Kaczmarski, SP5WWP -// M17 Project, 8 January 2024 -//-------------------------------------------------------------------- -#include - -//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}; diff --git a/SP5WWP/lib/lib.c b/SP5WWP/lib/lib.c deleted file mode 100644 index 8780ee0..0000000 --- a/SP5WWP/lib/lib.c +++ /dev/null @@ -1,80 +0,0 @@ -//-------------------------------------------------------------------- -// M17 C library - lib.c -// -// Wojciech Kaczmarski, SP5WWP -// M17 Project, 5 January 2024 -//-------------------------------------------------------------------- -#include - -/** - * @brief Generate symbol stream for a preamble. - * - * @param out Frame buffer (192 floats) - * @param cnt Pointer to a variable holding the number of written symbols. - * @param type Preamble type (pre-BERT or pre-LSF). - */ -void send_preamble(float out[SYM_PER_FRA], uint32_t *cnt, const uint8_t type) -{ - if(type) //pre-BERT - { - for(uint16_t i=0; i>(14-i))&3]; - } -} - -//send the data (can be used for both LSF and frames) -/** - * @brief Generate symbol stream for frame contents (without syncword). - * Can be used for both LSF and data frames. - * - * @param out Output buffer (184 floats). - * @param cnt Pointer to a variable holding the number of written symbols. - * @param in Data input. - */ -void send_data(float out[SYM_PER_PLD], uint32_t *cnt, const uint8_t* in) -{ - for(uint16_t i=0; i - -#include - -/** - * @brief Precomputed encoding matrix for Golay(24, 12). - * - */ -const uint16_t encode_matrix[12]= -{ - 0x8eb, 0x93e, 0xa97, 0xdc6, 0x367, 0x6cd, - 0xd99, 0x3da, 0x7b4, 0xf68, 0x63b, 0xc75 -}; - -/** - * @brief Precomputed decoding matrix for Golay(24, 12). - * - */ -const uint16_t decode_matrix[12]= -{ - 0xc75, 0x49f, 0x93e, 0x6e3, 0xdc6, 0xf13, - 0xab9, 0x1ed, 0x3da, 0x7b4, 0xf68, 0xa4f -}; - -/** - * @brief Encode a 12-bit value with Golay(24, 12). - * - * @param data 12-bit input value (right justified). - * @return uint32_t 24-bit Golay codeword. - */ -uint32_t golay24_encode(const uint16_t data) -{ - uint16_t checksum=0; - - for(uint8_t i=0; i<12; i++) - { - if(data&(1<0x7FFF) - { - soft_XOR(checksum, checksum, soft_em, 12); - } - } - - memcpy((uint8_t*)out, (uint8_t*)checksum, 12*2); -} - -/** - * @brief Detect errors in a soft-valued Golay(24, 12) codeword. - * - * @param codeword Input 24-bit soft codeword. - * @return uint32_t Detected errors vector. - */ -uint32_t s_detect_errors(const uint16_t* codeword) -{ - uint16_t data[12]; - uint16_t parity[12]; - uint16_t cksum[12]; - uint16_t syndrome[12]; - uint32_t weight; //for soft popcount - - memcpy((uint8_t*)data, (uint8_t*)&codeword[12], 2*12); - memcpy((uint8_t*)parity, (uint8_t*)&codeword[0], 2*12); - - s_calc_checksum(cksum, data); - soft_XOR(syndrome, parity, cksum, 12); - - weight=s_popcount(syndrome, 12); - - //all (less than 4) errors in the parity part - if(weight < 4*0xFFFE) - { - //printf("1: %1.2f\n", (float)weight/0xFFFF); - return soft_to_int(syndrome, 12); - } - - //one of the errors in data part, up to 3 in parity - for(uint8_t i = 0; i<12; i++) - { - uint16_t e = 1< 0x7FFF) - { - int_to_soft(dm, decode_matrix[i], 12); - soft_XOR(inv_syndrome, inv_syndrome, dm, 12); - } - } - - //all (less than 4) errors in the data part - weight=s_popcount(inv_syndrome, 12); - if(weight < 4*0xFFFF) - { - //printf("4: %1.2f\n", (float)weight/0xFFFF); - return soft_to_int(inv_syndrome, 12) << 12; - } - - //one error in parity bits, up to 3 in data - this part has some quirks, the reason remains unknown - for(uint8_t i=0; i<12; i++) - { - uint16_t e = 1<> 12) & 0x0FFF; -} - -/** - * @brief Soft decode LICH into a 6-byte array. - * - * @param outp An array of packed, decoded bits. - * @param inp Pointer to an array of 96 soft bits. - */ -void decode_LICH(uint8_t outp[6], const uint16_t inp[96]) -{ - uint16_t tmp; - - //memset(outp, 0, 6); - - tmp=golay24_sdecode(&inp[0]); - outp[0]=(tmp>>4)&0xFF; - outp[1]|=(tmp&0xF)<<4; - tmp=golay24_sdecode(&inp[1*24]); - outp[1]|=(tmp>>8)&0xF; - outp[2]=tmp&0xFF; - tmp=golay24_sdecode(&inp[2*24]); - outp[3]=(tmp>>4)&0xFF; - outp[4]|=(tmp&0xF)<<4; - tmp=golay24_sdecode(&inp[3*24]); - outp[4]|=(tmp>>8)&0xF; - outp[5]=tmp&0xFF; -} - -void encode_LICH(uint8_t outp[12], const uint8_t inp[6]) -{ - uint32_t val; - - val=golay24_encode((inp[0]<<4)|(inp[1]>>4)); - outp[0]=(val>>16)&0xFF; - outp[1]=(val>>8)&0xFF; - outp[2]=(val>>0)&0xFF; - val=golay24_encode(((inp[1]&0x0F)<<8)|inp[2]); - outp[3]=(val>>16)&0xFF; - outp[4]=(val>>8)&0xFF; - outp[5]=(val>>0)&0xFF; - val=golay24_encode((inp[3]<<4)|(inp[4]>>4)); - outp[6]=(val>>16)&0xFF; - outp[7]=(val>>8)&0xFF; - outp[8]=(val>>0)&0xFF; - val=golay24_encode(((inp[4]&0x0F)<<8)|inp[5]); - outp[9]=(val>>16)&0xFF; - outp[10]=(val>>8)&0xFF; - outp[11]=(val>>0)&0xFF; -} diff --git a/SP5WWP/lib/math/math.c b/SP5WWP/lib/math/math.c deleted file mode 100644 index c4cc896..0000000 --- a/SP5WWP/lib/math/math.c +++ /dev/null @@ -1,179 +0,0 @@ -//-------------------------------------------------------------------- -// M17 C library - math/math.c -// -// This file contains: -// - absolute difference value -// - Euclidean norm (L2) calculation for n-dimensional vectors (float) -// - soft-valued arrays to integer conversion (and vice-versa) -// - fixed-valued multiplication and division -// -// Wojciech Kaczmarski, SP5WWP -// M17 Project, 29 December 2023 -//-------------------------------------------------------------------- -#include -#include - -/** - * @brief Utility function returning the absolute value of a difference between - * two fixed-point values. - * - * @param v1 First value. - * @param v2 Second value. - * @return abs(v1-v2) value. - */ -uint16_t q_abs_diff(const uint16_t v1, const uint16_t v2) -{ - if(v2 > v1) return v2 - v1; - return v1 - v2; -} - -/** - * @brief Calculate L2 norm between two n-dimensional vectors of floats. - * - * @param in1 Vector 1. - * @param in2 Vector 2. - * @param n Vectors' size. - * @return float L2 norm. - */ -float eucl_norm(const float* in1, const int8_t* in2, const uint8_t n) -{ - float tmp = 0.0f; - - for(uint8_t i=0; i>i)&1 ? (out[i]=0xFFFF) : (out[i]=0); - } -} - -/** - * @brief Convert an array of soft, fixed-point - * Maximum length is 16. LSB is at index 0. - * @param in Pointer to an array of uint16_t. - * @param len Input's length. - * @return uint16_t Return value. - */ -uint16_t soft_to_int(const uint16_t* in, const uint8_t len) -{ - uint16_t tmp=0; - - for(uint8_t i=0; i0x7FFFU) - tmp|=(1<=b) - return a-b; - else - return 0x0000U; -} - -/** - * @brief 1st quadrant fixed point division with saturation. - * - * @param a Dividend. - * @param b Divisor. - * @return uint16_t Quotient = a/b. - */ -uint16_t div16(const uint16_t a, const uint16_t b) -{ - uint32_t aa=(uint32_t)a<<16; - uint32_t r=aa/b; - - return r<=0xFFFFU ? r : 0xFFFFU; -} - -/** - * @brief 1st quadrant fixed point multiplication. - * - * @param a Multiplicand. - * @param b Multiplier. - * @return uint16_t Product = a*b. - */ -uint16_t mul16(const uint16_t a, const uint16_t b) -{ - return (uint16_t)(((uint32_t)a*b)>>16); -} - -/** - * @brief Bilinear interpolation (soft-valued expansion) for XOR. - * This approach retains XOR(0.5, 0.5)=0.5 - * https://math.stackexchange.com/questions/3505934/evaluation-of-not-and-xor-in-fuzzy-logic-rules - * @param a Input A. - * @param b Input B. - * @return uint16_t Output = A xor B. - */ -uint16_t soft_bit_XOR(const uint16_t a, const uint16_t b) -{ - //a(1-b)+b(1-a) - //return mul16(div16(0xFFFF-b, 0xFFFF), div16(a, 0xFFFF)) + mul16(div16(b, 0xFFFF), div16(0xFFFF-a, 0xFFFF)); - return add16(mul16(a, sub16(0xFFFF, b)), mul16(b, sub16(0xFFFF, a))); -} - -/** - * @brief Soft logic NOT. - * - * @param a Input A. - * @return uint16_t Output = not A. - */ -uint16_t soft_bit_NOT(const uint16_t a) -{ - return 0xFFFFU-a; -} - -/** - * @brief XOR for vectors of soft-valued logic. - * Max length is 255. - * @param out Output vector = A xor B. - * @param a Input vector A. - * @param b Input vector B. - * @param len Vectors' size. - */ -void soft_XOR(uint16_t* out, const uint16_t* a, const uint16_t* b, const uint8_t len) -{ - for(uint8_t i=0; i - -//sample RRC filter for 48kHz sample rate -//alpha=0.5, span=8, sps=10, gain=sqrt(sps) -const float rrc_taps_10[8*10+1]= -{ - -0.003195702904062073f, -0.002930279157647190f, -0.001940667871554463f, - -0.000356087678023658f, 0.001547011339077758f, 0.003389554791179751f, - 0.004761898604225673f, 0.005310860846138910f, 0.004824746306020221f, - 0.003297923526848786f, 0.000958710871218619f, -0.001749908029791816f, - -0.004238694106631223f, -0.005881783042101693f, -0.006150256456781309f, - -0.004745376707651645f, -0.001704189656473565f, 0.002547854551539951f, - 0.007215575568844704f, 0.011231038205363532f, 0.013421952197060707f, - 0.012730475385624438f, 0.008449554307303753f, 0.000436744366018287f, - -0.010735380379191660f, -0.023726883538258272f, -0.036498030780605324f, - -0.046500883189991064f, -0.050979050575999614f, -0.047340680079891187f, - -0.033554880492651755f, -0.008513823955725943f, 0.027696543159614194f, - 0.073664520037517042f, 0.126689053778116234f, 0.182990955139333916f, - 0.238080025892859704f, 0.287235637987091563f, 0.326040247765297220f, - 0.350895727088112619f, 0.359452932027607974f, 0.350895727088112619f, - 0.326040247765297220f, 0.287235637987091563f, 0.238080025892859704f, - 0.182990955139333916f, 0.126689053778116234f, 0.073664520037517042f, - 0.027696543159614194f, -0.008513823955725943f, -0.033554880492651755f, - -0.047340680079891187f, -0.050979050575999614f, -0.046500883189991064f, - -0.036498030780605324f, -0.023726883538258272f, -0.010735380379191660f, - 0.000436744366018287f, 0.008449554307303753f, 0.012730475385624438f, - 0.013421952197060707f, 0.011231038205363532f, 0.007215575568844704f, - 0.002547854551539951f, -0.001704189656473565f, -0.004745376707651645f, - -0.006150256456781309f, -0.005881783042101693f, -0.004238694106631223f, - -0.001749908029791816f, 0.000958710871218619f, 0.003297923526848786f, - 0.004824746306020221f, 0.005310860846138910f, 0.004761898604225673f, - 0.003389554791179751f, 0.001547011339077758f, -0.000356087678023658f, - -0.001940667871554463f, -0.002930279157647190f, -0.003195702904062073f -}; - -//sample RRC filter for 24kHz sample rate -//alpha=0.5, span=8, sps=5, gain=sqrt(sps) -const float rrc_taps_5[8*5+1]= -{ - -0.004519384154389f, -0.002744505321971f, - 0.002187793653660f, 0.006734308458208f, - 0.006823188093192f, 0.001355815246317f, - -0.005994389201970f, -0.008697733303330f, - -0.002410076268276f, 0.010204314627992f, - 0.018981413448435f, 0.011949415510291f, - -0.015182045838927f, -0.051615756197679f, - -0.072094910038768f, -0.047453533621088f, - 0.039168634270669f, 0.179164496628150f, - 0.336694345124862f, 0.461088271869920f, - 0.508340710642860f, 0.461088271869920f, - 0.336694345124862f, 0.179164496628150f, - 0.039168634270669f, -0.047453533621088f, - -0.072094910038768f, -0.051615756197679f, - -0.015182045838927f, 0.011949415510291f, - 0.018981413448435f, 0.010204314627992f, - -0.002410076268276f, -0.008697733303330f, - -0.005994389201970f, 0.001355815246317f, - 0.006823188093192f, 0.006734308458208f, - 0.002187793653660f, -0.002744505321971f, - -0.004519384154389f -}; diff --git a/SP5WWP/lib/payload/call.c b/SP5WWP/lib/payload/call.c deleted file mode 100644 index 0aa2986..0000000 --- a/SP5WWP/lib/payload/call.c +++ /dev/null @@ -1,173 +0,0 @@ -//-------------------------------------------------------------------- -// M17 C library - payload/call.c -// -// This file contains: -// - callsign encoders and decoders -// -// Wojciech Kaczmarski, SP5WWP -// M17 Project, 29 December 2023 -//-------------------------------------------------------------------- -#include -#include -#include - -/** - * @brief Decode a 6-byte long array (little-endian) into callsign string. - * - * @param outp Decoded callsign string. - * @param inp Pointer to a byte array holding the encoded value (little-endian). - */ -void decode_callsign_bytes(uint8_t *outp, const uint8_t inp[6]) -{ - uint64_t encoded=0; - - //repack the data to a uint64_t - for(uint8_t i=0; i<6; i++) - encoded|=(uint64_t)inp[i]<<(8*i); - - //check if the value is reserved (not a callsign) - if(encoded>=262144000000000ULL) - { - if(encoded==0xFFFFFFFFFFFF) //"ALL" - { - sprintf((char*)outp, "ALL"); //'#' prefix needed here? - } - else - { - outp[0]=0; - } - - return; - } - - //decode the callsign - uint8_t i=0; - while(encoded>0) - { - outp[i]=CHAR_MAP[encoded%40]; - encoded/=40; - i++; - } - outp[i]=0; -} - -/** - * @brief Decode a 48-bit value (stored as uint64_t) into callsign string. - * - * @param outp Decoded callsign string. - * @param inp Encoded value. - */ -void decode_callsign_value(uint8_t *outp, const uint64_t inp) -{ - uint64_t encoded=inp; - - //check if the value is reserved (not a callsign) - if(encoded>=262144000000000ULL) - { - if(encoded==0xFFFFFFFFFFFF) //"ALL" - { - sprintf((char*)outp, "ALL"); //'#' prefix needed here? - } - else - { - outp[0]=0; - } - - return; - } - - //decode the callsign - uint8_t i=0; - while(encoded>0) - { - outp[i]=CHAR_MAP[encoded%40]; - encoded/=40; - i++; - } - outp[i]=0; -} - -/** - * @brief Encode callsign string and store in a 6-byte array (little-endian) - * - * @param out Pointer to a byte array for the encoded value (little-endian). - * @param inp Callsign string. - * @return int8_t Return value, 0 -> OK. - */ -int8_t encode_callsign_bytes(uint8_t out[6], const uint8_t *inp) -{ - //assert inp length - if(strlen((const char*)inp)>9) - { - return -1; - } - - const uint8_t charMap[40]=CHAR_MAP; - - uint64_t tmp=0; - - if(strcmp((const char*)inp, "ALL")==0) - { - tmp=0xFFFFFFFFFFFF; - } - else - { - for(int8_t i=strlen((const char*)inp)-1; i>=0; i--) - { - for(uint8_t j=0; j<40; j++) - { - if(inp[i]==charMap[j]) - { - tmp=tmp*40+j; - break; - } - } - } - } - - for(uint8_t i=0; i<6; i++) - out[i]=(tmp>>(8*i))&0xFF; - - return 0; -} - -/** - * @brief Encode callsign string into a 48-bit value, stored as uint64_t. - * - * @param out Pointer to a uint64_t variable for the encoded value. - * @param inp Callsign string. - * @return int8_t Return value, 0 -> OK. - */ -int8_t encode_callsign_value(uint64_t *out, const uint8_t *inp) -{ - //assert inp length - if(strlen((const char*)inp)>9) - { - return -1; - } - - const uint8_t charMap[40]=CHAR_MAP; - - uint64_t tmp=0; - - if(strcmp((const char*)inp, "ALL")==0) - { - *out=0xFFFFFFFFFFFF; - return 0; - } - - for(int8_t i=strlen((const char*)inp)-1; i>=0; i--) - { - for(uint8_t j=0; j<40; j++) - { - if(inp[i]==charMap[j]) - { - tmp=tmp*40+j; - break; - } - } - } - - *out=tmp; - return 0; -} diff --git a/SP5WWP/lib/payload/crc.c b/SP5WWP/lib/payload/crc.c deleted file mode 100644 index 51da222..0000000 --- a/SP5WWP/lib/payload/crc.c +++ /dev/null @@ -1,57 +0,0 @@ -//-------------------------------------------------------------------- -// M17 C library - payload/crc.c -// -// This file contains: -// - CRC calculating functions (arbitrary length) -// -// Wojciech Kaczmarski, SP5WWP -// M17 Project, 29 December 2023 -//-------------------------------------------------------------------- -#include -#include - -//M17 CRC polynomial -const uint16_t M17_CRC_POLY = 0x5935; - -/** - * @brief Calculate CRC value. - * - * @param in Pointer to the input byte array. - * @param len Input's length. - * @return uint16_t CRC value. - */ -uint16_t CRC_M17(const uint8_t *in, const uint16_t len) -{ - uint32_t crc=0xFFFF; //init val - - for(uint16_t i=0; idst, 6); - memcpy(&d[6], in->src, 6); - memcpy(&d[12], in->type, 2); - memcpy(&d[14], in->meta, 14); - - return CRC_M17(d, 28); -} diff --git a/SP5WWP/lib/payload/lich.c b/SP5WWP/lib/payload/lich.c deleted file mode 100644 index b1f34cc..0000000 --- a/SP5WWP/lib/payload/lich.c +++ /dev/null @@ -1,93 +0,0 @@ -//-------------------------------------------------------------------- -// M17 C library - payload/lich.c -// -// This file contains: -// - Link Information CHannel (LICH) repacking functions -// -// Wojciech Kaczmarski, SP5WWP -// M17 Project, 8 January 2024 -//-------------------------------------------------------------------- -#include -#include - -/** - * @brief Extract LICH from the whole LSF. - * - * @param outp 6-byte array for the LICH. - * @param cnt LICH counter (0 to 5) - * @param inp Pointer to an LSF struct. - */ -void extract_LICH(uint8_t outp[6], const uint8_t cnt, const struct LSF *inp) -{ - switch(cnt) - { - case 0: - outp[0]=inp->dst[0]; - outp[1]=inp->dst[1]; - outp[2]=inp->dst[2]; - outp[3]=inp->dst[3]; - outp[4]=inp->dst[4]; - break; - - case 1: - outp[0]=inp->dst[5]; - outp[1]=inp->src[0]; - outp[2]=inp->src[1]; - outp[3]=inp->src[2]; - outp[4]=inp->src[3]; - break; - - case 2: - outp[0]=inp->src[4]; - outp[1]=inp->src[5]; - outp[2]=inp->type[0]; - outp[3]=inp->type[1]; - outp[4]=inp->meta[0]; - break; - - case 3: - outp[0]=inp->meta[1]; - outp[1]=inp->meta[2]; - outp[2]=inp->meta[3]; - outp[3]=inp->meta[4]; - outp[4]=inp->meta[5]; - break; - - case 4: - outp[0]=inp->meta[6]; - outp[1]=inp->meta[7]; - outp[2]=inp->meta[8]; - outp[3]=inp->meta[9]; - outp[4]=inp->meta[10]; - break; - - case 5: - outp[0]=inp->meta[11]; - outp[1]=inp->meta[12]; - outp[2]=inp->meta[13]; - outp[3]=inp->crc[0]; - outp[4]=inp->crc[1]; - break; - - default: - ; - break; - } - - outp[5]=cnt<<5; -} - -/** - * @brief Unpack LICH bytes. - * - * @param out Unpacked, encoded LICH bits (array of at least 96 bytes). - * @param in 12-byte (96 bits) encoded LICH, packed. - */ -void unpack_LICH(uint8_t *out, const uint8_t in[12]) -{ - for(uint8_t i=0; i<12; i++) - { - for(uint8_t j=0; j<8; j++) - out[i*8+j]=(in[i]>>(7-j))&1; - } -} diff --git a/SP5WWP/lib/phy/interleave.c b/SP5WWP/lib/phy/interleave.c deleted file mode 100644 index eb28d5f..0000000 --- a/SP5WWP/lib/phy/interleave.c +++ /dev/null @@ -1,60 +0,0 @@ -//------------------------------- -// M17 C library - phy/interleave.c -// -// Wojciech Kaczmarski, SP5WWP -// M17 Project, 28 December 2023 -//------------------------------- - -#include - -//interleaver pattern -const uint16_t intrl_seq[SYM_PER_PLD*2]= -{ - 0, 137, 90, 227, 180, 317, 270, 39, 360, 129, 82, 219, 172, 309, 262, 31, - 352, 121, 74, 211, 164, 301, 254, 23, 344, 113, 66, 203, 156, 293, 246, 15, - 336, 105, 58, 195, 148, 285, 238, 7, 328, 97, 50, 187, 140, 277, 230, 367, - 320, 89, 42, 179, 132, 269, 222, 359, 312, 81, 34, 171, 124, 261, 214, 351, - 304, 73, 26, 163, 116, 253, 206, 343, 296, 65, 18, 155, 108, 245, 198, 335, - 288, 57, 10, 147, 100, 237, 190, 327, 280, 49, 2, 139, 92, 229, 182, 319, - 272, 41, 362, 131, 84, 221, 174, 311, 264, 33, 354, 123, 76, 213, 166, 303, - 256, 25, 346, 115, 68, 205, 158, 295, 248, 17, 338, 107, 60, 197, 150, 287, - 240, 9, 330, 99, 52, 189, 142, 279, 232, 1, 322, 91, 44, 181, 134, 271, - 224, 361, 314, 83, 36, 173, 126, 263, 216, 353, 306, 75, 28, 165, 118, 255, - 208, 345, 298, 67, 20, 157, 110, 247, 200, 337, 290, 59, 12, 149, 102, 239, - 192, 329, 282, 51, 4, 141, 94, 231, 184, 321, 274, 43, 364, 133, 86, 223, - 176, 313, 266, 35, 356, 125, 78, 215, 168, 305, 258, 27, 348, 117, 70, 207, - 160, 297, 250, 19, 340, 109, 62, 199, 152, 289, 242, 11, 332, 101, 54, 191, - 144, 281, 234, 3, 324, 93, 46, 183, 136, 273, 226, 363, 316, 85, 38, 175, - 128, 265, 218, 355, 308, 77, 30, 167, 120, 257, 210, 347, 300, 69, 22, 159, - 112, 249, 202, 339, 292, 61, 14, 151, 104, 241, 194, 331, 284, 53, 6, 143, - 96, 233, 186, 323, 276, 45, 366, 135, 88, 225, 178, 315, 268, 37, 358, 127, - 80, 217, 170, 307, 260, 29, 350, 119, 72, 209, 162, 299, 252, 21, 342, 111, - 64, 201, 154, 291, 244, 13, 334, 103, 56, 193, 146, 283, 236, 5, 326, 95, - 48, 185, 138, 275, 228, 365, 318, 87, 40, 177, 130, 267, 220, 357, 310, 79, - 32, 169, 122, 259, 212, 349, 302, 71, 24, 161, 114, 251, 204, 341, 294, 63, - 16, 153, 106, 243, 196, 333, 286, 55, 8, 145, 98, 235, 188, 325, 278, 47 -}; - -/** - * @brief Reorder (interleave) 368 unpacked payload bits. - * - * @param outp Reordered, unpacked type-4 bits. - * @param inp Input unpacked type-2/3 bits. - */ -void reorder_bits(uint8_t outp[SYM_PER_PLD*2], const uint8_t inp[SYM_PER_PLD*2]) -{ - for(uint16_t i=0; i - -//randomizing pattern -const uint8_t rand_seq[46]= -{ - 0xD6, 0xB5, 0xE2, 0x30, 0x82, 0xFF, 0x84, 0x62, 0xBA, 0x4E, 0x96, 0x90, 0xD8, 0x98, 0xDD, 0x5D, 0x0C, 0xC8, 0x52, 0x43, 0x91, 0x1D, 0xF8, - 0x6E, 0x68, 0x2F, 0x35, 0xDA, 0x14, 0xEA, 0xCD, 0x76, 0x19, 0x8D, 0xD5, 0x80, 0xD1, 0x33, 0x87, 0x13, 0x57, 0x18, 0x2D, 0x29, 0x78, 0xC3 -}; - -/** - * @brief Randomize type-4 unpacked bits. - * - * @param inp Input 368 unpacked type-4 bits. - */ -void randomize_bits(uint8_t inp[SYM_PER_PLD*2]) -{ - for(uint16_t i=0; i>(7-(i%8)))&1) //flip bit if '1' - { - if(inp[i]) - inp[i]=0; - else - inp[i]=1; - } - } -} - -/** - * @brief Randomize type-4 soft bits. - * - * @param inp Input 368 soft type-4 bits. - */ -void randomize_soft_bits(uint16_t inp[SYM_PER_PLD*2]) -{ - for(uint16_t i=0; i>(7-(i%8)))&1) //flip bit if '1' - { - inp[i]=soft_bit_NOT(inp[i]); - } - } -} diff --git a/SP5WWP/lib/phy/slice.c b/SP5WWP/lib/phy/slice.c deleted file mode 100644 index 3118345..0000000 --- a/SP5WWP/lib/phy/slice.c +++ /dev/null @@ -1,57 +0,0 @@ -//------------------------------- -// M17 C library - phy/slice.c -// -// Wojciech Kaczmarski, SP5WWP -// M17 Project, 14 January 2024 -//------------------------------- - -#include - -/** - * @brief Slice payload symbols into soft dibits. - * Input (RRC filtered baseband sampled at symbol centers) - * should be already normalized to {-3, -1, +1 +3}. - * @param out Soft valued dibits (type-4). - * @param inp Array of 184 floats (1 sample per symbol). - */ -void slice_symbols(uint16_t out[2*SYM_PER_PLD], const float inp[SYM_PER_PLD]) -{ - for(uint8_t i=0; i=symbol_list[3]) - { - out[i*2+1]=0xFFFF; - } - else if(inp[i]>=symbol_list[2]) - { - out[i*2+1]=-(float)0xFFFF/(symbol_list[3]-symbol_list[2])*symbol_list[2]+inp[i]*(float)0xFFFF/(symbol_list[3]-symbol_list[2]); - } - else if(inp[i]>=symbol_list[1]) - { - out[i*2+1]=0x0000; - } - else if(inp[i]>=symbol_list[0]) - { - out[i*2+1]=(float)0xFFFF/(symbol_list[1]-symbol_list[0])*symbol_list[1]-inp[i]*(float)0xFFFF/(symbol_list[1]-symbol_list[0]); - } - else - { - out[i*2+1]=0xFFFF; - } - - //bit 1 - if(inp[i]>=symbol_list[2]) - { - out[i*2]=0x0000; - } - else if(inp[i]>=symbol_list[1]) - { - out[i*2]=0x7FFF-inp[i]*(float)0xFFFF/(symbol_list[2]-symbol_list[1]); - } - else - { - out[i*2]=0xFFFF; - } - } -} diff --git a/SP5WWP/lib/phy/sync.c b/SP5WWP/lib/phy/sync.c deleted file mode 100644 index 1008c84..0000000 --- a/SP5WWP/lib/phy/sync.c +++ /dev/null @@ -1,14 +0,0 @@ -//-------------------------------------------------------------------- -// M17 C library - phy/sync.c -// -// Wojciech Kaczmarski, SP5WWP -// M17 Project, 29 December 2023 -//-------------------------------------------------------------------- -#include - -//syncwords -const uint16_t SYNC_LSF = 0x55F7; -const uint16_t SYNC_STR = 0xFF5D; -const uint16_t SYNC_PKT = 0x75FF; -const uint16_t SYNC_BER = 0xDF55; -const uint16_t EOT_MRKR = 0x555D; diff --git a/SP5WWP/m17-coder/Makefile b/SP5WWP/m17-coder/Makefile index 2f22dbd..e6e6d5f 100644 --- a/SP5WWP/m17-coder/Makefile +++ b/SP5WWP/m17-coder/Makefile @@ -1,5 +1,5 @@ m17-coder-sym: m17-coder-sym.c - gcc -I ../include -L ../lib -O2 -Wall -Wextra m17-coder-sym.c -o m17-coder-sym -lm -lm17 + gcc -I ../../libm17 -L ../../libm17 -O2 -Wall -Wextra m17-coder-sym.c -o m17-coder-sym -lm -lm17 clean: rm -f m17-coder-sym diff --git a/SP5WWP/m17-coder/m17-coder-sym.c b/SP5WWP/m17-coder/m17-coder-sym.c index 103eac0..91496c6 100644 --- a/SP5WWP/m17-coder/m17-coder-sym.c +++ b/SP5WWP/m17-coder/m17-coder-sym.c @@ -4,7 +4,7 @@ #include //libm17 -#include +#include //#define FN60_DEBUG diff --git a/SP5WWP/m17-decoder/Makefile b/SP5WWP/m17-decoder/Makefile index a453af4..0c21d5a 100644 --- a/SP5WWP/m17-decoder/Makefile +++ b/SP5WWP/m17-decoder/Makefile @@ -1,5 +1,5 @@ m17-decoder-sym: m17-decoder-sym.c - gcc -I ../include -L ../lib -Wall -Wextra -O2 m17-decoder-sym.c -o m17-decoder-sym -lm -lm17 + gcc -I ../../libm17 -L ../../libm17 -Wall -Wextra -O2 m17-decoder-sym.c -o m17-decoder-sym -lm -lm17 clean: rm -f m17-decoder-sym diff --git a/SP5WWP/m17-decoder/m17-decoder-sym.c b/SP5WWP/m17-decoder/m17-decoder-sym.c index 683e149..7f72b78 100644 --- a/SP5WWP/m17-decoder/m17-decoder-sym.c +++ b/SP5WWP/m17-decoder/m17-decoder-sym.c @@ -4,7 +4,7 @@ #include //libm17 -#include +#include #define DECODE_CALLSIGNS #define SHOW_VITERBI_ERRS diff --git a/SP5WWP/m17-packet/Makefile b/SP5WWP/m17-packet/Makefile index 9eeeb2f..24cd38f 100644 --- a/SP5WWP/m17-packet/Makefile +++ b/SP5WWP/m17-packet/Makefile @@ -1,10 +1,10 @@ all: m17-packet-encode m17-packet-decode m17-packet-encode: m17-packet-encode.c - gcc -I ../include -L ../lib -O2 -Wall -Wextra m17-packet-encode.c -o m17-packet-encode -lm -lm17 + gcc -I ../../libm17 -L ../../libm17 -O2 -Wall -Wextra m17-packet-encode.c -o m17-packet-encode -lm -lm17 m17-packet-decode: m17-packet-decode.c - gcc -I ../include -L ../lib -O2 -Wall -Wextra m17-packet-decode.c -o m17-packet-decode -lm -lm17 + gcc -I ../../libm17 -L ../../libm17 -O2 -Wall -Wextra m17-packet-decode.c -o m17-packet-decode -lm -lm17 install: all sudo install m17-packet-encode /usr/local/bin diff --git a/SP5WWP/m17-packet/m17-packet-decode.c b/SP5WWP/m17-packet/m17-packet-decode.c index 7b7e5bb..41a64e7 100644 --- a/SP5WWP/m17-packet/m17-packet-decode.c +++ b/SP5WWP/m17-packet/m17-packet-decode.c @@ -4,7 +4,7 @@ #include //libm17 -#include +#include float sample; //last raw sample from the stdin float last[8]; //look-back buffer for finding syncwords diff --git a/SP5WWP/m17-packet/m17-packet-encode.c b/SP5WWP/m17-packet/m17-packet-encode.c index f6b9b54..5978297 100644 --- a/SP5WWP/m17-packet/m17-packet-encode.c +++ b/SP5WWP/m17-packet/m17-packet-encode.c @@ -5,7 +5,7 @@ #include //libm17 -#include +#include #define FLT_LEN (BSB_SPS*FLT_SPAN+1) //for 48kHz sample rate this is 81 diff --git a/SP5WWP/tests/unit_tests.c b/SP5WWP/tests/unit_tests.c deleted file mode 100644 index fcf9560..0000000 --- a/SP5WWP/tests/unit_tests.c +++ /dev/null @@ -1,614 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#include - -//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_posnum_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; i0; 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(); -} diff --git a/libm17 b/libm17 new file mode 160000 index 0000000..1fcdeaf --- /dev/null +++ b/libm17 @@ -0,0 +1 @@ +Subproject commit 1fcdeafe6419802ea5b0fe423040569e8c596f50