示例#1
0
/**
 * Calculates 32-bit CRC for the specified input string
 *
 * @return A 32-bit unsigned integer representing the CRC
 */
uint32_t calculateCRC32C(uint32_t crc, const char *buf, size_t len) {
    // If the string is empty, return 0
    if (len == 0) {
        return crc;
    }


    // XOR the initial CRC with INT_MAX
    crc ^= 0xFFFFFFFF;


    // Align the input to the word boundary
    for (; (len > 0) && ((size_t)buf & ALIGN_MASK); len--, buf++) {
        crc = _mm_crc32_u8(crc, *buf);
    }


    // Blast off the CRC32 calculation
#ifdef __x86_64__
    CALC_CRC(_mm_crc32_u64, crc, uint64_t, buf, len);
#endif
    CALC_CRC(_mm_crc32_u32, crc, uint32_t, buf, len);
    CALC_CRC(_mm_crc32_u16, crc, uint16_t, buf, len);
    CALC_CRC(_mm_crc32_u8, crc, uint8_t, buf, len);


    // Post-process the crc
    return (crc ^= 0xFFFFFFFF);
}
示例#2
0
uint8_t check_crc(data_t* data)
{
	uint8_t remainder = CRC_INITIAL_REMAINDER;
	remainder ^= (*data).a;
	CALC_CRC(remainder);
	remainder ^= (*data).b;
	CALC_CRC(remainder);
	remainder ^= (*data).c;
	CALC_CRC(remainder);
	if(remainder != (*data).d)
		return 1;
	return 0;
}
示例#3
0
uint8_t manchester_send(data_t* data)
{
	(*data).d = CRC_INITIAL_REMAINDER;

	ZERO();

	// Calculate CRC here in parts. This should be well timed.

	(*data).d ^= (*data).a;                // 3 cycles
	CALC_CRC((*data).d);
	// Grand total 48+24+3 = 75 cycles = 9.375 us.

	(*data).d ^= (*data).b;                // 3 cycles
	CALC_CRC((*data).d);
	// Grand total 48+24+3 = 75 cycles = 9.375 us.

	del_us(25 - 9.375 - 9.375 - 0.250);

	ONE();

	(*data).d ^= (*data).c;                // 3 cycles
	CALC_CRC((*data).d);
	// Grand total 48+24+3 = 75 cycles = 9.375 us.

	del_us(25 - 9.375 - 0.250);


	for(uint8_t i = 32; i > 0; --i)
	{
		if((*data).a & 0b10000000)
		{
			ZERO();
			del_us(25-0.125);
			ONE();
		}
		else
		{
			ONE();
			del_us(25-0.125);
			ZERO();
		}
		del_us(25-0.125-2.5-0.250);

		(*data).abcd = (*data).abcd << 1;
	}

	ONE();

	return COMM_SUCCESS;

}
示例#4
0
uint8_t manchester_receive(data_t* data)  // Function call 4 clk, function overhead at start 5 clk
{
	// Grand total from the edge 15 us + 1.125 us = 16.125 us.
	uint8_t time_tmp;
	uint8_t remainder = CRC_INITIAL_REMAINDER; // 0 clk

	PULLUP_OFF();

	(*data).abcd = 0;  // 8 clk = 1 us.

	//if(pinstat)
	//	return 1;

	// Wait for high transition
	// Already consumed 17.125 us. For +13 us time window, it needs to come within (25+13) - 17.125 us = 20.875 us = 167 clk

	// Require two successive high readings.
	// LOOP: SBIS 2 + SBIC 2 + SUBI 1 + BRCC 2 = 7 clk /round.
	time_tmp = 24;	//167/7 would be 23.85, round to 24.

	while(time_tmp--)
	{
		if(pinstat && pinstat)
			goto OK1;

	}

	PULLUP_ON();
	return 2;

	OK1:

	// Now we are exactly aligned at first '1', which is discarded.

	_delay_us(10.125 + 1.5); // Compensation for CRC delay, see below.
	                         // +1.5 = measured correction.

	for(uint8_t i = 0; i < 32; i++)
	{
		(*data).abcd <<= 1;  // 20 clk = 2.5 us

		// Align at 35.0 us from previous data bit. 37.5 us is
		// halfway between the optional edge and the next data bit.
		// Sample the value between 35.0 us and 40.0 us.
		// The expected edge is at 50 us, but allow it some window
		// due to clock differences.

		del_us(35.0 - 2.5 - 10.125 - 2.5 + 1.0); // CRC calculation uses 10.125 us - see
		                             // below.
									 // -2.5 = measured correction.


		uint8_t n_low_readings = 0;
		for(uint8_t i = 8; i>0; --i)  // 5 clk per round (regardless of pin value.)
		{
			if(!pinstat)
				n_low_readings++;
		} // 40 clk = 5 us.


		// Num of zeroes: 0  1  2   3  4   5  6  7
		//                H I G H | ?  ? | L  O  W

		if(n_low_readings < 3) 
		{	// High -- expect low. 
			del_us(10-WINDOW_BEFORE);
			// time windows of +/-10 us = 20 us = 160 clock cycles starts here.
			// LOOP: SBIS 2 + SBIC 2 + SUBI 1 + BRCC 2 = 7 clk /round.
			time_tmp = 	((WINDOW_BEFORE+WINDOW_AFTER)*8)/7;
			while(time_tmp--)
			{ // Require two successive low readings.
				if((!pinstat) && (!pinstat))
					goto OK2;
			}
			PULLUP_ON();
			return 0x40+i;

			OK2:
			__asm__ __volatile__ ("nop");

		}
		else if(n_low_readings > 4) // low -- expect high
		{
			del_us(10-WINDOW_BEFORE);
			// time windows of +/-10 us = 20 us = 160 clock cycles starts here.
			// LOOP: SBIS 2 + SBIC 2 + SUBI 1 + BRCC 2 = 7 clk /round.
			time_tmp = 	((WINDOW_BEFORE+WINDOW_AFTER)*8)/7;
			while(time_tmp--)
			{ // Require two successive high readings.
				if(pinstat && pinstat)
					goto OK3;
			}
			PULLUP_ON();
			return 0x60+i;

			OK3:

			(*data).d |= 1; // 1 clk = 0.125 us

		}
		else
		{
			PULLUP_ON();
			return 0x20+i;
		}

		// Here, we are aligned perfectly again.


		// At the same time, calculate CRC8. Calculate every time 8 bits have been received,
		// but of course skip the last octet which is the CRC.

		// Consume a constant amount of time here, which can be then subtracted from
		// the delay at the beginning of the loop.

		if(i==7 || i==15 || i==23)  // 6 cycles used when not true, 3...7 if true.
		{
			// We have our latest full byte in data.d
			remainder ^= (*data).d;        // 3 cycles
			CALC_CRC(remainder);
			// Total 3+48+24 = 75 cycles = 9.375 us.
		}
		else
		{
			_delay_us(9.375);
		}
		// In total, 10.125 us was spent for the if + CRC.

	}

	PULLUP_ON();

	if(remainder != (*data).d)
		return CRC_ERROR;

	return COMM_SUCCESS;
}