From 573ff24a472d643789c9d3dc88608eba1e0ed8ea Mon Sep 17 00:00:00 2001 From: Xavier Arteaga Date: Mon, 25 Jan 2021 18:01:39 +0100 Subject: [PATCH] Fix CRC for more sizes --- lib/include/srslte/phy/fec/crc.h | 15 +++++++++--- lib/src/phy/fec/crc.c | 36 +++++++++++------------------ lib/src/phy/fec/test/CMakeLists.txt | 2 ++ lib/src/phy/fec/test/crc_test.c | 13 ++++++++++- lib/src/phy/fec/test/crc_test.h | 2 ++ 5 files changed, 42 insertions(+), 26 deletions(-) diff --git a/lib/include/srslte/phy/fec/crc.h b/lib/include/srslte/phy/fec/crc.h index b10814289..d03e1a441 100644 --- a/lib/include/srslte/phy/fec/crc.h +++ b/lib/include/srslte/phy/fec/crc.h @@ -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) { - // Polynom order 8, 16, 24 or 32 only. - int ord = h->order - 8; 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; } diff --git a/lib/src/phy/fec/crc.c b/lib/src/phy/fec/crc.c index 9b1c2f685..9d108b4f0 100644 --- a/lib/src/phy/fec/crc.c +++ b/lib/src/phy/fec/crc.c @@ -10,29 +10,27 @@ * */ -#include -#include -#include - #include "srslte/phy/fec/crc.h" #include "srslte/phy/utils/bit.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); - uint64_t bit, crc; - - for (i = 0; i < 256; i++) { - crc = ((uint64_t)i) << ord; - for (j = 0; j < 8; j++) { - bit = crc & h->crchighbit; - crc <<= 1; - if (bit) - crc ^= h->polynom; + for (uint32_t i = 0; i < 256; i++) { + uint64_t crc = ((uint64_t)i) << ord; + for (uint32_t j = 0; j < 8; j++) { + bool bit = crc & crchighbit; + crc <<= 1U; + if (bit) { + crc ^= 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->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)) { ERROR("Error setting CRC init word\n"); return -1; diff --git a/lib/src/phy/fec/test/CMakeLists.txt b/lib/src/phy/fec/test/CMakeLists.txt index cf7176ea2..be61c4a5d 100644 --- a/lib/src/phy/fec/test/CMakeLists.txt +++ b/lib/src/phy/fec/test/CMakeLists.txt @@ -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_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_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) diff --git a/lib/src/phy/fec/test/crc_test.c b/lib/src/phy/fec/test/crc_test.c index 0307b1388..17ef2e51f 100644 --- a/lib/src/phy/fec/test/crc_test.c +++ b/lib/src/phy/fec/test/crc_test.c @@ -32,12 +32,13 @@ void usage(char* prog) printf("\t-l crc_length [Default %d]\n", crc_length); printf("\t-p crc_poly (Hex) [Default 0x%x]\n", crc_poly); 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) { int opt; - while ((opt = getopt(argc, argv, "nlps")) != -1) { + while ((opt = getopt(argc, argv, "nlpsv")) != -1) { switch (opt) { case 'n': num_bits = (int)strtol(argv[optind], NULL, 10); @@ -51,6 +52,9 @@ void parse_args(int argc, char** argv) case 's': seed = (uint32_t)strtoul(argv[optind], NULL, 0); break; + case 'v': + srslte_verbose++; + break; default: usage(argv[0]); exit(-1); @@ -83,6 +87,11 @@ int main(int argc, char** argv) 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 if (srslte_crc_init(&crc_p, crc_poly, crc_length)) { exit(-1); @@ -91,6 +100,8 @@ int main(int argc, char** argv) // generate CRC word crc_word = srslte_crc_checksum(&crc_p, data, num_bits); + INFO("checksum=%x\n", crc_word); + free(data); // check if generated word is as expected diff --git a/lib/src/phy/fec/test/crc_test.h b/lib/src/phy/fec/test/crc_test.h index 2e68cb407..a417fa748 100644 --- a/lib/src/phy/fec/test/crc_test.h +++ b/lib/src/phy/fec/test/crc_test.h @@ -29,6 +29,8 @@ static expected_word_t expected_words[] = { {5001, 24, SRSLTE_LTE_CRC24B, 1, 0x36D1F0}, // LTE CRC24B {5001, 16, SRSLTE_LTE_CRC16, 1, 0x7FF4}, // LTE CRC16: 0x7FF4 {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}};