crc5-test: add simple program to generate SOF frames
This can be used to tell if we're properly decoding packets. Signed-off-by: Sean Cross <sean@xobs.io>
This commit is contained in:
parent
cad2ae01d7
commit
1cb67f8f8d
160
crc5-test.c
Normal file
160
crc5-test.c
Normal file
@ -0,0 +1,160 @@
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
|
||||
const uint8_t crc5Table4[] =
|
||||
{
|
||||
0x00, 0x0E, 0x1C, 0x12, 0x11, 0x1F, 0x0D, 0x03,
|
||||
0x0B, 0x05, 0x17, 0x19, 0x1A, 0x14, 0x06, 0x08};
|
||||
const uint8_t crc5Table0[] =
|
||||
{
|
||||
0x00, 0x16, 0x05, 0x13, 0x0A, 0x1C, 0x0F, 0x19,
|
||||
0x14, 0x02, 0x11, 0x07, 0x1E, 0x08, 0x1B, 0x0D};
|
||||
//---------------
|
||||
int crc5Check(const uint8_t *data)
|
||||
//---------------
|
||||
{
|
||||
uint8_t b = data[0] ^ 0x1F;
|
||||
uint8_t crc = crc5Table4[b & 0x0F] ^ crc5Table0[(b >> 4) & 0x0F];
|
||||
b = data[1] ^ crc;
|
||||
return (crc5Table4[b & 0x0F] ^ crc5Table0[(b >> 4) & 0x0F]) == 0x06;
|
||||
}
|
||||
// crc5Check
|
||||
|
||||
int do_check(uint16_t pkt) {
|
||||
uint8_t data[2] = {
|
||||
pkt >> 8,
|
||||
pkt,
|
||||
};
|
||||
return crc5Check(data);
|
||||
}
|
||||
|
||||
#define INT_SIZE 32
|
||||
unsigned CRC5(unsigned dwInput, int iBitcnt)
|
||||
{
|
||||
const uint32_t poly5 = (0x05 << (INT_SIZE-5));
|
||||
uint32_t crc5 = (0x1f << (INT_SIZE-5));
|
||||
uint32_t udata = (dwInput << (INT_SIZE-iBitcnt));
|
||||
|
||||
if ( (iBitcnt<1) || (iBitcnt>INT_SIZE) ) // Validate iBitcnt
|
||||
return 0xffffffff;
|
||||
|
||||
while (iBitcnt--)
|
||||
{
|
||||
if ( (udata ^ crc5) & (0x1<<(INT_SIZE-1)) ) // bit4 != bit4?
|
||||
{
|
||||
crc5 <<= 1;
|
||||
crc5 ^= poly5;
|
||||
}
|
||||
else
|
||||
crc5 <<= 1;
|
||||
|
||||
udata <<= 1;
|
||||
}
|
||||
|
||||
// Shift back into position
|
||||
crc5 >>= (INT_SIZE-5);
|
||||
|
||||
// Invert contents to generate crc field
|
||||
crc5 ^= 0x1f;
|
||||
|
||||
return crc5;
|
||||
} //CRC5()
|
||||
|
||||
static uint32_t reverse_sof(uint32_t data) {
|
||||
int i;
|
||||
uint32_t data_flipped = 0;
|
||||
for (i = 0; i < 11; i++)
|
||||
if (data & (1 << i))
|
||||
data_flipped |= 1 << (10 - i);
|
||||
|
||||
return data_flipped;
|
||||
}
|
||||
|
||||
static uint8_t reverse_byte(uint8_t data) {
|
||||
int i;
|
||||
uint8_t data_flipped = 0;
|
||||
for (i = 0; i < 8; i++)
|
||||
if (data & (1 << i))
|
||||
data_flipped |= 1 << (7 - i);
|
||||
|
||||
return data_flipped;
|
||||
}
|
||||
|
||||
static uint8_t reverse_crc5(uint8_t data) {
|
||||
int i;
|
||||
uint8_t data_flipped = 0;
|
||||
for (i = 0; i < 5; i++)
|
||||
if (data & (1 << i))
|
||||
data_flipped |= 1 << (4 - i);
|
||||
|
||||
return data_flipped;
|
||||
}
|
||||
|
||||
static uint16_t make_token(uint16_t data) {
|
||||
uint16_t val = 0;
|
||||
|
||||
data = reverse_sof(data);
|
||||
val = data << 5;
|
||||
val |= CRC5(data, 11);
|
||||
|
||||
return (reverse_byte(val >> 8) << 8) | reverse_byte(val);
|
||||
}
|
||||
|
||||
int do_crc5(uint16_t pkt) {
|
||||
uint8_t pkt_flipped[2] = {
|
||||
reverse_byte(pkt >> 8),
|
||||
reverse_byte(pkt),
|
||||
};
|
||||
uint32_t data = (pkt_flipped[1] >> 5) | (pkt_flipped[0] << 3);
|
||||
uint32_t data_flipped;
|
||||
uint8_t crc;
|
||||
uint8_t found_crc = (pkt >> 3) & 0x1f;
|
||||
|
||||
data_flipped = reverse_sof(data);
|
||||
|
||||
crc = CRC5(data, 11);
|
||||
crc = reverse_crc5(crc);
|
||||
|
||||
uint16_t reconstructed = make_token(data_flipped);
|
||||
uint16_t wire = (reverse_byte(pkt >> 8) << 8) | reverse_byte(pkt);
|
||||
|
||||
printf("Packet: 0x%04x FCRC: %02x Data: 0x%04x "
|
||||
"Flipped: 0x%04x CRC5: 0x%02x Pass? %d Reconstructed: 0x%04x Wire: %04x\n",
|
||||
pkt, found_crc, data, data_flipped, crc, do_check(pkt),
|
||||
reconstructed,
|
||||
wire
|
||||
);
|
||||
|
||||
return crc;
|
||||
}
|
||||
|
||||
#define ARRAY_SIZE(x) (sizeof(x) / sizeof(*x))
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
uint32_t check_bytes[] = {
|
||||
/*
|
||||
0xff3c,
|
||||
0x12c5,
|
||||
0xe17e,
|
||||
0x19f5,
|
||||
0x0225,
|
||||
0x0165,
|
||||
0x009d,
|
||||
0x102f,
|
||||
make_token(1013),
|
||||
make_token(1429),
|
||||
make_token(100),
|
||||
*/
|
||||
0x82bc,
|
||||
make_token(0x0483),//0x5fde,
|
||||
0x843c,
|
||||
|
||||
};
|
||||
|
||||
unsigned int i;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(check_bytes); i++)
|
||||
do_crc5(check_bytes[i]);
|
||||
|
||||
return 0;
|
||||
}
|
Loading…
Reference in New Issue
Block a user