MotorControlModuleSDFM_TMS3.../Projects/EFC_Communication/UMLibrary/common/CrcPolys.cpp
2024-06-07 11:12:56 +03:00

140 lines
3.9 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

//
// Created by titov on 27.11.2021.
//
#include "CrcPolys.hh"
#include <climits>
#ifndef CHAR_BIT
#define CHAR_BIT 8
#endif
template<typename Param>
uint16_t crc16(const char * data, std::size_t size) {
return common::crc::crcCalc<Param>(data, size * CHAR_BIT / 8);
}
//!width=3 poly=0x3 init=0x0 refin=false refout=false xorout=0x7 check=0x4 residue=0x2 name="CRC-3/GSM"
uint16_t crc3GSM( const char * data, std::size_t size ) {
uint16_t crc = 0;
const unsigned char high_octet_bit = (0x1u << (8 - 1));
for( int n = 0; n < size; ++n ) {
unsigned char byte = data[n];
while( byte ) {
unsigned char octet = byte & 0xFFu;
for( int bit = 0; bit < 8; ++bit ) {
bool is_set = (crc & 0x4u) ^ ((octet & high_octet_bit) >> (8 - 3));
octet <<= 1;
crc <<= 1;
if( is_set )
crc ^= 0x3u;
crc &= 0x7u;
}
byte >>= 8u;
}
}
return crc;
}
/*!
* Функция нахождения контрольной суммы BISS CRC6 при помощи табличного алгоритма.
* @param data массив данных, контрольную сумму которых надо расчитать, массив данных необходимо выровнять по младшему биту
* @param size количество байт из массива, контрольную сумму которых надо расчитать
* @return @note ИНВЕРТИРОВАННАЯ контрольная сумма ( в соответствии с протоколом BISS-C )
*/
uint16_t crcBiSS( const char * data, std::size_t size )
{
//!Таблица для расчёта чек сумы CRC6, для полинома: P(x) = x6 + x1 + x0
static uint16_t tableCRC6[64] = {
0x00, 0x03, 0x06, 0x05, 0x0C, 0x0F, 0x0A, 0x09,
0x18, 0x1B, 0x1E, 0x1D, 0x14, 0x17, 0x12, 0x11,
0x30, 0x33, 0x36, 0x35, 0x3C, 0x3F, 0x3A, 0x39,
0x28, 0x2B, 0x2E, 0x2D, 0x24, 0x27, 0x22, 0x21,
0x23, 0x20, 0x25, 0x26, 0x2F, 0x2C, 0x29, 0x2A,
0x3B, 0x38, 0x3D, 0x3E, 0x37, 0x34, 0x31, 0x32,
0x13, 0x10, 0x15, 0x16, 0x1F, 0x1C, 0x19, 0x1A,
0x0B, 0x08, 0x0D, 0x0E, 0x07, 0x04, 0x01, 0x02
};
const uint16_t CRC6_BITS = 6;
const uint16_t SIX_BITS_MASK = 0x3Fu;
uint32_t CHAR_MASK;
if( CHAR_BIT == 8 ) {
CHAR_MASK = 0xFF;
}
if( CHAR_BIT == 16) {
CHAR_MASK = 0xFFFF;
}
uint32_t _data = 0;
uint16_t crc;
uint32_t tmp { 0 };
uint16_t cycle_crc_xor = ( size * CHAR_BIT ) / CRC6_BITS;
uint16_t shift = ( size * CHAR_BIT ) - ( size * CHAR_BIT ) % CRC6_BITS;
for ( int i = 0; i < size; i++ ) {
uint32_t data_tmp = data[ i ];
_data |= ( ( data_tmp ) << ( i * CHAR_BIT ) ) & ( CHAR_MASK << ( i * CHAR_BIT ) );
}
uint16_t bits_in_mask = ( 1 << ( CHAR_BIT - ( shift % ( CHAR_BIT ) ) ) ) - 1;
tmp = ( _data >> shift ) & bits_in_mask;
do {
cycle_crc_xor--;
crc = ( ( _data >> CRC6_BITS * cycle_crc_xor ) & SIX_BITS_MASK );
tmp = ( ( crc ) ^ tableCRC6[ tmp ] ) & SIX_BITS_MASK ;
} while( cycle_crc_xor > 0 );
crc = tableCRC6[tmp];
return ( crc ^ SIX_BITS_MASK );
}
common::crc::CrcPolynoms::CrcInstance common::crc::CrcPolynoms::instanse(common::crc::CrcPolynoms::Types type) {
CrcInstance crc_instance;
switch (type) {
case CrcPolynoms::Crc3_GSM: {
crc_instance.poly.crc16 = crc3GSM;//&crc16<common::crc::Crc3_GSM>;
crc_instance.bit_size = 3;//common::crc::Crc3_GSM::width_bit;
} break;
case CrcPolynoms::Crc6_BISS: {
common::crc::CrcTable<common::crc::Crc6_BISS>::Instance().inititialize();
crc_instance.poly.crc16 = crcBiSS;
crc_instance.bit_size = 6;
} break;
default: {} break;
}
return crc_instance;
}