kopia lustrzana https://github.com/projecthorus/horusdemodlib
Initial stab at combined 22/32-byte decoders
rodzic
a555089582
commit
03038b3823
395
src/horus_api.c
395
src/horus_api.c
|
@ -77,7 +77,7 @@ int8_t uw_horus_rtty_8N2[] = {
|
|||
0,0,1,0,0,1,0,0,1,1,0,
|
||||
};
|
||||
|
||||
/* Unique word for Horus Binary V1 */
|
||||
/* Unique word for Horus Binary V1 / V2 */
|
||||
|
||||
int8_t uw_horus_binary_v1[] = {
|
||||
0,0,1,0,0,1,0,0,
|
||||
|
@ -85,19 +85,20 @@ int8_t uw_horus_binary_v1[] = {
|
|||
};
|
||||
|
||||
|
||||
/* Unique word for Horus Binary V2 128/256 bit modes (Last row in the 32x32 Hadamard matrix) */
|
||||
// Old LDPC-mode stuff.
|
||||
// /* Unique word for Horus Binary V2 128/256 bit modes (Last row in the 32x32 Hadamard matrix) */
|
||||
|
||||
int8_t uw_horus_binary_v2[] = {
|
||||
1, 0, 0, 1, 0, 1, 1, 0, // 0x96
|
||||
0, 1, 1, 0, 1, 0, 0, 1, // 0x69
|
||||
0, 1, 1, 0, 1, 0, 0, 1, // 0x69
|
||||
1, 0, 0, 1, 0, 1, 1, 0 // 0x96
|
||||
};
|
||||
// int8_t uw_horus_binary_v2[] = {
|
||||
// 1, 0, 0, 1, 0, 1, 1, 0, // 0x96
|
||||
// 0, 1, 1, 0, 1, 0, 0, 1, // 0x69
|
||||
// 0, 1, 1, 0, 1, 0, 0, 1, // 0x69
|
||||
// 1, 0, 0, 1, 0, 1, 1, 0 // 0x96
|
||||
// };
|
||||
|
||||
|
||||
|
||||
struct horus *horus_open (int mode) {
|
||||
assert((mode == HORUS_MODE_RTTY_7N1) || (mode == HORUS_MODE_RTTY_7N2) || (mode == HORUS_MODE_RTTY_8N2) || (mode == HORUS_MODE_BINARY_V1) || (mode == HORUS_MODE_BINARY_V2_256BIT) || (mode == HORUS_MODE_BINARY_V2_128BIT));
|
||||
assert((mode == HORUS_MODE_RTTY_7N1) || (mode == HORUS_MODE_RTTY_7N2) || (mode == HORUS_MODE_RTTY_8N2) || (mode == HORUS_MODE_BINARY_V1) ); //|| (mode == HORUS_MODE_BINARY_V2_256BIT) || (mode == HORUS_MODE_BINARY_V2_128BIT));
|
||||
|
||||
if (mode == HORUS_MODE_RTTY_7N1){
|
||||
// RTTY Mode defaults - 100 baud, no assumptions about tone spacing.
|
||||
|
@ -115,20 +116,20 @@ struct horus *horus_open (int mode) {
|
|||
// Legacy Horus Binary Mode defaults - 100 baud, Disable mask estimation.
|
||||
return horus_open_advanced(HORUS_MODE_BINARY_V1, HORUS_BINARY_V1_DEFAULT_BAUD, -1);
|
||||
}
|
||||
if (mode == HORUS_MODE_BINARY_V2_128BIT){
|
||||
// V2 Horus Binary Mode defaults - 100 baud, Disable mask estimation.
|
||||
return horus_open_advanced(HORUS_MODE_BINARY_V2_128BIT, HORUS_BINARY_V2_128BIT_DEFAULT_BAUD, -1);
|
||||
}
|
||||
if (mode == HORUS_MODE_BINARY_V2_256BIT){
|
||||
// V2 Horus Binary Mode defaults - 100 baud, Disable mask estimation.
|
||||
return horus_open_advanced(HORUS_MODE_BINARY_V2_256BIT, HORUS_BINARY_V2_256BIT_DEFAULT_BAUD, -1);
|
||||
}
|
||||
// if (mode == HORUS_MODE_BINARY_V2_128BIT){
|
||||
// // V2 Horus Binary Mode defaults - 100 baud, Disable mask estimation.
|
||||
// return horus_open_advanced(HORUS_MODE_BINARY_V2_128BIT, HORUS_BINARY_V2_128BIT_DEFAULT_BAUD, -1);
|
||||
// }
|
||||
// if (mode == HORUS_MODE_BINARY_V2_256BIT){
|
||||
// // V2 Horus Binary Mode defaults - 100 baud, Disable mask estimation.
|
||||
// return horus_open_advanced(HORUS_MODE_BINARY_V2_256BIT, HORUS_BINARY_V2_256BIT_DEFAULT_BAUD, -1);
|
||||
// }
|
||||
}
|
||||
|
||||
|
||||
struct horus *horus_open_advanced (int mode, int Rs, int tx_tone_spacing) {
|
||||
int i, mask;
|
||||
assert((mode == HORUS_MODE_RTTY_7N1) || (mode == HORUS_MODE_RTTY_7N2) || (mode == HORUS_MODE_RTTY_8N2) || (mode == HORUS_MODE_BINARY_V1) || (mode == HORUS_MODE_BINARY_V2_256BIT) || (mode == HORUS_MODE_BINARY_V2_128BIT));
|
||||
assert((mode == HORUS_MODE_RTTY_7N1) || (mode == HORUS_MODE_RTTY_7N2) || (mode == HORUS_MODE_RTTY_8N2) || (mode == HORUS_MODE_BINARY_V1) );// || (mode == HORUS_MODE_BINARY_V2_256BIT) || (mode == HORUS_MODE_BINARY_V2_128BIT));
|
||||
|
||||
struct horus *hstates = (struct horus *)malloc(sizeof(struct horus));
|
||||
assert(hstates != NULL);
|
||||
|
@ -226,7 +227,7 @@ struct horus *horus_open_advanced (int mode, int Rs, int tx_tone_spacing) {
|
|||
// Parameter setup for the Legacy Horus Binary Mode (22 byte frames, Golay encoding)
|
||||
|
||||
hstates->mFSK = 4;
|
||||
hstates->max_packet_len = HORUS_BINARY_V1_NUM_CODED_BITS;
|
||||
hstates->max_packet_len = HORUS_BINARY_V1V2_MAX_BITS;// HORUS_BINARY_V1_NUM_CODED_BITS;
|
||||
|
||||
// If baud rate not provided, use default
|
||||
if (hstates->Rs == -1){
|
||||
|
@ -251,64 +252,64 @@ struct horus *horus_open_advanced (int mode, int Rs, int tx_tone_spacing) {
|
|||
hstates->rx_bits_len = hstates->max_packet_len;
|
||||
}
|
||||
|
||||
if (mode == HORUS_MODE_BINARY_V2_256BIT) {
|
||||
// if (mode == HORUS_MODE_BINARY_V2_256BIT) {
|
||||
|
||||
hstates->mFSK = 2;
|
||||
hstates->max_packet_len = HORUS_BINARY_V2_256BIT_NUM_CODED_BITS ;
|
||||
// hstates->mFSK = 2;
|
||||
// hstates->max_packet_len = HORUS_BINARY_V2_256BIT_NUM_CODED_BITS ;
|
||||
|
||||
// If baud rate not provided, use default
|
||||
if (hstates->Rs == -1){
|
||||
hstates->Rs = HORUS_BINARY_V2_256BIT_DEFAULT_BAUD;
|
||||
}
|
||||
// // If baud rate not provided, use default
|
||||
// if (hstates->Rs == -1){
|
||||
// hstates->Rs = HORUS_BINARY_V2_256BIT_DEFAULT_BAUD;
|
||||
// }
|
||||
|
||||
if (tx_tone_spacing == -1){
|
||||
// No tone spacing provided. Disable mask estimation, and use the default tone spacing value as a dummy value.
|
||||
tx_tone_spacing = HORUS_BINARY_V2_256BIT_DEFAULT_TONE_SPACING;
|
||||
mask = 0;
|
||||
} else {
|
||||
// Tone spacing provided, enable mask estimation.
|
||||
mask = 1;
|
||||
}
|
||||
// if (tx_tone_spacing == -1){
|
||||
// // No tone spacing provided. Disable mask estimation, and use the default tone spacing value as a dummy value.
|
||||
// tx_tone_spacing = HORUS_BINARY_V2_256BIT_DEFAULT_TONE_SPACING;
|
||||
// mask = 0;
|
||||
// } else {
|
||||
// // Tone spacing provided, enable mask estimation.
|
||||
// mask = 1;
|
||||
// }
|
||||
|
||||
for (i=0; i<sizeof(uw_horus_binary_v2); i++) {
|
||||
hstates->uw[i] = 2*uw_horus_binary_v2[i] - 1;
|
||||
}
|
||||
hstates->uw_len = sizeof(uw_horus_binary_v2);
|
||||
hstates->uw_thresh = sizeof(uw_horus_binary_v2) - 2; /* allow a few bit errors in UW detection */
|
||||
// TODO: Any initialization required?
|
||||
// horus_l2_init();
|
||||
hstates->rx_bits_len = hstates->max_packet_len;
|
||||
}
|
||||
// for (i=0; i<sizeof(uw_horus_binary_v2); i++) {
|
||||
// hstates->uw[i] = 2*uw_horus_binary_v2[i] - 1;
|
||||
// }
|
||||
// hstates->uw_len = sizeof(uw_horus_binary_v2);
|
||||
// hstates->uw_thresh = sizeof(uw_horus_binary_v2) - 2; /* allow a few bit errors in UW detection */
|
||||
// // TODO: Any initialization required?
|
||||
// // horus_l2_init();
|
||||
// hstates->rx_bits_len = hstates->max_packet_len;
|
||||
// }
|
||||
|
||||
if (mode == HORUS_MODE_BINARY_V2_128BIT) {
|
||||
// Parameter setup for the New v2 Horus Binary mode.
|
||||
// if (mode == HORUS_MODE_BINARY_V2_128BIT) {
|
||||
// // Parameter setup for the New v2 Horus Binary mode.
|
||||
|
||||
hstates->mFSK = 2; // Lock to 2FSK until we have decent LLRs for 4FSK.
|
||||
hstates->max_packet_len = HORUS_BINARY_V2_128BIT_NUM_CODED_BITS ;
|
||||
// hstates->mFSK = 2; // Lock to 2FSK until we have decent LLRs for 4FSK.
|
||||
// hstates->max_packet_len = HORUS_BINARY_V2_128BIT_NUM_CODED_BITS ;
|
||||
|
||||
// If baud rate not provided, use default
|
||||
if (hstates->Rs == -1){
|
||||
hstates->Rs = HORUS_BINARY_V2_128BIT_DEFAULT_BAUD;
|
||||
}
|
||||
// // If baud rate not provided, use default
|
||||
// if (hstates->Rs == -1){
|
||||
// hstates->Rs = HORUS_BINARY_V2_128BIT_DEFAULT_BAUD;
|
||||
// }
|
||||
|
||||
if (tx_tone_spacing == -1){
|
||||
// No tone spacing provided. Disable mask estimation, and use the default tone spacing value as a dummy value.
|
||||
tx_tone_spacing = HORUS_BINARY_V2_128BIT_DEFAULT_TONE_SPACING;
|
||||
mask = 0;
|
||||
} else {
|
||||
// Tone spacing provided, enable mask estimation.
|
||||
mask = 1;
|
||||
}
|
||||
// if (tx_tone_spacing == -1){
|
||||
// // No tone spacing provided. Disable mask estimation, and use the default tone spacing value as a dummy value.
|
||||
// tx_tone_spacing = HORUS_BINARY_V2_128BIT_DEFAULT_TONE_SPACING;
|
||||
// mask = 0;
|
||||
// } else {
|
||||
// // Tone spacing provided, enable mask estimation.
|
||||
// mask = 1;
|
||||
// }
|
||||
|
||||
for (i=0; i<sizeof(uw_horus_binary_v2); i++) {
|
||||
hstates->uw[i] = 2*uw_horus_binary_v2[i] - 1;
|
||||
}
|
||||
hstates->uw_len = sizeof(uw_horus_binary_v2);
|
||||
hstates->uw_thresh = sizeof(uw_horus_binary_v2) - 2; /* allow a few bit errors in UW detection */
|
||||
// TODO: Any initialization required?
|
||||
// horus_l2_init();
|
||||
hstates->rx_bits_len = hstates->max_packet_len;
|
||||
}
|
||||
// for (i=0; i<sizeof(uw_horus_binary_v2); i++) {
|
||||
// hstates->uw[i] = 2*uw_horus_binary_v2[i] - 1;
|
||||
// }
|
||||
// hstates->uw_len = sizeof(uw_horus_binary_v2);
|
||||
// hstates->uw_thresh = sizeof(uw_horus_binary_v2) - 2; /* allow a few bit errors in UW detection */
|
||||
// // TODO: Any initialization required?
|
||||
// // horus_l2_init();
|
||||
// hstates->rx_bits_len = hstates->max_packet_len;
|
||||
// }
|
||||
|
||||
// Create the FSK modedm struct. Note that the low-tone-frequency parameter is unused.
|
||||
#define UNUSED 1000
|
||||
|
@ -579,83 +580,6 @@ int extract_horus_binary_v1(struct horus *hstates, char hex_out[], int uw_loc) {
|
|||
return hstates->crc_ok;
|
||||
}
|
||||
|
||||
|
||||
int extract_horus_binary_v2_128(struct horus *hstates, char hex_out[], int uw_loc) {
|
||||
const int nfield = 8; /* 8 bit binary */
|
||||
int st = uw_loc; /* first bit of first char */
|
||||
int en = uw_loc + hstates->max_packet_len; /* last bit of max length packet */
|
||||
|
||||
int j, b, nout;
|
||||
uint8_t rxpacket[hstates->max_packet_len];
|
||||
uint8_t rxbyte, *pout;
|
||||
|
||||
/* convert bits to a packet of bytes */
|
||||
|
||||
pout = rxpacket; nout = 0;
|
||||
|
||||
for (b=st; b<en; b+=nfield) {
|
||||
|
||||
/* assemble bytes MSB to LSB */
|
||||
|
||||
rxbyte = 0;
|
||||
for(j=0; j<nfield; j++) {
|
||||
assert(hstates->rx_bits[b+j] <= 1);
|
||||
rxbyte <<= 1;
|
||||
rxbyte |= hstates->rx_bits[b+j];
|
||||
}
|
||||
|
||||
/* build up output array */
|
||||
|
||||
*pout++ = rxbyte;
|
||||
nout++;
|
||||
}
|
||||
|
||||
if (hstates->verbose) {
|
||||
fprintf(stderr, " extract_horus_binary_v2_128 nout: %d\n Received Packet before decoding:\n ", nout);
|
||||
for (b=0; b<nout; b++) {
|
||||
fprintf(stderr, "%02X", rxpacket[b]);
|
||||
}
|
||||
fprintf(stderr, "\n");
|
||||
}
|
||||
|
||||
uint8_t payload_bytes[HORUS_BINARY_V2_128BIT_NUM_UNCODED_PAYLOAD_BYTES];
|
||||
float *softbits = hstates->soft_bits + uw_loc + sizeof(uw_horus_binary_v2);
|
||||
horus_ldpc_decode( payload_bytes, softbits , HORUS_MODE_BINARY_V2_128BIT);
|
||||
|
||||
uint16_t crc_tx, crc_rx;
|
||||
crc_rx = horus_l2_gen_crc16(payload_bytes, HORUS_BINARY_V2_128BIT_NUM_UNCODED_PAYLOAD_BYTES-2);
|
||||
crc_tx = (uint16_t)payload_bytes[HORUS_BINARY_V2_128BIT_NUM_UNCODED_PAYLOAD_BYTES-2] +
|
||||
((uint16_t)payload_bytes[HORUS_BINARY_V2_128BIT_NUM_UNCODED_PAYLOAD_BYTES-1]<<8);
|
||||
|
||||
if (hstates->verbose) {
|
||||
fprintf(stderr, " extract_horus_binary_v2_128 crc_tx: %04X crc_rx: %04X\n", crc_tx, crc_rx);
|
||||
}
|
||||
|
||||
/* convert to ASCII string of hex characters */
|
||||
|
||||
hex_out[0] = 0;
|
||||
char hex[3];
|
||||
for (b=0; b<HORUS_BINARY_V2_128BIT_NUM_UNCODED_PAYLOAD_BYTES; b++) {
|
||||
sprintf(hex, "%02X", payload_bytes[b]);
|
||||
strcat(hex_out, hex);
|
||||
}
|
||||
|
||||
if (hstates->verbose) {
|
||||
fprintf(stderr, " nout: %d Decoded Payload bytes:\n %s\n", nout, hex_out);
|
||||
}
|
||||
|
||||
/* With noise input to FSK demod we can get occasinal UW matches,
|
||||
so a good idea to only pass on any packets that pass CRC */
|
||||
|
||||
hstates->crc_ok = (crc_tx == crc_rx);
|
||||
if ( hstates->crc_ok) {
|
||||
hstates->total_payload_bits = HORUS_BINARY_V2_128BIT_NUM_UNCODED_PAYLOAD_BYTES;
|
||||
}
|
||||
|
||||
return hstates->crc_ok;
|
||||
|
||||
}
|
||||
|
||||
int extract_horus_binary_v2_256(struct horus *hstates, char hex_out[], int uw_loc) {
|
||||
const int nfield = 8; /* 8 bit binary */
|
||||
int st = uw_loc; /* first bit of first char */
|
||||
|
@ -693,10 +617,9 @@ int extract_horus_binary_v2_256(struct horus *hstates, char hex_out[], int uw_lo
|
|||
}
|
||||
fprintf(stderr, "\n");
|
||||
}
|
||||
|
||||
|
||||
uint8_t payload_bytes[HORUS_BINARY_V2_256BIT_NUM_UNCODED_PAYLOAD_BYTES];
|
||||
float *softbits = hstates->soft_bits + uw_loc + sizeof(uw_horus_binary_v2);
|
||||
horus_ldpc_decode( payload_bytes, softbits , HORUS_MODE_BINARY_V2_256BIT);
|
||||
horus_l2_decode_rx_packet(payload_bytes, rxpacket, HORUS_BINARY_V2_256BIT_NUM_UNCODED_PAYLOAD_BYTES);
|
||||
|
||||
uint16_t crc_tx, crc_rx;
|
||||
crc_rx = horus_l2_gen_crc16(payload_bytes, HORUS_BINARY_V2_256BIT_NUM_UNCODED_PAYLOAD_BYTES-2);
|
||||
|
@ -717,7 +640,7 @@ int extract_horus_binary_v2_256(struct horus *hstates, char hex_out[], int uw_lo
|
|||
}
|
||||
|
||||
if (hstates->verbose) {
|
||||
fprintf(stderr, " nout: %d Decoded Payload bytes:\n %s\n", nout, hex_out);
|
||||
fprintf(stderr, " nout: %d Decoded Payload bytes:\n %s", nout, hex_out);
|
||||
}
|
||||
|
||||
/* With noise input to FSK demod we can get occasinal UW matches,
|
||||
|
@ -727,11 +650,162 @@ int extract_horus_binary_v2_256(struct horus *hstates, char hex_out[], int uw_lo
|
|||
if ( hstates->crc_ok) {
|
||||
hstates->total_payload_bits = HORUS_BINARY_V2_256BIT_NUM_UNCODED_PAYLOAD_BYTES;
|
||||
}
|
||||
|
||||
return hstates->crc_ok;
|
||||
|
||||
}
|
||||
|
||||
|
||||
// int extract_horus_binary_v2_128(struct horus *hstates, char hex_out[], int uw_loc) {
|
||||
// const int nfield = 8; /* 8 bit binary */
|
||||
// int st = uw_loc; /* first bit of first char */
|
||||
// int en = uw_loc + hstates->max_packet_len; /* last bit of max length packet */
|
||||
|
||||
// int j, b, nout;
|
||||
// uint8_t rxpacket[hstates->max_packet_len];
|
||||
// uint8_t rxbyte, *pout;
|
||||
|
||||
// /* convert bits to a packet of bytes */
|
||||
|
||||
// pout = rxpacket; nout = 0;
|
||||
|
||||
// for (b=st; b<en; b+=nfield) {
|
||||
|
||||
// /* assemble bytes MSB to LSB */
|
||||
|
||||
// rxbyte = 0;
|
||||
// for(j=0; j<nfield; j++) {
|
||||
// assert(hstates->rx_bits[b+j] <= 1);
|
||||
// rxbyte <<= 1;
|
||||
// rxbyte |= hstates->rx_bits[b+j];
|
||||
// }
|
||||
|
||||
// /* build up output array */
|
||||
|
||||
// *pout++ = rxbyte;
|
||||
// nout++;
|
||||
// }
|
||||
|
||||
// if (hstates->verbose) {
|
||||
// fprintf(stderr, " extract_horus_binary_v2_128 nout: %d\n Received Packet before decoding:\n ", nout);
|
||||
// for (b=0; b<nout; b++) {
|
||||
// fprintf(stderr, "%02X", rxpacket[b]);
|
||||
// }
|
||||
// fprintf(stderr, "\n");
|
||||
// }
|
||||
|
||||
// uint8_t payload_bytes[HORUS_BINARY_V2_128BIT_NUM_UNCODED_PAYLOAD_BYTES];
|
||||
// float *softbits = hstates->soft_bits + uw_loc + sizeof(uw_horus_binary_v2);
|
||||
// horus_ldpc_decode( payload_bytes, softbits , HORUS_MODE_BINARY_V2_128BIT);
|
||||
|
||||
// uint16_t crc_tx, crc_rx;
|
||||
// crc_rx = horus_l2_gen_crc16(payload_bytes, HORUS_BINARY_V2_128BIT_NUM_UNCODED_PAYLOAD_BYTES-2);
|
||||
// crc_tx = (uint16_t)payload_bytes[HORUS_BINARY_V2_128BIT_NUM_UNCODED_PAYLOAD_BYTES-2] +
|
||||
// ((uint16_t)payload_bytes[HORUS_BINARY_V2_128BIT_NUM_UNCODED_PAYLOAD_BYTES-1]<<8);
|
||||
|
||||
// if (hstates->verbose) {
|
||||
// fprintf(stderr, " extract_horus_binary_v2_128 crc_tx: %04X crc_rx: %04X\n", crc_tx, crc_rx);
|
||||
// }
|
||||
|
||||
// /* convert to ASCII string of hex characters */
|
||||
|
||||
// hex_out[0] = 0;
|
||||
// char hex[3];
|
||||
// for (b=0; b<HORUS_BINARY_V2_128BIT_NUM_UNCODED_PAYLOAD_BYTES; b++) {
|
||||
// sprintf(hex, "%02X", payload_bytes[b]);
|
||||
// strcat(hex_out, hex);
|
||||
// }
|
||||
|
||||
// if (hstates->verbose) {
|
||||
// fprintf(stderr, " nout: %d Decoded Payload bytes:\n %s\n", nout, hex_out);
|
||||
// }
|
||||
|
||||
// /* With noise input to FSK demod we can get occasinal UW matches,
|
||||
// so a good idea to only pass on any packets that pass CRC */
|
||||
|
||||
// hstates->crc_ok = (crc_tx == crc_rx);
|
||||
// if ( hstates->crc_ok) {
|
||||
// hstates->total_payload_bits = HORUS_BINARY_V2_128BIT_NUM_UNCODED_PAYLOAD_BYTES;
|
||||
// }
|
||||
|
||||
// return hstates->crc_ok;
|
||||
|
||||
// }
|
||||
|
||||
// int extract_horus_binary_v2_256(struct horus *hstates, char hex_out[], int uw_loc) {
|
||||
// const int nfield = 8; /* 8 bit binary */
|
||||
// int st = uw_loc; /* first bit of first char */
|
||||
// int en = uw_loc + hstates->max_packet_len; /* last bit of max length packet */
|
||||
|
||||
// int j, b, nout;
|
||||
// uint8_t rxpacket[hstates->max_packet_len];
|
||||
// uint8_t rxbyte, *pout;
|
||||
|
||||
// /* convert bits to a packet of bytes */
|
||||
|
||||
// pout = rxpacket; nout = 0;
|
||||
|
||||
// for (b=st; b<en; b+=nfield) {
|
||||
|
||||
// /* assemble bytes MSB to LSB */
|
||||
|
||||
// rxbyte = 0;
|
||||
// for(j=0; j<nfield; j++) {
|
||||
// assert(hstates->rx_bits[b+j] <= 1);
|
||||
// rxbyte <<= 1;
|
||||
// rxbyte |= hstates->rx_bits[b+j];
|
||||
// }
|
||||
|
||||
// /* build up output array */
|
||||
|
||||
// *pout++ = rxbyte;
|
||||
// nout++;
|
||||
// }
|
||||
|
||||
// if (hstates->verbose) {
|
||||
// fprintf(stderr, " extract_horus_binary_v2_256 nout: %d\n Received Packet before decoding:\n ", nout);
|
||||
// for (b=0; b<nout; b++) {
|
||||
// fprintf(stderr, "%02X", rxpacket[b]);
|
||||
// }
|
||||
// fprintf(stderr, "\n");
|
||||
// }
|
||||
|
||||
// uint8_t payload_bytes[HORUS_BINARY_V2_256BIT_NUM_UNCODED_PAYLOAD_BYTES];
|
||||
// float *softbits = hstates->soft_bits + uw_loc + sizeof(uw_horus_binary_v2);
|
||||
// horus_ldpc_decode( payload_bytes, softbits , HORUS_MODE_BINARY_V2_256BIT);
|
||||
|
||||
// uint16_t crc_tx, crc_rx;
|
||||
// crc_rx = horus_l2_gen_crc16(payload_bytes, HORUS_BINARY_V2_256BIT_NUM_UNCODED_PAYLOAD_BYTES-2);
|
||||
// crc_tx = (uint16_t)payload_bytes[HORUS_BINARY_V2_256BIT_NUM_UNCODED_PAYLOAD_BYTES-2] +
|
||||
// ((uint16_t)payload_bytes[HORUS_BINARY_V2_256BIT_NUM_UNCODED_PAYLOAD_BYTES-1]<<8);
|
||||
|
||||
// if (hstates->verbose) {
|
||||
// fprintf(stderr, " extract_horus_binary_v2_256 crc_tx: %04X crc_rx: %04X\n", crc_tx, crc_rx);
|
||||
// }
|
||||
|
||||
// /* convert to ASCII string of hex characters */
|
||||
|
||||
// hex_out[0] = 0;
|
||||
// char hex[3];
|
||||
// for (b=0; b<HORUS_BINARY_V2_256BIT_NUM_UNCODED_PAYLOAD_BYTES; b++) {
|
||||
// sprintf(hex, "%02X", payload_bytes[b]);
|
||||
// strcat(hex_out, hex);
|
||||
// }
|
||||
|
||||
// if (hstates->verbose) {
|
||||
// fprintf(stderr, " nout: %d Decoded Payload bytes:\n %s\n", nout, hex_out);
|
||||
// }
|
||||
|
||||
// /* With noise input to FSK demod we can get occasinal UW matches,
|
||||
// so a good idea to only pass on any packets that pass CRC */
|
||||
|
||||
// hstates->crc_ok = (crc_tx == crc_rx);
|
||||
// if ( hstates->crc_ok) {
|
||||
// hstates->total_payload_bits = HORUS_BINARY_V2_256BIT_NUM_UNCODED_PAYLOAD_BYTES;
|
||||
// }
|
||||
|
||||
// return hstates->crc_ok;
|
||||
|
||||
// }
|
||||
|
||||
int horus_rx(struct horus *hstates, char ascii_out[], short demod_in[], int quadrature) {
|
||||
int i, j, uw_loc, packet_detected;
|
||||
|
||||
|
@ -825,6 +899,10 @@ int horus_rx(struct horus *hstates, char ascii_out[], short demod_in[], int quad
|
|||
}
|
||||
if (hstates->mode == HORUS_MODE_BINARY_V1) {
|
||||
packet_detected = extract_horus_binary_v1(hstates, ascii_out, uw_loc);
|
||||
if (!packet_detected){
|
||||
// Try v2 256 bit decoder instead
|
||||
packet_detected = extract_horus_binary_v2_256(hstates, ascii_out, uw_loc);
|
||||
}
|
||||
//#define DUMP_BINARY_PACKET
|
||||
#ifdef DUMP_BINARY_PACKET
|
||||
FILE *f = fopen("packetbits.txt", "wt"); assert(f != NULL);
|
||||
|
@ -835,12 +913,12 @@ int horus_rx(struct horus *hstates, char ascii_out[], short demod_in[], int quad
|
|||
exit(0);
|
||||
#endif
|
||||
}
|
||||
if (hstates->mode == HORUS_MODE_BINARY_V2_128BIT){
|
||||
packet_detected = extract_horus_binary_v2_128(hstates, ascii_out, uw_loc);
|
||||
}
|
||||
if (hstates->mode == HORUS_MODE_BINARY_V2_256BIT){
|
||||
packet_detected = extract_horus_binary_v2_256(hstates, ascii_out, uw_loc);
|
||||
}
|
||||
// if (hstates->mode == HORUS_MODE_BINARY_V2_128BIT){
|
||||
// packet_detected = extract_horus_binary_v2_128(hstates, ascii_out, uw_loc);
|
||||
// }
|
||||
// if (hstates->mode == HORUS_MODE_BINARY_V2_256BIT){
|
||||
// packet_detected = extract_horus_binary_v2_256(hstates, ascii_out, uw_loc);
|
||||
// }
|
||||
}
|
||||
return packet_detected;
|
||||
}
|
||||
|
@ -881,7 +959,8 @@ int horus_get_max_ascii_out_len(struct horus *hstates) {
|
|||
return hstates->max_packet_len/11; /* 8 bit ASCII, plus 3 sync bits */
|
||||
}
|
||||
if (hstates->mode == HORUS_MODE_BINARY_V1) {
|
||||
return (HORUS_BINARY_V1_NUM_UNCODED_PAYLOAD_BYTES*2+1); /* Hexadecimal encoded */
|
||||
//return (HORUS_BINARY_V1_NUM_UNCODED_PAYLOAD_BYTES*2+1); /* Hexadecimal encoded */
|
||||
return (HORUS_BINARY_V1V2_MAX_UNCODED_BYTES*2+1);
|
||||
}
|
||||
if (hstates->mode == HORUS_MODE_BINARY_V2_256BIT) {
|
||||
return (HORUS_BINARY_V2_256BIT_NUM_UNCODED_PAYLOAD_BYTES*2+1); /* Hexadecimal encoded */
|
||||
|
|
|
@ -37,14 +37,14 @@
|
|||
|
||||
/* Horus API Modes */
|
||||
#define HORUS_MODE_BINARY_V1 0 // Legacy binary mode
|
||||
#define HORUS_MODE_BINARY_V2_256BIT 1 // New 256-bit LDPC-encoded mode
|
||||
#define HORUS_MODE_BINARY_V2_128BIT 2 // New 128-bit LDPC-encoded mode
|
||||
#define HORUS_MODE_BINARY_V2_256BIT 1 // New 256-bit Golay Encoded Mode
|
||||
#define HORUS_MODE_BINARY_V2_128BIT 2 // New 128-bit Golay Encoded Mode (Not used yet)
|
||||
#define HORUS_MODE_RTTY_7N1 89 // RTTY Decoding - 7N1
|
||||
#define HORUS_MODE_RTTY_7N2 90 // RTTY Decoding - 7N2
|
||||
#define HORUS_MODE_RTTY_8N2 91 // RTTY Decoding - 8N2
|
||||
|
||||
|
||||
// Settings for Legacy Horus Binary Mode (Golay Encoding)
|
||||
// Settings for Legacy Horus Binary Mode (Golay (23,12) encoding)
|
||||
#define HORUS_BINARY_V1_NUM_CODED_BITS 360
|
||||
#define HORUS_BINARY_V1_NUM_UNCODED_PAYLOAD_BYTES 22
|
||||
#define HORUS_BINARY_V1_DEFAULT_BAUD 100
|
||||
|
@ -53,18 +53,36 @@
|
|||
// Note that mask estimation is turned off by default for
|
||||
// this mode, and hence this spacing is not used.
|
||||
|
||||
// Settings for Horus Binary 256-bit mode (LDPC Encoding, r=1/3)
|
||||
#define HORUS_BINARY_V2_256BIT_NUM_CODED_BITS (768+32)
|
||||
// Settings for Horus Binary 256-bit mode (Golay (23,12) encoding)
|
||||
#define HORUS_BINARY_V2_256BIT_NUM_CODED_BITS 520
|
||||
#define HORUS_BINARY_V2_256BIT_NUM_UNCODED_PAYLOAD_BYTES 32
|
||||
#define HORUS_BINARY_V2_256BIT_DEFAULT_BAUD 100
|
||||
#define HORUS_BINARY_V2_256BIT_DEFAULT_TONE_SPACING 270
|
||||
|
||||
// Settings for Horus Binary 128-bit mode (LDPC Encoding, r=1/3)
|
||||
#define HORUS_BINARY_V2_128BIT_NUM_CODED_BITS (384+32)
|
||||
// Settings for Horus Binary 128-bit mode (Golay (23,12) encoding) - not used yet
|
||||
#define HORUS_BINARY_V2_128BIT_NUM_CODED_BITS 272
|
||||
#define HORUS_BINARY_V2_128BIT_NUM_UNCODED_PAYLOAD_BYTES 16
|
||||
#define HORUS_BINARY_V2_128BIT_DEFAULT_BAUD 100
|
||||
#define HORUS_BINARY_V2_128BIT_DEFAULT_TONE_SPACING 270
|
||||
|
||||
|
||||
#define HORUS_BINARY_V1V2_MAX_BITS HORUS_BINARY_V2_256BIT_NUM_CODED_BITS
|
||||
#define HORUS_BINARY_V1V2_MAX_UNCODED_BYTES HORUS_BINARY_V2_256BIT_NUM_UNCODED_PAYLOAD_BYTES
|
||||
|
||||
// Not using LDPC any more...
|
||||
// // Settings for Horus Binary 256-bit mode (LDPC Encoding, r=1/3)
|
||||
// #define HORUS_BINARY_V2_256BIT_NUM_CODED_BITS (768+32)
|
||||
// #define HORUS_BINARY_V2_256BIT_NUM_UNCODED_PAYLOAD_BYTES 32
|
||||
// #define HORUS_BINARY_V2_256BIT_DEFAULT_BAUD 100
|
||||
// #define HORUS_BINARY_V2_256BIT_DEFAULT_TONE_SPACING 270
|
||||
|
||||
// // Settings for Horus Binary 128-bit mode (LDPC Encoding, r=1/3)
|
||||
// #define HORUS_BINARY_V2_128BIT_NUM_CODED_BITS (384+32)
|
||||
// #define HORUS_BINARY_V2_128BIT_NUM_UNCODED_PAYLOAD_BYTES 16
|
||||
// #define HORUS_BINARY_V2_128BIT_DEFAULT_BAUD 100
|
||||
// #define HORUS_BINARY_V2_128BIT_DEFAULT_TONE_SPACING 270
|
||||
|
||||
|
||||
// Settings for RTTY Decoder
|
||||
#define HORUS_RTTY_MAX_CHARS 120
|
||||
#define HORUS_RTTY_7N1_NUM_BITS (HORUS_RTTY_MAX_CHARS*9)
|
||||
|
|
|
@ -93,12 +93,12 @@ int main(int argc, char *argv[]) {
|
|||
if ((strcmp(optarg, "BINARY") == 0) || (strcmp(optarg, "binary") == 0)) {
|
||||
mode = HORUS_MODE_BINARY_V1;
|
||||
}
|
||||
if ((strcmp(optarg, "256BIT") == 0) || (strcmp(optarg, "256bit") == 0)) {
|
||||
mode = HORUS_MODE_BINARY_V2_256BIT;
|
||||
}
|
||||
if ((strcmp(optarg, "128BIT") == 0) || (strcmp(optarg, "128bit") == 0)) {
|
||||
mode = HORUS_MODE_BINARY_V2_128BIT;
|
||||
}
|
||||
// if ((strcmp(optarg, "256BIT") == 0) || (strcmp(optarg, "256bit") == 0)) {
|
||||
// mode = HORUS_MODE_BINARY_V2_256BIT;
|
||||
// }
|
||||
// if ((strcmp(optarg, "128BIT") == 0) || (strcmp(optarg, "128bit") == 0)) {
|
||||
// mode = HORUS_MODE_BINARY_V2_128BIT;
|
||||
// }
|
||||
if (mode == -1) {
|
||||
fprintf(stderr, "use --mode RTTY or --mode binary\n");
|
||||
exit(1);
|
||||
|
|
430
src/horus_l2.c
430
src/horus_l2.c
|
@ -65,15 +65,15 @@
|
|||
#include "mpdecode_core.h"
|
||||
#include "horus_l2.h"
|
||||
#include "golay23.h"
|
||||
#include "H_128_384_23.h"
|
||||
#include "H_256_768_22.h"
|
||||
//#include "H_128_384_23.h"
|
||||
//#include "H_256_768_22.h"
|
||||
|
||||
#ifdef HORUS_L2_UNITTEST
|
||||
#define HORUS_L2_RX
|
||||
#endif
|
||||
|
||||
static const char uw[] = {'$','$'}; // UW for Horus Binary v1
|
||||
static const char uw_v2[] = {0x96, 0x69, 0x69, 0x96}; // UW for Horus Binary v2 modes
|
||||
static const char uw[] = {'$','$'}; // UW for Horus Binary v1 and v2 Golay modes
|
||||
//static const char uw_v2[] = {0x96, 0x69, 0x69, 0x96}; // UW for Horus Binary v2 modes - DEPRECATED.
|
||||
|
||||
/* Function Prototypes ------------------------------------------------*/
|
||||
|
||||
|
@ -748,7 +748,8 @@ int test_sending_bytes(int nbytes, float ber, int error_pattern) {
|
|||
/* unit test designed to run on a PC */
|
||||
|
||||
int main(void) {
|
||||
printf("Horus v1 length packets (22 bytes)\n");
|
||||
int num_tx_data_bytes_v1 = horus_l2_get_num_tx_data_bytes(22);
|
||||
printf("Horus v1 length packets (22 bytes uncoded, %d bytes coded)\n", num_tx_data_bytes_v1);
|
||||
printf("test 0: BER: 0.00 ...........: %d\n", test_sending_bytes(22, 0.00, 0));
|
||||
printf("test 1: BER: 0.01 ...........: %d\n", test_sending_bytes(22, 0.01, 0));
|
||||
printf("test 2: BER: 0.05 ...........: %d\n", test_sending_bytes(22, 0.05, 0));
|
||||
|
@ -768,7 +769,9 @@ int main(void) {
|
|||
|
||||
printf("test 5: 1 error every 12 bits: %d\n", test_sending_bytes(22, 0.00, 2));
|
||||
|
||||
printf("Horus v2 length packets (16 bytes)\n");
|
||||
int num_tx_data_bytes_v2_16 = horus_l2_get_num_tx_data_bytes(16);
|
||||
printf("Horus v2 length packets (16 bytes uncoded, %d bytes coded)\n", num_tx_data_bytes_v2_16);
|
||||
|
||||
printf("test 0: BER: 0.00 ...........: %d\n", test_sending_bytes(16, 0.00, 0));
|
||||
printf("test 1: BER: 0.01 ...........: %d\n", test_sending_bytes(16, 0.01, 0));
|
||||
printf("test 2: BER: 0.05 ...........: %d\n", test_sending_bytes(16, 0.05, 0));
|
||||
|
@ -788,7 +791,8 @@ int main(void) {
|
|||
|
||||
printf("test 5: 1 error every 12 bits: %d\n", test_sending_bytes(16, 0.00, 2));
|
||||
|
||||
printf("Horus v2 length packets (32 bytes)\n");
|
||||
int num_tx_data_bytes_v2_32 = horus_l2_get_num_tx_data_bytes(32);
|
||||
printf("Horus v2 length packets (32 bytes uncoded, %d bytes coded)\n", num_tx_data_bytes_v2_32);
|
||||
printf("test 0: BER: 0.00 ...........: %d\n", test_sending_bytes(32, 0.00, 0));
|
||||
printf("test 1: BER: 0.01 ...........: %d\n", test_sending_bytes(32, 0.01, 0));
|
||||
printf("test 2: BER: 0.05 ...........: %d\n", test_sending_bytes(32, 0.05, 0));
|
||||
|
@ -833,8 +837,6 @@ struct TBinaryPacket
|
|||
|
||||
struct V2SmallBinaryPacket
|
||||
{
|
||||
// 4 byte preamble for high error rates ("0x96696996")
|
||||
// - to improve soft bit prediction
|
||||
uint8_t PayloadID; // Legacy list
|
||||
uint8_t Counter; // 8 bit counter
|
||||
uint16_t BiSeconds; // Time of day / 2
|
||||
|
@ -1004,62 +1006,6 @@ int main(int argc,char *argv[]) {
|
|||
|
||||
horus_l2_encode_tx_packet(tx, (unsigned char*)&input_payload, nbytes);
|
||||
|
||||
int b;
|
||||
uint8_t tx_bit;
|
||||
while(framecnt >= 0){
|
||||
for(i=0; i<num_tx_data_bytes; i++) {
|
||||
for(b=0; b<8; b++) {
|
||||
tx_bit = (tx[i] >> (7-b)) & 0x1; /* msb first */
|
||||
fwrite(&tx_bit,sizeof(uint8_t),1,stdout);
|
||||
fflush(stdout);
|
||||
}
|
||||
}
|
||||
framecnt -= 1;
|
||||
}
|
||||
|
||||
} else if (mode == 1) {
|
||||
// 32-byte horus mode
|
||||
int nbytes = sizeof(struct V2LargeBinaryPacket);
|
||||
struct V2LargeBinaryPacket input_payload;
|
||||
|
||||
int num_tx_data_bytes = sizeof(uw_v2) + H_256_768_22_DATA_BYTES + H_256_768_22_PARITY_BYTES;
|
||||
unsigned char tx[num_tx_data_bytes];
|
||||
memset(&input_payload, 0, nbytes);
|
||||
|
||||
input_payload.PayloadID = 1;
|
||||
input_payload.Counter = 2;
|
||||
input_payload.Checksum = horus_l2_gen_crc16((unsigned char*)&input_payload, nbytes-2);
|
||||
|
||||
int ldpc_tx_bytes = ldpc_encode_packet(tx, (unsigned char*)&input_payload, 1);
|
||||
|
||||
int b;
|
||||
uint8_t tx_bit;
|
||||
while(framecnt >= 0){
|
||||
for(i=0; i<num_tx_data_bytes; i++) {
|
||||
for(b=0; b<8; b++) {
|
||||
tx_bit = (tx[i] >> (7-b)) & 0x1; /* msb first */
|
||||
fwrite(&tx_bit,sizeof(uint8_t),1,stdout);
|
||||
fflush(stdout);
|
||||
}
|
||||
}
|
||||
framecnt -= 1;
|
||||
}
|
||||
|
||||
} else if (mode == 2) {
|
||||
// 16-byte horus mode
|
||||
int nbytes = sizeof(struct V2SmallBinaryPacket);
|
||||
struct V2SmallBinaryPacket input_payload;
|
||||
|
||||
int num_tx_data_bytes = sizeof(uw_v2) + H_128_384_23_DATA_BYTES + H_128_384_23_PARITY_BYTES;
|
||||
unsigned char tx[num_tx_data_bytes];
|
||||
memset(&input_payload, 0, nbytes);
|
||||
input_payload.PayloadID = 1;
|
||||
input_payload.Counter = 2;
|
||||
|
||||
input_payload.Checksum = horus_l2_gen_crc16((unsigned char*)&input_payload, nbytes-2);
|
||||
|
||||
int ldpc_tx_bytes = ldpc_encode_packet(tx, (unsigned char*)&input_payload, 2);
|
||||
|
||||
int b;
|
||||
uint8_t tx_bit;
|
||||
while(framecnt >= 0){
|
||||
|
@ -1073,6 +1019,62 @@ int main(int argc,char *argv[]) {
|
|||
framecnt -= 1;
|
||||
}
|
||||
}
|
||||
// } else if (mode == 1) {
|
||||
// // 32-byte horus mode
|
||||
// int nbytes = sizeof(struct V2LargeBinaryPacket);
|
||||
// struct V2LargeBinaryPacket input_payload;
|
||||
|
||||
// int num_tx_data_bytes = sizeof(uw_v2) + H_256_768_22_DATA_BYTES + H_256_768_22_PARITY_BYTES;
|
||||
// unsigned char tx[num_tx_data_bytes];
|
||||
// memset(&input_payload, 0, nbytes);
|
||||
|
||||
// input_payload.PayloadID = 1;
|
||||
// input_payload.Counter = 2;
|
||||
// input_payload.Checksum = horus_l2_gen_crc16((unsigned char*)&input_payload, nbytes-2);
|
||||
|
||||
// int ldpc_tx_bytes = ldpc_encode_packet(tx, (unsigned char*)&input_payload, 1);
|
||||
|
||||
// int b;
|
||||
// uint8_t tx_bit;
|
||||
// while(framecnt >= 0){
|
||||
// for(i=0; i<num_tx_data_bytes; i++) {
|
||||
// for(b=0; b<8; b++) {
|
||||
// tx_bit = (tx[i] >> (7-b)) & 0x1; /* msb first */
|
||||
// fwrite(&tx_bit,sizeof(uint8_t),1,stdout);
|
||||
// fflush(stdout);
|
||||
// }
|
||||
// }
|
||||
// framecnt -= 1;
|
||||
// }
|
||||
|
||||
// } else if (mode == 2) {
|
||||
// // 16-byte horus mode
|
||||
// int nbytes = sizeof(struct V2SmallBinaryPacket);
|
||||
// struct V2SmallBinaryPacket input_payload;
|
||||
|
||||
// int num_tx_data_bytes = sizeof(uw_v2) + H_128_384_23_DATA_BYTES + H_128_384_23_PARITY_BYTES;
|
||||
// unsigned char tx[num_tx_data_bytes];
|
||||
// memset(&input_payload, 0, nbytes);
|
||||
// input_payload.PayloadID = 1;
|
||||
// input_payload.Counter = 2;
|
||||
|
||||
// input_payload.Checksum = horus_l2_gen_crc16((unsigned char*)&input_payload, nbytes-2);
|
||||
|
||||
// int ldpc_tx_bytes = ldpc_encode_packet(tx, (unsigned char*)&input_payload, 2);
|
||||
|
||||
// int b;
|
||||
// uint8_t tx_bit;
|
||||
// while(framecnt >= 0){
|
||||
// for(i=0; i<num_tx_data_bytes; i++) {
|
||||
// for(b=0; b<8; b++) {
|
||||
// tx_bit = (tx[i] >> (7-b)) & 0x1; /* msb first */
|
||||
// fwrite(&tx_bit,sizeof(uint8_t),1,stdout);
|
||||
// fflush(stdout);
|
||||
// }
|
||||
// }
|
||||
// framecnt -= 1;
|
||||
// }
|
||||
// }
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -1093,108 +1095,108 @@ unsigned short horus_l2_gen_crc16(unsigned char* data_p, unsigned char length) {
|
|||
}
|
||||
|
||||
|
||||
// Take payload data bytes, prepend a unique word and append parity bits
|
||||
int ldpc_encode_packet(unsigned char *out_data, unsigned char *in_data, int mode) {
|
||||
unsigned int i, last = 0;
|
||||
unsigned char *pout;
|
||||
// // Take payload data bytes, prepend a unique word and append parity bits
|
||||
// int ldpc_encode_packet(unsigned char *out_data, unsigned char *in_data, int mode) {
|
||||
// unsigned int i, last = 0;
|
||||
// unsigned char *pout;
|
||||
|
||||
unsigned int data_bytes, parity_bytes, number_parity_bits, max_row_weight;
|
||||
// unsigned int data_bytes, parity_bytes, number_parity_bits, max_row_weight;
|
||||
|
||||
if (mode == 1){
|
||||
// 32-byte Mode.
|
||||
data_bytes = H_256_768_22_DATA_BYTES;
|
||||
parity_bytes = H_256_768_22_PARITY_BYTES;
|
||||
number_parity_bits = H_256_768_22_NUMBERPARITYBITS;
|
||||
max_row_weight = H_256_768_22_MAX_ROW_WEIGHT;
|
||||
} else {
|
||||
// 16-byte Mode.
|
||||
data_bytes = H_128_384_23_DATA_BYTES;
|
||||
parity_bytes = H_128_384_23_PARITY_BYTES;
|
||||
number_parity_bits = H_128_384_23_NUMBERPARITYBITS;
|
||||
max_row_weight = H_128_384_23_MAX_ROW_WEIGHT;
|
||||
}
|
||||
// if (mode == 1){
|
||||
// // 32-byte Mode.
|
||||
// data_bytes = H_256_768_22_DATA_BYTES;
|
||||
// parity_bytes = H_256_768_22_PARITY_BYTES;
|
||||
// number_parity_bits = H_256_768_22_NUMBERPARITYBITS;
|
||||
// max_row_weight = H_256_768_22_MAX_ROW_WEIGHT;
|
||||
// } else {
|
||||
// // 16-byte Mode.
|
||||
// data_bytes = H_128_384_23_DATA_BYTES;
|
||||
// parity_bytes = H_128_384_23_PARITY_BYTES;
|
||||
// number_parity_bits = H_128_384_23_NUMBERPARITYBITS;
|
||||
// max_row_weight = H_128_384_23_MAX_ROW_WEIGHT;
|
||||
// }
|
||||
|
||||
pout = out_data;
|
||||
memcpy(pout, uw_v2, sizeof(uw_v2));
|
||||
pout += sizeof(uw_v2);
|
||||
memcpy(pout, in_data, data_bytes);
|
||||
pout += data_bytes;
|
||||
memset(pout, 0, parity_bytes);
|
||||
// pout = out_data;
|
||||
// memcpy(pout, uw_v2, sizeof(uw_v2));
|
||||
// pout += sizeof(uw_v2);
|
||||
// memcpy(pout, in_data, data_bytes);
|
||||
// pout += data_bytes;
|
||||
// memset(pout, 0, parity_bytes);
|
||||
|
||||
// process parity bit offsets
|
||||
for (i = 0; i < number_parity_bits; i++) {
|
||||
unsigned int shift, j;
|
||||
uint8_t tmp;
|
||||
// // process parity bit offsets
|
||||
// for (i = 0; i < number_parity_bits; i++) {
|
||||
// unsigned int shift, j;
|
||||
// uint8_t tmp;
|
||||
|
||||
for(j = 0; j < max_row_weight; j++) {
|
||||
// This is a bit silly, move this out of this loop.
|
||||
if (mode == 1){
|
||||
tmp = H_256_768_22_H_rows[i + number_parity_bits * j];
|
||||
} else if (mode == 2) {
|
||||
tmp = H_128_384_23_H_rows[i + number_parity_bits * j];
|
||||
}
|
||||
if (!tmp)
|
||||
continue;
|
||||
tmp--;
|
||||
shift = 7 - (tmp & 7); // MSB
|
||||
last ^= in_data[tmp >> 3] >> shift;
|
||||
}
|
||||
shift = 7 - (i & 7); // MSB
|
||||
pout[i >> 3] |= (last & 1) << shift;
|
||||
}
|
||||
// for(j = 0; j < max_row_weight; j++) {
|
||||
// // This is a bit silly, move this out of this loop.
|
||||
// if (mode == 1){
|
||||
// tmp = H_256_768_22_H_rows[i + number_parity_bits * j];
|
||||
// } else if (mode == 2) {
|
||||
// tmp = H_128_384_23_H_rows[i + number_parity_bits * j];
|
||||
// }
|
||||
// if (!tmp)
|
||||
// continue;
|
||||
// tmp--;
|
||||
// shift = 7 - (tmp & 7); // MSB
|
||||
// last ^= in_data[tmp >> 3] >> shift;
|
||||
// }
|
||||
// shift = 7 - (i & 7); // MSB
|
||||
// pout[i >> 3] |= (last & 1) << shift;
|
||||
// }
|
||||
|
||||
pout = out_data + sizeof(uw_v2);
|
||||
interleave(pout, data_bytes + parity_bytes, 0);
|
||||
scramble(pout, data_bytes + parity_bytes);
|
||||
// pout = out_data + sizeof(uw_v2);
|
||||
// interleave(pout, data_bytes + parity_bytes, 0);
|
||||
// scramble(pout, data_bytes + parity_bytes);
|
||||
|
||||
return data_bytes + parity_bytes + sizeof(uw_v2);
|
||||
}
|
||||
// return data_bytes + parity_bytes + sizeof(uw_v2);
|
||||
// }
|
||||
|
||||
/* Scramble and interleave are 8bit lsb, but bitstream is sent msb */
|
||||
#define LSB2MSB(X) (X + 7 - 2 * (X & 7) )
|
||||
// /* Scramble and interleave are 8bit lsb, but bitstream is sent msb */
|
||||
// #define LSB2MSB(X) (X + 7 - 2 * (X & 7) )
|
||||
|
||||
/* Invert bits - ldpc expects negative floats for high hits */
|
||||
void soft_unscramble(float *in, float* out, int nbits) {
|
||||
int i, ibit;
|
||||
uint16_t scrambler = 0x4a80; /* init additive scrambler at start of every frame */
|
||||
uint16_t scrambler_out;
|
||||
// /* Invert bits - ldpc expects negative floats for high hits */
|
||||
// void soft_unscramble(float *in, float* out, int nbits) {
|
||||
// int i, ibit;
|
||||
// uint16_t scrambler = 0x4a80; /* init additive scrambler at start of every frame */
|
||||
// uint16_t scrambler_out;
|
||||
|
||||
for ( i = 0; i < nbits; i++ ) {
|
||||
scrambler_out = ( (scrambler >> 1) ^ scrambler) & 0x1;
|
||||
// for ( i = 0; i < nbits; i++ ) {
|
||||
// scrambler_out = ( (scrambler >> 1) ^ scrambler) & 0x1;
|
||||
|
||||
/* modify i-th bit by xor-ing with scrambler output sequence */
|
||||
ibit = LSB2MSB(i);
|
||||
if ( scrambler_out ) {
|
||||
out[ibit] = in[ibit];
|
||||
} else {
|
||||
out[ibit] = -in[ibit];
|
||||
}
|
||||
// /* modify i-th bit by xor-ing with scrambler output sequence */
|
||||
// ibit = LSB2MSB(i);
|
||||
// if ( scrambler_out ) {
|
||||
// out[ibit] = in[ibit];
|
||||
// } else {
|
||||
// out[ibit] = -in[ibit];
|
||||
// }
|
||||
|
||||
scrambler >>= 1;
|
||||
scrambler |= scrambler_out << 14;
|
||||
}
|
||||
}
|
||||
// scrambler >>= 1;
|
||||
// scrambler |= scrambler_out << 14;
|
||||
// }
|
||||
// }
|
||||
|
||||
// soft bit deinterleave
|
||||
void soft_deinterleave(float *in, float* out, int mode) {
|
||||
int n, i, j, bits_per_packet, coprime;
|
||||
// // soft bit deinterleave
|
||||
// void soft_deinterleave(float *in, float* out, int mode) {
|
||||
// int n, i, j, bits_per_packet, coprime;
|
||||
|
||||
if (mode == 1) {
|
||||
// 256_768
|
||||
bits_per_packet = H_256_768_22_BITS_PER_PACKET;
|
||||
coprime = H_256_768_22_COPRIME;
|
||||
} else {
|
||||
bits_per_packet = H_128_384_23_BITS_PER_PACKET;
|
||||
coprime = H_128_384_23_COPRIME;
|
||||
}
|
||||
// if (mode == 1) {
|
||||
// // 256_768
|
||||
// bits_per_packet = H_256_768_22_BITS_PER_PACKET;
|
||||
// coprime = H_256_768_22_COPRIME;
|
||||
// } else {
|
||||
// bits_per_packet = H_128_384_23_BITS_PER_PACKET;
|
||||
// coprime = H_128_384_23_COPRIME;
|
||||
// }
|
||||
|
||||
|
||||
for ( n = 0; n < bits_per_packet; n++ ) {
|
||||
i = LSB2MSB(n);
|
||||
j = LSB2MSB( (coprime * n) % bits_per_packet);
|
||||
out[i] = in[j];
|
||||
}
|
||||
}
|
||||
// for ( n = 0; n < bits_per_packet; n++ ) {
|
||||
// i = LSB2MSB(n);
|
||||
// j = LSB2MSB( (coprime * n) % bits_per_packet);
|
||||
// out[i] = in[j];
|
||||
// }
|
||||
// }
|
||||
|
||||
// // packed bit deinterleave - same as Golay version , but different Coprime
|
||||
// void bitwise_deinterleave(uint8_t *inout, int nbytes)
|
||||
|
@ -1249,76 +1251,76 @@ void soft_deinterleave(float *in, float* out, int mode) {
|
|||
// set_error_count( percentage );
|
||||
// }
|
||||
|
||||
/* LDPC decode */
|
||||
void horus_ldpc_decode(uint8_t *payload, float *sd, int mode) {
|
||||
float sum, mean, sumsq, estEsN0, x;
|
||||
int bits_per_packet, payload_bytes;
|
||||
// /* LDPC decode */
|
||||
// void horus_ldpc_decode(uint8_t *payload, float *sd, int mode) {
|
||||
// float sum, mean, sumsq, estEsN0, x;
|
||||
// int bits_per_packet, payload_bytes;
|
||||
|
||||
if(mode == 1){
|
||||
bits_per_packet = H_256_768_22_BITS_PER_PACKET;
|
||||
payload_bytes = H_256_768_22_DATA_BYTES;
|
||||
} else {
|
||||
bits_per_packet = H_128_384_23_BITS_PER_PACKET;
|
||||
payload_bytes = H_128_384_23_DATA_BYTES;
|
||||
}
|
||||
// if(mode == 1){
|
||||
// bits_per_packet = H_256_768_22_BITS_PER_PACKET;
|
||||
// payload_bytes = H_256_768_22_DATA_BYTES;
|
||||
// } else {
|
||||
// bits_per_packet = H_128_384_23_BITS_PER_PACKET;
|
||||
// payload_bytes = H_128_384_23_DATA_BYTES;
|
||||
// }
|
||||
|
||||
double sd_double[bits_per_packet];
|
||||
float llr[bits_per_packet];
|
||||
float temp[bits_per_packet];
|
||||
uint8_t outbits[bits_per_packet];
|
||||
// double sd_double[bits_per_packet];
|
||||
// float llr[bits_per_packet];
|
||||
// float temp[bits_per_packet];
|
||||
// uint8_t outbits[bits_per_packet];
|
||||
|
||||
int b, i, parityCC;
|
||||
struct LDPC ldpc;
|
||||
// int b, i, parityCC;
|
||||
// struct LDPC ldpc;
|
||||
|
||||
// cast incoming SDs to doubles for sd_to_llr
|
||||
// For some reason I need to flip the sign ?!?!
|
||||
for ( i = 0; i < bits_per_packet; i++ )
|
||||
sd_double[i] = (double)sd[i]*-1.0;
|
||||
// // cast incoming SDs to doubles for sd_to_llr
|
||||
// // For some reason I need to flip the sign ?!?!
|
||||
// for ( i = 0; i < bits_per_packet; i++ )
|
||||
// sd_double[i] = (double)sd[i]*-1.0;
|
||||
|
||||
|
||||
sd_to_llr(llr, sd_double, bits_per_packet);
|
||||
// sd_to_llr(llr, sd_double, bits_per_packet);
|
||||
|
||||
/* reverse whitening and re-order bits */
|
||||
soft_unscramble(llr, temp, bits_per_packet);
|
||||
soft_deinterleave(temp, llr, mode);
|
||||
// /* reverse whitening and re-order bits */
|
||||
// soft_unscramble(llr, temp, bits_per_packet);
|
||||
// soft_deinterleave(temp, llr, mode);
|
||||
|
||||
/* correct errors */
|
||||
if (mode == 1){
|
||||
// 32-byte mode H_256_768_22
|
||||
ldpc.max_iter = H_256_768_22_MAX_ITER;
|
||||
ldpc.dec_type = 0;
|
||||
ldpc.q_scale_factor = 1;
|
||||
ldpc.r_scale_factor = 1;
|
||||
ldpc.CodeLength = H_256_768_22_CODELENGTH;
|
||||
ldpc.NumberParityBits = H_256_768_22_NUMBERPARITYBITS;
|
||||
ldpc.NumberRowsHcols = H_256_768_22_NUMBERROWSHCOLS;
|
||||
ldpc.max_row_weight = H_256_768_22_MAX_ROW_WEIGHT;
|
||||
ldpc.max_col_weight = H_256_768_22_MAX_COL_WEIGHT;
|
||||
ldpc.H_rows = (uint16_t *)H_256_768_22_H_rows;
|
||||
ldpc.H_cols = (uint16_t *)H_256_768_22_H_cols;
|
||||
} else {
|
||||
// 16-byte mode
|
||||
ldpc.max_iter = H_128_384_23_MAX_ITER;
|
||||
ldpc.dec_type = 0;
|
||||
ldpc.q_scale_factor = 1;
|
||||
ldpc.r_scale_factor = 1;
|
||||
ldpc.CodeLength = H_128_384_23_CODELENGTH;
|
||||
ldpc.NumberParityBits = H_128_384_23_NUMBERPARITYBITS;
|
||||
ldpc.NumberRowsHcols = H_128_384_23_NUMBERROWSHCOLS;
|
||||
ldpc.max_row_weight = H_128_384_23_MAX_ROW_WEIGHT;
|
||||
ldpc.max_col_weight = H_128_384_23_MAX_COL_WEIGHT;
|
||||
ldpc.H_rows = (uint16_t *)H_128_384_23_H_rows;
|
||||
ldpc.H_cols = (uint16_t *)H_128_384_23_H_cols;
|
||||
}
|
||||
// /* correct errors */
|
||||
// if (mode == 1){
|
||||
// // 32-byte mode H_256_768_22
|
||||
// ldpc.max_iter = H_256_768_22_MAX_ITER;
|
||||
// ldpc.dec_type = 0;
|
||||
// ldpc.q_scale_factor = 1;
|
||||
// ldpc.r_scale_factor = 1;
|
||||
// ldpc.CodeLength = H_256_768_22_CODELENGTH;
|
||||
// ldpc.NumberParityBits = H_256_768_22_NUMBERPARITYBITS;
|
||||
// ldpc.NumberRowsHcols = H_256_768_22_NUMBERROWSHCOLS;
|
||||
// ldpc.max_row_weight = H_256_768_22_MAX_ROW_WEIGHT;
|
||||
// ldpc.max_col_weight = H_256_768_22_MAX_COL_WEIGHT;
|
||||
// ldpc.H_rows = (uint16_t *)H_256_768_22_H_rows;
|
||||
// ldpc.H_cols = (uint16_t *)H_256_768_22_H_cols;
|
||||
// } else {
|
||||
// // 16-byte mode
|
||||
// ldpc.max_iter = H_128_384_23_MAX_ITER;
|
||||
// ldpc.dec_type = 0;
|
||||
// ldpc.q_scale_factor = 1;
|
||||
// ldpc.r_scale_factor = 1;
|
||||
// ldpc.CodeLength = H_128_384_23_CODELENGTH;
|
||||
// ldpc.NumberParityBits = H_128_384_23_NUMBERPARITYBITS;
|
||||
// ldpc.NumberRowsHcols = H_128_384_23_NUMBERROWSHCOLS;
|
||||
// ldpc.max_row_weight = H_128_384_23_MAX_ROW_WEIGHT;
|
||||
// ldpc.max_col_weight = H_128_384_23_MAX_COL_WEIGHT;
|
||||
// ldpc.H_rows = (uint16_t *)H_128_384_23_H_rows;
|
||||
// ldpc.H_cols = (uint16_t *)H_128_384_23_H_cols;
|
||||
// }
|
||||
|
||||
i = run_ldpc_decoder(&ldpc, outbits, llr, &parityCC);
|
||||
fprintf(stderr,"iterations: %d\n", i);
|
||||
// i = run_ldpc_decoder(&ldpc, outbits, llr, &parityCC);
|
||||
// fprintf(stderr,"iterations: %d\n", i);
|
||||
|
||||
/* convert MSB bits to a packet of bytes */
|
||||
for (b = 0; b < payload_bytes; b++) {
|
||||
uint8_t rxbyte = 0;
|
||||
for(i=0; i<8; i++)
|
||||
rxbyte |= outbits[b*8+i] << (7 - i);
|
||||
payload[b] = rxbyte;
|
||||
}
|
||||
}
|
||||
// /* convert MSB bits to a packet of bytes */
|
||||
// for (b = 0; b < payload_bytes; b++) {
|
||||
// uint8_t rxbyte = 0;
|
||||
// for(i=0; i<8; i++)
|
||||
// rxbyte |= outbits[b*8+i] << (7 - i);
|
||||
// payload[b] = rxbyte;
|
||||
// }
|
||||
// }
|
||||
|
|
|
@ -27,10 +27,10 @@ void horus_l2_decode_rx_packet(unsigned char *output_payload_data,
|
|||
|
||||
unsigned short horus_l2_gen_crc16(unsigned char* data_p, unsigned char length);
|
||||
|
||||
int ldpc_encode_packet(uint8_t *buff_mfsk, uint8_t *FSK, int mode);
|
||||
// int ldpc_encode_packet(uint8_t *buff_mfsk, uint8_t *FSK, int mode);
|
||||
|
||||
void soft_unscramble(float *in, float* out, int nbits);
|
||||
void soft_deinterleave(float *in, float* out, int mode);
|
||||
void horus_ldpc_decode(uint8_t *payload, float *sd, int mode);
|
||||
// void soft_unscramble(float *in, float* out, int nbits);
|
||||
// void soft_deinterleave(float *in, float* out, int mode);
|
||||
// void horus_ldpc_decode(uint8_t *payload, float *sd, int mode);
|
||||
|
||||
#endif
|
||||
|
|
Ładowanie…
Reference in New Issue