This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

What elements of the over-the-air package are fed in which order and endianess into the crc module?

Hello,

In an ongoing company project we use a couple of nRF51 transceivers forming a beacon enabled wireless sensor network consisting of one base station and multiple sensor nodes. For our application it is required that we are able to perform a off-base-CRC calculation of the data received from the sensor nodes and get to the same result as the hardware crc of the radio module does. The CRC Module is configured for CRC-CITT-16 with an initial value of 0xFFFF.

After some research I found this piece of code, which describes how to calculate the crc in crc-citt-16:


// code provided by github.com/.../ble_modify_setup_data.ino
boost::uint16_t crc_16_ccitt(boost::uint16_t crc, boost::uint8_t * data_in, boost::uint16_t data_len) {

	for(boost::uint16_t i = 0; i < data_len; i++) {
		crc  = (unsigned char)(crc >> 8) | (crc << 8);
		crc ^= data_in[i];
		crc ^= (unsigned char)(crc & 0xff) >> 4;
		crc ^= (crc << 8) << 4;
		crc ^= ((crc & 0xff) << 4) << 1;
	}

	return crc;
}

// usage 
boost::uint8_t data[2] = {0x01, 0x02};
boost::uint16_t const crc = crc_16_ccitt(0xFFFF, data, 2);

This code gets with the same data to the same result as our previously used boost crc-citt-16 implementation:


boost::uint16_t calculate_crc(boost::uint8_t *data, boost::uint8_t const length) {
	boost::crc_basic<16>  crc_ccitt_16(0x1021, 0xFFFF, 0, false, false );
	crc_ccitt_16.process_bytes(data, length);
        return crc_ccitt_16.checksum();
}

However, regardless how many combinations of byte and bit oder for base, prefix and payload I try, I never get to the same result as the hardware crc module (which can be read from the RXCRC) register. In our configuration we use 2 Bytes for BASE (BASE0), 1 Byte for Prefix (PREFIX0.AP0), S0 and S1 is disabled. The flag for including the address into the crc calculation is set.

I suspect that the problem might come from feeding the data to be crced in a wrong order into the crc module. Could someone shed some light on which data fields exactly are fed into the crc, in which order and in which endianess?

Heres my example code:


// data obtained from debugging
boost::uint8_t test_data[29] = {
							0xC9, // BASE0 - turning this and the next byte does not get right crc either
							0xE7, // BASE0
							0x34, // PREFIX0.AP0
							0x19, // LENGTH
							0x12, // PAYLOAD0
							0x0C,
							0x01,
							0x03,
							0x5D,
							0x02, 0x09, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00,
							0x02, 0x00,	0x02, 0x00,	0x02, 0x00,	0x02, 0x00,	0x02, 0x00
	};

std::cout << "test_data: crc according to docmentation: 0x" << std::hex << crc_16_ccitt(0xFFFF, test_data, 29) << std::dec << std::endl; // result is 0xc3b1 but should be 0xA80F according to RXCRC


Related