diff --git a/SP5WWP/include/m17/m17.h b/SP5WWP/include/m17/m17.h index 8e2a711..1988c1b 100644 --- a/SP5WWP/include/m17/m17.h +++ b/SP5WWP/include/m17/m17.h @@ -29,7 +29,6 @@ void send_syncword(float out[SYM_PER_SWD], uint32_t *cnt, const uint16_t syncwor 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-/." @@ -68,17 +67,23 @@ 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); + // 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, const uint16_t* inp); +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[368]; +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]); // M17 C library - lib/math/math.c uint16_t q_abs_diff(const uint16_t v1, const uint16_t v2); @@ -94,6 +99,8 @@ void soft_XOR(uint16_t* out, const uint16_t* a, const uint16_t* b, const uint8_t //randomizing pattern extern const uint8_t rand_seq[46]; +void randomize_bits(uint8_t inp[SYM_PER_PLD*2]); + // M17 C library - lib/math/rrc.c //sample RRC filter for 48kHz sample rate //alpha=0.5, span=8, sps=10, gain=sqrt(sps) diff --git a/SP5WWP/lib/math/golay.c b/SP5WWP/lib/math/golay.c index 410322d..82b0d45 100644 --- a/SP5WWP/lib/math/golay.c +++ b/SP5WWP/lib/math/golay.c @@ -241,11 +241,11 @@ uint16_t golay24_sdecode(const uint16_t codeword[24]) * @param outp An array of packed, decoded bits. * @param inp Pointer to an array of 96 soft bits. */ -void decode_LICH(uint8_t* outp, const uint16_t* inp) +void decode_LICH(uint8_t outp[6], const uint16_t inp[96]) { uint16_t tmp; - memset(outp, 0, 5); + //memset(outp, 0, 6); tmp=golay24_sdecode(&inp[0]); outp[0]=(tmp>>4)&0xFF; @@ -260,3 +260,25 @@ void decode_LICH(uint8_t* outp, const uint16_t* inp) 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/payload/call.c b/SP5WWP/lib/payload/call.c index 7246cbb..0aa2986 100644 --- a/SP5WWP/lib/payload/call.c +++ b/SP5WWP/lib/payload/call.c @@ -2,7 +2,7 @@ // M17 C library - payload/call.c // // This file contains: -// - callsign encoder and decoders +// - callsign encoders and decoders // // Wojciech Kaczmarski, SP5WWP // M17 Project, 29 December 2023 diff --git a/SP5WWP/lib/payload/lich.c b/SP5WWP/lib/payload/lich.c new file mode 100644 index 0000000..8d00c24 --- /dev/null +++ b/SP5WWP/lib/payload/lich.c @@ -0,0 +1,78 @@ +//-------------------------------------------------------------------- +// 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; +} diff --git a/SP5WWP/lib/phy/interleave.c b/SP5WWP/lib/phy/interleave.c index 2b30218..f0a8e26 100644 --- a/SP5WWP/lib/phy/interleave.c +++ b/SP5WWP/lib/phy/interleave.c @@ -8,7 +8,7 @@ #include //interleaver pattern -const uint16_t intrl_seq[368]= +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, @@ -34,3 +34,15 @@ const uint16_t intrl_seq[368]= 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) 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>(7-(i%8)))&1) //flip bit if '1' + { + if(inp[i]) + inp[i]=0; + else + inp[i]=1; + } + } +} diff --git a/SP5WWP/m17-coder/Makefile b/SP5WWP/m17-coder/Makefile index f0a429c..2f22dbd 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 m17-coder-sym.c -o m17-coder-sym -lm -lm17 + gcc -I ../include -L ../lib -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 f32de65..5bb9f26 100644 --- a/SP5WWP/m17-coder/m17-coder-sym.c +++ b/SP5WWP/m17-coder/m17-coder-sym.c @@ -66,81 +66,10 @@ int main(void) send_syncword(frame_buff, &frame_buff_cnt, SYNC_STR); //extract LICH from the whole LSF - switch(lich_cnt) - { - case 0: - lich[0]=lsf.dst[0]; - lich[1]=lsf.dst[1]; - lich[2]=lsf.dst[2]; - lich[3]=lsf.dst[3]; - lich[4]=lsf.dst[4]; - break; - - case 1: - lich[0]=lsf.dst[5]; - lich[1]=lsf.src[0]; - lich[2]=lsf.src[1]; - lich[3]=lsf.src[2]; - lich[4]=lsf.src[3]; - break; - - case 2: - lich[0]=lsf.src[4]; - lich[1]=lsf.src[5]; - lich[2]=lsf.type[0]; - lich[3]=lsf.type[1]; - lich[4]=lsf.meta[0]; - break; - - case 3: - lich[0]=lsf.meta[1]; - lich[1]=lsf.meta[2]; - lich[2]=lsf.meta[3]; - lich[3]=lsf.meta[4]; - lich[4]=lsf.meta[5]; - break; - - case 4: - lich[0]=lsf.meta[6]; - lich[1]=lsf.meta[7]; - lich[2]=lsf.meta[8]; - lich[3]=lsf.meta[9]; - lich[4]=lsf.meta[10]; - break; - - case 5: - lich[0]=lsf.meta[11]; - lich[1]=lsf.meta[12]; - lich[2]=lsf.meta[13]; - lich[3]=lsf.crc[0]; - lich[4]=lsf.crc[1]; - break; - - default: - ; - break; - } - lich[5]=lich_cnt<<5; + extract_LICH(lich, lich_cnt, &lsf); //encode the LICH - uint32_t val; - - val=golay24_encode((lich[0]<<4)|(lich[1]>>4)); - lich_encoded[0]=(val>>16)&0xFF; - lich_encoded[1]=(val>>8)&0xFF; - lich_encoded[2]=(val>>0)&0xFF; - val=golay24_encode(((lich[1]&0x0F)<<8)|lich[2]); - lich_encoded[3]=(val>>16)&0xFF; - lich_encoded[4]=(val>>8)&0xFF; - lich_encoded[5]=(val>>0)&0xFF; - val=golay24_encode((lich[3]<<4)|(lich[4]>>4)); - lich_encoded[6]=(val>>16)&0xFF; - lich_encoded[7]=(val>>8)&0xFF; - lich_encoded[8]=(val>>0)&0xFF; - val=golay24_encode(((lich[4]&0x0F)<<8)|lich[5]); - lich_encoded[9]=(val>>16)&0xFF; - lich_encoded[10]=(val>>8)&0xFF; - lich_encoded[11]=(val>>0)&0xFF; + encode_LICH(lich_encoded, lich); //unpack LICH (12 bytes) memset(enc_bits, 0, SYM_PER_PLD*2); @@ -154,20 +83,10 @@ int main(void) conv_encode_stream_frame(&enc_bits[96], data, finished ? (fn | 0x8000) : fn); //reorder bits - for(uint16_t i=0; i>(7-(i%8)))&1) //flip bit if '1' - { - if(rf_bits[i]) - rf_bits[i]=0; - else - rf_bits[i]=1; - } - } + randomize_bits(rf_bits); //send dummy symbols (debug) /*float s=0.0; diff --git a/SP5WWP/m17-decoder/Makefile b/SP5WWP/m17-decoder/Makefile index aaa3e2a..a453af4 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 -O2 m17-decoder-sym.c -o m17-decoder-sym -lm -lm17 + gcc -I ../include -L ../lib -Wall -Wextra -O2 m17-decoder-sym.c -o m17-decoder-sym -lm -lm17 clean: rm -f m17-decoder-sym diff --git a/SP5WWP/m17-packet/Makefile b/SP5WWP/m17-packet/Makefile index 8a9e2a1..9eeeb2f 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 m17-packet-encode.c -o m17-packet-encode -lm -lm17 + gcc -I ../include -L ../lib -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 m17-packet-decode.c -o m17-packet-decode -lm -lm17 + gcc -I ../include -L ../lib -O2 -Wall -Wextra m17-packet-decode.c -o m17-packet-decode -lm -lm17 install: all sudo install m17-packet-encode /usr/local/bin