MotorControlModuleSDFM_TMS3.../Projects/EFC_Communication/UMLibrary/common/Crc.hh

126 lines
4.9 KiB
C++
Raw Permalink Normal View History

2024-06-07 11:12:56 +03:00
/*
* CCRC.h
*
* Created on: 25 дек. 2014 г.
* Author: Gorbunov_DV
*/
#ifndef CCRC_H_
#define CCRC_H_
//! \brief Модуль расчета контрольной суммы по табличному алгоритму CRC
/*! \details Модуль реализует параметрируемый алгоритм расчета контрольной суммы.
* В качестве параметров выступают:
* *Степень алгоритма
* *Полином
* *Начальное значение контрольной суммы
* *Указание, обращать ли входные байты
* *Указание, обращать ли результат перед выдачей
* *Значение, которое комбинируется с результатом расчета контрольной суммы перед выдачей
*
* \author Gorbunov_DV
*/
template <short width, unsigned long poly, unsigned long init, bool refin, bool refout, unsigned long xorout>
class Crc {
private:
static unsigned long CRCTable[256]; //!< Таблица полиномов
unsigned long crc; //!< Результат вычисления контрольной суммы
/*!\brief Функция получения маски в соответствии со степенью алгоритма. */
unsigned long widmask() { return ( ( ( 1L << ( width - 1 ) ) - 1L ) << 1 ) | 1L; }
/*!\brief Функция обращения заданного количества бит в передаваемом значении.
* \return обращенное значение.
* \param[in] value значение для обращения
* \param[in] numBits количество бит для обращения
*/
unsigned long reflect( unsigned long value, short numBits );
public:
/*!\brief Конструктор по умолчанию */
Crc();
/*!\brief Функция расчета контрольной суммы блока данных
* \return рассчитанная контрольная сумма.
* \param[in] data указатель на начало блока данных.
* \param[in] size размер блока в байтах.
*/
unsigned long calc( char *data, short size );
/*!\brief Функция расчета контрольной суммы по частям
* \return рассчитанная контрольная сумма.
* \param[in] data указатель на начало текущей части данных
* \param[in] size размер части данных
* \param[in] firstPart признак первой части данных
*/
unsigned long calcPartial( char *data, short size, bool firstPart );
/*!\brief Функция получения рассчитанной контрольной суммы
* \return рассчитанная контрольная сумма.
*/
unsigned long get() { return widmask() & crc; }
};
template <short width, unsigned long poly, unsigned long init, bool refin, bool refout, unsigned long xorout>
Crc<width, poly, init, refin, refout, xorout>::Crc() : /*model(),*/ crc(init)
{
// инициализация таблицы
unsigned long topbit = 1L << ( width - 1 );
unsigned long inbyte;
for( int i = 0; i < 256; i++ )
{
inbyte = refin ? reflect( i, 8 ) : i;
inbyte = inbyte << ( width - 8 );
for( int j = 0; j < 8; j++ )
inbyte = ( inbyte & topbit ) != 0 ? ( inbyte << 1 ) ^ poly : inbyte << 1;
CRCTable[i] = ( refin ? reflect(inbyte, width) : inbyte ) & widmask();
}
}
template <short width, unsigned long poly, unsigned long init, bool refin, bool refout, unsigned long xorout>
unsigned long Crc<width, poly, init, refin, refout, xorout>::reflect( unsigned long value, short numBits )
{
unsigned long t = value;
for( int i = 0; i < numBits; i++ )
{
if( t & 1L ) value |= 1L << ( (numBits-1) - i );
else value &= ~( 1L << ( (numBits-1) - i ) );
}
return value;
}
template <short width, unsigned long poly, unsigned long init, bool refin, bool refout, unsigned long xorout>
unsigned long Crc<width, poly, init, refin, refout, xorout>::calc( char *data, short size )
{
crc = init;
while( size-- )
crc = CRCTable[(( crc >> (width - 8) ) ^ *data++ ) & 0xFF] ^ ( crc << 8 );
return widmask() & ( crc ^ xorout );
}
template <short width, unsigned long poly, unsigned long init, bool refin, bool refout, unsigned long xorout>
unsigned long Crc<width, poly, init, refin, refout, xorout>::calcPartial( char *data, short size, bool firstPart )
{
if( firstPart ) crc = init;
while( size-- )
crc = CRCTable[(( crc >> (width - 8) ) ^ *data++ ) & 0xFF] ^ ( crc << 8 );
return widmask() & ( crc ^ xorout );
}
template <short width, unsigned long poly, unsigned long init, bool refin, bool refout, unsigned long xorout>
unsigned long Crc<width, poly, init, refin, refout, xorout>::CRCTable[256];
#endif /* CCRC_H_ */