Fix CRC for more sizes

This commit is contained in:
Xavier Arteaga 2021-01-25 18:01:39 +01:00 committed by Xavier Arteaga
parent 1ee4d84f80
commit 573ff24a47
5 changed files with 42 additions and 26 deletions

View File

@ -47,11 +47,20 @@ SRSLTE_API uint32_t srslte_crc_attach_byte(srslte_crc_t* h, uint8_t* data, int l
static inline void srslte_crc_checksum_put_byte(srslte_crc_t* h, uint8_t byte) static inline void srslte_crc_checksum_put_byte(srslte_crc_t* h, uint8_t byte)
{ {
// Polynom order 8, 16, 24 or 32 only.
int ord = h->order - 8;
uint64_t crc = h->crcinit; uint64_t crc = h->crcinit;
crc = (crc << 8) ^ h->table[((crc >> (ord)) & 0xff) ^ byte]; uint32_t idx;
if (h->order > 8) {
// For more than 8 bits
uint32_t ord = h->order - 8U;
idx = ((crc >> (ord)) & 0xffU) ^ byte;
} else {
// For 8 bits or less
uint32_t ord = 8U - h->order;
idx = ((crc << (ord)) & 0xffU) ^ byte;
}
crc = (crc << 8U) ^ h->table[idx];
h->crcinit = crc; h->crcinit = crc;
} }

View File

@ -10,29 +10,27 @@
* *
*/ */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "srslte/phy/fec/crc.h" #include "srslte/phy/fec/crc.h"
#include "srslte/phy/utils/bit.h" #include "srslte/phy/utils/bit.h"
#include "srslte/phy/utils/debug.h" #include "srslte/phy/utils/debug.h"
void gen_crc_table(srslte_crc_t* h) static void gen_crc_table(srslte_crc_t* h)
{ {
uint32_t pad = (h->order < 8) ? (8 - h->order) : 0;
uint32_t ord = h->order + pad - 8;
uint32_t polynom = h->polynom << pad;
uint32_t crchighbit = h->crchighbit << pad;
int i, j, ord = (h->order - 8); for (uint32_t i = 0; i < 256; i++) {
uint64_t bit, crc; uint64_t crc = ((uint64_t)i) << ord;
for (uint32_t j = 0; j < 8; j++) {
for (i = 0; i < 256; i++) { bool bit = crc & crchighbit;
crc = ((uint64_t)i) << ord; crc <<= 1U;
for (j = 0; j < 8; j++) { if (bit) {
bit = crc & h->crchighbit; crc ^= polynom;
crc <<= 1; }
if (bit)
crc ^= h->polynom;
} }
h->table[i] = crc & h->crcmask; h->table[i] = (crc >> pad) & h->crcmask;
} }
} }
@ -73,12 +71,6 @@ int srslte_crc_init(srslte_crc_t* h, uint32_t crc_poly, int crc_order)
h->crcmask = ((((uint64_t)1 << (h->order - 1)) - 1) << 1) | 1; h->crcmask = ((((uint64_t)1 << (h->order - 1)) - 1) << 1) | 1;
h->crchighbit = (uint64_t)1 << (h->order - 1); h->crchighbit = (uint64_t)1 << (h->order - 1);
// check parameters
if (h->order % 8 != 0) {
ERROR("ERROR(invalid order=%d, it must be 8, 16, 24 or 32.\n", h->order);
return -1;
}
if (srslte_crc_set_init(h, h->crcinit)) { if (srslte_crc_set_init(h, h->crcinit)) {
ERROR("Error setting CRC init word\n"); ERROR("Error setting CRC init word\n");
return -1; return -1;

View File

@ -17,5 +17,7 @@ add_test(crc_24A crc_test -n 5001 -l 24 -p 0x1864CFB -s 1)
add_test(crc_24B crc_test -n 5001 -l 24 -p 0x1800063 -s 1) add_test(crc_24B crc_test -n 5001 -l 24 -p 0x1800063 -s 1)
add_test(crc_16 crc_test -n 5001 -l 16 -p 0x11021 -s 1) add_test(crc_16 crc_test -n 5001 -l 16 -p 0x11021 -s 1)
add_test(crc_8 crc_test -n 5001 -l 8 -p 0x19B -s 1) add_test(crc_8 crc_test -n 5001 -l 8 -p 0x19B -s 1)
add_test(crc_11 crc_test -n 30 -l 11 -p 0xE21 -s 1)
add_test(crc_6 crc_test -n 20 -l 6 -p 0x61 -s 1)

View File

@ -32,12 +32,13 @@ void usage(char* prog)
printf("\t-l crc_length [Default %d]\n", crc_length); printf("\t-l crc_length [Default %d]\n", crc_length);
printf("\t-p crc_poly (Hex) [Default 0x%x]\n", crc_poly); printf("\t-p crc_poly (Hex) [Default 0x%x]\n", crc_poly);
printf("\t-s seed [Default 0=time]\n"); printf("\t-s seed [Default 0=time]\n");
printf("\t-v [set srslte_verbose to debug, default none]\n");
} }
void parse_args(int argc, char** argv) void parse_args(int argc, char** argv)
{ {
int opt; int opt;
while ((opt = getopt(argc, argv, "nlps")) != -1) { while ((opt = getopt(argc, argv, "nlpsv")) != -1) {
switch (opt) { switch (opt) {
case 'n': case 'n':
num_bits = (int)strtol(argv[optind], NULL, 10); num_bits = (int)strtol(argv[optind], NULL, 10);
@ -51,6 +52,9 @@ void parse_args(int argc, char** argv)
case 's': case 's':
seed = (uint32_t)strtoul(argv[optind], NULL, 0); seed = (uint32_t)strtoul(argv[optind], NULL, 0);
break; break;
case 'v':
srslte_verbose++;
break;
default: default:
usage(argv[0]); usage(argv[0]);
exit(-1); exit(-1);
@ -83,6 +87,11 @@ int main(int argc, char** argv)
data[i] = rand() % 2; data[i] = rand() % 2;
} }
if (SRSLTE_DEBUG_ENABLED && srslte_verbose >= SRSLTE_VERBOSE_INFO && !handler_registered) {
INFO("data=");
srslte_vec_fprint_b(stdout, data, num_bits);
}
// Initialize CRC params and tables // Initialize CRC params and tables
if (srslte_crc_init(&crc_p, crc_poly, crc_length)) { if (srslte_crc_init(&crc_p, crc_poly, crc_length)) {
exit(-1); exit(-1);
@ -91,6 +100,8 @@ int main(int argc, char** argv)
// generate CRC word // generate CRC word
crc_word = srslte_crc_checksum(&crc_p, data, num_bits); crc_word = srslte_crc_checksum(&crc_p, data, num_bits);
INFO("checksum=%x\n", crc_word);
free(data); free(data);
// check if generated word is as expected // check if generated word is as expected

View File

@ -29,6 +29,8 @@ static expected_word_t expected_words[] = {
{5001, 24, SRSLTE_LTE_CRC24B, 1, 0x36D1F0}, // LTE CRC24B {5001, 24, SRSLTE_LTE_CRC24B, 1, 0x36D1F0}, // LTE CRC24B
{5001, 16, SRSLTE_LTE_CRC16, 1, 0x7FF4}, // LTE CRC16: 0x7FF4 {5001, 16, SRSLTE_LTE_CRC16, 1, 0x7FF4}, // LTE CRC16: 0x7FF4
{5001, 8, SRSLTE_LTE_CRC8, 1, 0xF0}, // LTE CRC8 0xF8 {5001, 8, SRSLTE_LTE_CRC8, 1, 0xF0}, // LTE CRC8 0xF8
{30, 11, SRSLTE_LTE_CRC11, 1, 0x114}, // NR CRC11 0x114
{20, 6, SRSLTE_LTE_CRC6, 1, 0x1F}, // NR CRC6 0x1F
{-1, -1, 0, 0, 0}}; {-1, -1, 0, 0, 0}};