Merge pull request #2 from agelonch/master

CRC issues solved and code reshaped to libLTE format
This commit is contained in:
Ismael Gómez-Miguelez 2014-05-13 15:59:45 +01:00
commit 801f7b52ee
5 changed files with 166 additions and 71 deletions

View File

@ -36,7 +36,30 @@
#define LTE_CRC8 0x19B
unsigned int crc(unsigned int crc, char *bufptr, int len,
int long_crc,unsigned int poly, int paste_word);
#define _WITHMALLOC
#ifndef _WITHMALLOC
#define MAX_LENGTH 1024*16
#endif
typedef struct {
unsigned long table[256];
#ifdef _WITHMALLOC
unsigned char *data0;
#else
unsigned char data0[MAX_LENGTH];
#endif
int polynom;
int order;
unsigned long crcinit;
unsigned long crcxor;
unsigned long crcmask;
unsigned long crchighbit;
unsigned int crc_out;
} crc_t;
int crc_init(crc_t *crc_par);
unsigned int crc_attach(char *bufptr, int len, crc_t *crc_params);
#endif

View File

@ -28,63 +28,129 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "lte/utils/pack.h"
unsigned int cword;
#include "lte/fec/crc.h"
unsigned int icrc1(unsigned int crc, unsigned short onech,int long_crc,
int left_shift,unsigned int poly)
{
int i;
unsigned int tmp=(unsigned int) (crc ^ (onech << (long_crc >> 1) ));
for (i=0;i<left_shift;i++) {
if (tmp & (0x1<<(long_crc-1)))
tmp=(tmp<<1)^poly;
else
tmp <<= 1;
}
void gen_crc_table(crc_t *crc_params) {
return tmp;
}
int i, j, ord=(crc_params->order-8);
unsigned long bit, crc;
unsigned int crc(unsigned int crc, char *bufptr, int len,
int long_crc,unsigned int poly, int paste_word) {
int i,k;
unsigned int data;
int stop;
unsigned int ret;
cword=crc;
k=0;
stop=0;
while(!stop) {
data=0;
for (i=0;i<long_crc/2;i++) {
if (bufptr[k] && k<len)
data|=(0x1<<(long_crc/2-1-i));
k++;
if (k==len) {
stop=1;
i++;
break;
}
}
cword=(unsigned int) (icrc1((unsigned int) (cword<<long_crc>>long_crc),
data,long_crc,i,poly)<<long_crc)>>long_crc;
}
ret=cword;
if (paste_word) {
cword<<=32-long_crc;
for (i=0;i<long_crc;i++) {
bufptr[i+len]=((cword&(0x1<<31))>>31);
cword<<=1;
}
}
return (ret);
for (i=0; i<256; i++) {
crc = ((unsigned long)i)<<ord;
for (j=0; j<8; j++) {
bit = crc & crc_params->crchighbit;
crc<<= 1;
if (bit) crc^= crc_params->polynom;
}
crc_params->table[i]=crc & crc_params->crcmask;
}
}
unsigned long crctable (unsigned long length, crc_t *crc_params) {
// Polynom order 8, 16, 24 or 32 only.
int ord=crc_params->order-8;
unsigned long crc = crc_params->crcinit;
unsigned char* data = crc_params->data0;
while (length--){
crc = (crc << 8) ^ crc_params->table[ ((crc >> (ord)) & 0xff) ^ *data++];
}
return((crc ^ crc_params->crcxor) & crc_params->crcmask);
}
unsigned long reversecrcbit(unsigned int crc, int nbits, crc_t *crc_params) {
unsigned long m, rmask=0x1;
for(m=0; m<nbits; m++){
if((rmask & crc) == 0x01 )crc = (crc ^ crc_params->polynom)>>1;
else crc = crc >> 1;
}
return((crc ^ crc_params->crcxor) & crc_params->crcmask);
}
int crc_init(crc_t *crc_par){
// Compute bit masks for whole CRC and CRC high bit
crc_par->crcmask = ((((unsigned long)1<<(crc_par->order-1))-1)<<1)|1;
crc_par->crchighbit = (unsigned long)1<<(crc_par->order-1);
printf("crcmask=%x, crchightbit=%x\n",
(unsigned int)crc_par->crcmask, (unsigned int)crc_par->crchighbit);
// check parameters
if (crc_par->order%8 != 0) {
printf("ERROR, invalid order=%d, it must be 8, 16, 24 or 32.\n", crc_par->order);
return(0);
}
if (crc_par->crcinit != (crc_par->crcinit & crc_par->crcmask)) {
printf("ERROR, invalid crcinit.\n");
return(0);
}
if (crc_par->crcxor != (crc_par->crcxor & crc_par->crcmask)) {
printf("ERROR, invalid crcxor.\n");
return(0);
}
// generate lookup table
gen_crc_table(crc_par);
return(1);
}
unsigned int crc_attach(char *bufptr, int len, crc_t *crc_params) {
int i, len8, res8, a;
unsigned int crc;
char *pter;
#ifdef _WITHMALLOC
crc_params->data0 = (unsigned char *)malloc(sizeof(*crc_params->data0) * (len+crc_params->order)*2);
if (!crc_params->data0) {
perror("malloc ERROR: Allocating memory for data pointer in crc() function");
return(-1);
}
#else
if((((len+crc_params->order)>>3) + 1) > MAX_LENGTH){
printf("ERROR: Not enough memory allocated\n");
return(-1);
}
#endif
//# Pack bits into bytes
len8=(len>>3);
res8=8-(len - (len8<<3));
if(res8>0)a=1;
else a=0;
// Zeroed additional bits
memset((char *)(bufptr+len),0,(32)*sizeof(char));
for(i=0; i<len8+a; i++){
pter=(char *)(bufptr+8*i);
crc_params->data0[i]=(unsigned char)(unpack_bits(&pter, 8)&0xFF);
}
// Calculate CRC
crc=crctable(len8+a, crc_params);
// Reverse CRC res8 positions
if(a==1)crc=reversecrcbit(crc, res8, crc_params);
// Add CRC
pter=(char *)(bufptr+len);
pack_bits(crc, &pter, crc_params->order);
#ifdef _WITHMALLOC
free(crc_params->data0);
crc_params->data0=NULL;
#endif
//Return CRC value
return crc;
}

View File

@ -43,9 +43,9 @@ ADD_TEST(viterbi_1000_4 viterbi_test -n 100 -s 1 -l 1000 -k 7 -t -e 4.5)
ADD_EXECUTABLE(crc_test crc_test.c)
TARGET_LINK_LIBRARIES(crc_test lte)
ADD_TEST(crc_24A crc_test -n 5000 -l 24 -p 0x1864CFB -s 1)
ADD_TEST(crc_24B crc_test -n 5000 -l 24 -p 0x1800063 -s 1)
ADD_TEST(crc_16 crc_test -n 5000 -l 16 -p 0x11021 -s 1)
ADD_TEST(crc_8 crc_test -n 5000 -l 8 -p 0x19B -s 1)
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)

View File

@ -35,12 +35,11 @@
#include <time.h>
#include "lte.h"
#include "crc_test.h"
int num_bits = 1000, crc_length = 16;
unsigned int crc_poly = 0x11021;
unsigned int seed = 0;
int num_bits = 5000, crc_length = 24;
unsigned int crc_poly = 0x1864CFB;
unsigned int seed = 1;
void usage(char *prog) {
@ -78,10 +77,11 @@ int main(int argc, char **argv) {
int i;
char *data;
unsigned int crc_word, expected_word;
crc_t crc_p;
parse_args(argc, argv);
data = malloc(sizeof(char) * (num_bits+crc_length));
data = malloc(sizeof(char) * (num_bits+crc_length)*2);
if (!data) {
perror("malloc");
exit(-1);
@ -97,19 +97,24 @@ int main(int argc, char **argv) {
data[i] = rand()%2;
}
//Initialize CRC params and tables
crc_p.polynom=crc_poly;
crc_p.order=crc_length;
crc_p.crcinit=0x00000000;
crc_p.crcxor=0x00000000;
if(!crc_init(&crc_p))exit(0);
// generate CRC word
crc_word = crc(0, data, num_bits, crc_length, crc_poly, 1);
crc_word = crc_attach(data, num_bits, &crc_p);
// check if result is zero
if (crc(0, data, num_bits + crc_length, crc_length, crc_poly, 0)) {
if (crc_attach(data, num_bits + crc_length, &crc_p)) {
printf("CRC check is non-zero\n");
exit(-1);
}
free(data);
printf("CRC word: 0x%x\n", crc_word);
// check if generated word is as expected
if (get_expected_word(num_bits, crc_length, crc_poly, seed, &expected_word)) {
fprintf(stderr, "Test parameters not defined in test_results.h\n");

View File

@ -39,10 +39,11 @@ typedef struct {
static expected_word_t expected_words[] = {
{5000, 24, LTE_CRC24A, 1, 0x4D0836}, // LTE CRC24A (36.212 Sec 5.1.1)
{5000, 24, LTE_CRC24B, 1, 0x9B68F8}, // LTE CRC24B
{5000, 16, LTE_CRC16, 1, 0xBFFA}, // LTE CRC16
{5000, 8, LTE_CRC8, 1, 0xF8}, // LTE CRC8
{5001, 24, LTE_CRC24A, 1, 0x1C5C97}, // LTE CRC24A (36.212 Sec 5.1.1)
{5001, 24, LTE_CRC24B, 1, 0x36D1F0}, // LTE CRC24B
{5001, 16, LTE_CRC16, 1, 0x7FF4}, // LTE CRC16: 0x7FF4
{5001, 8, LTE_CRC8, 1, 0xF0}, // LTE CRC8 0xF8
{-1, -1, 0, 0, 0}
};