Intermediate commit

This commit is contained in:
John Wellbelove 2021-03-24 09:24:45 +00:00
parent c75e7afe68
commit 23bf71d06a
29 changed files with 9259 additions and 0 deletions

View File

@ -472,6 +472,9 @@ namespace etl
return second ^ ((second ^ first) & MASK);
}
template <typename T, T Value>
struct reverse_bits_const;
#if ETL_8BIT_SUPPORT
//***************************************************************************
/// Reverse 8 bits.
@ -486,10 +489,39 @@ namespace etl
return value;
}
//***********************************
inline ETL_CONSTEXPR14 int8_t reverse_bits(int8_t value)
{
return int8_t(reverse_bits(uint8_t(value)));
}
//***********************************
template <uint8_t Value>
struct reverse_bits_const<uint8_t, Value>
{
private:
static ETL_CONSTANT uint8_t value1 = uint8_t(((Value & 0xAA) >> 1) | ((Value & 0x55) << 1));
static ETL_CONSTANT uint8_t value2 = uint8_t(((value1 & 0xCC) >> 2) | ((value1 & 0x33) << 2));
public:
static ETL_CONSTANT uint8_t value = uint8_t((value2 >> 4) | (value2 << 4));
};
//***********************************
template <int8_t Value>
struct reverse_bits_const<int8_t, Value>
{
private:
static ETL_CONSTANT int8_t value1 = int8_t(((Value & 0xAA) >> 1) | ((Value & 0x55) << 1));
static ETL_CONSTANT int8_t value2 = int8_t(((value1 & 0xCC) >> 2) | ((value1 & 0x33) << 2));
public:
static ETL_CONSTANT int8_t value = int8_t((value2 >> 4) | (value2 << 4));
};
#endif
//***************************************************************************
@ -506,11 +538,42 @@ namespace etl
return value;
}
//***********************************
inline ETL_CONSTEXPR14 int16_t reverse_bits(int16_t value)
{
return int16_t(reverse_bits(uint16_t(value)));
}
//***********************************
template <uint16_t Value>
struct reverse_bits_const<uint16_t, Value>
{
private:
static ETL_CONSTANT uint16_t value1 = uint16_t(((Value & 0xAAAA) >> 1) | ((Value & 0x5555) << 1));
static ETL_CONSTANT uint16_t value2 = uint16_t(((value1 & 0xCCCC) >> 2) | ((value1 & 0x3333) << 2));
static ETL_CONSTANT uint16_t value3 = uint16_t(((value2 & 0xF0F0) >> 4) | ((value2 & 0x0F0F) << 4));
public:
static ETL_CONSTANT uint16_t value = uint16_t((value3 >> 8) | (value3 << 8));
};
//***********************************
template <int16_t Value>
struct reverse_bits_const<int16_t, Value>
{
private:
static ETL_CONSTANT int16_t value1 = int16_t(((Value & 0xAAAA) >> 1) | ((Value & 0x5555) << 1));
static ETL_CONSTANT int16_t value2 = int16_t(((value1 & 0xCCCC) >> 2) | ((value1 & 0x3333) << 2));
static ETL_CONSTANT int16_t value3 = int16_t(((value2 & 0xF0F0) >> 4) | ((value2 & 0x0F0F) << 4));
public:
static ETL_CONSTANT int16_t value = int16_t((value3 >> 8) | (value3 << 8));
};
//***************************************************************************
/// Reverse 32 bits.
///\ingroup binary
@ -526,11 +589,44 @@ namespace etl
return value;
}
//***********************************
inline ETL_CONSTEXPR14 int32_t reverse_bits(int32_t value)
{
return int32_t(reverse_bits(uint32_t(value)));
}
//***********************************
template <uint32_t Value>
struct reverse_bits_const<uint32_t, Value>
{
private:
static ETL_CONSTANT uint32_t value1 = uint32_t(((Value & 0xAAAAAAAA) >> 1) | ((Value & 0x55555555) << 1));
static ETL_CONSTANT uint32_t value2 = uint32_t(((value1 & 0xCCCCCCCC) >> 2) | ((value1 & 0x33333333) << 2));
static ETL_CONSTANT uint32_t value3 = uint32_t(((value2 & 0xF0F0F0F0) >> 4) | ((value2 & 0x0F0F0F0F) << 4));
static ETL_CONSTANT uint32_t value4 = uint32_t(((value3 & 0xFF00FF00) >> 8) | ((value3 & 0x00FF00FF) << 8));
public:
static ETL_CONSTANT uint32_t value = uint32_t((value4 >> 16) | (value4 << 16));
};
//***********************************
template <int32_t Value>
struct reverse_bits_const<int32_t, Value>
{
private:
static ETL_CONSTANT int32_t value1 = int32_t(((Value & 0xAAAAAAAA) >> 1) | ((Value & 0x55555555) << 1));
static ETL_CONSTANT int32_t value2 = int32_t(((value1 & 0xCCCCCCCC) >> 2) | ((value1 & 0x33333333) << 2));
static ETL_CONSTANT int32_t value3 = int32_t(((value2 & 0xF0F0F0F0) >> 4) | ((value2 & 0x0F0F0F0F) << 4));
static ETL_CONSTANT int32_t value4 = int32_t(((value3 & 0xFF00FF00) >> 8) | ((value3 & 0x00FF00FF) << 8));
public:
static ETL_CONSTANT int32_t value = int32_t((value4 >> 16) | (value4 << 16));
};
#if ETL_USING_64BIT_TYPES
//***************************************************************************
/// Reverse 64 bits.
@ -548,10 +644,45 @@ namespace etl
return value;
}
//***********************************
inline ETL_CONSTEXPR14 int64_t reverse_bits(int64_t value)
{
return int64_t(reverse_bits(uint64_t(value)));
}
//***********************************
template <uint64_t Value>
struct reverse_bits_const<uint64_t, Value>
{
private:
static ETL_CONSTANT uint64_t value1 = uint64_t(((Value & 0xAAAAAAAAAAAAAAAA) >> 1) | ((Value & 0x5555555555555555) << 1));
static ETL_CONSTANT uint64_t value2 = uint64_t(((value1 & 0xCCCCCCCCCCCCCCCC) >> 2) | ((value1 & 0x3333333333333333) << 2));
static ETL_CONSTANT uint64_t value3 = uint64_t(((value2 & 0xF0F0F0F0F0F0F0F0) >> 4) | ((value2 & 0x0F0F0F0F0F0F0F0F) << 4));
static ETL_CONSTANT uint64_t value4 = uint64_t(((value3 & 0xFF00FF00FF00FF00) >> 8) | ((value3 & 0x00FF00FF00FF00FF) << 8));
static ETL_CONSTANT uint64_t value5 = uint64_t(((value4 & 0xFFFF0000FFFF0000) >> 16) | ((value4 & 0x0000FFFF0000FFFF) << 16));
public:
static ETL_CONSTANT uint64_t value = uint64_t((value5 >> 32) | (value5 << 32));
};
//***********************************
template <int64_t Value>
struct reverse_bits_const<int64_t, Value>
{
private:
static ETL_CONSTANT int64_t value1 = int64_t(((Value & 0xAAAAAAAAAAAAAAAA) >> 1) | ((Value & 0x5555555555555555) << 1));
static ETL_CONSTANT int64_t value2 = int64_t(((value1 & 0xCCCCCCCCCCCCCCCC) >> 2) | ((value1 & 0x3333333333333333) << 2));
static ETL_CONSTANT int64_t value3 = int64_t(((value2 & 0xF0F0F0F0F0F0F0F0) >> 4) | ((value2 & 0x0F0F0F0F0F0F0F0F) << 4));
static ETL_CONSTANT int64_t value4 = int64_t(((value3 & 0xFF00FF00FF00FF00) >> 8) | ((value3 & 0x00FF00FF00FF00FF) << 8));
static ETL_CONSTANT int64_t value5 = int64_t(((value4 & 0xFFFF0000FFFF0000) >> 16) | ((value4 & 0x0000FFFF0000FFFF) << 16));
public:
static ETL_CONSTANT int64_t value = int64_t((value5 >> 32) | (value5 << 32));
};
#endif
//***************************************************************************

View File

@ -0,0 +1,82 @@
///\file
/******************************************************************************
The MIT License(MIT)
Embedded Template Library.
https://github.com/ETLCPP/etl
https://www.etlcpp.com
Copyright(c) 2021 jwellbelove
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files(the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and / or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions :
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
******************************************************************************/
#ifndef ETL_CRC8_CCITT_EXP_INCLUDED
#define ETL_CRC8_CCITT_EXP_INCLUDED
#include "../platform.h"
#include "crc_implementation.h"
#include "crc_parameters.h"
namespace etl
{
namespace crc
{
#if ETL_CPP11_SUPPORTED
template <size_t Table_Size>
using crc8_ccitt_t = etl::private_crc::crc_type<etl::private_crc::crc8_ccitt_parameters, Table_Size>;
#else
template <size_t Table_Size>
class crc8_ccitt_t : public etl::private_crc::crc_type<etl::private_crc::crc8_ccitt_parameters, Table_Size>
{
public:
ETL_STATIC_ASSERT((Table_Size == 4U) || (Table_Size == 16U) || (Table_Size == 256U), "Table size must be 4, 16 or 256");
//*************************************************************************
/// Default constructor.
//*************************************************************************
crc8_ccitt_t()
{
this->reset();
}
//*************************************************************************
/// Constructor from range.
/// \param begin Start of the range.
/// \param end End of the range.
//*************************************************************************
template<typename TIterator>
crc8_ccitt_t(TIterator begin, const TIterator end)
{
this->reset();
this->add(begin, end);
}
};
#endif
typedef crc8_ccitt_t<256U> crc8_ccitt_t256;
typedef crc8_ccitt_t<16U> crc8_ccitt_t16;
typedef crc8_ccitt_t<4U> crc8_ccitt_t4;
typedef crc8_ccitt_t256 crc8_ccitt;
}
}
#endif

View File

@ -0,0 +1,82 @@
///\file
/******************************************************************************
The MIT License(MIT)
Embedded Template Library.
https://github.com/ETLCPP/etl
https://www.etlcpp.com
Copyright(c) 2021 jwellbelove
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files(the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and / or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions :
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
******************************************************************************/
#ifndef ETL_CRC16_EX_INCLUDED
#define ETL_CRC16_EX_INCLUDED
#include "../platform.h"
#include "crc_implementation.h"
#if defined(ETL_COMPILER_KEIL)
#pragma diag_suppress 1300
#endif
///\defgroup crc16 16 bit CRC calculation
///\ingroup crc
namespace etl
{
namespace crc
{
template <size_t Table_Size>
class crc16_t : public etl::private_crc::crc_type<uint16_t, 0x8005U, 0x0000U, 0x0000U, true, Table_Size>
{
public:
ETL_STATIC_ASSERT((Table_Size == 4U) || (Table_Size == 16U) || (Table_Size == 256U), "Table size must be 4, 16 or 256");
//*************************************************************************
/// Default constructor.
//*************************************************************************
crc16_t()
{
this->reset();
}
//*************************************************************************
/// Constructor from range.
/// \param begin Start of the range.
/// \param end End of the range.
//*************************************************************************
template<typename TIterator>
crc16_t(TIterator begin, const TIterator end)
{
this->reset();
this->add(begin, end);
}
};
typedef etl::crc::crc16_t<256U> crc16_t256;
typedef etl::crc::crc16_t<16U> crc16_t16;
typedef etl::crc::crc16_t<4U> crc16_t4;
typedef crc16_t256 crc16;
}
}
#endif

View File

@ -0,0 +1,82 @@
///\file
/******************************************************************************
The MIT License(MIT)
Embedded Template Library.
https://github.com/ETLCPP/etl
https://www.etlcpp.com
Copyright(c) 2021 jwellbelove
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files(the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and / or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions :
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
******************************************************************************/
#ifndef ETL_CRC16_AUG_CCITT_EX_INCLUDED
#define ETL_CRC16_AUG_CCITT_EX_INCLUDED
#include "../platform.h"
#include "crc_implementation.h"
#if defined(ETL_COMPILER_KEIL)
#pragma diag_suppress 1300
#endif
///\defgroup crc16_aug_ccitt 16 bit CRC calculation
///\ingroup crc
namespace etl
{
namespace crc
{
template <size_t Table_Size>
class crc16_aug_ccitt_t : public etl::private_crc::crc_type<uint16_t, 0x1021U, 0x1D0FU, 0x0000U, false, Table_Size>
{
public:
ETL_STATIC_ASSERT((Table_Size == 4U) || (Table_Size == 16U) || (Table_Size == 256U), "Table size must be 4, 16 or 256");
//*************************************************************************
/// Default constructor.
//*************************************************************************
crc16_aug_ccitt_t()
{
this->reset();
}
//*************************************************************************
/// Constructor from range.
/// \param begin Start of the range.
/// \param end End of the range.
//*************************************************************************
template<typename TIterator>
crc16_aug_ccitt_t(TIterator begin, const TIterator end)
{
this->reset();
this->add(begin, end);
}
};
typedef etl::crc::crc16_aug_ccitt_t<256U> crc16_aug_ccitt_t256;
typedef etl::crc::crc16_aug_ccitt_t<16U> crc16_aug_ccitt_t16;
typedef etl::crc::crc16_aug_ccitt_t<4U> crc16_aug_ccitt_t4;
typedef crc16_aug_ccitt_t256 crc16_aug_ccitt;
}
}
#endif

View File

@ -0,0 +1,82 @@
///\file
/******************************************************************************
The MIT License(MIT)
Embedded Template Library.
https://github.com/ETLCPP/etl
https://www.etlcpp.com
Copyright(c) 2021 jwellbelove
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files(the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and / or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions :
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
******************************************************************************/
#ifndef ETL_CRC16_CCITT_EX_INCLUDED
#define ETL_CRC16_CCITT_EX_INCLUDED
#include "../platform.h"
#include "crc_implementation.h"
#if defined(ETL_COMPILER_KEIL)
#pragma diag_suppress 1300
#endif
///\defgroup crc16_ccitt 16 bit CRC calculation
///\ingroup crc
namespace etl
{
namespace crc
{
template <size_t Table_Size>
class crc16_ccitt_t : public etl::private_crc::crc_type<uint16_t, 0x1021U, 0xFFFFU, 0x0000U, false, Table_Size>
{
public:
ETL_STATIC_ASSERT((Table_Size == 4U) || (Table_Size == 16U) || (Table_Size == 256U), "Table size must be 4, 16 or 256");
//*************************************************************************
/// Default constructor.
//*************************************************************************
crc16_ccitt_t()
{
this->reset();
}
//*************************************************************************
/// Constructor from range.
/// \param begin Start of the range.
/// \param end End of the range.
//*************************************************************************
template<typename TIterator>
crc16_ccitt_t(TIterator begin, const TIterator end)
{
this->reset();
this->add(begin, end);
}
};
typedef etl::crc::crc16_ccitt_t<256U> crc16_ccitt_t256;
typedef etl::crc::crc16_ccitt_t<16U> crc16_ccitt_t16;
typedef etl::crc::crc16_ccitt_t<4U> crc16_ccitt_t4;
typedef crc16_ccitt_t256 crc16_ccitt;
}
}
#endif

View File

@ -0,0 +1,82 @@
///\file
/******************************************************************************
The MIT License(MIT)
Embedded Template Library.
https://github.com/ETLCPP/etl
https://www.etlcpp.com
Copyright(c) 2021 jwellbelove
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files(the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and / or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions :
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
******************************************************************************/
#ifndef ETL_CRC16_GENIBUS_EX_INCLUDED
#define ETL_CRC16_GENIBUS_EX_INCLUDED
#include "../platform.h"
#include "crc_implementation.h"
#if defined(ETL_COMPILER_KEIL)
#pragma diag_suppress 1300
#endif
///\defgroup crc16_genibus 16 bit CRC calculation
///\ingroup crc
namespace etl
{
namespace crc
{
template <size_t Table_Size>
class crc16_genibus_t : public etl::private_crc::crc_type<uint16_t, 0x1021U, 0xFFFFU, 0xFFFFU, false, Table_Size>
{
public:
ETL_STATIC_ASSERT((Table_Size == 4U) || (Table_Size == 16U) || (Table_Size == 256U), "Table size must be 4, 16 or 256");
//*************************************************************************
/// Default constructor.
//*************************************************************************
crc16_genibus_t()
{
this->reset();
}
//*************************************************************************
/// Constructor from range.
/// \param begin Start of the range.
/// \param end End of the range.
//*************************************************************************
template<typename TIterator>
crc16_genibus_t(TIterator begin, const TIterator end)
{
this->reset();
this->add(begin, end);
}
};
typedef etl::crc::crc16_genibus_t<256U> crc16_genibus_t256;
typedef etl::crc::crc16_genibus_t<16U> crc16_genibus_t16;
typedef etl::crc::crc16_genibus_t<4U> crc16_genibus_t4;
typedef crc16_genibus_t256 crc16_genibus;
}
}
#endif

View File

@ -0,0 +1,82 @@
///\file
/******************************************************************************
The MIT License(MIT)
Embedded Template Library.
https://github.com/ETLCPP/etl
https://www.etlcpp.com
Copyright(c) 2021 jwellbelove
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files(the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and / or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions :
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
******************************************************************************/
#ifndef ETL_CRC16_KERMIT_EX_INCLUDED
#define ETL_CRC16_KERMIT_EX_INCLUDED
#include "../platform.h"
#include "crc_implementation.h"
#if defined(ETL_COMPILER_KEIL)
#pragma diag_suppress 1300
#endif
///\defgroup crc16_kermit 16 bit CRC calculation
///\ingroup crc
namespace etl
{
namespace crc
{
template <size_t Table_Size>
class crc16_kermit_t : public etl::private_crc::crc_type<uint16_t, 0x1021U,0x0000U, 0x0000U, true, Table_Size>
{
public:
ETL_STATIC_ASSERT((Table_Size == 4U) || (Table_Size == 16U) || (Table_Size == 256U), "Table size must be 4, 16 or 256");
//*************************************************************************
/// Default constructor.
//*************************************************************************
crc16_kermit_t()
{
this->reset();
}
//*************************************************************************
/// Constructor from range.
/// \param begin Start of the range.
/// \param end End of the range.
//*************************************************************************
template<typename TIterator>
crc16_kermit_t(TIterator begin, const TIterator end)
{
this->reset();
this->add(begin, end);
}
};
typedef etl::crc::crc16_kermit_t<256U> crc16_kermit_t256;
typedef etl::crc::crc16_kermit_t<16U> crc16_kermit_t16;
typedef etl::crc::crc16_kermit_t<4U> crc16_kermit_t4;
typedef crc16_kermit_t256 crc16_kermit;
}
}
#endif

View File

@ -0,0 +1,82 @@
///\file
/******************************************************************************
The MIT License(MIT)
Embedded Template Library.
https://github.com/ETLCPP/etl
https://www.etlcpp.com
Copyright(c) 2021 jwellbelove
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files(the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and / or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions :
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
******************************************************************************/
#ifndef ETL_CRC16_MODBUS_EX_INCLUDED
#define ETL_CRC16_MODBUS_EX_INCLUDED
#include "../platform.h"
#include "crc_implementation.h"
#if defined(ETL_COMPILER_KEIL)
#pragma diag_suppress 1300
#endif
///\defgroup crc16_modbus 16 bit CRC calculation
///\ingroup crc
namespace etl
{
namespace crc
{
template <size_t Table_Size>
class crc16_modbus_t : public etl::private_crc::crc_type<uint16_t, 0x8005U, 0xFFFFU, 0x0000U, true, Table_Size>
{
public:
ETL_STATIC_ASSERT((Table_Size == 4U) || (Table_Size == 16U) || (Table_Size == 256U), "Table size must be 4, 16 or 256");
//*************************************************************************
/// Default constructor.
//*************************************************************************
crc16_modbus_t()
{
this->reset();
}
//*************************************************************************
/// Constructor from range.
/// \param begin Start of the range.
/// \param end End of the range.
//*************************************************************************
template<typename TIterator>
crc16_modbus_t(TIterator begin, const TIterator end)
{
this->reset();
this->add(begin, end);
}
};
typedef etl::crc::crc16_modbus_t<256U> crc16_modbus_t256;
typedef etl::crc::crc16_modbus_t<16U> crc16_modbus_t16;
typedef etl::crc::crc16_modbus_t<4U> crc16_modbus_t4;
typedef crc16_modbus_t256 crc16_modbus;
}
}
#endif

View File

@ -0,0 +1,82 @@
///\file
/******************************************************************************
The MIT License(MIT)
Embedded Template Library.
https://github.com/ETLCPP/etl
https://www.etlcpp.com
Copyright(c) 2021 jwellbelove
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files(the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and / or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions :
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
******************************************************************************/
#ifndef ETL_CRC16_USB_EX_INCLUDED
#define ETL_CRC16_USB_EX_INCLUDED
#include "../platform.h"
#include "crc_implementation.h"
#if defined(ETL_COMPILER_KEIL)
#pragma diag_suppress 1300
#endif
///\defgroup crc16_usb 16 bit CRC calculation
///\ingroup crc
namespace etl
{
namespace crc
{
template <size_t Table_Size>
class crc16_usb_t : public etl::private_crc::crc_type<uint16_t, 0x8005U, 0xFFFFU, 0xFFFFU, true, Table_Size>
{
public:
ETL_STATIC_ASSERT((Table_Size == 4U) || (Table_Size == 16U) || (Table_Size == 256U), "Table size must be 4, 16 or 256");
//*************************************************************************
/// Default constructor.
//*************************************************************************
crc16_usb_t()
{
this->reset();
}
//*************************************************************************
/// Constructor from range.
/// \param begin Start of the range.
/// \param end End of the range.
//*************************************************************************
template<typename TIterator>
crc16_usb_t(TIterator begin, const TIterator end)
{
this->reset();
this->add(begin, end);
}
};
typedef etl::crc::crc16_usb_t<256U> crc16_usb_t256;
typedef etl::crc::crc16_usb_t<16U> crc16_usb_t16;
typedef etl::crc::crc16_usb_t<4U> crc16_usb_t4;
typedef crc16_usb_t256 crc16_usb;
}
}
#endif

View File

@ -0,0 +1,82 @@
///\file
/******************************************************************************
The MIT License(MIT)
Embedded Template Library.
https://github.com/ETLCPP/etl
https://www.etlcpp.com
Copyright(c) 2021 jwellbelove
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files(the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and / or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions :
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
******************************************************************************/
#ifndef ETL_CRC16_X25_EX_INCLUDED
#define ETL_CRC16_X25_EX_INCLUDED
#include "../platform.h"
#include "crc_implementation.h"
#if defined(ETL_COMPILER_KEIL)
#pragma diag_suppress 1300
#endif
///\defgroup crc16_x25 16 bit CRC calculation
///\ingroup crc
namespace etl
{
namespace crc
{
template <size_t Table_Size>
class crc16_x25_t : public etl::private_crc::crc_type<uint16_t, 0x1021, 0xFFFFU, 0xFFFFU, true, Table_Size>
{
public:
ETL_STATIC_ASSERT((Table_Size == 4U) || (Table_Size == 16U) || (Table_Size == 256U), "Table size must be 4, 16 or 256");
//*************************************************************************
/// Default constructor.
//*************************************************************************
crc16_x25_t()
{
this->reset();
}
//*************************************************************************
/// Constructor from range.
/// \param begin Start of the range.
/// \param end End of the range.
//*************************************************************************
template<typename TIterator>
crc16_x25_t(TIterator begin, const TIterator end)
{
this->reset();
this->add(begin, end);
}
};
typedef etl::crc::crc16_x25_t<256U> crc16_x25_t256;
typedef etl::crc::crc16_x25_t<16U> crc16_x25_t16;
typedef etl::crc::crc16_x25_t<4U> crc16_x25_t4;
typedef crc16_x25_t256 crc16_x25;
}
}
#endif

View File

@ -0,0 +1,87 @@
///\file
/******************************************************************************
The MIT License(MIT)
Embedded Template Library.
https://github.com/ETLCPP/etl
https://www.etlcpp.com
Copyright(c) 2021 jwellbelove
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files(the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and / or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions :
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
******************************************************************************/
#ifndef ETL_CRC16_XMODEM_EX_INCLUDED
#define ETL_CRC16_XMODEM_EX_INCLUDED
#include "../platform.h"
#include "crc_implementation.h"
#if defined(ETL_COMPILER_KEIL)
#pragma diag_suppress 1300
#endif
///\defgroup crc16_xmodem 16 bit CRC calculation
///\ingroup crc
namespace etl
{
namespace crc
{
#if ETL_CPP11_SUPPORTED
template <size_t Table_Size>
using crc16_xmodem_t = etl::private_crc::crc_type<uint16_t, 0x1021, 0x0000U, 0x0000U, false, Table_Size>;
#else
template <size_t Table_Size>
class crc16_xmodem_t : public etl::private_crc::crc_type<uint16_t, 0x1021, 0x0000U, 0x0000U, false, Table_Size>
{
public:
ETL_STATIC_ASSERT((Table_Size == 4U) || (Table_Size == 16U) || (Table_Size == 256U), "Table size must be 4, 16 or 256");
//*************************************************************************
/// Default constructor.
//*************************************************************************
crc16_xmodem_t()
{
this->reset();
}
//*************************************************************************
/// Constructor from range.
/// \param begin Start of the range.
/// \param end End of the range.
//*************************************************************************
template<typename TIterator>
crc16_xmodem_t(TIterator begin, const TIterator end)
{
this->reset();
this->add(begin, end);
}
};
#endif
typedef etl::crc::crc16_xmodem_t<256U> crc16_xmodem_t256;
typedef etl::crc::crc16_xmodem_t<16U> crc16_xmodem_t16;
typedef etl::crc::crc16_xmodem_t<4U> crc16_xmodem_t4;
typedef crc16_xmodem_t256 crc16_xmodem;
}
}
#endif

View File

@ -0,0 +1,82 @@
///\file
/******************************************************************************
The MIT License(MIT)
Embedded Template Library.
https://github.com/ETLCPP/etl
https://www.etlcpp.com
Copyright(c) 2021 jwellbelove
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files(the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and / or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions :
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
******************************************************************************/
#ifndef ETL_CRC32_EX_INCLUDED
#define ETL_CRC32_EX_INCLUDED
#include "../platform.h"
#include "crc_implementation.h"
#if defined(ETL_COMPILER_KEIL)
#pragma diag_suppress 1300
#endif
///\defgroup crc32 32 bit CRC calculation
///\ingroup crc
namespace etl
{
namespace crc
{
template <size_t Table_Size>
class crc32_t : public etl::private_crc::crc_type<uint32_t, 0X04C11DB7U, 0xFFFFFFFFU, 0xFFFFFFFFU, true, Table_Size>
{
public:
ETL_STATIC_ASSERT((Table_Size == 4U) || (Table_Size == 16U) || (Table_Size == 256U), "Table size must be 4, 16 or 256");
//*************************************************************************
/// Default constructor.
//*************************************************************************
crc32_t()
{
this->reset();
}
//*************************************************************************
/// Constructor from range.
/// \param begin Start of the range.
/// \param end End of the range.
//*************************************************************************
template<typename TIterator>
crc32_t(TIterator begin, const TIterator end)
{
this->reset();
this->add(begin, end);
}
};
typedef etl::crc::crc32_t<256U> crc32_t256;
typedef etl::crc::crc32_t<16U> crc32_t16;
typedef etl::crc::crc32_t<4U> crc32_t4;
typedef crc32_t256 crc32;
}
}
#endif

View File

@ -0,0 +1,82 @@
///\file
/******************************************************************************
The MIT License(MIT)
Embedded Template Library.
https://github.com/ETLCPP/etl
https://www.etlcpp.com
Copyright(c) 2021 jwellbelove
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files(the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and / or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions :
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
******************************************************************************/
#ifndef ETL_CRC64_ECMA_EX_INCLUDED
#define ETL_CRC64_ECMA_EX_INCLUDED
#include "../platform.h"
#include "crc_implementation.h"
#if defined(ETL_COMPILER_KEIL)
#pragma diag_suppress 1300
#endif
///\defgroup crc64_ecma 64 bit ECMA CRC calculation
///\ingroup crc
namespace etl
{
namespace crc
{
template <size_t Table_Size>
class crc64_ecma_t : public etl::private_crc::crc_type<uint64_t, 0x42F0E1EBA9EA3693U, 0x0000000000000000U, 0x0000000000000000U, false, Table_Size>
{
public:
ETL_STATIC_ASSERT((Table_Size == 4U) || (Table_Size == 16U) || (Table_Size == 256U), "Table size must be 4, 16 or 256");
//*************************************************************************
/// Default constructor.
//*************************************************************************
crc64_ecma_t()
{
this->reset();
}
//*************************************************************************
/// Constructor from range.
/// \param begin Start of the range.
/// \param end End of the range.
//*************************************************************************
template<typename TIterator>
crc64_ecma_t(TIterator begin, const TIterator end)
{
this->reset();
this->add(begin, end);
}
};
typedef etl::crc::crc64_ecma_t<256U> crc64_ecma_t256;
typedef etl::crc::crc64_ecma_t<16U> crc64_ecma_t16;
typedef etl::crc::crc64_ecma_t<4U> crc64_ecma_t4;
typedef crc64_ecma_t256 crc64_ecma;
}
}
#endif

View File

@ -0,0 +1,83 @@
///\file
/******************************************************************************
The MIT License(MIT)
Embedded Template Library.
https://github.com/ETLCPP/etl
https://www.etlcpp.com
Copyright(c) 2021 jwellbelove
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files(the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and / or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions :
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
******************************************************************************/
#ifndef ETL_CRC8_CCITT_EXP_INCLUDED
#define ETL_CRC8_CCITT_EXP_INCLUDED
#include "../platform.h"
#include "crc_implementation.h"
#if defined(ETL_COMPILER_KEIL)
#pragma diag_suppress 1300
#endif
///\defgroup crc8_ccitt 8 bit CRC calculation
///\ingroup crc
namespace etl
{
namespace crc
{
template <size_t Table_Size>
class crc8_ccitt_t : public etl::private_crc::crc_type<uint8_t, 0x07U, 0x00U, 0x00U, false, Table_Size>
{
public:
ETL_STATIC_ASSERT((Table_Size == 4U) || (Table_Size == 16U) || (Table_Size == 256U), "Table size must be 4, 16 or 256");
//*************************************************************************
/// Default constructor.
//*************************************************************************
crc8_ccitt_t()
{
this->reset();
}
//*************************************************************************
/// Constructor from range.
/// \param begin Start of the range.
/// \param end End of the range.
//*************************************************************************
template<typename TIterator>
crc8_ccitt_t(TIterator begin, const TIterator end)
{
this->reset();
this->add(begin, end);
}
};
typedef etl::crc::crc8_ccitt_t<256U> crc8_ccitt_t256;
typedef etl::crc::crc8_ccitt_t<16U> crc8_ccitt_t16;
typedef etl::crc::crc8_ccitt_t<4U> crc8_ccitt_t4;
typedef crc8_ccitt_t256 crc8_ccitt;
}
}
#endif

View File

@ -0,0 +1,83 @@
///\file
/******************************************************************************
The MIT License(MIT)
Embedded Template Library.
https://github.com/ETLCPP/etl
https://www.etlcpp.com
Copyright(c) 2021 jwellbelove
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files(the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and / or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions :
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
******************************************************************************/
#ifndef ETL_CRC8_ROHC_EXP_INCLUDED
#define ETL_CRC8_ROHC_EXP_INCLUDED
#include "../platform.h"
#include "crc_implementation.h"
#if defined(ETL_COMPILER_KEIL)
#pragma diag_suppress 1300
#endif
///\defgroup rohc 8 bit CRC calculation
///\ingroup crc
namespace etl
{
namespace crc
{
template <size_t Table_Size>
class crc8_rohc_t : public etl::private_crc::crc_type<uint8_t, 0x07U, 0xFFU, 0x00U, true, Table_Size>
{
public:
ETL_STATIC_ASSERT((Table_Size == 4U) || (Table_Size == 16U) || (Table_Size == 256U), "Table size must be 4, 16 or 256");
//*************************************************************************
/// Default constructor.
//*************************************************************************
crc8_rohc_t()
{
this->reset();
}
//*************************************************************************
/// Constructor from range.
/// \param begin Start of the range.
/// \param end End of the range.
//*************************************************************************
template<typename TIterator>
crc8_rohc_t(TIterator begin, const TIterator end)
{
this->reset();
this->add(begin, end);
}
};
typedef etl::crc::crc8_rohc_t<256U> crc8_rohc_t256;
typedef etl::crc::crc8_rohc_t<16U> crc8_rohc_t16;
typedef etl::crc::crc8_rohc_t<4U> crc8_rohc_t4;
typedef crc8_rohc_t256 crc8_rohc;
}
}
#endif

View File

@ -0,0 +1,234 @@
#pragma once
#include "../platform.h"
#include "../frame_check_sequence.h"
#include "../binary.h"
#include "stdint.h"
namespace etl
{
namespace crc
{
//*****************************************************************************
//
//*****************************************************************************
template <uint8_t Polynomial, uint8_t Initial, uint8_t Xor_Out, bool Reflect>
struct crc8_policy_table16;
//*****************************************************************************
// Specialisation for Reflect = false
//*****************************************************************************
template <uint8_t Polynomial, uint8_t Initial, uint8_t Xor_Out>
struct crc8_policy_table16<Polynomial, Initial, Xor_Out, false>
{
static ETL_CONSTANT uint8_t Mask = 0x0FU;
static ETL_CONSTANT uint8_t Chunk_Size = 4U;
typedef uint8_t value_type;
//*****************************************************************************
template <uint8_t Polynomial, uint8_t Entry>
class entry
{
public:
static ETL_CONSTANT size_t Accumulator_Bits = etl::integral_limits<uint8_t>::bits;
static ETL_CONSTANT bool Do_Poly = (Entry & (uint8_t(1U) << (Accumulator_Bits - 1U))) != 0U;
static ETL_CONSTANT uint8_t value = uint8_t(Do_Poly ? (Entry << 1U) ^ Polynomial : (Entry << 1U));
};
//*************************************************************************
template <size_t Index, uint8_t Polynomial>
class table_entry
{
public:
static ETL_CONSTANT size_t Accumulator_Bits = entry<Polynomial, Index>::Accumulator_Bits;
static ETL_CONSTANT size_t Shift_Bits = size_t(Accumulator_Bits - Chunk_Size);
static ETL_CONSTANT uint8_t Entry = uint8_t(Index << Shift_Bits);
static ETL_CONSTANT uint8_t value = entry<Polynomial,
entry<Polynomial,
entry<Polynomial,
entry<Polynomial, Entry>::value>::value>::value>::value;
};
//*************************************************************************
ETL_CONSTEXPR uint8_t initial() const
{
return Initial;
}
//*************************************************************************
uint8_t update_chunk(uint8_t crc, uint8_t value, const uint8_t* table) const
{
// Extract the most significant nibble of the crc and xor with the value nibble.
uint8_t index = (crc >> (etl::integral_limits<uint8_t>::bits - Chunk_Size)) ^ value;
crc <<= Chunk_Size;
crc ^= table[index];
return crc;
}
//*************************************************************************
uint8_t add(uint8_t crc, uint8_t value) const
{
static ETL_CONSTANT uint8_t table[16] =
{
table_entry<0U, Polynomial>::value,
table_entry<1U, Polynomial>::value,
table_entry<2U, Polynomial>::value,
table_entry<3U, Polynomial>::value,
table_entry<4U, Polynomial>::value,
table_entry<5U, Polynomial>::value,
table_entry<6U, Polynomial>::value,
table_entry<7U, Polynomial>::value,
table_entry<8U, Polynomial>::value,
table_entry<9U, Polynomial>::value,
table_entry<10U, Polynomial>::value,
table_entry<11U, Polynomial>::value,
table_entry<12U, Polynomial>::value,
table_entry<13U, Polynomial>::value,
table_entry<14U, Polynomial>::value,
table_entry<15U, Polynomial>::value
};
crc = update_chunk(crc, (value >> Chunk_Size) & Mask, table);
crc = update_chunk(crc, value & Mask, table);
return crc;
}
//*************************************************************************
uint8_t final(uint8_t crc) const
{
return crc ^ Xor_Out;
}
};
//*****************************************************************************
// Specialisation for Reflect = true
//*****************************************************************************
template <uint8_t Polynomial, uint8_t Initial, uint8_t Xor_Out>
struct crc8_policy_table16<Polynomial, Initial, Xor_Out, true>
{
static ETL_CONSTANT uint8_t Mask = 0x0FU;
static ETL_CONSTANT uint8_t Chunk_Size = 4U;
typedef uint8_t value_type;
//*****************************************************************************
template <uint8_t Polynomial, uint8_t Entry>
class entry
{
public:
static ETL_CONSTANT size_t Accumulator_Bits = etl::integral_limits<uint8_t>::bits;
static ETL_CONSTANT bool Do_Poly = (Entry & uint8_t(1U)) != 0U;
static ETL_CONSTANT uint8_t value = uint8_t(Do_Poly ? (Entry >> 1U) ^ etl::reverse_bits_const<uint8_t, Polynomial>::value : (Entry >> 1U));
};
//*************************************************************************
template <size_t Index, uint8_t Polynomial>
class table_entry
{
public:
static ETL_CONSTANT size_t Accumulator_Bits = entry<Polynomial,Index>::Accumulator_Bits;
static ETL_CONSTANT size_t Shift_Bits = size_t(Accumulator_Bits - Chunk_Size);
static ETL_CONSTANT uint8_t Entry = uint8_t(Index << Shift_Bits);
static ETL_CONSTANT uint8_t value = entry<Polynomial,
entry<Polynomial,
entry<Polynomial,
entry<Polynomial, Entry>::value>::value>::value>::value;
};
//*************************************************************************
ETL_CONSTEXPR uint8_t initial() const
{
return Initial;
}
//*************************************************************************
uint8_t update_chunk(uint8_t crc, uint8_t value, const uint8_t* const table) const
{
// Extract the most significant nibble of the crc and xor with the value nibble.
uint8_t index = (crc >> (Accumulator_Bits - 4U)) ^ value;
crc <<= Chunk_Size;
crc ^= table[index];
return crc;
}
//*************************************************************************
uint8_t add(uint8_t crc, uint8_t value) const
{
static ETL_CONSTANT uint8_t table[16] =
{
table_entry<0U, Polynomial>::value,
table_entry<1U, Polynomial>::value,
table_entry<2U, Polynomial>::value,
table_entry<3U, Polynomial>::value,
table_entry<4U, Polynomial>::value,
table_entry<5U, Polynomial>::value,
table_entry<6U, Polynomial>::value,
table_entry<7U, Polynomial>::value,
table_entry<8U, Polynomial>::value,
table_entry<9U, Polynomial>::value,
table_entry<10U, Polynomial>::value,
table_entry<11U, Polynomial>::value,
table_entry<12U, Polynomial>::value,
table_entry<13U, Polynomial>::value,
table_entry<14U, Polynomial>::value,
table_entry<15U, Polynomial>::value
};
crc = update_chunk(crc, (value >> Chunk_Size) & Mask, table); // high nibble
crc = update_chunk(crc, value & Mask, table); // low nibble
return crc;
}
//*************************************************************************
uint8_t final(uint8_t crc) const
{
return crc ^ Xor_Out;
}
};
//*****************************************************************************
//
//*****************************************************************************
template <uint8_t Polynomial, uint8_t Initial, uint8_t Xor_In, uint8_t Xor_Out, bool Reflect>
class crc8_table16 : public etl::frame_check_sequence<etl::crc::crc8_policy_table16<Polynomial, Initial, Xor_Out, Reflect> >
{
public:
//*************************************************************************
/// Default constructor.
//*************************************************************************
crc8_table16()
{
this->reset();
}
//*************************************************************************
/// Constructor from range.
/// \param begin Start of the range.
/// \param end End of the range.
//*************************************************************************
template<typename TIterator>
crc8_table16(TIterator begin, const TIterator end)
{
this->reset();
this->add(begin, end);
}
};
}
}

View File

@ -0,0 +1,347 @@
#pragma once
#include "../platform.h"
#include "../frame_check_sequence.h"
#include "../binary.h"
#include "crc_common.h"
#include "stdint.h"
namespace etl
{
namespace crc
{
//*****************************************************************************
//
//*****************************************************************************
template <uint8_t Polynomial, uint8_t Initial, uint8_t Xor_Out, bool Reflect>
struct crc8_policy_table256
{
static ETL_CONSTANT uint8_t Chunk_Mask = etl::private_crc::crc_traits<256U>::Chunk_Mask;
static ETL_CONSTANT uint8_t Chunk_Bits = etl::private_crc::crc_traits<256U>::Chunk_Bits;
typedef uint8_t value_type;
//*************************************************************************
ETL_CONSTEXPR uint8_t initial() const
{
return Initial;
}
//*************************************************************************
static uint8_t update_chunk(uint8_t crc, uint8_t value, const uint8_t* const table)
{
uint8_t t = crc ^ value;
crc = table[t];
return crc;
}
//*************************************************************************
uint8_t add(uint8_t crc, uint8_t value) const
{
static ETL_CONSTANT uint8_t table[256] =
{
etl::private_crc::table_entry<uint8_t, 0U, Polynomial, Reflect, Chunk_Bits>::value,
etl::private_crc::table_entry<uint8_t, 1U, Polynomial, Reflect, Chunk_Bits>::value,
etl::private_crc::table_entry<uint8_t, 2U, Polynomial, Reflect, Chunk_Bits>::value,
etl::private_crc::table_entry<uint8_t, 3U, Polynomial, Reflect, Chunk_Bits>::value,
etl::private_crc::table_entry<uint8_t, 4U, Polynomial, Reflect, Chunk_Bits>::value,
etl::private_crc::table_entry<uint8_t, 5U, Polynomial, Reflect, Chunk_Bits>::value,
etl::private_crc::table_entry<uint8_t, 6U, Polynomial, Reflect, Chunk_Bits>::value,
etl::private_crc::table_entry<uint8_t, 7U, Polynomial, Reflect, Chunk_Bits>::value,
etl::private_crc::table_entry<uint8_t, 8U, Polynomial, Reflect, Chunk_Bits>::value,
etl::private_crc::table_entry<uint8_t, 9U, Polynomial, Reflect, Chunk_Bits>::value,
etl::private_crc::table_entry<uint8_t, 10U, Polynomial, Reflect, Chunk_Bits>::value,
etl::private_crc::table_entry<uint8_t, 11U, Polynomial, Reflect, Chunk_Bits>::value,
etl::private_crc::table_entry<uint8_t, 12U, Polynomial, Reflect, Chunk_Bits>::value,
etl::private_crc::table_entry<uint8_t, 13U, Polynomial, Reflect, Chunk_Bits>::value,
etl::private_crc::table_entry<uint8_t, 14U, Polynomial, Reflect, Chunk_Bits>::value,
etl::private_crc::table_entry<uint8_t, 15U, Polynomial, Reflect, Chunk_Bits>::value,
etl::private_crc::table_entry<uint8_t, 16U, Polynomial, Reflect, Chunk_Bits>::value,
etl::private_crc::table_entry<uint8_t, 17U, Polynomial, Reflect, Chunk_Bits>::value,
etl::private_crc::table_entry<uint8_t, 18U, Polynomial, Reflect, Chunk_Bits>::value,
etl::private_crc::table_entry<uint8_t, 19U, Polynomial, Reflect, Chunk_Bits>::value,
etl::private_crc::table_entry<uint8_t, 20U, Polynomial, Reflect, Chunk_Bits>::value,
etl::private_crc::table_entry<uint8_t, 21U, Polynomial, Reflect, Chunk_Bits>::value,
etl::private_crc::table_entry<uint8_t, 22U, Polynomial, Reflect, Chunk_Bits>::value,
etl::private_crc::table_entry<uint8_t, 23U, Polynomial, Reflect, Chunk_Bits>::value,
etl::private_crc::table_entry<uint8_t, 24U, Polynomial, Reflect, Chunk_Bits>::value,
etl::private_crc::table_entry<uint8_t, 25U, Polynomial, Reflect, Chunk_Bits>::value,
etl::private_crc::table_entry<uint8_t, 26U, Polynomial, Reflect, Chunk_Bits>::value,
etl::private_crc::table_entry<uint8_t, 27U, Polynomial, Reflect, Chunk_Bits>::value,
etl::private_crc::table_entry<uint8_t, 28U, Polynomial, Reflect, Chunk_Bits>::value,
etl::private_crc::table_entry<uint8_t, 29U, Polynomial, Reflect, Chunk_Bits>::value,
etl::private_crc::table_entry<uint8_t, 30U, Polynomial, Reflect, Chunk_Bits>::value,
etl::private_crc::table_entry<uint8_t, 31U, Polynomial, Reflect, Chunk_Bits>::value,
etl::private_crc::table_entry<uint8_t, 32U, Polynomial, Reflect, Chunk_Bits>::value,
etl::private_crc::table_entry<uint8_t, 33U, Polynomial, Reflect, Chunk_Bits>::value,
etl::private_crc::table_entry<uint8_t, 34U, Polynomial, Reflect, Chunk_Bits>::value,
etl::private_crc::table_entry<uint8_t, 35U, Polynomial, Reflect, Chunk_Bits>::value,
etl::private_crc::table_entry<uint8_t, 36U, Polynomial, Reflect, Chunk_Bits>::value,
etl::private_crc::table_entry<uint8_t, 37U, Polynomial, Reflect, Chunk_Bits>::value,
etl::private_crc::table_entry<uint8_t, 38U, Polynomial, Reflect, Chunk_Bits>::value,
etl::private_crc::table_entry<uint8_t, 39U, Polynomial, Reflect, Chunk_Bits>::value,
etl::private_crc::table_entry<uint8_t, 40U, Polynomial, Reflect, Chunk_Bits>::value,
etl::private_crc::table_entry<uint8_t, 41U, Polynomial, Reflect, Chunk_Bits>::value,
etl::private_crc::table_entry<uint8_t, 42U, Polynomial, Reflect, Chunk_Bits>::value,
etl::private_crc::table_entry<uint8_t, 43U, Polynomial, Reflect, Chunk_Bits>::value,
etl::private_crc::table_entry<uint8_t, 44U, Polynomial, Reflect, Chunk_Bits>::value,
etl::private_crc::table_entry<uint8_t, 45U, Polynomial, Reflect, Chunk_Bits>::value,
etl::private_crc::table_entry<uint8_t, 46U, Polynomial, Reflect, Chunk_Bits>::value,
etl::private_crc::table_entry<uint8_t, 47U, Polynomial, Reflect, Chunk_Bits>::value,
etl::private_crc::table_entry<uint8_t, 48U, Polynomial, Reflect, Chunk_Bits>::value,
etl::private_crc::table_entry<uint8_t, 49U, Polynomial, Reflect, Chunk_Bits>::value,
etl::private_crc::table_entry<uint8_t, 50U, Polynomial, Reflect, Chunk_Bits>::value,
etl::private_crc::table_entry<uint8_t, 51U, Polynomial, Reflect, Chunk_Bits>::value,
etl::private_crc::table_entry<uint8_t, 52U, Polynomial, Reflect, Chunk_Bits>::value,
etl::private_crc::table_entry<uint8_t, 53U, Polynomial, Reflect, Chunk_Bits>::value,
etl::private_crc::table_entry<uint8_t, 54U, Polynomial, Reflect, Chunk_Bits>::value,
etl::private_crc::table_entry<uint8_t, 55U, Polynomial, Reflect, Chunk_Bits>::value,
etl::private_crc::table_entry<uint8_t, 56U, Polynomial, Reflect, Chunk_Bits>::value,
etl::private_crc::table_entry<uint8_t, 57U, Polynomial, Reflect, Chunk_Bits>::value,
etl::private_crc::table_entry<uint8_t, 58U, Polynomial, Reflect, Chunk_Bits>::value,
etl::private_crc::table_entry<uint8_t, 59U, Polynomial, Reflect, Chunk_Bits>::value,
etl::private_crc::table_entry<uint8_t, 60U, Polynomial, Reflect, Chunk_Bits>::value,
etl::private_crc::table_entry<uint8_t, 61U, Polynomial, Reflect, Chunk_Bits>::value,
etl::private_crc::table_entry<uint8_t, 62U, Polynomial, Reflect, Chunk_Bits>::value,
etl::private_crc::table_entry<uint8_t, 63U, Polynomial, Reflect, Chunk_Bits>::value,
etl::private_crc::table_entry<uint8_t, 64U, Polynomial, Reflect, Chunk_Bits>::value,
etl::private_crc::table_entry<uint8_t, 65U, Polynomial, Reflect, Chunk_Bits>::value,
etl::private_crc::table_entry<uint8_t, 66U, Polynomial, Reflect, Chunk_Bits>::value,
etl::private_crc::table_entry<uint8_t, 67U, Polynomial, Reflect, Chunk_Bits>::value,
etl::private_crc::table_entry<uint8_t, 68U, Polynomial, Reflect, Chunk_Bits>::value,
etl::private_crc::table_entry<uint8_t, 69U, Polynomial, Reflect, Chunk_Bits>::value,
etl::private_crc::table_entry<uint8_t, 70U, Polynomial, Reflect, Chunk_Bits>::value,
etl::private_crc::table_entry<uint8_t, 71U, Polynomial, Reflect, Chunk_Bits>::value,
etl::private_crc::table_entry<uint8_t, 72U, Polynomial, Reflect, Chunk_Bits>::value,
etl::private_crc::table_entry<uint8_t, 73U, Polynomial, Reflect, Chunk_Bits>::value,
etl::private_crc::table_entry<uint8_t, 74U, Polynomial, Reflect, Chunk_Bits>::value,
etl::private_crc::table_entry<uint8_t, 75U, Polynomial, Reflect, Chunk_Bits>::value,
etl::private_crc::table_entry<uint8_t, 76U, Polynomial, Reflect, Chunk_Bits>::value,
etl::private_crc::table_entry<uint8_t, 77U, Polynomial, Reflect, Chunk_Bits>::value,
etl::private_crc::table_entry<uint8_t, 78U, Polynomial, Reflect, Chunk_Bits>::value,
etl::private_crc::table_entry<uint8_t, 79U, Polynomial, Reflect, Chunk_Bits>::value,
etl::private_crc::table_entry<uint8_t, 80U, Polynomial, Reflect, Chunk_Bits>::value,
etl::private_crc::table_entry<uint8_t, 81U, Polynomial, Reflect, Chunk_Bits>::value,
etl::private_crc::table_entry<uint8_t, 82U, Polynomial, Reflect, Chunk_Bits>::value,
etl::private_crc::table_entry<uint8_t, 83U, Polynomial, Reflect, Chunk_Bits>::value,
etl::private_crc::table_entry<uint8_t, 84U, Polynomial, Reflect, Chunk_Bits>::value,
etl::private_crc::table_entry<uint8_t, 85U, Polynomial, Reflect, Chunk_Bits>::value,
etl::private_crc::table_entry<uint8_t, 86U, Polynomial, Reflect, Chunk_Bits>::value,
etl::private_crc::table_entry<uint8_t, 87U, Polynomial, Reflect, Chunk_Bits>::value,
etl::private_crc::table_entry<uint8_t, 88U, Polynomial, Reflect, Chunk_Bits>::value,
etl::private_crc::table_entry<uint8_t, 89U, Polynomial, Reflect, Chunk_Bits>::value,
etl::private_crc::table_entry<uint8_t, 90U, Polynomial, Reflect, Chunk_Bits>::value,
etl::private_crc::table_entry<uint8_t, 91U, Polynomial, Reflect, Chunk_Bits>::value,
etl::private_crc::table_entry<uint8_t, 92U, Polynomial, Reflect, Chunk_Bits>::value,
etl::private_crc::table_entry<uint8_t, 93U, Polynomial, Reflect, Chunk_Bits>::value,
etl::private_crc::table_entry<uint8_t, 94U, Polynomial, Reflect, Chunk_Bits>::value,
etl::private_crc::table_entry<uint8_t, 95U, Polynomial, Reflect, Chunk_Bits>::value,
etl::private_crc::table_entry<uint8_t, 96U, Polynomial, Reflect, Chunk_Bits>::value,
etl::private_crc::table_entry<uint8_t, 97U, Polynomial, Reflect, Chunk_Bits>::value,
etl::private_crc::table_entry<uint8_t, 98U, Polynomial, Reflect, Chunk_Bits>::value,
etl::private_crc::table_entry<uint8_t, 99U, Polynomial, Reflect, Chunk_Bits>::value,
etl::private_crc::table_entry<uint8_t, 100U, Polynomial, Reflect, Chunk_Bits>::value,
etl::private_crc::table_entry<uint8_t, 101U, Polynomial, Reflect, Chunk_Bits>::value,
etl::private_crc::table_entry<uint8_t, 102U, Polynomial, Reflect, Chunk_Bits>::value,
etl::private_crc::table_entry<uint8_t, 103U, Polynomial, Reflect, Chunk_Bits>::value,
etl::private_crc::table_entry<uint8_t, 104U, Polynomial, Reflect, Chunk_Bits>::value,
etl::private_crc::table_entry<uint8_t, 105U, Polynomial, Reflect, Chunk_Bits>::value,
etl::private_crc::table_entry<uint8_t, 106U, Polynomial, Reflect, Chunk_Bits>::value,
etl::private_crc::table_entry<uint8_t, 107U, Polynomial, Reflect, Chunk_Bits>::value,
etl::private_crc::table_entry<uint8_t, 108U, Polynomial, Reflect, Chunk_Bits>::value,
etl::private_crc::table_entry<uint8_t, 109U, Polynomial, Reflect, Chunk_Bits>::value,
etl::private_crc::table_entry<uint8_t, 110U, Polynomial, Reflect, Chunk_Bits>::value,
etl::private_crc::table_entry<uint8_t, 111U, Polynomial, Reflect, Chunk_Bits>::value,
etl::private_crc::table_entry<uint8_t, 112U, Polynomial, Reflect, Chunk_Bits>::value,
etl::private_crc::table_entry<uint8_t, 113U, Polynomial, Reflect, Chunk_Bits>::value,
etl::private_crc::table_entry<uint8_t, 114U, Polynomial, Reflect, Chunk_Bits>::value,
etl::private_crc::table_entry<uint8_t, 115U, Polynomial, Reflect, Chunk_Bits>::value,
etl::private_crc::table_entry<uint8_t, 116U, Polynomial, Reflect, Chunk_Bits>::value,
etl::private_crc::table_entry<uint8_t, 117U, Polynomial, Reflect, Chunk_Bits>::value,
etl::private_crc::table_entry<uint8_t, 118U, Polynomial, Reflect, Chunk_Bits>::value,
etl::private_crc::table_entry<uint8_t, 119U, Polynomial, Reflect, Chunk_Bits>::value,
etl::private_crc::table_entry<uint8_t, 120U, Polynomial, Reflect, Chunk_Bits>::value,
etl::private_crc::table_entry<uint8_t, 121U, Polynomial, Reflect, Chunk_Bits>::value,
etl::private_crc::table_entry<uint8_t, 122U, Polynomial, Reflect, Chunk_Bits>::value,
etl::private_crc::table_entry<uint8_t, 123U, Polynomial, Reflect, Chunk_Bits>::value,
etl::private_crc::table_entry<uint8_t, 124U, Polynomial, Reflect, Chunk_Bits>::value,
etl::private_crc::table_entry<uint8_t, 125U, Polynomial, Reflect, Chunk_Bits>::value,
etl::private_crc::table_entry<uint8_t, 126U, Polynomial, Reflect, Chunk_Bits>::value,
etl::private_crc::table_entry<uint8_t, 127U, Polynomial, Reflect, Chunk_Bits>::value,
etl::private_crc::table_entry<uint8_t, 128U, Polynomial, Reflect, Chunk_Bits>::value,
etl::private_crc::table_entry<uint8_t, 129U, Polynomial, Reflect, Chunk_Bits>::value,
etl::private_crc::table_entry<uint8_t, 130U, Polynomial, Reflect, Chunk_Bits>::value,
etl::private_crc::table_entry<uint8_t, 131U, Polynomial, Reflect, Chunk_Bits>::value,
etl::private_crc::table_entry<uint8_t, 132U, Polynomial, Reflect, Chunk_Bits>::value,
etl::private_crc::table_entry<uint8_t, 133U, Polynomial, Reflect, Chunk_Bits>::value,
etl::private_crc::table_entry<uint8_t, 134U, Polynomial, Reflect, Chunk_Bits>::value,
etl::private_crc::table_entry<uint8_t, 135U, Polynomial, Reflect, Chunk_Bits>::value,
etl::private_crc::table_entry<uint8_t, 136U, Polynomial, Reflect, Chunk_Bits>::value,
etl::private_crc::table_entry<uint8_t, 137U, Polynomial, Reflect, Chunk_Bits>::value,
etl::private_crc::table_entry<uint8_t, 138U, Polynomial, Reflect, Chunk_Bits>::value,
etl::private_crc::table_entry<uint8_t, 139U, Polynomial, Reflect, Chunk_Bits>::value,
etl::private_crc::table_entry<uint8_t, 140U, Polynomial, Reflect, Chunk_Bits>::value,
etl::private_crc::table_entry<uint8_t, 141U, Polynomial, Reflect, Chunk_Bits>::value,
etl::private_crc::table_entry<uint8_t, 142U, Polynomial, Reflect, Chunk_Bits>::value,
etl::private_crc::table_entry<uint8_t, 143U, Polynomial, Reflect, Chunk_Bits>::value,
etl::private_crc::table_entry<uint8_t, 144U, Polynomial, Reflect, Chunk_Bits>::value,
etl::private_crc::table_entry<uint8_t, 145U, Polynomial, Reflect, Chunk_Bits>::value,
etl::private_crc::table_entry<uint8_t, 146U, Polynomial, Reflect, Chunk_Bits>::value,
etl::private_crc::table_entry<uint8_t, 147U, Polynomial, Reflect, Chunk_Bits>::value,
etl::private_crc::table_entry<uint8_t, 148U, Polynomial, Reflect, Chunk_Bits>::value,
etl::private_crc::table_entry<uint8_t, 149U, Polynomial, Reflect, Chunk_Bits>::value,
etl::private_crc::table_entry<uint8_t, 150U, Polynomial, Reflect, Chunk_Bits>::value,
etl::private_crc::table_entry<uint8_t, 151U, Polynomial, Reflect, Chunk_Bits>::value,
etl::private_crc::table_entry<uint8_t, 152U, Polynomial, Reflect, Chunk_Bits>::value,
etl::private_crc::table_entry<uint8_t, 153U, Polynomial, Reflect, Chunk_Bits>::value,
etl::private_crc::table_entry<uint8_t, 154U, Polynomial, Reflect, Chunk_Bits>::value,
etl::private_crc::table_entry<uint8_t, 155U, Polynomial, Reflect, Chunk_Bits>::value,
etl::private_crc::table_entry<uint8_t, 156U, Polynomial, Reflect, Chunk_Bits>::value,
etl::private_crc::table_entry<uint8_t, 157U, Polynomial, Reflect, Chunk_Bits>::value,
etl::private_crc::table_entry<uint8_t, 158U, Polynomial, Reflect, Chunk_Bits>::value,
etl::private_crc::table_entry<uint8_t, 159U, Polynomial, Reflect, Chunk_Bits>::value,
etl::private_crc::table_entry<uint8_t, 160U, Polynomial, Reflect, Chunk_Bits>::value,
etl::private_crc::table_entry<uint8_t, 161U, Polynomial, Reflect, Chunk_Bits>::value,
etl::private_crc::table_entry<uint8_t, 162U, Polynomial, Reflect, Chunk_Bits>::value,
etl::private_crc::table_entry<uint8_t, 163U, Polynomial, Reflect, Chunk_Bits>::value,
etl::private_crc::table_entry<uint8_t, 164U, Polynomial, Reflect, Chunk_Bits>::value,
etl::private_crc::table_entry<uint8_t, 165U, Polynomial, Reflect, Chunk_Bits>::value,
etl::private_crc::table_entry<uint8_t, 166U, Polynomial, Reflect, Chunk_Bits>::value,
etl::private_crc::table_entry<uint8_t, 167U, Polynomial, Reflect, Chunk_Bits>::value,
etl::private_crc::table_entry<uint8_t, 168U, Polynomial, Reflect, Chunk_Bits>::value,
etl::private_crc::table_entry<uint8_t, 169U, Polynomial, Reflect, Chunk_Bits>::value,
etl::private_crc::table_entry<uint8_t, 170U, Polynomial, Reflect, Chunk_Bits>::value,
etl::private_crc::table_entry<uint8_t, 171U, Polynomial, Reflect, Chunk_Bits>::value,
etl::private_crc::table_entry<uint8_t, 172U, Polynomial, Reflect, Chunk_Bits>::value,
etl::private_crc::table_entry<uint8_t, 173U, Polynomial, Reflect, Chunk_Bits>::value,
etl::private_crc::table_entry<uint8_t, 174U, Polynomial, Reflect, Chunk_Bits>::value,
etl::private_crc::table_entry<uint8_t, 175U, Polynomial, Reflect, Chunk_Bits>::value,
etl::private_crc::table_entry<uint8_t, 176U, Polynomial, Reflect, Chunk_Bits>::value,
etl::private_crc::table_entry<uint8_t, 177U, Polynomial, Reflect, Chunk_Bits>::value,
etl::private_crc::table_entry<uint8_t, 178U, Polynomial, Reflect, Chunk_Bits>::value,
etl::private_crc::table_entry<uint8_t, 179U, Polynomial, Reflect, Chunk_Bits>::value,
etl::private_crc::table_entry<uint8_t, 180U, Polynomial, Reflect, Chunk_Bits>::value,
etl::private_crc::table_entry<uint8_t, 181U, Polynomial, Reflect, Chunk_Bits>::value,
etl::private_crc::table_entry<uint8_t, 182U, Polynomial, Reflect, Chunk_Bits>::value,
etl::private_crc::table_entry<uint8_t, 183U, Polynomial, Reflect, Chunk_Bits>::value,
etl::private_crc::table_entry<uint8_t, 184U, Polynomial, Reflect, Chunk_Bits>::value,
etl::private_crc::table_entry<uint8_t, 185U, Polynomial, Reflect, Chunk_Bits>::value,
etl::private_crc::table_entry<uint8_t, 186U, Polynomial, Reflect, Chunk_Bits>::value,
etl::private_crc::table_entry<uint8_t, 187U, Polynomial, Reflect, Chunk_Bits>::value,
etl::private_crc::table_entry<uint8_t, 188U, Polynomial, Reflect, Chunk_Bits>::value,
etl::private_crc::table_entry<uint8_t, 189U, Polynomial, Reflect, Chunk_Bits>::value,
etl::private_crc::table_entry<uint8_t, 190U, Polynomial, Reflect, Chunk_Bits>::value,
etl::private_crc::table_entry<uint8_t, 191U, Polynomial, Reflect, Chunk_Bits>::value,
etl::private_crc::table_entry<uint8_t, 192U, Polynomial, Reflect, Chunk_Bits>::value,
etl::private_crc::table_entry<uint8_t, 193U, Polynomial, Reflect, Chunk_Bits>::value,
etl::private_crc::table_entry<uint8_t, 194U, Polynomial, Reflect, Chunk_Bits>::value,
etl::private_crc::table_entry<uint8_t, 195U, Polynomial, Reflect, Chunk_Bits>::value,
etl::private_crc::table_entry<uint8_t, 196U, Polynomial, Reflect, Chunk_Bits>::value,
etl::private_crc::table_entry<uint8_t, 197U, Polynomial, Reflect, Chunk_Bits>::value,
etl::private_crc::table_entry<uint8_t, 198U, Polynomial, Reflect, Chunk_Bits>::value,
etl::private_crc::table_entry<uint8_t, 199U, Polynomial, Reflect, Chunk_Bits>::value,
etl::private_crc::table_entry<uint8_t, 200U, Polynomial, Reflect, Chunk_Bits>::value,
etl::private_crc::table_entry<uint8_t, 201U, Polynomial, Reflect, Chunk_Bits>::value,
etl::private_crc::table_entry<uint8_t, 202U, Polynomial, Reflect, Chunk_Bits>::value,
etl::private_crc::table_entry<uint8_t, 203U, Polynomial, Reflect, Chunk_Bits>::value,
etl::private_crc::table_entry<uint8_t, 204U, Polynomial, Reflect, Chunk_Bits>::value,
etl::private_crc::table_entry<uint8_t, 205U, Polynomial, Reflect, Chunk_Bits>::value,
etl::private_crc::table_entry<uint8_t, 206U, Polynomial, Reflect, Chunk_Bits>::value,
etl::private_crc::table_entry<uint8_t, 207U, Polynomial, Reflect, Chunk_Bits>::value,
etl::private_crc::table_entry<uint8_t, 208U, Polynomial, Reflect, Chunk_Bits>::value,
etl::private_crc::table_entry<uint8_t, 209U, Polynomial, Reflect, Chunk_Bits>::value,
etl::private_crc::table_entry<uint8_t, 210U, Polynomial, Reflect, Chunk_Bits>::value,
etl::private_crc::table_entry<uint8_t, 211U, Polynomial, Reflect, Chunk_Bits>::value,
etl::private_crc::table_entry<uint8_t, 212U, Polynomial, Reflect, Chunk_Bits>::value,
etl::private_crc::table_entry<uint8_t, 213U, Polynomial, Reflect, Chunk_Bits>::value,
etl::private_crc::table_entry<uint8_t, 214U, Polynomial, Reflect, Chunk_Bits>::value,
etl::private_crc::table_entry<uint8_t, 215U, Polynomial, Reflect, Chunk_Bits>::value,
etl::private_crc::table_entry<uint8_t, 216U, Polynomial, Reflect, Chunk_Bits>::value,
etl::private_crc::table_entry<uint8_t, 217U, Polynomial, Reflect, Chunk_Bits>::value,
etl::private_crc::table_entry<uint8_t, 218U, Polynomial, Reflect, Chunk_Bits>::value,
etl::private_crc::table_entry<uint8_t, 219U, Polynomial, Reflect, Chunk_Bits>::value,
etl::private_crc::table_entry<uint8_t, 220U, Polynomial, Reflect, Chunk_Bits>::value,
etl::private_crc::table_entry<uint8_t, 221U, Polynomial, Reflect, Chunk_Bits>::value,
etl::private_crc::table_entry<uint8_t, 222U, Polynomial, Reflect, Chunk_Bits>::value,
etl::private_crc::table_entry<uint8_t, 223U, Polynomial, Reflect, Chunk_Bits>::value,
etl::private_crc::table_entry<uint8_t, 224U, Polynomial, Reflect, Chunk_Bits>::value,
etl::private_crc::table_entry<uint8_t, 225U, Polynomial, Reflect, Chunk_Bits>::value,
etl::private_crc::table_entry<uint8_t, 226U, Polynomial, Reflect, Chunk_Bits>::value,
etl::private_crc::table_entry<uint8_t, 227U, Polynomial, Reflect, Chunk_Bits>::value,
etl::private_crc::table_entry<uint8_t, 228U, Polynomial, Reflect, Chunk_Bits>::value,
etl::private_crc::table_entry<uint8_t, 229U, Polynomial, Reflect, Chunk_Bits>::value,
etl::private_crc::table_entry<uint8_t, 230U, Polynomial, Reflect, Chunk_Bits>::value,
etl::private_crc::table_entry<uint8_t, 231U, Polynomial, Reflect, Chunk_Bits>::value,
etl::private_crc::table_entry<uint8_t, 232U, Polynomial, Reflect, Chunk_Bits>::value,
etl::private_crc::table_entry<uint8_t, 233U, Polynomial, Reflect, Chunk_Bits>::value,
etl::private_crc::table_entry<uint8_t, 234U, Polynomial, Reflect, Chunk_Bits>::value,
etl::private_crc::table_entry<uint8_t, 235U, Polynomial, Reflect, Chunk_Bits>::value,
etl::private_crc::table_entry<uint8_t, 236U, Polynomial, Reflect, Chunk_Bits>::value,
etl::private_crc::table_entry<uint8_t, 237U, Polynomial, Reflect, Chunk_Bits>::value,
etl::private_crc::table_entry<uint8_t, 238U, Polynomial, Reflect, Chunk_Bits>::value,
etl::private_crc::table_entry<uint8_t, 239U, Polynomial, Reflect, Chunk_Bits>::value,
etl::private_crc::table_entry<uint8_t, 240U, Polynomial, Reflect, Chunk_Bits>::value,
etl::private_crc::table_entry<uint8_t, 241U, Polynomial, Reflect, Chunk_Bits>::value,
etl::private_crc::table_entry<uint8_t, 242U, Polynomial, Reflect, Chunk_Bits>::value,
etl::private_crc::table_entry<uint8_t, 243U, Polynomial, Reflect, Chunk_Bits>::value,
etl::private_crc::table_entry<uint8_t, 244U, Polynomial, Reflect, Chunk_Bits>::value,
etl::private_crc::table_entry<uint8_t, 245U, Polynomial, Reflect, Chunk_Bits>::value,
etl::private_crc::table_entry<uint8_t, 246U, Polynomial, Reflect, Chunk_Bits>::value,
etl::private_crc::table_entry<uint8_t, 247U, Polynomial, Reflect, Chunk_Bits>::value,
etl::private_crc::table_entry<uint8_t, 248U, Polynomial, Reflect, Chunk_Bits>::value,
etl::private_crc::table_entry<uint8_t, 249U, Polynomial, Reflect, Chunk_Bits>::value,
etl::private_crc::table_entry<uint8_t, 250U, Polynomial, Reflect, Chunk_Bits>::value,
etl::private_crc::table_entry<uint8_t, 251U, Polynomial, Reflect, Chunk_Bits>::value,
etl::private_crc::table_entry<uint8_t, 252U, Polynomial, Reflect, Chunk_Bits>::value,
etl::private_crc::table_entry<uint8_t, 253U, Polynomial, Reflect, Chunk_Bits>::value,
etl::private_crc::table_entry<uint8_t, 254U, Polynomial, Reflect, Chunk_Bits>::value,
etl::private_crc::table_entry<uint8_t, 255U, Polynomial, Reflect, Chunk_Bits>::value
};
crc = update_chunk(crc, value, table);
return crc;
}
//*************************************************************************
uint8_t final(uint8_t crc) const
{
return crc ^ Xor_Out;
}
};
//*****************************************************************************
//
//*****************************************************************************
template <uint8_t Polynomial, uint8_t Initial, uint8_t Xor_In, uint8_t Xor_Out, bool Reflect>
class crc8_table256 : public etl::frame_check_sequence<etl::crc::crc8_policy_table256<Polynomial, Initial, Xor_Out, Reflect> >
{
public:
//*************************************************************************
/// Default constructor.
//*************************************************************************
crc8_table256()
{
this->reset();
}
//*************************************************************************
/// Constructor from range.
/// \param begin Start of the range.
/// \param end End of the range.
//*************************************************************************
template<typename TIterator>
crc8_table256(TIterator begin, const TIterator end)
{
this->reset();
this->add(begin, end);
}
};
}
}

View File

@ -0,0 +1,212 @@
#pragma once
#include "../platform.h"
#include "../frame_check_sequence.h"
#include "../binary.h"
#include "stdint.h"
namespace etl
{
namespace crc
{
//*****************************************************************************
//
//*****************************************************************************
template <uint8_t Polynomial, uint8_t Initial, uint8_t Xor_Out, bool Reflect>
struct crc8_policy_table4;
//*****************************************************************************
// Specialisation for Reflect = false
//*****************************************************************************
template <uint8_t Polynomial, uint8_t Initial, uint8_t Xor_Out>
struct crc8_policy_table4<Polynomial, Initial, Xor_Out, false>
{
static ETL_CONSTANT uint8_t Mask = 0x03U;
static ETL_CONSTANT uint8_t Chunk_Size = 2U;
typedef uint8_t value_type;
//*****************************************************************************
template <uint8_t Polynomial, uint8_t Entry>
class entry
{
public:
static ETL_CONSTANT size_t Accumulator_Bits = etl::integral_limits<uint8_t>::bits;
static ETL_CONSTANT bool Do_Poly = (Entry & (uint8_t(1U) << (Accumulator_Bits - 1U))) != 0U;
static ETL_CONSTANT uint8_t value = uint8_t(Do_Poly ? (Entry << 1U) ^ Polynomial : (Entry << 1U));
};
//*************************************************************************
template <size_t Index, uint8_t Polynomial>
class table_entry
{
public:
static ETL_CONSTANT size_t Accumulator_Bits = entry<Index, Polynomial>::Accumulator_Bits;
static ETL_CONSTANT size_t Shift_Bits = size_t(Accumulator_Bits - Chunk_Size);
static ETL_CONSTANT uint8_t Entry = uint8_t(Index << Shift_Bits);
static ETL_CONSTANT uint8_t value = entry<Polynomial,
entry<Polynomial, Entry>::value>::value;
};
//*************************************************************************
ETL_CONSTEXPR uint8_t initial() const
{
return Initial;
}
//*************************************************************************
uint8_t update_chunk(uint8_t crc, uint8_t value, const uint8_t* table) const
{
// Extract the most significant nibble of the crc and xor with the value nibble.
uint8_t index = (crc >> (etl::integral_limits<uint8_t>::bits - Chunk_Size)) ^ value;
crc <<= Chunk_Size;
crc ^= table[index];
return crc;
}
//*************************************************************************
uint8_t add(uint8_t crc, uint8_t value) const
{
static ETL_CONSTANT uint8_t table[4] =
{
table_entry<0U, Polynomial>::value,
table_entry<1U, Polynomial>::value,
table_entry<2U, Polynomial>::value,
table_entry<3U, Polynomial>::value
};
crc = update_chunk(crc, (value >> (Chunk_Size * 3U)) & Mask, table);
crc = update_chunk(crc, (value >> (Chunk_Size * 2U)) & Mask, table);
crc = update_chunk(crc, (value >> (Chunk_Size * 1U)) & Mask, table);
crc = update_chunk(crc, value & Mask, table);
return crc;
}
//*************************************************************************
uint8_t final(uint8_t crc) const
{
return crc ^ Xor_Out;
}
};
//*****************************************************************************
// Specialisation for Reflect = true
//*****************************************************************************
template <uint8_t Polynomial, uint8_t Initial, uint8_t Xor_Out>
struct crc8_policy_table4<Polynomial, Initial, Xor_Out, true>
{
static ETL_CONSTANT uint8_t Mask = 0x03;
static ETL_CONSTANT uint8_t Chunk_Size = 2U;
typedef uint8_t value_type;
//*****************************************************************************
template <uint8_t Polynomial, uint8_t Entry>
class entry
{
public:
static ETL_CONSTANT size_t Accumulator_Bits = etl::integral_limits<uint8_t>::bits;
static ETL_CONSTANT bool Do_Poly = (Entry & uint8_t(1U)) != 0U;
static ETL_CONSTANT uint8_t value = uint8_t(Do_Poly ? (Entry >> 1U) ^ etl::reverse_bits_const<uint8_t, Polynomial>::value : (Entry >> 1U));
};
//*************************************************************************
template <size_t Index, uint8_t Polynomial>
class table_entry
{
public:
static ETL_CONSTANT size_t Accumulator_Bits = entry<Index, Polynomial>::Accumulator_Bits;
static ETL_CONSTANT size_t Shift_Bits = size_t(Accumulator_Bits - Chunk_Size);
static ETL_CONSTANT uint8_t Entry = uint8_t(Index << Shift_Bits);
static ETL_CONSTANT uint8_t value = entry<Polynomial,
entry<Polynomial,
entry<Polynomial,
entry<Polynomial, Entry>::value>::value>::value>::value;
};
//*************************************************************************
ETL_CONSTEXPR uint8_t initial() const
{
return Initial;
}
//*************************************************************************
uint8_t update_chunk(uint8_t crc, uint8_t value, const uint8_t* const table) const
{
// Extract the most significant nibble of the crc and xor with the value nibble.
uint8_t index = (crc >> (Accumulator_Bits - Chunk_Size)) ^ value;
crc <<= Chunk_Size;
crc ^= table[index];
return crc;
}
//*************************************************************************
uint8_t add(uint8_t crc, uint8_t value) const
{
static ETL_CONSTANT uint8_t table[4] =
{
table_entry<0U, Polynomial>::value,
table_entry<1U, Polynomial>::value,
table_entry<2U, Polynomial>::value,
table_entry<3U, Polynomial>::value
};
crc = update_chunk(crc, (value >> (Chunk_Size * 3U)) & Mask, table);
crc = update_chunk(crc, (value >> (Chunk_Size * 2U)) & Mask, table);
crc = update_chunk(crc, (value >> (Chunk_Size * 1U)) & Mask, table);
crc = update_chunk(crc, value & Mask, table);
return crc;
}
//*************************************************************************
uint8_t final(uint8_t crc) const
{
return crc ^ Xor_Out;
}
};
//*****************************************************************************
//
//*****************************************************************************
template <uint8_t Polynomial, uint8_t Initial, uint8_t Xor_In, uint8_t Xor_Out, bool Reflect>
class crc8_table4 : public etl::frame_check_sequence<etl::crc::crc8_policy_table4<Polynomial, Initial, Xor_Out, Reflect> >
{
public:
//*************************************************************************
/// Default constructor.
//*************************************************************************
crc8_table4()
{
this->reset();
}
//*************************************************************************
/// Constructor from range.
/// \param begin Start of the range.
/// \param end End of the range.
//*************************************************************************
template<typename TIterator>
crc8_table4(TIterator begin, const TIterator end)
{
this->reset();
this->add(begin, end);
}
};
}
}

View File

@ -0,0 +1,656 @@
#pragma once
#include "../platform.h"
#include "../frame_check_sequence.h"
#include "../static_assert.h"
#include "../binary.h"
#include "stdint.h"
namespace etl
{
namespace private_crc
{
//*****************************************************************************
/// CRC Traits
//*****************************************************************************
template <size_t Table_Size>
struct crc_traits
{
ETL_STATIC_ASSERT((Table_Size == 4U) || (Table_Size == 16U) || (Table_Size == 256U), "Table size must be 4, 16 or 256");
};
//*********************************
// Traits for table size of 4.
template <>
struct crc_traits<4U>
{
static ETL_CONSTANT uint8_t Chunk_Mask = 0x03U;
static ETL_CONSTANT size_t Chunk_Bits = 2U;
};
//*********************************
// Traits for table size of 16.
template <>
struct crc_traits<16U>
{
static ETL_CONSTANT uint8_t Chunk_Mask = 0x0FU;
static ETL_CONSTANT size_t Chunk_Bits = 4U;
};
//*********************************
// Traits for table size of 256.
template <>
struct crc_traits<256U>
{
static ETL_CONSTANT uint8_t Chunk_Mask = 0xFFU;
static ETL_CONSTANT size_t Chunk_Bits = 8U;
};
//*****************************************************************************
/// CRC Entry
//*****************************************************************************
template <typename TAccumulator, TAccumulator Polynomial, bool Reflect, TAccumulator Entry>
class crc_entry;
//*********************************
// Not reflected
template <typename TAccumulator, TAccumulator Polynomial, TAccumulator Entry>
class crc_entry<TAccumulator, Polynomial, false, Entry>
{
private:
static ETL_CONSTANT size_t Accumulator_Bits = etl::integral_limits<TAccumulator>::bits;
static ETL_CONSTANT bool Do_Poly = (Entry & (TAccumulator(1U) << (Accumulator_Bits - 1U))) != 0U;
public:
static ETL_CONSTANT TAccumulator value = TAccumulator(Do_Poly ? (Entry << 1U) ^ Polynomial : (Entry << 1U));
};
//*********************************
// Reflected
template <typename TAccumulator, TAccumulator Polynomial, TAccumulator Entry>
class crc_entry<TAccumulator, Polynomial, true, Entry>
{
private:
static ETL_CONSTANT size_t Accumulator_Bits = etl::integral_limits<TAccumulator>::bits;
static ETL_CONSTANT bool Do_Poly = (Entry & TAccumulator(1U)) != 0U;
public:
static ETL_CONSTANT TAccumulator value = TAccumulator(Do_Poly ? (Entry >> 1U) ^ etl::reverse_bits_const<TAccumulator, Polynomial>::value : (Entry >> 1U));
};
//*****************************************************************************
/// CRC Table Entry
//*****************************************************************************
template <typename TAccumulator, size_t Index, TAccumulator Polynomial, bool Reflect, uint8_t Chunk_Bits>
class crc_table_entry
{
ETL_STATIC_ASSERT((Chunk_Bits == 2U) || (Chunk_Bits == 4U) || (Chunk_Bits == 8U), "Chunk bits must be 2, 4 or 8");
};
//*********************************
// Chunk bit size of 8.
template <typename TAccumulator, size_t Index, TAccumulator Polynomial, bool Reflect>
class crc_table_entry<TAccumulator, Index, Polynomial, Reflect, 8U>
{
public:
static ETL_CONSTANT size_t Accumulator_Bits = etl::integral_limits<TAccumulator>::bits;
static ETL_CONSTANT size_t Shift_Bits = size_t(Accumulator_Bits - 8U);
static ETL_CONSTANT TAccumulator Entry = Reflect ? TAccumulator(Index) : TAccumulator(TAccumulator(Index) << Shift_Bits);
static ETL_CONSTANT TAccumulator value = crc_entry<TAccumulator, Polynomial, Reflect,
crc_entry<TAccumulator, Polynomial, Reflect,
crc_entry<TAccumulator, Polynomial, Reflect,
crc_entry<TAccumulator, Polynomial, Reflect,
crc_entry<TAccumulator, Polynomial, Reflect,
crc_entry<TAccumulator, Polynomial, Reflect,
crc_entry<TAccumulator, Polynomial, Reflect,
crc_entry<TAccumulator, Polynomial, Reflect, Entry>::value>::value>::value>::value>::value>::value>::value>::value;
};
//*********************************
// Chunk bit size of 4.
template <typename TAccumulator, size_t Index, TAccumulator Polynomial, bool Reflect>
class crc_table_entry<TAccumulator, Index, Polynomial, Reflect, 4U>
{
public:
static ETL_CONSTANT size_t Accumulator_Bits = etl::integral_limits<TAccumulator>::bits;
static ETL_CONSTANT size_t Shift_Bits = size_t(Accumulator_Bits - 4U);
static ETL_CONSTANT TAccumulator Entry = Reflect ? TAccumulator(Index) : TAccumulator(TAccumulator(Index) << Shift_Bits);
static const TAccumulator value = crc_entry<TAccumulator, Polynomial, Reflect,
crc_entry<TAccumulator, Polynomial, Reflect,
crc_entry<TAccumulator, Polynomial, Reflect,
crc_entry<TAccumulator, Polynomial, Reflect, Entry>::value>::value>::value>::value;
};
//*********************************
// Chunk bit size of 2.
template <typename TAccumulator, size_t Index, TAccumulator Polynomial, bool Reflect>
class crc_table_entry<TAccumulator, Index, Polynomial, Reflect, 2U>
{
public:
static ETL_CONSTANT size_t Accumulator_Bits = etl::integral_limits<TAccumulator>::bits;
static ETL_CONSTANT size_t Shift_Bits = size_t(Accumulator_Bits - 2U);
static ETL_CONSTANT TAccumulator Entry = Reflect ? TAccumulator(Index) : TAccumulator(TAccumulator(Index) << Shift_Bits);
static const TAccumulator value = crc_entry<TAccumulator, Polynomial, Reflect,
crc_entry<TAccumulator, Polynomial, Reflect, Entry>::value>::value;
};
//*************************************************************************
// Accumulator_Bits > Chunk_Bits and not reflected
template <typename TAccumulator, uint8_t Chunk_Mask, uint8_t Chunk_Bits, uint8_t Accumulator_Bits, bool Reflect>
typename etl::enable_if<(Accumulator_Bits > Chunk_Bits) && !Reflect, TAccumulator>::type
crc_update_chunk(TAccumulator crc, uint8_t value, const TAccumulator table[])
{
size_t index = (crc >> (Accumulator_Bits - Chunk_Bits)) ^ value;
crc <<= Chunk_Bits;
crc ^= table[index];
return crc;
}
//*************************************************************************
// Accumulator_Bits > Chunk_Bits and reflected
template <typename TAccumulator, uint8_t Chunk_Mask, uint8_t Chunk_Bits, uint8_t Accumulator_Bits, bool Reflect>
typename etl::enable_if<(Accumulator_Bits > Chunk_Bits) && Reflect, TAccumulator>::type
crc_update_chunk(TAccumulator crc, uint8_t value, const TAccumulator table[])
{
size_t index = (crc & Chunk_Mask) ^ value;
crc >>= Chunk_Bits;
crc ^= table[index];
return crc;
}
//*************************************************************************
// Accumulator_Bits == Chunk_Bits and not reflected
template <typename TAccumulator, uint8_t Chunk_Mask, uint8_t Chunk_Bits, uint8_t Accumulator_Bits, bool Reflect>
typename etl::enable_if<(Accumulator_Bits == Chunk_Bits) && !Reflect, TAccumulator>::type
crc_update_chunk(TAccumulator crc, uint8_t value, const TAccumulator table[])
{
size_t index = (crc >> (Accumulator_Bits - Chunk_Bits)) ^ value;
crc = table[index];
return crc;
}
//*************************************************************************
// Accumulator_Bits == Chunk_Bits and reflected
template <typename TAccumulator, uint8_t Chunk_Mask, uint8_t Chunk_Bits, uint8_t Accumulator_Bits, bool Reflect>
typename etl::enable_if<(Accumulator_Bits == Chunk_Bits) && Reflect, TAccumulator>::type
crc_update_chunk(TAccumulator crc, uint8_t value, const TAccumulator table[])
{
size_t index = (crc & Chunk_Mask) ^ value;
crc = table[index];
return crc;
}
//*****************************************************************************
//
//*****************************************************************************
template <typename TAccumulator, TAccumulator Polynomial, TAccumulator Initial, TAccumulator Xor_Out, bool Reflect, size_t Table_Size>
struct crc_policy
{
ETL_STATIC_ASSERT((Table_Size == 4U) || (Table_Size == 16U) || (Table_Size == 256U), "Table size must be 4, 16 or 256");
};
//*********************************
template <typename TAccumulator, TAccumulator Polynomial, TAccumulator Initial, TAccumulator Xor_Out, bool Reflect>
struct crc_policy<TAccumulator, Polynomial, Initial, Xor_Out, Reflect, 256U>
{
static ETL_CONSTANT size_t Table_Size = 256U;
static ETL_CONSTANT uint8_t Chunk_Mask = crc_traits<Table_Size>::Chunk_Mask;
static ETL_CONSTANT uint8_t Chunk_Bits = crc_traits<Table_Size>::Chunk_Bits;
static ETL_CONSTANT size_t Accumulator_Bits = etl::integral_limits<TAccumulator>::bits;
typedef TAccumulator value_type;
//*************************************************************************
ETL_CONSTEXPR TAccumulator initial() const
{
return Initial;
}
//*************************************************************************
TAccumulator add(TAccumulator crc, uint8_t value) const
{
static ETL_CONSTANT TAccumulator table[Table_Size] =
{
crc_table_entry<TAccumulator, 0U, Polynomial, Reflect, Chunk_Bits>::value,
crc_table_entry<TAccumulator, 1U, Polynomial, Reflect, Chunk_Bits>::value,
crc_table_entry<TAccumulator, 2U, Polynomial, Reflect, Chunk_Bits>::value,
crc_table_entry<TAccumulator, 3U, Polynomial, Reflect, Chunk_Bits>::value,
crc_table_entry<TAccumulator, 4U, Polynomial, Reflect, Chunk_Bits>::value,
crc_table_entry<TAccumulator, 5U, Polynomial, Reflect, Chunk_Bits>::value,
crc_table_entry<TAccumulator, 6U, Polynomial, Reflect, Chunk_Bits>::value,
crc_table_entry<TAccumulator, 7U, Polynomial, Reflect, Chunk_Bits>::value,
crc_table_entry<TAccumulator, 8U, Polynomial, Reflect, Chunk_Bits>::value,
crc_table_entry<TAccumulator, 9U, Polynomial, Reflect, Chunk_Bits>::value,
crc_table_entry<TAccumulator, 10U, Polynomial, Reflect, Chunk_Bits>::value,
crc_table_entry<TAccumulator, 11U, Polynomial, Reflect, Chunk_Bits>::value,
crc_table_entry<TAccumulator, 12U, Polynomial, Reflect, Chunk_Bits>::value,
crc_table_entry<TAccumulator, 13U, Polynomial, Reflect, Chunk_Bits>::value,
crc_table_entry<TAccumulator, 14U, Polynomial, Reflect, Chunk_Bits>::value,
crc_table_entry<TAccumulator, 15U, Polynomial, Reflect, Chunk_Bits>::value,
crc_table_entry<TAccumulator, 16U, Polynomial, Reflect, Chunk_Bits>::value,
crc_table_entry<TAccumulator, 17U, Polynomial, Reflect, Chunk_Bits>::value,
crc_table_entry<TAccumulator, 18U, Polynomial, Reflect, Chunk_Bits>::value,
crc_table_entry<TAccumulator, 19U, Polynomial, Reflect, Chunk_Bits>::value,
crc_table_entry<TAccumulator, 20U, Polynomial, Reflect, Chunk_Bits>::value,
crc_table_entry<TAccumulator, 21U, Polynomial, Reflect, Chunk_Bits>::value,
crc_table_entry<TAccumulator, 22U, Polynomial, Reflect, Chunk_Bits>::value,
crc_table_entry<TAccumulator, 23U, Polynomial, Reflect, Chunk_Bits>::value,
crc_table_entry<TAccumulator, 24U, Polynomial, Reflect, Chunk_Bits>::value,
crc_table_entry<TAccumulator, 25U, Polynomial, Reflect, Chunk_Bits>::value,
crc_table_entry<TAccumulator, 26U, Polynomial, Reflect, Chunk_Bits>::value,
crc_table_entry<TAccumulator, 27U, Polynomial, Reflect, Chunk_Bits>::value,
crc_table_entry<TAccumulator, 28U, Polynomial, Reflect, Chunk_Bits>::value,
crc_table_entry<TAccumulator, 29U, Polynomial, Reflect, Chunk_Bits>::value,
crc_table_entry<TAccumulator, 30U, Polynomial, Reflect, Chunk_Bits>::value,
crc_table_entry<TAccumulator, 31U, Polynomial, Reflect, Chunk_Bits>::value,
crc_table_entry<TAccumulator, 32U, Polynomial, Reflect, Chunk_Bits>::value,
crc_table_entry<TAccumulator, 33U, Polynomial, Reflect, Chunk_Bits>::value,
crc_table_entry<TAccumulator, 34U, Polynomial, Reflect, Chunk_Bits>::value,
crc_table_entry<TAccumulator, 35U, Polynomial, Reflect, Chunk_Bits>::value,
crc_table_entry<TAccumulator, 36U, Polynomial, Reflect, Chunk_Bits>::value,
crc_table_entry<TAccumulator, 37U, Polynomial, Reflect, Chunk_Bits>::value,
crc_table_entry<TAccumulator, 38U, Polynomial, Reflect, Chunk_Bits>::value,
crc_table_entry<TAccumulator, 39U, Polynomial, Reflect, Chunk_Bits>::value,
crc_table_entry<TAccumulator, 40U, Polynomial, Reflect, Chunk_Bits>::value,
crc_table_entry<TAccumulator, 41U, Polynomial, Reflect, Chunk_Bits>::value,
crc_table_entry<TAccumulator, 42U, Polynomial, Reflect, Chunk_Bits>::value,
crc_table_entry<TAccumulator, 43U, Polynomial, Reflect, Chunk_Bits>::value,
crc_table_entry<TAccumulator, 44U, Polynomial, Reflect, Chunk_Bits>::value,
crc_table_entry<TAccumulator, 45U, Polynomial, Reflect, Chunk_Bits>::value,
crc_table_entry<TAccumulator, 46U, Polynomial, Reflect, Chunk_Bits>::value,
crc_table_entry<TAccumulator, 47U, Polynomial, Reflect, Chunk_Bits>::value,
crc_table_entry<TAccumulator, 48U, Polynomial, Reflect, Chunk_Bits>::value,
crc_table_entry<TAccumulator, 49U, Polynomial, Reflect, Chunk_Bits>::value,
crc_table_entry<TAccumulator, 50U, Polynomial, Reflect, Chunk_Bits>::value,
crc_table_entry<TAccumulator, 51U, Polynomial, Reflect, Chunk_Bits>::value,
crc_table_entry<TAccumulator, 52U, Polynomial, Reflect, Chunk_Bits>::value,
crc_table_entry<TAccumulator, 53U, Polynomial, Reflect, Chunk_Bits>::value,
crc_table_entry<TAccumulator, 54U, Polynomial, Reflect, Chunk_Bits>::value,
crc_table_entry<TAccumulator, 55U, Polynomial, Reflect, Chunk_Bits>::value,
crc_table_entry<TAccumulator, 56U, Polynomial, Reflect, Chunk_Bits>::value,
crc_table_entry<TAccumulator, 57U, Polynomial, Reflect, Chunk_Bits>::value,
crc_table_entry<TAccumulator, 58U, Polynomial, Reflect, Chunk_Bits>::value,
crc_table_entry<TAccumulator, 59U, Polynomial, Reflect, Chunk_Bits>::value,
crc_table_entry<TAccumulator, 60U, Polynomial, Reflect, Chunk_Bits>::value,
crc_table_entry<TAccumulator, 61U, Polynomial, Reflect, Chunk_Bits>::value,
crc_table_entry<TAccumulator, 62U, Polynomial, Reflect, Chunk_Bits>::value,
crc_table_entry<TAccumulator, 63U, Polynomial, Reflect, Chunk_Bits>::value,
crc_table_entry<TAccumulator, 64U, Polynomial, Reflect, Chunk_Bits>::value,
crc_table_entry<TAccumulator, 65U, Polynomial, Reflect, Chunk_Bits>::value,
crc_table_entry<TAccumulator, 66U, Polynomial, Reflect, Chunk_Bits>::value,
crc_table_entry<TAccumulator, 67U, Polynomial, Reflect, Chunk_Bits>::value,
crc_table_entry<TAccumulator, 68U, Polynomial, Reflect, Chunk_Bits>::value,
crc_table_entry<TAccumulator, 69U, Polynomial, Reflect, Chunk_Bits>::value,
crc_table_entry<TAccumulator, 70U, Polynomial, Reflect, Chunk_Bits>::value,
crc_table_entry<TAccumulator, 71U, Polynomial, Reflect, Chunk_Bits>::value,
crc_table_entry<TAccumulator, 72U, Polynomial, Reflect, Chunk_Bits>::value,
crc_table_entry<TAccumulator, 73U, Polynomial, Reflect, Chunk_Bits>::value,
crc_table_entry<TAccumulator, 74U, Polynomial, Reflect, Chunk_Bits>::value,
crc_table_entry<TAccumulator, 75U, Polynomial, Reflect, Chunk_Bits>::value,
crc_table_entry<TAccumulator, 76U, Polynomial, Reflect, Chunk_Bits>::value,
crc_table_entry<TAccumulator, 77U, Polynomial, Reflect, Chunk_Bits>::value,
crc_table_entry<TAccumulator, 78U, Polynomial, Reflect, Chunk_Bits>::value,
crc_table_entry<TAccumulator, 79U, Polynomial, Reflect, Chunk_Bits>::value,
crc_table_entry<TAccumulator, 80U, Polynomial, Reflect, Chunk_Bits>::value,
crc_table_entry<TAccumulator, 81U, Polynomial, Reflect, Chunk_Bits>::value,
crc_table_entry<TAccumulator, 82U, Polynomial, Reflect, Chunk_Bits>::value,
crc_table_entry<TAccumulator, 83U, Polynomial, Reflect, Chunk_Bits>::value,
crc_table_entry<TAccumulator, 84U, Polynomial, Reflect, Chunk_Bits>::value,
crc_table_entry<TAccumulator, 85U, Polynomial, Reflect, Chunk_Bits>::value,
crc_table_entry<TAccumulator, 86U, Polynomial, Reflect, Chunk_Bits>::value,
crc_table_entry<TAccumulator, 87U, Polynomial, Reflect, Chunk_Bits>::value,
crc_table_entry<TAccumulator, 88U, Polynomial, Reflect, Chunk_Bits>::value,
crc_table_entry<TAccumulator, 89U, Polynomial, Reflect, Chunk_Bits>::value,
crc_table_entry<TAccumulator, 90U, Polynomial, Reflect, Chunk_Bits>::value,
crc_table_entry<TAccumulator, 91U, Polynomial, Reflect, Chunk_Bits>::value,
crc_table_entry<TAccumulator, 92U, Polynomial, Reflect, Chunk_Bits>::value,
crc_table_entry<TAccumulator, 93U, Polynomial, Reflect, Chunk_Bits>::value,
crc_table_entry<TAccumulator, 94U, Polynomial, Reflect, Chunk_Bits>::value,
crc_table_entry<TAccumulator, 95U, Polynomial, Reflect, Chunk_Bits>::value,
crc_table_entry<TAccumulator, 96U, Polynomial, Reflect, Chunk_Bits>::value,
crc_table_entry<TAccumulator, 97U, Polynomial, Reflect, Chunk_Bits>::value,
crc_table_entry<TAccumulator, 98U, Polynomial, Reflect, Chunk_Bits>::value,
crc_table_entry<TAccumulator, 99U, Polynomial, Reflect, Chunk_Bits>::value,
crc_table_entry<TAccumulator, 100U, Polynomial, Reflect, Chunk_Bits>::value,
crc_table_entry<TAccumulator, 101U, Polynomial, Reflect, Chunk_Bits>::value,
crc_table_entry<TAccumulator, 102U, Polynomial, Reflect, Chunk_Bits>::value,
crc_table_entry<TAccumulator, 103U, Polynomial, Reflect, Chunk_Bits>::value,
crc_table_entry<TAccumulator, 104U, Polynomial, Reflect, Chunk_Bits>::value,
crc_table_entry<TAccumulator, 105U, Polynomial, Reflect, Chunk_Bits>::value,
crc_table_entry<TAccumulator, 106U, Polynomial, Reflect, Chunk_Bits>::value,
crc_table_entry<TAccumulator, 107U, Polynomial, Reflect, Chunk_Bits>::value,
crc_table_entry<TAccumulator, 108U, Polynomial, Reflect, Chunk_Bits>::value,
crc_table_entry<TAccumulator, 109U, Polynomial, Reflect, Chunk_Bits>::value,
crc_table_entry<TAccumulator, 110U, Polynomial, Reflect, Chunk_Bits>::value,
crc_table_entry<TAccumulator, 111U, Polynomial, Reflect, Chunk_Bits>::value,
crc_table_entry<TAccumulator, 112U, Polynomial, Reflect, Chunk_Bits>::value,
crc_table_entry<TAccumulator, 113U, Polynomial, Reflect, Chunk_Bits>::value,
crc_table_entry<TAccumulator, 114U, Polynomial, Reflect, Chunk_Bits>::value,
crc_table_entry<TAccumulator, 115U, Polynomial, Reflect, Chunk_Bits>::value,
crc_table_entry<TAccumulator, 116U, Polynomial, Reflect, Chunk_Bits>::value,
crc_table_entry<TAccumulator, 117U, Polynomial, Reflect, Chunk_Bits>::value,
crc_table_entry<TAccumulator, 118U, Polynomial, Reflect, Chunk_Bits>::value,
crc_table_entry<TAccumulator, 119U, Polynomial, Reflect, Chunk_Bits>::value,
crc_table_entry<TAccumulator, 120U, Polynomial, Reflect, Chunk_Bits>::value,
crc_table_entry<TAccumulator, 121U, Polynomial, Reflect, Chunk_Bits>::value,
crc_table_entry<TAccumulator, 122U, Polynomial, Reflect, Chunk_Bits>::value,
crc_table_entry<TAccumulator, 123U, Polynomial, Reflect, Chunk_Bits>::value,
crc_table_entry<TAccumulator, 124U, Polynomial, Reflect, Chunk_Bits>::value,
crc_table_entry<TAccumulator, 125U, Polynomial, Reflect, Chunk_Bits>::value,
crc_table_entry<TAccumulator, 126U, Polynomial, Reflect, Chunk_Bits>::value,
crc_table_entry<TAccumulator, 127U, Polynomial, Reflect, Chunk_Bits>::value,
crc_table_entry<TAccumulator, 128U, Polynomial, Reflect, Chunk_Bits>::value,
crc_table_entry<TAccumulator, 129U, Polynomial, Reflect, Chunk_Bits>::value,
crc_table_entry<TAccumulator, 130U, Polynomial, Reflect, Chunk_Bits>::value,
crc_table_entry<TAccumulator, 131U, Polynomial, Reflect, Chunk_Bits>::value,
crc_table_entry<TAccumulator, 132U, Polynomial, Reflect, Chunk_Bits>::value,
crc_table_entry<TAccumulator, 133U, Polynomial, Reflect, Chunk_Bits>::value,
crc_table_entry<TAccumulator, 134U, Polynomial, Reflect, Chunk_Bits>::value,
crc_table_entry<TAccumulator, 135U, Polynomial, Reflect, Chunk_Bits>::value,
crc_table_entry<TAccumulator, 136U, Polynomial, Reflect, Chunk_Bits>::value,
crc_table_entry<TAccumulator, 137U, Polynomial, Reflect, Chunk_Bits>::value,
crc_table_entry<TAccumulator, 138U, Polynomial, Reflect, Chunk_Bits>::value,
crc_table_entry<TAccumulator, 139U, Polynomial, Reflect, Chunk_Bits>::value,
crc_table_entry<TAccumulator, 140U, Polynomial, Reflect, Chunk_Bits>::value,
crc_table_entry<TAccumulator, 141U, Polynomial, Reflect, Chunk_Bits>::value,
crc_table_entry<TAccumulator, 142U, Polynomial, Reflect, Chunk_Bits>::value,
crc_table_entry<TAccumulator, 143U, Polynomial, Reflect, Chunk_Bits>::value,
crc_table_entry<TAccumulator, 144U, Polynomial, Reflect, Chunk_Bits>::value,
crc_table_entry<TAccumulator, 145U, Polynomial, Reflect, Chunk_Bits>::value,
crc_table_entry<TAccumulator, 146U, Polynomial, Reflect, Chunk_Bits>::value,
crc_table_entry<TAccumulator, 147U, Polynomial, Reflect, Chunk_Bits>::value,
crc_table_entry<TAccumulator, 148U, Polynomial, Reflect, Chunk_Bits>::value,
crc_table_entry<TAccumulator, 149U, Polynomial, Reflect, Chunk_Bits>::value,
crc_table_entry<TAccumulator, 150U, Polynomial, Reflect, Chunk_Bits>::value,
crc_table_entry<TAccumulator, 151U, Polynomial, Reflect, Chunk_Bits>::value,
crc_table_entry<TAccumulator, 152U, Polynomial, Reflect, Chunk_Bits>::value,
crc_table_entry<TAccumulator, 153U, Polynomial, Reflect, Chunk_Bits>::value,
crc_table_entry<TAccumulator, 154U, Polynomial, Reflect, Chunk_Bits>::value,
crc_table_entry<TAccumulator, 155U, Polynomial, Reflect, Chunk_Bits>::value,
crc_table_entry<TAccumulator, 156U, Polynomial, Reflect, Chunk_Bits>::value,
crc_table_entry<TAccumulator, 157U, Polynomial, Reflect, Chunk_Bits>::value,
crc_table_entry<TAccumulator, 158U, Polynomial, Reflect, Chunk_Bits>::value,
crc_table_entry<TAccumulator, 159U, Polynomial, Reflect, Chunk_Bits>::value,
crc_table_entry<TAccumulator, 160U, Polynomial, Reflect, Chunk_Bits>::value,
crc_table_entry<TAccumulator, 161U, Polynomial, Reflect, Chunk_Bits>::value,
crc_table_entry<TAccumulator, 162U, Polynomial, Reflect, Chunk_Bits>::value,
crc_table_entry<TAccumulator, 163U, Polynomial, Reflect, Chunk_Bits>::value,
crc_table_entry<TAccumulator, 164U, Polynomial, Reflect, Chunk_Bits>::value,
crc_table_entry<TAccumulator, 165U, Polynomial, Reflect, Chunk_Bits>::value,
crc_table_entry<TAccumulator, 166U, Polynomial, Reflect, Chunk_Bits>::value,
crc_table_entry<TAccumulator, 167U, Polynomial, Reflect, Chunk_Bits>::value,
crc_table_entry<TAccumulator, 168U, Polynomial, Reflect, Chunk_Bits>::value,
crc_table_entry<TAccumulator, 169U, Polynomial, Reflect, Chunk_Bits>::value,
crc_table_entry<TAccumulator, 170U, Polynomial, Reflect, Chunk_Bits>::value,
crc_table_entry<TAccumulator, 171U, Polynomial, Reflect, Chunk_Bits>::value,
crc_table_entry<TAccumulator, 172U, Polynomial, Reflect, Chunk_Bits>::value,
crc_table_entry<TAccumulator, 173U, Polynomial, Reflect, Chunk_Bits>::value,
crc_table_entry<TAccumulator, 174U, Polynomial, Reflect, Chunk_Bits>::value,
crc_table_entry<TAccumulator, 175U, Polynomial, Reflect, Chunk_Bits>::value,
crc_table_entry<TAccumulator, 176U, Polynomial, Reflect, Chunk_Bits>::value,
crc_table_entry<TAccumulator, 177U, Polynomial, Reflect, Chunk_Bits>::value,
crc_table_entry<TAccumulator, 178U, Polynomial, Reflect, Chunk_Bits>::value,
crc_table_entry<TAccumulator, 179U, Polynomial, Reflect, Chunk_Bits>::value,
crc_table_entry<TAccumulator, 180U, Polynomial, Reflect, Chunk_Bits>::value,
crc_table_entry<TAccumulator, 181U, Polynomial, Reflect, Chunk_Bits>::value,
crc_table_entry<TAccumulator, 182U, Polynomial, Reflect, Chunk_Bits>::value,
crc_table_entry<TAccumulator, 183U, Polynomial, Reflect, Chunk_Bits>::value,
crc_table_entry<TAccumulator, 184U, Polynomial, Reflect, Chunk_Bits>::value,
crc_table_entry<TAccumulator, 185U, Polynomial, Reflect, Chunk_Bits>::value,
crc_table_entry<TAccumulator, 186U, Polynomial, Reflect, Chunk_Bits>::value,
crc_table_entry<TAccumulator, 187U, Polynomial, Reflect, Chunk_Bits>::value,
crc_table_entry<TAccumulator, 188U, Polynomial, Reflect, Chunk_Bits>::value,
crc_table_entry<TAccumulator, 189U, Polynomial, Reflect, Chunk_Bits>::value,
crc_table_entry<TAccumulator, 190U, Polynomial, Reflect, Chunk_Bits>::value,
crc_table_entry<TAccumulator, 191U, Polynomial, Reflect, Chunk_Bits>::value,
crc_table_entry<TAccumulator, 192U, Polynomial, Reflect, Chunk_Bits>::value,
crc_table_entry<TAccumulator, 193U, Polynomial, Reflect, Chunk_Bits>::value,
crc_table_entry<TAccumulator, 194U, Polynomial, Reflect, Chunk_Bits>::value,
crc_table_entry<TAccumulator, 195U, Polynomial, Reflect, Chunk_Bits>::value,
crc_table_entry<TAccumulator, 196U, Polynomial, Reflect, Chunk_Bits>::value,
crc_table_entry<TAccumulator, 197U, Polynomial, Reflect, Chunk_Bits>::value,
crc_table_entry<TAccumulator, 198U, Polynomial, Reflect, Chunk_Bits>::value,
crc_table_entry<TAccumulator, 199U, Polynomial, Reflect, Chunk_Bits>::value,
crc_table_entry<TAccumulator, 200U, Polynomial, Reflect, Chunk_Bits>::value,
crc_table_entry<TAccumulator, 201U, Polynomial, Reflect, Chunk_Bits>::value,
crc_table_entry<TAccumulator, 202U, Polynomial, Reflect, Chunk_Bits>::value,
crc_table_entry<TAccumulator, 203U, Polynomial, Reflect, Chunk_Bits>::value,
crc_table_entry<TAccumulator, 204U, Polynomial, Reflect, Chunk_Bits>::value,
crc_table_entry<TAccumulator, 205U, Polynomial, Reflect, Chunk_Bits>::value,
crc_table_entry<TAccumulator, 206U, Polynomial, Reflect, Chunk_Bits>::value,
crc_table_entry<TAccumulator, 207U, Polynomial, Reflect, Chunk_Bits>::value,
crc_table_entry<TAccumulator, 208U, Polynomial, Reflect, Chunk_Bits>::value,
crc_table_entry<TAccumulator, 209U, Polynomial, Reflect, Chunk_Bits>::value,
crc_table_entry<TAccumulator, 210U, Polynomial, Reflect, Chunk_Bits>::value,
crc_table_entry<TAccumulator, 211U, Polynomial, Reflect, Chunk_Bits>::value,
crc_table_entry<TAccumulator, 212U, Polynomial, Reflect, Chunk_Bits>::value,
crc_table_entry<TAccumulator, 213U, Polynomial, Reflect, Chunk_Bits>::value,
crc_table_entry<TAccumulator, 214U, Polynomial, Reflect, Chunk_Bits>::value,
crc_table_entry<TAccumulator, 215U, Polynomial, Reflect, Chunk_Bits>::value,
crc_table_entry<TAccumulator, 216U, Polynomial, Reflect, Chunk_Bits>::value,
crc_table_entry<TAccumulator, 217U, Polynomial, Reflect, Chunk_Bits>::value,
crc_table_entry<TAccumulator, 218U, Polynomial, Reflect, Chunk_Bits>::value,
crc_table_entry<TAccumulator, 219U, Polynomial, Reflect, Chunk_Bits>::value,
crc_table_entry<TAccumulator, 220U, Polynomial, Reflect, Chunk_Bits>::value,
crc_table_entry<TAccumulator, 221U, Polynomial, Reflect, Chunk_Bits>::value,
crc_table_entry<TAccumulator, 222U, Polynomial, Reflect, Chunk_Bits>::value,
crc_table_entry<TAccumulator, 223U, Polynomial, Reflect, Chunk_Bits>::value,
crc_table_entry<TAccumulator, 224U, Polynomial, Reflect, Chunk_Bits>::value,
crc_table_entry<TAccumulator, 225U, Polynomial, Reflect, Chunk_Bits>::value,
crc_table_entry<TAccumulator, 226U, Polynomial, Reflect, Chunk_Bits>::value,
crc_table_entry<TAccumulator, 227U, Polynomial, Reflect, Chunk_Bits>::value,
crc_table_entry<TAccumulator, 228U, Polynomial, Reflect, Chunk_Bits>::value,
crc_table_entry<TAccumulator, 229U, Polynomial, Reflect, Chunk_Bits>::value,
crc_table_entry<TAccumulator, 230U, Polynomial, Reflect, Chunk_Bits>::value,
crc_table_entry<TAccumulator, 231U, Polynomial, Reflect, Chunk_Bits>::value,
crc_table_entry<TAccumulator, 232U, Polynomial, Reflect, Chunk_Bits>::value,
crc_table_entry<TAccumulator, 233U, Polynomial, Reflect, Chunk_Bits>::value,
crc_table_entry<TAccumulator, 234U, Polynomial, Reflect, Chunk_Bits>::value,
crc_table_entry<TAccumulator, 235U, Polynomial, Reflect, Chunk_Bits>::value,
crc_table_entry<TAccumulator, 236U, Polynomial, Reflect, Chunk_Bits>::value,
crc_table_entry<TAccumulator, 237U, Polynomial, Reflect, Chunk_Bits>::value,
crc_table_entry<TAccumulator, 238U, Polynomial, Reflect, Chunk_Bits>::value,
crc_table_entry<TAccumulator, 239U, Polynomial, Reflect, Chunk_Bits>::value,
crc_table_entry<TAccumulator, 240U, Polynomial, Reflect, Chunk_Bits>::value,
crc_table_entry<TAccumulator, 241U, Polynomial, Reflect, Chunk_Bits>::value,
crc_table_entry<TAccumulator, 242U, Polynomial, Reflect, Chunk_Bits>::value,
crc_table_entry<TAccumulator, 243U, Polynomial, Reflect, Chunk_Bits>::value,
crc_table_entry<TAccumulator, 244U, Polynomial, Reflect, Chunk_Bits>::value,
crc_table_entry<TAccumulator, 245U, Polynomial, Reflect, Chunk_Bits>::value,
crc_table_entry<TAccumulator, 246U, Polynomial, Reflect, Chunk_Bits>::value,
crc_table_entry<TAccumulator, 247U, Polynomial, Reflect, Chunk_Bits>::value,
crc_table_entry<TAccumulator, 248U, Polynomial, Reflect, Chunk_Bits>::value,
crc_table_entry<TAccumulator, 249U, Polynomial, Reflect, Chunk_Bits>::value,
crc_table_entry<TAccumulator, 250U, Polynomial, Reflect, Chunk_Bits>::value,
crc_table_entry<TAccumulator, 251U, Polynomial, Reflect, Chunk_Bits>::value,
crc_table_entry<TAccumulator, 252U, Polynomial, Reflect, Chunk_Bits>::value,
crc_table_entry<TAccumulator, 253U, Polynomial, Reflect, Chunk_Bits>::value,
crc_table_entry<TAccumulator, 254U, Polynomial, Reflect, Chunk_Bits>::value,
crc_table_entry<TAccumulator, 255U, Polynomial, Reflect, Chunk_Bits>::value
};
crc = crc_update_chunk<TAccumulator, Chunk_Mask, Chunk_Bits, Accumulator_Bits, Reflect>(crc, value, table);
return crc;
}
//*************************************************************************
TAccumulator final(TAccumulator crc) const
{
return crc ^ Xor_Out;
}
};
//*********************************
template <typename TAccumulator, TAccumulator Polynomial, TAccumulator Initial, TAccumulator Xor_Out, bool Reflect>
struct crc_policy<TAccumulator, Polynomial, Initial, Xor_Out, Reflect, 16U>
{
static ETL_CONSTANT size_t Table_Size = 16U;
static ETL_CONSTANT uint8_t Chunk_Mask = crc_traits<Table_Size>::Chunk_Mask;
static ETL_CONSTANT uint8_t Chunk_Bits = crc_traits<Table_Size>::Chunk_Bits;
static ETL_CONSTANT size_t Accumulator_Bits = etl::integral_limits<TAccumulator>::bits;
typedef TAccumulator value_type;
//*************************************************************************
ETL_CONSTEXPR TAccumulator initial() const
{
return Initial;
}
//*************************************************************************
static TAccumulator update_chunk(TAccumulator crc, uint8_t value, const TAccumulator table[])
{
// Extract the most significant nibble of the crc and xor with the value nibble.
size_t index = (crc >> (etl::integral_limits<uint8_t>::bits - Chunk_Bits)) ^ value;
crc <<= Chunk_Bits;
crc ^= table[index];
return crc;
}
//*************************************************************************
TAccumulator add(TAccumulator crc, uint8_t value) const
{
static ETL_CONSTANT TAccumulator table[Table_Size] =
{
crc_table_entry<TAccumulator, 0U, Polynomial, Reflect, Chunk_Bits>::value,
crc_table_entry<TAccumulator, 1U, Polynomial, Reflect, Chunk_Bits>::value,
crc_table_entry<TAccumulator, 2U, Polynomial, Reflect, Chunk_Bits>::value,
crc_table_entry<TAccumulator, 3U, Polynomial, Reflect, Chunk_Bits>::value,
crc_table_entry<TAccumulator, 4U, Polynomial, Reflect, Chunk_Bits>::value,
crc_table_entry<TAccumulator, 5U, Polynomial, Reflect, Chunk_Bits>::value,
crc_table_entry<TAccumulator, 6U, Polynomial, Reflect, Chunk_Bits>::value,
crc_table_entry<TAccumulator, 7U, Polynomial, Reflect, Chunk_Bits>::value,
crc_table_entry<TAccumulator, 8U, Polynomial, Reflect, Chunk_Bits>::value,
crc_table_entry<TAccumulator, 9U, Polynomial, Reflect, Chunk_Bits>::value,
crc_table_entry<TAccumulator, 10U, Polynomial, Reflect, Chunk_Bits>::value,
crc_table_entry<TAccumulator, 11U, Polynomial, Reflect, Chunk_Bits>::value,
crc_table_entry<TAccumulator, 12U, Polynomial, Reflect, Chunk_Bits>::value,
crc_table_entry<TAccumulator, 13U, Polynomial, Reflect, Chunk_Bits>::value,
crc_table_entry<TAccumulator, 14U, Polynomial, Reflect, Chunk_Bits>::value,
crc_table_entry<TAccumulator, 15U, Polynomial, Reflect, Chunk_Bits>::value
};
crc = update_chunk(crc, (value >> Chunk_Bits) & Chunk_Mask, table);
crc = update_chunk(crc, value & Chunk_Mask, table);
return crc;
}
//*************************************************************************
TAccumulator final(TAccumulator crc) const
{
return crc ^ Xor_Out;
}
};
//*********************************
template <typename TAccumulator, TAccumulator Polynomial, TAccumulator Initial, TAccumulator Xor_Out, bool Reflect>
struct crc_policy<TAccumulator, Polynomial, Initial, Xor_Out, Reflect, 4U>
{
static ETL_CONSTANT size_t Table_Size = 4U;
static ETL_CONSTANT uint8_t Chunk_Mask = crc_traits<Table_Size>::Chunk_Mask;
static ETL_CONSTANT uint8_t Chunk_Bits = crc_traits<Table_Size>::Chunk_Bits;
static ETL_CONSTANT size_t Accumulator_Bits = etl::integral_limits<TAccumulator>::bits;
typedef TAccumulator value_type;
//*************************************************************************
ETL_CONSTEXPR TAccumulator initial() const
{
return Initial;
}
//*************************************************************************
static TAccumulator update_chunk(TAccumulator crc, uint8_t value, const TAccumulator table[])
{
// Extract the most significant nibble of the crc and xor with the value nibble.
size_t index = (crc >> (etl::integral_limits<uint8_t>::bits - Chunk_Bits)) ^ value;
crc <<= Chunk_Bits;
crc ^= table[index];
return crc;
}
//*************************************************************************
TAccumulator add(TAccumulator crc, uint8_t value) const
{
static ETL_CONSTANT TAccumulator table[Table_Size] =
{
crc_table_entry<TAccumulator, 0U, Polynomial, Reflect, Chunk_Bits>::value,
crc_table_entry<TAccumulator, 1U, Polynomial, Reflect, Chunk_Bits>::value,
crc_table_entry<TAccumulator, 2U, Polynomial, Reflect, Chunk_Bits>::value,
crc_table_entry<TAccumulator, 3U, Polynomial, Reflect, Chunk_Bits>::value
};
crc = update_chunk(crc, (value >> (Chunk_Bits * 3U)) & Chunk_Mask, table);
crc = update_chunk(crc, (value >> (Chunk_Bits * 2U)) & Chunk_Mask, table);
crc = update_chunk(crc, (value >> (Chunk_Bits * 1U)) & Chunk_Mask, table);
crc = update_chunk(crc, value & Chunk_Mask, table);
return crc;
}
//*************************************************************************
TAccumulator final(TAccumulator crc) const
{
return crc ^ Xor_Out;
}
};
//*****************************************************************************
///
//*****************************************************************************
template <typename TAccumulator, TAccumulator Polynomial, TAccumulator Initial, TAccumulator Xor_Out, bool Reflect, size_t Table_Size>
class crc_type : public etl::frame_check_sequence<crc_policy<TAccumulator, Polynomial, Initial, Xor_Out, Reflect, Table_Size> >
{
public:
ETL_STATIC_ASSERT((Table_Size == 4U) || (Table_Size == 16U) || (Table_Size == 256U), "Table size must be 4, 16 or 256");
//*************************************************************************
/// Default constructor.
//*************************************************************************
crc_type()
{
this->reset();
}
//*************************************************************************
/// Constructor from range.
/// \param begin Start of the range.
/// \param end End of the range.
//*************************************************************************
template<typename TIterator>
crc_type(TIterator begin, const TIterator end)
{
this->reset();
this->add(begin, end);
}
};
}
}

View File

@ -0,0 +1,42 @@
#pragma once
#include "../platform.h"
namespace etl
{
namespace private_crc
{
template <typename TAccumulator, TAccumulator Polynomial_, TAccumulator Initial_, TAccumulator Xor_Out_, bool Reflect_>
struct crc_parameters
{
typedef TAccumulator accumulator_type;
static ETL_CONSTANT TAccumulator Polynomial = Polynomial_;
static ETL_CONSTANT TAccumulator Initial = Initial_;
static ETL_CONSTANT TAccumulator Xor_Out = Xor_Out_;
static ETL_CONSTANT bool Reflect = Reflect_;
};
// 8 bit.
typedef crc_parameters<uint8_t, 0x07U, 0x00U, 0x00U, false> crc8_ccitt_parameters;
typedef crc_parameters<uint8_t, 0x07U, 0xFFU, 0x00U, true> crc8_rohc_parameters;
// 16 bit.
typedef crc_parameters<uint16_t, 0x8005U, 0x0000U, 0x0000U, true> crc16_parameters;
typedef crc_parameters<uint16_t, 0x1021U, 0xFFFFU, 0x0000U, false> crc16_ccitt_parameters;
typedef crc_parameters<uint16_t, 0x1021U, 0x1D0FU, 0x0000U, false> crc16_aug_ccitt_parameters;
typedef crc_parameters<uint16_t, 0x1021U, 0xFFFFU, 0xFFFFU, false> crc16_genibus_parameters;
typedef crc_parameters<uint16_t, 0x1021U, 0x0000U, 0x0000U, true> crc16_kermit_parameters;
typedef crc_parameters<uint16_t, 0x8005U, 0xFFFFU, 0x0000U, true> crc16_modbus_parameters;
typedef crc_parameters<uint16_t, 0x8005U, 0xFFFFU, 0xFFFFU, true> crc16_usb_parameters;
typedef crc_parameters<uint16_t, 0x1021U, 0xFFFFU, 0xFFFFU, true> crc16_x25_parameters;
typedef crc_parameters<uint16_t, 0x1021, 0x0000U, 0x0000U, false> crc16_xmodem_parameters;
// 32 bit.
typedef crc_parameters<uint32_t, 0X04C11DB7U, 0xFFFFFFFFU, 0xFFFFFFFFU, true> crc32_parameters;
// 64 bit.
typedef crc_parameters<uint64_t, 0x42F0E1EBA9EA3693U, 0x0000000000000000U, 0x0000000000000000U, false> crc64_ecma_parameters;
}
}

View File

@ -0,0 +1,701 @@
#pragma once
#include <stdint.h>
#include <limits.h>
//*****************************************************************************
template <typename TAccumulator, TAccumulator Polynomial, TAccumulator Entry>
class entry
{
private:
static const size_t Accumulator_Bits = sizeof(TAccumulator) * CHAR_BIT;
static const bool Do_Poly = (Entry & (TAccumulator(1U) << (Accumulator_Bits - 1))) != 0U;
public:
static const TAccumulator value = TAccumulator(Do_Poly ? (Entry << 1U) ^ Polynomial : (Entry << 1U));
};
//*****************************************************************************
/// 8 bit chunks
//*****************************************************************************
template <typename TAccumulator, size_t Index, TAccumulator Polynomial>
class table_entry_8
{
//private:
public:
static const size_t Accumulator_Bits = sizeof(TAccumulator) * CHAR_BIT;
static const size_t Shift_Bits = size_t(Accumulator_Bits - 8U);
static const TAccumulator Entry = TAccumulator(Index << Shift_Bits);
public:
static const TAccumulator value = entry<TAccumulator, Polynomial,
entry<TAccumulator, Polynomial,
entry<TAccumulator, Polynomial,
entry<TAccumulator, Polynomial,
entry<TAccumulator, Polynomial,
entry<TAccumulator, Polynomial,
entry<TAccumulator, Polynomial,
entry<TAccumulator, Polynomial, Entry>::value>::value>::value>::value>::value>::value>::value>::value;
};
//*****************************************************************************
/// 4 bit chunks
//*****************************************************************************
template <typename TAccumulator, size_t Index, TAccumulator Polynomial>
class table_entry_4
{
private:
static const size_t Accumulator_Bits = sizeof(TAccumulator) * CHAR_BIT;
static const size_t Shift_Bits = size_t(Accumulator_Bits - Chunk_4_Bits);
static const TAccumulator Entry = TAccumulator(Index << Shift_Bits);
public:
static const TAccumulator value = entry<TAccumulator, Polynomial,
entry<TAccumulator, Polynomial,
entry<TAccumulator, Polynomial,
entry<TAccumulator, Polynomial, Entry>::value>::value>::value>::value;
};
//*****************************************************************************
/// 2 bit chunks
//*****************************************************************************
template <typename TAccumulator, size_t Index, TAccumulator Polynomial>
class table_entry_2
{
private:
static const size_t Accumulator_Bits = sizeof(TAccumulator) * CHAR_BIT;
static const size_t Shift_Bits = size_t(Accumulator_Bits - Chunk_2_Bits);
static const TAccumulator Entry = TAccumulator(Index << Shift_Bits);
public:
static const TAccumulator value = entry<TAccumulator, Polynomial,
entry<TAccumulator, Polynomial, Entry>::value>::value;
};
//*****************************************************************************
template <typename TAccumulator, TAccumulator Polynomial, size_t Table_Size>
struct crc_table;
template <typename TAccumulator, TAccumulator Polynomial>
struct crc_table<TAccumulator, Polynomial, 256>
{
static const TAccumulator* get_table()
{
static const TAccumulator table[256] =
{
table_entry<TAccumulator, 0U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 1U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 2U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 3U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 4U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 5U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 6U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 7U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 8U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 9U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 10U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 11U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 12U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 13U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 14U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 15U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 16U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 17U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 18U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 19U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 20U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 21U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 22U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 23U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 24U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 25U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 26U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 27U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 28U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 29U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 30U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 31U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 32U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 33U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 34U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 35U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 36U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 37U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 38U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 39U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 40U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 41U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 42U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 43U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 44U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 45U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 46U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 47U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 48U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 49U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 50U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 51U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 52U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 53U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 54U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 55U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 56U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 57U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 58U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 59U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 60U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 61U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 62U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 63U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 64U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 65U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 66U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 67U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 68U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 69U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 70U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 71U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 72U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 73U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 74U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 75U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 76U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 77U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 78U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 79U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 80U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 81U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 82U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 83U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 84U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 85U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 86U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 87U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 88U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 89U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 90U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 91U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 92U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 93U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 94U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 95U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 96U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 97U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 98U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 99U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 100U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 101U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 102U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 103U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 104U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 105U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 106U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 107U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 108U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 109U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 110U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 111U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 112U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 113U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 114U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 115U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 116U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 117U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 118U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 119U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 120U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 121U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 122U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 123U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 124U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 125U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 126U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 127U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 128U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 129U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 130U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 131U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 132U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 133U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 134U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 135U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 136U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 137U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 138U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 139U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 140U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 141U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 142U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 143U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 144U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 145U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 146U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 147U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 148U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 149U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 150U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 151U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 152U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 153U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 154U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 155U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 156U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 157U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 158U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 159U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 160U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 161U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 162U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 163U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 164U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 165U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 166U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 167U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 168U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 169U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 170U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 171U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 172U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 173U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 174U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 175U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 176U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 177U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 178U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 179U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 180U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 181U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 182U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 183U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 184U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 185U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 186U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 187U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 188U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 189U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 190U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 191U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 192U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 193U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 194U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 195U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 196U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 197U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 198U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 199U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 200U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 201U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 202U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 203U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 204U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 205U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 206U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 207U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 208U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 209U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 210U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 211U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 212U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 213U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 214U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 215U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 216U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 217U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 218U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 219U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 220U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 221U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 222U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 223U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 224U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 225U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 226U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 227U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 228U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 229U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 230U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 231U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 232U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 233U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 234U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 235U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 236U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 237U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 238U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 239U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 240U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 241U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 242U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 243U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 244U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 245U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 246U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 247U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 248U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 249U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 250U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 251U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 252U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 253U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 254U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 255U, Polynomial, Chunk_8_Bits>::value
};
return table;
}
};
template <typename TAccumulator, TAccumulator Polynomial>
struct crc_table<TAccumulator, Polynomial, 16>
{
static const TAccumulator* get_table()
{
static const TAccumulator table[16] =
{
table_entry<TAccumulator, 0U, Polynomial, Chunk_4_Bits>::value,
table_entry<TAccumulator, 1U, Polynomial, Chunk_4_Bits>::value,
table_entry<TAccumulator, 2U, Polynomial, Chunk_4_Bits>::value,
table_entry<TAccumulator, 3U, Polynomial, Chunk_4_Bits>::value,
table_entry<TAccumulator, 4U, Polynomial, Chunk_4_Bits>::value,
table_entry<TAccumulator, 5U, Polynomial, Chunk_4_Bits>::value,
table_entry<TAccumulator, 6U, Polynomial, Chunk_4_Bits>::value,
table_entry<TAccumulator, 7U, Polynomial, Chunk_4_Bits>::value,
table_entry<TAccumulator, 8U, Polynomial, Chunk_4_Bits>::value,
table_entry<TAccumulator, 9U, Polynomial, Chunk_4_Bits>::value,
table_entry<TAccumulator, 10U, Polynomial, Chunk_4_Bits>::value,
table_entry<TAccumulator, 11U, Polynomial, Chunk_4_Bits>::value,
table_entry<TAccumulator, 12U, Polynomial, Chunk_4_Bits>::value,
table_entry<TAccumulator, 13U, Polynomial, Chunk_4_Bits>::value,
table_entry<TAccumulator, 14U, Polynomial, Chunk_4_Bits>::value,
table_entry<TAccumulator, 15U, Polynomial, Chunk_4_Bits>::value
};
return table;
}
};
template <typename TAccumulator, TAccumulator Polynomial>
struct crc_table<TAccumulator, Polynomial, 4>
{
static const TAccumulator* get_table()
{
static const TAccumulator table[4] =
{
table_entry<TAccumulator, 0U, Polynomial, Chunk_2_Bits>::value,
table_entry<TAccumulator, 1U, Polynomial, Chunk_2_Bits>::value,
table_entry<TAccumulator, 2U, Polynomial, Chunk_2_Bits>::value,
table_entry<TAccumulator, 3U, Polynomial, Chunk_2_Bits>::value
};
return table;
}
};
//
// Define the CRC algorithm parameters
//
template <typename TAccumulator, TAccumulator Polynomial, TAccumulator Initial, TAccumulator Xor_Out, bool Reverse>
struct crc_algorithm
{
using accumulator_type = TAccumulator;
static constexpr TAccumulator polynomial = Polynomial;
static constexpr TAccumulator initial_value = Initial;
static constexpr TAccumulator xor_out_value = Xor_Out;
static constexpr bool reverse = Reverse;
};
//
// Define the basic traits we use in our CRC accumulators and Table Lookup
//
template <typename TAccumulator, const size_t Table_Size>
struct crc_traits {};
template <typename TAccumulator>
struct crc_traits<TAccumulator, size_t::tiny>
{
static constexpr std::size_t ACCUMULATOR_BITS = sizeof(TAccumulator) * 8;
static constexpr std::size_t CHUNK_BITS = 2;
static constexpr uint8_t CHUNK_MASK = 0x03u;
static constexpr std::size_t TABLE_ENTRIES = 1u << CHUNK_BITS;
using table_type = std::array<TAccumulator, TABLE_ENTRIES>;
};
template <typename TAccumulator>
struct crc_traits<TAccumulator, size_t::small>
{
static constexpr std::size_t ACCUMULATOR_BITS = sizeof(TAccumulator) * 8;
static constexpr std::size_t CHUNK_BITS = 4;
static constexpr uint8_t CHUNK_MASK = 0x0Fu;
static constexpr std::size_t TABLE_ENTRIES = 1u << CHUNK_BITS;
using table_type = std::array<TAccumulator, TABLE_ENTRIES>;
};
template <typename TAccumulator>
struct crc_traits<TAccumulator, size_t::large>
{
static constexpr std::size_t ACCUMULATOR_BITS = sizeof(TAccumulator) * 8;
static constexpr std::size_t CHUNK_BITS = 8;
static constexpr uint8_t CHUNK_MASK = 0xFFu;
static constexpr std::size_t TABLE_ENTRIES = 1u << CHUNK_BITS;
using table_type = std::array<TAccumulator, TABLE_ENTRIES>;
};
//
// CRC rotation policies.
//
// Forward rotation means that we clock in data MSB->LSB and rotate the Accumulator register left
// Reverse rotation means that we clock in data LSB->MSB and rotate the Accumulator register right
//
template <typename TAccumulator, const size_t Table_Size>
struct crc_forward_policy
{
using traits = crc_traits<TAccumulator, Table_Size>;
[[nodiscard]] static constexpr TAccumulator update_impl_tiny(
TAccumulator crc, uint8_t value, typename traits::table_type const& table)
{
crc = update_chunk(crc, (value >> (traits::CHUNK_BITS * 3)) & traits::CHUNK_MASK, table); // high chunk
crc = update_chunk(crc, (value >> (traits::CHUNK_BITS * 2)) & traits::CHUNK_MASK, table);
crc = update_chunk(crc, (value >> (traits::CHUNK_BITS * 1)) & traits::CHUNK_MASK, table);
crc = update_chunk(crc, value & traits::CHUNK_MASK, table); // low chunk
return crc;
}
[[nodiscard]] static constexpr TAccumulator update_impl_small(
TAccumulator crc, uint8_t value, typename traits::table_type const& table)
{
crc = update_chunk(crc, value >> traits::CHUNK_BITS, table); // high nibble
crc = update_chunk(crc, value & traits::CHUNK_MASK, table); // low nibble
return crc;
}
[[nodiscard]] static constexpr TAccumulator update_impl_large(
TAccumulator crc, uint8_t value, typename traits::table_type const& table)
{
crc = update_chunk(crc, value, table); // full byte
return crc;
}
[[nodiscard]] static constexpr TAccumulator update_chunk(
TAccumulator crc, uint8_t value, typename traits::table_type const& table)
{
// ensure we have only 4 bits
value &= traits::CHUNK_MASK;
// Extract the most significant nibble of the crc and xor with the value nibble
uint8_t t = (crc >> (traits::ACCUMULATOR_BITS - traits::CHUNK_BITS)) ^ value;
// special case for when chunk size is same as accumulator size.
if constexpr (traits::ACCUMULATOR_BITS > traits::CHUNK_BITS) {
// shit crc left the size of the nibble
crc <<= traits::CHUNK_BITS;
// xor in the table data
crc ^= table[t];
}
else {
crc = table[t];
}
return crc;
}
[[nodiscard]] static constexpr TAccumulator generate_entry(TAccumulator const polynomial, uint8_t const index)
{
// initialise with the register in the upper bits
TAccumulator entry = TAccumulator(index) << (traits::ACCUMULATOR_BITS - traits::CHUNK_BITS);
for (std::size_t i = 0; i < traits::CHUNK_BITS; i++)
{
// We are processing MSBs / rotating left so we need to check the high bit
if (entry & (TAccumulator(1u) << (traits::ACCUMULATOR_BITS - 1))) {
entry = (entry << 1) ^ polynomial;
}
else {
entry = (entry << 1);
}
}
return entry;
}
[[nodiscard]] static constexpr TAccumulator make_initial_value(TAccumulator init)
{
return init;
}
};
template <typename TAccumulator, const size_t Table_Size>
struct crc_reverse_policy
{
using traits = crc_traits<TAccumulator, Table_Size>;
[[nodiscard]] static constexpr TAccumulator update_impl_tiny(
TAccumulator crc, uint8_t value, typename traits::table_type const& table)
{
crc = update_chunk(crc, value & traits::CHUNK_MASK, table); // low chunk
crc = update_chunk(crc, (value >> (traits::CHUNK_BITS * 1)) & traits::CHUNK_MASK, table);
crc = update_chunk(crc, (value >> (traits::CHUNK_BITS * 2)) & traits::CHUNK_MASK, table);
crc = update_chunk(crc, (value >> (traits::CHUNK_BITS * 3)) & traits::CHUNK_MASK, table); // high chunk
return crc;
}
[[nodiscard]] static constexpr TAccumulator update_impl_small(
TAccumulator crc, uint8_t value, typename traits::table_type const& table)
{
crc = update_chunk(crc, value & traits::CHUNK_MASK, table); // low nibble
crc = update_chunk(crc, value >> traits::CHUNK_BITS, table); // high nibble
return crc;
}
[[nodiscard]] static constexpr TAccumulator update_impl_large(
TAccumulator crc, uint8_t value, typename traits::table_type const& table)
{
crc = update_chunk(crc, value, table); // full byte
return crc;
}
[[nodiscard]] static constexpr TAccumulator update_chunk(
TAccumulator crc, uint8_t value, typename traits::table_type const& table)
{
// ensure we have only 4 bits
value &= traits::CHUNK_MASK;
// Extract the least significant nibble of the crc and xor with the value nibble
uint8_t t = (crc & traits::CHUNK_MASK) ^ value;
// special case for when chunk size is same as accumulator size.
if constexpr (traits::ACCUMULATOR_BITS > traits::CHUNK_BITS) {
// shit crc right the size of a nibble
crc >>= traits::CHUNK_BITS;
// xor in the table data
crc ^= table[t];
}
else {
crc = table[t];
}
return crc;
}
[[nodiscard]] static constexpr TAccumulator generate_entry(TAccumulator const polynomial, uint8_t const index)
{
// initialise with the register in the lower bits
TAccumulator entry = TAccumulator(index);
for (std::size_t i = 0; i < traits::CHUNK_BITS; i++)
{
// we are processing LSBs/rotating right
if (entry & 0x1u) {
entry = (entry >> 1) ^ util::reverse_bits(polynomial);
}
else {
entry = (entry >> 1);
}
}
return entry;
}
[[nodiscard]] static constexpr TAccumulator make_initial_value(TAccumulator init)
{
return util::reverse_bits(init);
}
};
//
// A generic CRC lookup table sized for computing a nibble (4 bits) at a time.
//
// This is can be a large reduction of table space storage for embedded devices.
//
template <typename TAccumulator, TAccumulator Polynomial, bool Reverse, size_t Table_Size, typename = std::enable_if_t<std::is_unsigned<TAccumulator>::value>>
class crc_chunk_table
{
public:
using policy = typename std::conditional<Reverse, crc_reverse_policy<TAccumulator, Table_Size>, crc_forward_policy<TAccumulator, Table_Size>>::type;
using traits = typename policy::traits;
// update the given crc accumulator with the value
[[nodiscard]] static constexpr TAccumulator update(TAccumulator crc, uint8_t value)
{
if constexpr (Table_Size == size_t::tiny) {
return policy::update_impl_tiny(crc, value, m_Table);
}
else if constexpr (Table_Size == size_t::small) {
return policy::update_impl_small(crc, value, m_Table);
}
else if constexpr (Table_Size == size_t::large) {
return policy::update_impl_large(crc, value, m_Table);
}
else {
static_assert("Unknown size_t");
}
}
// the crc accumulator initial value may need to be modified by the policy
// to account for rotation direction
[[nodiscard]] static constexpr TAccumulator make_initial_value(TAccumulator init)
{
return policy::make_initial_value(init);
}
private:
};
//
// The generic CRC accumulator that is table driven
//
template <typename TAlgorithm, size_t Table_Size>
class crc
{
public:
using algorithm = TAlgorithm;
using accumulator_type = typename algorithm::accumulator_type;
//
// Update the accumulator with a new byte
//
void update(uint8_t value)
{
m_crc = table_impl::update(m_crc, value);
}
//
// Extract the final value of the accumulator.
//
[[nodiscard]] accumulator_type final() { return m_crc ^ algorithm::xor_out_value; }
//
// Reset the state of the accumulator back to the INITIAL value.
//
void reset() { m_crc = table_impl::make_initial_value(algorithm::initial_value); }
private:
using table_impl = crc_chunk_table<accumulator_type, algorithm::polynomial, algorithm::reverse, Table_Size>;
accumulator_type m_crc = table_impl::make_initial_value(algorithm::initial_value);
};

View File

@ -0,0 +1,519 @@
#pragma once
#include <stdint.h>
#include <limits.h>
#include "../binary.h"
#include "../integral_limits.h"
//*****************************************************************************
template <typename TAccumulator, TAccumulator Polynomial, TAccumulator Entry>
class entry
{
private:
static ETL_CONSTANT size_t Accumulator_Bits = etl::integral_limits<TAccumulator>::bits;
static ETL_CONSTANT bool Do_Poly = (Entry & (TAccumulator(1U) << (Accumulator_Bits - 1))) != 0U;
public:
static const TAccumulator value = TAccumulator(Do_Poly ? (Entry << 1U) ^ Polynomial : (Entry << 1U));
};
//*****************************************************************************
/// 8 bit chunks
//*****************************************************************************
template <typename TAccumulator, size_t Index, TAccumulator Polynomial>
class table_entry_8
{
//private:
public:
static const size_t Accumulator_Bits = entry<TAccumulator, Index, Polynomial>::Accumulator_Bits;
static const size_t Shift_Bits = size_t(Accumulator_Bits - 8U);
static const TAccumulator Entry = TAccumulator(Index << Shift_Bits);
public:
static const TAccumulator value = entry<TAccumulator, Polynomial,
entry<TAccumulator, Polynomial,
entry<TAccumulator, Polynomial,
entry<TAccumulator, Polynomial,
entry<TAccumulator, Polynomial,
entry<TAccumulator, Polynomial,
entry<TAccumulator, Polynomial,
entry<TAccumulator, Polynomial, Entry>::value>::value>::value>::value>::value>::value>::value>::value;
};
//*****************************************************************************
template <typename TAccumulator, TAccumulator Polynomial>
struct crc_table_256
{
static const TAccumulator* get_table()
{
static const TAccumulator table[256] =
{
table_entry_8<TAccumulator, 0U, Polynomial>::value,
table_entry_8<TAccumulator, 1U, Polynomial>::value,
table_entry_8<TAccumulator, 2U, Polynomial>::value,
table_entry_8<TAccumulator, 3U, Polynomial>::value,
table_entry_8<TAccumulator, 4U, Polynomial>::value,
table_entry_8<TAccumulator, 5U, Polynomial>::value,
table_entry_8<TAccumulator, 6U, Polynomial>::value,
table_entry_8<TAccumulator, 7U, Polynomial>::value,
table_entry_8<TAccumulator, 8U, Polynomial>::value,
table_entry_8<TAccumulator, 9U, Polynomial>::value,
table_entry_8<TAccumulator, 10U, Polynomial>::value,
table_entry_8<TAccumulator, 11U, Polynomial>::value,
table_entry_8<TAccumulator, 12U, Polynomial>::value,
table_entry_8<TAccumulator, 13U, Polynomial>::value,
table_entry_8<TAccumulator, 14U, Polynomial>::value,
table_entry_8<TAccumulator, 15U, Polynomial>::value,
table_entry_8<TAccumulator, 16U, Polynomial>::value,
table_entry_8<TAccumulator, 17U, Polynomial>::value,
table_entry_8<TAccumulator, 18U, Polynomial>::value,
table_entry_8<TAccumulator, 19U, Polynomial>::value,
table_entry_8<TAccumulator, 20U, Polynomial>::value,
table_entry_8<TAccumulator, 21U, Polynomial>::value,
table_entry_8<TAccumulator, 22U, Polynomial>::value,
table_entry_8<TAccumulator, 23U, Polynomial>::value,
table_entry_8<TAccumulator, 24U, Polynomial>::value,
table_entry_8<TAccumulator, 25U, Polynomial>::value,
table_entry_8<TAccumulator, 26U, Polynomial>::value,
table_entry_8<TAccumulator, 27U, Polynomial>::value,
table_entry_8<TAccumulator, 28U, Polynomial>::value,
table_entry_8<TAccumulator, 29U, Polynomial>::value,
table_entry_8<TAccumulator, 30U, Polynomial>::value,
table_entry_8<TAccumulator, 31U, Polynomial>::value,
table_entry_8<TAccumulator, 32U, Polynomial>::value,
table_entry_8<TAccumulator, 33U, Polynomial>::value,
table_entry_8<TAccumulator, 34U, Polynomial>::value,
table_entry_8<TAccumulator, 35U, Polynomial>::value,
table_entry_8<TAccumulator, 36U, Polynomial>::value,
table_entry_8<TAccumulator, 37U, Polynomial>::value,
table_entry_8<TAccumulator, 38U, Polynomial>::value,
table_entry_8<TAccumulator, 39U, Polynomial>::value,
table_entry_8<TAccumulator, 40U, Polynomial>::value,
table_entry_8<TAccumulator, 41U, Polynomial>::value,
table_entry_8<TAccumulator, 42U, Polynomial>::value,
table_entry_8<TAccumulator, 43U, Polynomial>::value,
table_entry_8<TAccumulator, 44U, Polynomial>::value,
table_entry_8<TAccumulator, 45U, Polynomial>::value,
table_entry_8<TAccumulator, 46U, Polynomial>::value,
table_entry_8<TAccumulator, 47U, Polynomial>::value,
table_entry_8<TAccumulator, 48U, Polynomial>::value,
table_entry_8<TAccumulator, 49U, Polynomial>::value,
table_entry_8<TAccumulator, 50U, Polynomial>::value,
table_entry_8<TAccumulator, 51U, Polynomial>::value,
table_entry_8<TAccumulator, 52U, Polynomial>::value,
table_entry_8<TAccumulator, 53U, Polynomial>::value,
table_entry_8<TAccumulator, 54U, Polynomial>::value,
table_entry_8<TAccumulator, 55U, Polynomial>::value,
table_entry_8<TAccumulator, 56U, Polynomial>::value,
table_entry_8<TAccumulator, 57U, Polynomial>::value,
table_entry_8<TAccumulator, 58U, Polynomial>::value,
table_entry_8<TAccumulator, 59U, Polynomial>::value,
table_entry_8<TAccumulator, 60U, Polynomial>::value,
table_entry_8<TAccumulator, 61U, Polynomial>::value,
table_entry_8<TAccumulator, 62U, Polynomial>::value,
table_entry_8<TAccumulator, 63U, Polynomial>::value,
table_entry_8<TAccumulator, 64U, Polynomial>::value,
table_entry_8<TAccumulator, 65U, Polynomial>::value,
table_entry_8<TAccumulator, 66U, Polynomial>::value,
table_entry_8<TAccumulator, 67U, Polynomial>::value,
table_entry_8<TAccumulator, 68U, Polynomial>::value,
table_entry_8<TAccumulator, 69U, Polynomial>::value,
table_entry_8<TAccumulator, 70U, Polynomial>::value,
table_entry_8<TAccumulator, 71U, Polynomial>::value,
table_entry_8<TAccumulator, 72U, Polynomial>::value,
table_entry_8<TAccumulator, 73U, Polynomial>::value,
table_entry_8<TAccumulator, 74U, Polynomial>::value,
table_entry_8<TAccumulator, 75U, Polynomial>::value,
table_entry_8<TAccumulator, 76U, Polynomial>::value,
table_entry_8<TAccumulator, 77U, Polynomial>::value,
table_entry_8<TAccumulator, 78U, Polynomial>::value,
table_entry_8<TAccumulator, 79U, Polynomial>::value,
table_entry_8<TAccumulator, 80U, Polynomial>::value,
table_entry_8<TAccumulator, 81U, Polynomial>::value,
table_entry_8<TAccumulator, 82U, Polynomial>::value,
table_entry_8<TAccumulator, 83U, Polynomial>::value,
table_entry_8<TAccumulator, 84U, Polynomial>::value,
table_entry_8<TAccumulator, 85U, Polynomial>::value,
table_entry_8<TAccumulator, 86U, Polynomial>::value,
table_entry_8<TAccumulator, 87U, Polynomial>::value,
table_entry_8<TAccumulator, 88U, Polynomial>::value,
table_entry_8<TAccumulator, 89U, Polynomial>::value,
table_entry_8<TAccumulator, 90U, Polynomial>::value,
table_entry_8<TAccumulator, 91U, Polynomial>::value,
table_entry_8<TAccumulator, 92U, Polynomial>::value,
table_entry_8<TAccumulator, 93U, Polynomial>::value,
table_entry_8<TAccumulator, 94U, Polynomial>::value,
table_entry_8<TAccumulator, 95U, Polynomial>::value,
table_entry_8<TAccumulator, 96U, Polynomial>::value,
table_entry_8<TAccumulator, 97U, Polynomial>::value,
table_entry_8<TAccumulator, 98U, Polynomial>::value,
table_entry_8<TAccumulator, 99U, Polynomial>::value,
table_entry_8<TAccumulator, 100U, Polynomial>::value,
table_entry_8<TAccumulator, 101U, Polynomial>::value,
table_entry_8<TAccumulator, 102U, Polynomial>::value,
table_entry_8<TAccumulator, 103U, Polynomial>::value,
table_entry_8<TAccumulator, 104U, Polynomial>::value,
table_entry_8<TAccumulator, 105U, Polynomial>::value,
table_entry_8<TAccumulator, 106U, Polynomial>::value,
table_entry_8<TAccumulator, 107U, Polynomial>::value,
table_entry_8<TAccumulator, 108U, Polynomial>::value,
table_entry_8<TAccumulator, 109U, Polynomial>::value,
table_entry_8<TAccumulator, 110U, Polynomial>::value,
table_entry_8<TAccumulator, 111U, Polynomial>::value,
table_entry_8<TAccumulator, 112U, Polynomial>::value,
table_entry_8<TAccumulator, 113U, Polynomial>::value,
table_entry_8<TAccumulator, 114U, Polynomial>::value,
table_entry_8<TAccumulator, 115U, Polynomial>::value,
table_entry_8<TAccumulator, 116U, Polynomial>::value,
table_entry_8<TAccumulator, 117U, Polynomial>::value,
table_entry_8<TAccumulator, 118U, Polynomial>::value,
table_entry_8<TAccumulator, 119U, Polynomial>::value,
table_entry_8<TAccumulator, 120U, Polynomial>::value,
table_entry_8<TAccumulator, 121U, Polynomial>::value,
table_entry_8<TAccumulator, 122U, Polynomial>::value,
table_entry_8<TAccumulator, 123U, Polynomial>::value,
table_entry_8<TAccumulator, 124U, Polynomial>::value,
table_entry_8<TAccumulator, 125U, Polynomial>::value,
table_entry_8<TAccumulator, 126U, Polynomial>::value,
table_entry_8<TAccumulator, 127U, Polynomial>::value,
table_entry_8<TAccumulator, 128U, Polynomial>::value,
table_entry_8<TAccumulator, 129U, Polynomial>::value,
table_entry_8<TAccumulator, 130U, Polynomial>::value,
table_entry_8<TAccumulator, 131U, Polynomial>::value,
table_entry_8<TAccumulator, 132U, Polynomial>::value,
table_entry_8<TAccumulator, 133U, Polynomial>::value,
table_entry_8<TAccumulator, 134U, Polynomial>::value,
table_entry_8<TAccumulator, 135U, Polynomial>::value,
table_entry_8<TAccumulator, 136U, Polynomial>::value,
table_entry_8<TAccumulator, 137U, Polynomial>::value,
table_entry_8<TAccumulator, 138U, Polynomial>::value,
table_entry_8<TAccumulator, 139U, Polynomial>::value,
table_entry_8<TAccumulator, 140U, Polynomial>::value,
table_entry_8<TAccumulator, 141U, Polynomial>::value,
table_entry_8<TAccumulator, 142U, Polynomial>::value,
table_entry_8<TAccumulator, 143U, Polynomial>::value,
table_entry_8<TAccumulator, 144U, Polynomial>::value,
table_entry_8<TAccumulator, 145U, Polynomial>::value,
table_entry_8<TAccumulator, 146U, Polynomial>::value,
table_entry_8<TAccumulator, 147U, Polynomial>::value,
table_entry_8<TAccumulator, 148U, Polynomial>::value,
table_entry_8<TAccumulator, 149U, Polynomial>::value,
table_entry_8<TAccumulator, 150U, Polynomial>::value,
table_entry_8<TAccumulator, 151U, Polynomial>::value,
table_entry_8<TAccumulator, 152U, Polynomial>::value,
table_entry_8<TAccumulator, 153U, Polynomial>::value,
table_entry_8<TAccumulator, 154U, Polynomial>::value,
table_entry_8<TAccumulator, 155U, Polynomial>::value,
table_entry_8<TAccumulator, 156U, Polynomial>::value,
table_entry_8<TAccumulator, 157U, Polynomial>::value,
table_entry_8<TAccumulator, 158U, Polynomial>::value,
table_entry_8<TAccumulator, 159U, Polynomial>::value,
table_entry_8<TAccumulator, 160U, Polynomial>::value,
table_entry_8<TAccumulator, 161U, Polynomial>::value,
table_entry_8<TAccumulator, 162U, Polynomial>::value,
table_entry_8<TAccumulator, 163U, Polynomial>::value,
table_entry_8<TAccumulator, 164U, Polynomial>::value,
table_entry_8<TAccumulator, 165U, Polynomial>::value,
table_entry_8<TAccumulator, 166U, Polynomial>::value,
table_entry_8<TAccumulator, 167U, Polynomial>::value,
table_entry_8<TAccumulator, 168U, Polynomial>::value,
table_entry_8<TAccumulator, 169U, Polynomial>::value,
table_entry_8<TAccumulator, 170U, Polynomial>::value,
table_entry_8<TAccumulator, 171U, Polynomial>::value,
table_entry_8<TAccumulator, 172U, Polynomial>::value,
table_entry_8<TAccumulator, 173U, Polynomial>::value,
table_entry_8<TAccumulator, 174U, Polynomial>::value,
table_entry_8<TAccumulator, 175U, Polynomial>::value,
table_entry_8<TAccumulator, 176U, Polynomial>::value,
table_entry_8<TAccumulator, 177U, Polynomial>::value,
table_entry_8<TAccumulator, 178U, Polynomial>::value,
table_entry_8<TAccumulator, 179U, Polynomial>::value,
table_entry_8<TAccumulator, 180U, Polynomial>::value,
table_entry_8<TAccumulator, 181U, Polynomial>::value,
table_entry_8<TAccumulator, 182U, Polynomial>::value,
table_entry_8<TAccumulator, 183U, Polynomial>::value,
table_entry_8<TAccumulator, 184U, Polynomial>::value,
table_entry_8<TAccumulator, 185U, Polynomial>::value,
table_entry_8<TAccumulator, 186U, Polynomial>::value,
table_entry_8<TAccumulator, 187U, Polynomial>::value,
table_entry_8<TAccumulator, 188U, Polynomial>::value,
table_entry_8<TAccumulator, 189U, Polynomial>::value,
table_entry_8<TAccumulator, 190U, Polynomial>::value,
table_entry_8<TAccumulator, 191U, Polynomial>::value,
table_entry_8<TAccumulator, 192U, Polynomial>::value,
table_entry_8<TAccumulator, 193U, Polynomial>::value,
table_entry_8<TAccumulator, 194U, Polynomial>::value,
table_entry_8<TAccumulator, 195U, Polynomial>::value,
table_entry_8<TAccumulator, 196U, Polynomial>::value,
table_entry_8<TAccumulator, 197U, Polynomial>::value,
table_entry_8<TAccumulator, 198U, Polynomial>::value,
table_entry_8<TAccumulator, 199U, Polynomial>::value,
table_entry_8<TAccumulator, 200U, Polynomial>::value,
table_entry_8<TAccumulator, 201U, Polynomial>::value,
table_entry_8<TAccumulator, 202U, Polynomial>::value,
table_entry_8<TAccumulator, 203U, Polynomial>::value,
table_entry_8<TAccumulator, 204U, Polynomial>::value,
table_entry_8<TAccumulator, 205U, Polynomial>::value,
table_entry_8<TAccumulator, 206U, Polynomial>::value,
table_entry_8<TAccumulator, 207U, Polynomial>::value,
table_entry_8<TAccumulator, 208U, Polynomial>::value,
table_entry_8<TAccumulator, 209U, Polynomial>::value,
table_entry_8<TAccumulator, 210U, Polynomial>::value,
table_entry_8<TAccumulator, 211U, Polynomial>::value,
table_entry_8<TAccumulator, 212U, Polynomial>::value,
table_entry_8<TAccumulator, 213U, Polynomial>::value,
table_entry_8<TAccumulator, 214U, Polynomial>::value,
table_entry_8<TAccumulator, 215U, Polynomial>::value,
table_entry_8<TAccumulator, 216U, Polynomial>::value,
table_entry_8<TAccumulator, 217U, Polynomial>::value,
table_entry_8<TAccumulator, 218U, Polynomial>::value,
table_entry_8<TAccumulator, 219U, Polynomial>::value,
table_entry_8<TAccumulator, 220U, Polynomial>::value,
table_entry_8<TAccumulator, 221U, Polynomial>::value,
table_entry_8<TAccumulator, 222U, Polynomial>::value,
table_entry_8<TAccumulator, 223U, Polynomial>::value,
table_entry_8<TAccumulator, 224U, Polynomial>::value,
table_entry_8<TAccumulator, 225U, Polynomial>::value,
table_entry_8<TAccumulator, 226U, Polynomial>::value,
table_entry_8<TAccumulator, 227U, Polynomial>::value,
table_entry_8<TAccumulator, 228U, Polynomial>::value,
table_entry_8<TAccumulator, 229U, Polynomial>::value,
table_entry_8<TAccumulator, 230U, Polynomial>::value,
table_entry_8<TAccumulator, 231U, Polynomial>::value,
table_entry_8<TAccumulator, 232U, Polynomial>::value,
table_entry_8<TAccumulator, 233U, Polynomial>::value,
table_entry_8<TAccumulator, 234U, Polynomial>::value,
table_entry_8<TAccumulator, 235U, Polynomial>::value,
table_entry_8<TAccumulator, 236U, Polynomial>::value,
table_entry_8<TAccumulator, 237U, Polynomial>::value,
table_entry_8<TAccumulator, 238U, Polynomial>::value,
table_entry_8<TAccumulator, 239U, Polynomial>::value,
table_entry_8<TAccumulator, 240U, Polynomial>::value,
table_entry_8<TAccumulator, 241U, Polynomial>::value,
table_entry_8<TAccumulator, 242U, Polynomial>::value,
table_entry_8<TAccumulator, 243U, Polynomial>::value,
table_entry_8<TAccumulator, 244U, Polynomial>::value,
table_entry_8<TAccumulator, 245U, Polynomial>::value,
table_entry_8<TAccumulator, 246U, Polynomial>::value,
table_entry_8<TAccumulator, 247U, Polynomial>::value,
table_entry_8<TAccumulator, 248U, Polynomial>::value,
table_entry_8<TAccumulator, 249U, Polynomial>::value,
table_entry_8<TAccumulator, 250U, Polynomial>::value,
table_entry_8<TAccumulator, 251U, Polynomial>::value,
table_entry_8<TAccumulator, 252U, Polynomial>::value,
table_entry_8<TAccumulator, 253U, Polynomial>::value,
table_entry_8<TAccumulator, 254U, Polynomial>::value,
table_entry_8<TAccumulator, 255U, Polynomial>::value
};
return table;
}
};
//
////
//// Define the CRC algorithm parameters
////
//template <typename TAccumulator, TAccumulator Polynomial, TAccumulator Initial, TAccumulator Xor_Out, bool Reverse>
//struct crc_algorithm
//{
// using accumulator_type = TAccumulator;
// static constexpr TAccumulator polynomial = Polynomial;
// static constexpr TAccumulator initial_value = Initial;
// static constexpr TAccumulator xor_out_value = Xor_Out;
// static constexpr bool reverse = Reverse;
//};
//
////
//// Define the basic traits we use in our CRC accumulators and Table Lookup
////
//template <typename TAccumulator, const size_t Table_Size>
//struct crc_traits {};
//
//template <typename TAccumulator>
//struct crc_traits_256
//{
// static constexpr std::size_t ACCUMULATOR_BITS = etl::integral_limits<TAccumulator>::bits;
// static constexpr std::size_t CHUNK_BITS = 8;
// static constexpr uint8_t CHUNK_MASK = 0xFFu;
// static constexpr std::size_t TABLE_ENTRIES = 1u << CHUNK_BITS;
//
// using table_type = std::array<TAccumulator, TABLE_ENTRIES>;
//};
//
////
//// CRC rotation policies.
////
//// Forward rotation means that we clock in data MSB->LSB and rotate the Accumulator register left
//// Reverse rotation means that we clock in data LSB->MSB and rotate the Accumulator register right
////
//
//template <typename TAccumulator>
//struct crc_forward_policy_256
//{
// typedef crc_traits_256<TAccumulator> traits;
//
// ETL_NODISCARD static constexpr TAccumulator update_impl_256(TAccumulator crc,
// uint8_t value,
// typename traits::table_type const& table)
// {
// crc = update_chunk(crc, value, table); // full byte
// return crc;
// }
//
// ETL_NODISCARD static constexpr TAccumulator update_chunk(TAccumulator crc,
// uint8_t value,
// typename traits::table_type const& table)
// {
// value &= traits::CHUNK_MASK;
//
// // Extract the most significant nibble of the crc and xor with the value nibble
// uint8_t t = (crc >> (traits::ACCUMULATOR_BITS - traits::CHUNK_BITS)) ^ value;
//
// // special case for when chunk size is same as accumulator size.
// if constexpr (traits::ACCUMULATOR_BITS > traits::CHUNK_BITS) {
// // shift crc left the size of the nibble
// crc <<= traits::CHUNK_BITS;
//
// // xor in the table data
// crc ^= table[t];
// }
// else {
// crc = table[t];
// }
//
// return crc;
// }
//
// ETL_NODISCARD static constexpr TAccumulator make_initial_value(TAccumulator init)
// {
// return init;
// }
//};
//
//template <typename TAccumulator, const size_t Table_Size>
//struct crc_reverse_policy_256
//{
// typedef crc_traits_256<TAccumulator> traits;
//
// ETL_NODISCARD static constexpr TAccumulator update_impl(
// TAccumulator crc, uint8_t value, typename traits::table_type const& table)
// {
// crc = update_chunk(crc, value, table); // full byte
// return crc;
// }
//
// ETL_NODISCARD static constexpr TAccumulator update_chunk(
// TAccumulator crc, uint8_t value, typename traits::table_type const& table)
// {
// // ensure we have only 4 bits
// value &= traits::CHUNK_MASK;
//
// // Extract the least significant nibble of the crc and xor with the value nibble
// uint8_t t = (crc & traits::CHUNK_MASK) ^ value;
//
// // special case for when chunk size is same as accumulator size.
// if constexpr (traits::ACCUMULATOR_BITS > traits::CHUNK_BITS) {
// // shit crc right the size of a nibble
// crc >>= traits::CHUNK_BITS;
//
// // xor in the table data
// crc ^= table[t];
// }
// else {
// crc = table[t];
// }
//
// return crc;
// }
//
// ETL_NODISCARD static constexpr TAccumulator make_initial_value(TAccumulator init)
// {
// return etl::reverse_bits(init);
// }
//};
//
//
////
//// A generic CRC lookup table sized for computing a nibble (4 bits) at a time.
////
//// This is can be a large reduction of table space storage for embedded devices.
////
//template <typename TAccumulator, TAccumulator Polynomial, bool Reverse, size_t Table_Size, typename = std::enable_if_t<std::is_unsigned<TAccumulator>::value>>
//class crc_chunk_table
//{
//public:
//
// using policy = typename std::conditional<Reverse, crc_reverse_policy<TAccumulator, Table_Size>, crc_forward_policy<TAccumulator, Table_Size>>::type;
//
// using traits = typename policy::traits;
//
//
// // update the given crc accumulator with the value
// ETL_NODISCARD static constexpr TAccumulator update(TAccumulator crc, uint8_t value)
// {
// if constexpr (Table_Size == size_t::tiny) {
// return policy::update_impl_tiny(crc, value, m_Table);
// }
// else if constexpr (Table_Size == size_t::small) {
// return policy::update_impl_small(crc, value, m_Table);
// }
// else if constexpr (Table_Size == size_t::large) {
// return policy::update_impl_large(crc, value, m_Table);
// }
// else {
// static_assert("Unknown size_t");
// }
// }
//
// // the crc accumulator initial value may need to be modified by the policy
// // to account for rotation direction
// ETL_NODISCARD static constexpr TAccumulator make_initial_value(TAccumulator init)
// {
// return policy::make_initial_value(init);
// }
//
//private:
//
//};
//
//
////
//// The generic CRC accumulator that is table driven
////
//template <typename TAlgorithm, size_t Table_Size>
//class crc
//{
//public:
// using algorithm = TAlgorithm;
// using accumulator_type = typename algorithm::accumulator_type;
//
// //
// // Update the accumulator with a new byte
// //
// void update(uint8_t value)
// {
// m_crc = table_impl::update(m_crc, value);
// }
//
// //
// // Extract the final value of the accumulator.
// //
// ETL_NODISCARD accumulator_type final() { return m_crc ^ algorithm::xor_out_value; }
//
// //
// // Reset the state of the accumulator back to the INITIAL value.
// //
// void reset() { m_crc = table_impl::make_initial_value(algorithm::initial_value); }
//
//
//private:
// using table_impl = crc_chunk_table<accumulator_type, algorithm::polynomial, algorithm::reverse, Table_Size>;
//
// accumulator_type m_crc = table_impl::make_initial_value(algorithm::initial_value);
//};

View File

@ -0,0 +1,698 @@
#pragma once
#include <stdint.h>
#include <limits.h>
//*****************************************************************************
template <typename TAccumulator, TAccumulator Polynomial, TAccumulator Entry>
class entry
{
private:
static const size_t Accumulator_Bits = sizeof(TAccumulator) * CHAR_BIT;
static const bool Do_Poly = (Entry & (TAccumulator(1U) << (Accumulator_Bits - 1))) != 0U;
public:
static const TAccumulator value = TAccumulator(Do_Poly ? (Entry << 1U) ^ Polynomial : (Entry << 1U));
};
//*****************************************************************************
/// 8 bit chunks
//*****************************************************************************
template <typename TAccumulator, size_t Index, TAccumulator Polynomial>
class table_entry_8
{
//private:
public:
static const size_t Accumulator_Bits = sizeof(TAccumulator) * CHAR_BIT;
static const size_t Shift_Bits = size_t(Accumulator_Bits - 8U);
static const TAccumulator Entry = TAccumulator(Index << Shift_Bits);
public:
static const TAccumulator value = entry<TAccumulator, Polynomial,
entry<TAccumulator, Polynomial,
entry<TAccumulator, Polynomial,
entry<TAccumulator, Polynomial,
entry<TAccumulator, Polynomial,
entry<TAccumulator, Polynomial,
entry<TAccumulator, Polynomial,
entry<TAccumulator, Polynomial, Entry>::value>::value>::value>::value>::value>::value>::value>::value;
};
//*****************************************************************************
/// 4 bit chunks
//*****************************************************************************
template <typename TAccumulator, size_t Index, TAccumulator Polynomial>
class table_entry_4
{
private:
static const size_t Accumulator_Bits = sizeof(TAccumulator) * CHAR_BIT;
static const size_t Shift_Bits = size_t(Accumulator_Bits - Chunk_4_Bits);
static const TAccumulator Entry = TAccumulator(Index << Shift_Bits);
public:
static const TAccumulator value = entry<TAccumulator, Polynomial,
entry<TAccumulator, Polynomial,
entry<TAccumulator, Polynomial,
entry<TAccumulator, Polynomial, Entry>::value>::value>::value>::value;
};
//*****************************************************************************
/// 2 bit chunks
//*****************************************************************************
template <typename TAccumulator, size_t Index, TAccumulator Polynomial>
class table_entry_2
{
private:
static const size_t Accumulator_Bits = sizeof(TAccumulator) * CHAR_BIT;
static const size_t Shift_Bits = size_t(Accumulator_Bits - Chunk_2_Bits);
static const TAccumulator Entry = TAccumulator(Index << Shift_Bits);
public:
static const TAccumulator value = entry<TAccumulator, Polynomial,
entry<TAccumulator, Polynomial, Entry>::value>::value;
};
//*****************************************************************************
template <typename TAccumulator, TAccumulator Polynomial>
struct crc_table<TAccumulator, Polynomial, 256>
{
static const TAccumulator* get_table()
{
static const TAccumulator table[256] =
{
table_entry<TAccumulator, 0U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 1U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 2U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 3U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 4U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 5U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 6U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 7U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 8U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 9U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 10U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 11U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 12U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 13U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 14U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 15U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 16U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 17U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 18U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 19U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 20U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 21U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 22U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 23U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 24U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 25U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 26U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 27U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 28U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 29U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 30U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 31U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 32U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 33U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 34U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 35U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 36U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 37U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 38U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 39U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 40U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 41U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 42U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 43U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 44U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 45U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 46U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 47U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 48U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 49U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 50U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 51U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 52U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 53U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 54U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 55U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 56U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 57U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 58U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 59U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 60U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 61U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 62U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 63U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 64U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 65U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 66U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 67U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 68U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 69U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 70U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 71U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 72U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 73U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 74U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 75U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 76U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 77U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 78U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 79U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 80U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 81U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 82U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 83U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 84U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 85U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 86U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 87U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 88U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 89U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 90U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 91U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 92U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 93U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 94U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 95U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 96U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 97U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 98U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 99U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 100U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 101U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 102U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 103U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 104U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 105U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 106U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 107U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 108U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 109U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 110U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 111U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 112U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 113U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 114U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 115U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 116U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 117U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 118U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 119U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 120U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 121U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 122U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 123U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 124U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 125U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 126U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 127U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 128U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 129U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 130U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 131U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 132U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 133U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 134U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 135U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 136U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 137U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 138U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 139U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 140U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 141U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 142U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 143U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 144U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 145U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 146U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 147U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 148U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 149U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 150U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 151U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 152U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 153U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 154U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 155U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 156U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 157U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 158U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 159U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 160U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 161U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 162U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 163U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 164U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 165U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 166U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 167U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 168U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 169U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 170U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 171U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 172U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 173U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 174U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 175U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 176U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 177U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 178U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 179U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 180U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 181U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 182U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 183U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 184U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 185U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 186U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 187U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 188U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 189U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 190U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 191U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 192U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 193U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 194U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 195U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 196U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 197U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 198U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 199U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 200U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 201U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 202U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 203U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 204U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 205U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 206U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 207U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 208U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 209U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 210U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 211U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 212U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 213U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 214U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 215U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 216U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 217U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 218U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 219U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 220U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 221U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 222U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 223U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 224U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 225U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 226U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 227U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 228U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 229U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 230U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 231U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 232U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 233U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 234U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 235U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 236U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 237U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 238U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 239U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 240U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 241U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 242U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 243U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 244U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 245U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 246U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 247U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 248U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 249U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 250U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 251U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 252U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 253U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 254U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 255U, Polynomial, Chunk_8_Bits>::value
};
return table;
}
};
template <typename TAccumulator, TAccumulator Polynomial>
struct crc_table<TAccumulator, Polynomial, 16>
{
static const TAccumulator* get_table()
{
static const TAccumulator table[16] =
{
table_entry<TAccumulator, 0U, Polynomial, Chunk_4_Bits>::value,
table_entry<TAccumulator, 1U, Polynomial, Chunk_4_Bits>::value,
table_entry<TAccumulator, 2U, Polynomial, Chunk_4_Bits>::value,
table_entry<TAccumulator, 3U, Polynomial, Chunk_4_Bits>::value,
table_entry<TAccumulator, 4U, Polynomial, Chunk_4_Bits>::value,
table_entry<TAccumulator, 5U, Polynomial, Chunk_4_Bits>::value,
table_entry<TAccumulator, 6U, Polynomial, Chunk_4_Bits>::value,
table_entry<TAccumulator, 7U, Polynomial, Chunk_4_Bits>::value,
table_entry<TAccumulator, 8U, Polynomial, Chunk_4_Bits>::value,
table_entry<TAccumulator, 9U, Polynomial, Chunk_4_Bits>::value,
table_entry<TAccumulator, 10U, Polynomial, Chunk_4_Bits>::value,
table_entry<TAccumulator, 11U, Polynomial, Chunk_4_Bits>::value,
table_entry<TAccumulator, 12U, Polynomial, Chunk_4_Bits>::value,
table_entry<TAccumulator, 13U, Polynomial, Chunk_4_Bits>::value,
table_entry<TAccumulator, 14U, Polynomial, Chunk_4_Bits>::value,
table_entry<TAccumulator, 15U, Polynomial, Chunk_4_Bits>::value
};
return table;
}
};
template <typename TAccumulator, TAccumulator Polynomial>
struct crc_table<TAccumulator, Polynomial, 4>
{
static const TAccumulator* get_table()
{
static const TAccumulator table[4] =
{
table_entry<TAccumulator, 0U, Polynomial, Chunk_2_Bits>::value,
table_entry<TAccumulator, 1U, Polynomial, Chunk_2_Bits>::value,
table_entry<TAccumulator, 2U, Polynomial, Chunk_2_Bits>::value,
table_entry<TAccumulator, 3U, Polynomial, Chunk_2_Bits>::value
};
return table;
}
};
//
// Define the CRC algorithm parameters
//
template <typename TAccumulator, TAccumulator Polynomial, TAccumulator Initial, TAccumulator Xor_Out, bool Reverse>
struct crc_algorithm
{
using accumulator_type = TAccumulator;
static constexpr TAccumulator polynomial = Polynomial;
static constexpr TAccumulator initial_value = Initial;
static constexpr TAccumulator xor_out_value = Xor_Out;
static constexpr bool reverse = Reverse;
};
//
// Define the basic traits we use in our CRC accumulators and Table Lookup
//
template <typename TAccumulator, const size_t Table_Size>
struct crc_traits {};
template <typename TAccumulator>
struct crc_traits<TAccumulator, size_t::tiny>
{
static constexpr std::size_t ACCUMULATOR_BITS = sizeof(TAccumulator) * 8;
static constexpr std::size_t CHUNK_BITS = 2;
static constexpr uint8_t CHUNK_MASK = 0x03u;
static constexpr std::size_t TABLE_ENTRIES = 1u << CHUNK_BITS;
using table_type = std::array<TAccumulator, TABLE_ENTRIES>;
};
template <typename TAccumulator>
struct crc_traits<TAccumulator, size_t::small>
{
static constexpr std::size_t ACCUMULATOR_BITS = sizeof(TAccumulator) * 8;
static constexpr std::size_t CHUNK_BITS = 4;
static constexpr uint8_t CHUNK_MASK = 0x0Fu;
static constexpr std::size_t TABLE_ENTRIES = 1u << CHUNK_BITS;
using table_type = std::array<TAccumulator, TABLE_ENTRIES>;
};
template <typename TAccumulator>
struct crc_traits<TAccumulator, size_t::large>
{
static constexpr std::size_t ACCUMULATOR_BITS = sizeof(TAccumulator) * 8;
static constexpr std::size_t CHUNK_BITS = 8;
static constexpr uint8_t CHUNK_MASK = 0xFFu;
static constexpr std::size_t TABLE_ENTRIES = 1u << CHUNK_BITS;
using table_type = std::array<TAccumulator, TABLE_ENTRIES>;
};
//
// CRC rotation policies.
//
// Forward rotation means that we clock in data MSB->LSB and rotate the Accumulator register left
// Reverse rotation means that we clock in data LSB->MSB and rotate the Accumulator register right
//
template <typename TAccumulator, const size_t Table_Size>
struct crc_forward_policy
{
using traits = crc_traits<TAccumulator, Table_Size>;
[[nodiscard]] static constexpr TAccumulator update_impl_tiny(
TAccumulator crc, uint8_t value, typename traits::table_type const& table)
{
crc = update_chunk(crc, (value >> (traits::CHUNK_BITS * 3)) & traits::CHUNK_MASK, table); // high chunk
crc = update_chunk(crc, (value >> (traits::CHUNK_BITS * 2)) & traits::CHUNK_MASK, table);
crc = update_chunk(crc, (value >> (traits::CHUNK_BITS * 1)) & traits::CHUNK_MASK, table);
crc = update_chunk(crc, value & traits::CHUNK_MASK, table); // low chunk
return crc;
}
[[nodiscard]] static constexpr TAccumulator update_impl_small(
TAccumulator crc, uint8_t value, typename traits::table_type const& table)
{
crc = update_chunk(crc, value >> traits::CHUNK_BITS, table); // high nibble
crc = update_chunk(crc, value & traits::CHUNK_MASK, table); // low nibble
return crc;
}
[[nodiscard]] static constexpr TAccumulator update_impl_large(
TAccumulator crc, uint8_t value, typename traits::table_type const& table)
{
crc = update_chunk(crc, value, table); // full byte
return crc;
}
[[nodiscard]] static constexpr TAccumulator update_chunk(
TAccumulator crc, uint8_t value, typename traits::table_type const& table)
{
// ensure we have only 4 bits
value &= traits::CHUNK_MASK;
// Extract the most significant nibble of the crc and xor with the value nibble
uint8_t t = (crc >> (traits::ACCUMULATOR_BITS - traits::CHUNK_BITS)) ^ value;
// special case for when chunk size is same as accumulator size.
if constexpr (traits::ACCUMULATOR_BITS > traits::CHUNK_BITS) {
// shit crc left the size of the nibble
crc <<= traits::CHUNK_BITS;
// xor in the table data
crc ^= table[t];
}
else {
crc = table[t];
}
return crc;
}
[[nodiscard]] static constexpr TAccumulator generate_entry(TAccumulator const polynomial, uint8_t const index)
{
// initialise with the register in the upper bits
TAccumulator entry = TAccumulator(index) << (traits::ACCUMULATOR_BITS - traits::CHUNK_BITS);
for (std::size_t i = 0; i < traits::CHUNK_BITS; i++)
{
// We are processing MSBs / rotating left so we need to check the high bit
if (entry & (TAccumulator(1u) << (traits::ACCUMULATOR_BITS - 1))) {
entry = (entry << 1) ^ polynomial;
}
else {
entry = (entry << 1);
}
}
return entry;
}
[[nodiscard]] static constexpr TAccumulator make_initial_value(TAccumulator init)
{
return init;
}
};
template <typename TAccumulator, const size_t Table_Size>
struct crc_reverse_policy
{
using traits = crc_traits<TAccumulator, Table_Size>;
[[nodiscard]] static constexpr TAccumulator update_impl_tiny(
TAccumulator crc, uint8_t value, typename traits::table_type const& table)
{
crc = update_chunk(crc, value & traits::CHUNK_MASK, table); // low chunk
crc = update_chunk(crc, (value >> (traits::CHUNK_BITS * 1)) & traits::CHUNK_MASK, table);
crc = update_chunk(crc, (value >> (traits::CHUNK_BITS * 2)) & traits::CHUNK_MASK, table);
crc = update_chunk(crc, (value >> (traits::CHUNK_BITS * 3)) & traits::CHUNK_MASK, table); // high chunk
return crc;
}
[[nodiscard]] static constexpr TAccumulator update_impl_small(
TAccumulator crc, uint8_t value, typename traits::table_type const& table)
{
crc = update_chunk(crc, value & traits::CHUNK_MASK, table); // low nibble
crc = update_chunk(crc, value >> traits::CHUNK_BITS, table); // high nibble
return crc;
}
[[nodiscard]] static constexpr TAccumulator update_impl_large(
TAccumulator crc, uint8_t value, typename traits::table_type const& table)
{
crc = update_chunk(crc, value, table); // full byte
return crc;
}
[[nodiscard]] static constexpr TAccumulator update_chunk(
TAccumulator crc, uint8_t value, typename traits::table_type const& table)
{
// ensure we have only 4 bits
value &= traits::CHUNK_MASK;
// Extract the least significant nibble of the crc and xor with the value nibble
uint8_t t = (crc & traits::CHUNK_MASK) ^ value;
// special case for when chunk size is same as accumulator size.
if constexpr (traits::ACCUMULATOR_BITS > traits::CHUNK_BITS) {
// shit crc right the size of a nibble
crc >>= traits::CHUNK_BITS;
// xor in the table data
crc ^= table[t];
}
else {
crc = table[t];
}
return crc;
}
[[nodiscard]] static constexpr TAccumulator generate_entry(TAccumulator const polynomial, uint8_t const index)
{
// initialise with the register in the lower bits
TAccumulator entry = TAccumulator(index);
for (std::size_t i = 0; i < traits::CHUNK_BITS; i++)
{
// we are processing LSBs/rotating right
if (entry & 0x1u) {
entry = (entry >> 1) ^ util::reverse_bits(polynomial);
}
else {
entry = (entry >> 1);
}
}
return entry;
}
[[nodiscard]] static constexpr TAccumulator make_initial_value(TAccumulator init)
{
return util::reverse_bits(init);
}
};
//
// A generic CRC lookup table sized for computing a nibble (4 bits) at a time.
//
// This is can be a large reduction of table space storage for embedded devices.
//
template <typename TAccumulator, TAccumulator Polynomial, bool Reverse, size_t Table_Size, typename = std::enable_if_t<std::is_unsigned<TAccumulator>::value>>
class crc_chunk_table
{
public:
using policy = typename std::conditional<Reverse, crc_reverse_policy<TAccumulator, Table_Size>, crc_forward_policy<TAccumulator, Table_Size>>::type;
using traits = typename policy::traits;
// update the given crc accumulator with the value
[[nodiscard]] static constexpr TAccumulator update(TAccumulator crc, uint8_t value)
{
if constexpr (Table_Size == size_t::tiny) {
return policy::update_impl_tiny(crc, value, m_Table);
}
else if constexpr (Table_Size == size_t::small) {
return policy::update_impl_small(crc, value, m_Table);
}
else if constexpr (Table_Size == size_t::large) {
return policy::update_impl_large(crc, value, m_Table);
}
else {
static_assert("Unknown size_t");
}
}
// the crc accumulator initial value may need to be modified by the policy
// to account for rotation direction
[[nodiscard]] static constexpr TAccumulator make_initial_value(TAccumulator init)
{
return policy::make_initial_value(init);
}
private:
};
//
// The generic CRC accumulator that is table driven
//
template <typename TAlgorithm, size_t Table_Size>
class crc
{
public:
using algorithm = TAlgorithm;
using accumulator_type = typename algorithm::accumulator_type;
//
// Update the accumulator with a new byte
//
void update(uint8_t value)
{
m_crc = table_impl::update(m_crc, value);
}
//
// Extract the final value of the accumulator.
//
[[nodiscard]] accumulator_type final() { return m_crc ^ algorithm::xor_out_value; }
//
// Reset the state of the accumulator back to the INITIAL value.
//
void reset() { m_crc = table_impl::make_initial_value(algorithm::initial_value); }
private:
using table_impl = crc_chunk_table<accumulator_type, algorithm::polynomial, algorithm::reverse, Table_Size>;
accumulator_type m_crc = table_impl::make_initial_value(algorithm::initial_value);
};

View File

@ -0,0 +1,712 @@
#pragma once
#include <stdint.h>
#include <limits.h>
enum
{
Chunk_8_Bits = 8,
Chunk_4_Bits = 4,
Chunk_2_Bits = 2
};
//*****************************************************************************
template <typename TAccumulator, TAccumulator Polynomial, TAccumulator Entry>
class entry
{
private:
static const size_t Accumulator_Bits = sizeof(TAccumulator) * CHAR_BIT;
static const bool Do_Poly = (Entry & (TAccumulator(1U) << (Accumulator_Bits - 1U))) != 0U;
public:
static const TAccumulator value = TAccumulator(Do_Poly ? (Entry << 1U) ^ Polynomial : (Entry << 1U));
};
//*****************************************************************************
template <typename TAccumulator, size_t Index, TAccumulator Polynomial, size_t CHUNK_BITS>
class table_entry;
//*****************************************************************************
/// 8 bit chunks
//*****************************************************************************
template <typename TAccumulator, size_t Index, TAccumulator Polynomial>
class table_entry<TAccumulator, Index, Polynomial, Chunk_8_Bits>
{
//private:
public:
static const size_t Accumulator_Bits = sizeof(TAccumulator) * CHAR_BIT;
static const size_t Shift_Bits = size_t(Accumulator_Bits - Chunk_8_Bits);
static const TAccumulator Entry = TAccumulator(Index << Shift_Bits);
public:
static const TAccumulator value = entry<TAccumulator, Polynomial,
entry<TAccumulator, Polynomial,
entry<TAccumulator, Polynomial,
entry<TAccumulator, Polynomial,
entry<TAccumulator, Polynomial,
entry<TAccumulator, Polynomial,
entry<TAccumulator, Polynomial,
entry<TAccumulator, Polynomial, Entry>::value>::value>::value>::value>::value>::value>::value>::value;
};
//*****************************************************************************
/// 4 bit chunks
//*****************************************************************************
template <typename TAccumulator, size_t Index, TAccumulator Polynomial>
class table_entry<TAccumulator, Index, Polynomial, Chunk_4_Bits>
{
private:
static const size_t Accumulator_Bits = sizeof(TAccumulator) * CHAR_BIT;
static const size_t Shift_Bits = size_t(Accumulator_Bits - Chunk_4_Bits);
static const TAccumulator Entry = TAccumulator(Index << Shift_Bits);
public:
static const TAccumulator value = entry<TAccumulator, Polynomial,
entry<TAccumulator, Polynomial,
entry<TAccumulator, Polynomial,
entry<TAccumulator, Polynomial, Entry>::value>::value>::value>::value;
};
//*****************************************************************************
/// 2 bit chunks
//*****************************************************************************
template <typename TAccumulator, size_t Index, TAccumulator Polynomial>
class table_entry<TAccumulator, Index, Polynomial, Chunk_2_Bits>
{
private:
static const size_t Accumulator_Bits = sizeof(TAccumulator) * CHAR_BIT;
static const size_t Shift_Bits = size_t(Accumulator_Bits - Chunk_2_Bits);
static const TAccumulator Entry = TAccumulator(Index << Shift_Bits);
public:
static const TAccumulator value = entry<TAccumulator, Polynomial,
entry<TAccumulator, Polynomial, Entry>::value>::value;
};
//*****************************************************************************
template <typename TAccumulator, TAccumulator Polynomial, size_t Table_Size>
struct crc_table;
template <typename TAccumulator, TAccumulator Polynomial>
struct crc_table<TAccumulator, Polynomial, 256>
{
static const TAccumulator* get_table()
{
static const TAccumulator table[256] =
{
table_entry<TAccumulator, 0U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 1U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 2U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 3U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 4U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 5U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 6U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 7U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 8U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 9U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 10U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 11U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 12U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 13U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 14U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 15U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 16U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 17U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 18U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 19U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 20U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 21U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 22U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 23U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 24U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 25U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 26U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 27U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 28U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 29U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 30U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 31U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 32U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 33U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 34U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 35U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 36U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 37U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 38U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 39U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 40U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 41U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 42U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 43U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 44U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 45U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 46U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 47U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 48U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 49U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 50U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 51U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 52U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 53U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 54U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 55U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 56U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 57U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 58U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 59U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 60U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 61U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 62U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 63U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 64U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 65U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 66U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 67U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 68U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 69U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 70U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 71U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 72U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 73U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 74U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 75U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 76U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 77U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 78U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 79U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 80U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 81U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 82U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 83U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 84U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 85U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 86U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 87U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 88U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 89U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 90U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 91U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 92U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 93U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 94U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 95U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 96U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 97U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 98U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 99U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 100U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 101U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 102U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 103U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 104U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 105U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 106U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 107U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 108U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 109U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 110U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 111U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 112U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 113U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 114U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 115U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 116U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 117U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 118U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 119U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 120U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 121U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 122U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 123U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 124U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 125U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 126U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 127U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 128U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 129U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 130U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 131U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 132U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 133U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 134U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 135U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 136U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 137U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 138U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 139U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 140U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 141U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 142U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 143U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 144U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 145U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 146U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 147U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 148U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 149U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 150U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 151U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 152U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 153U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 154U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 155U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 156U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 157U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 158U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 159U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 160U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 161U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 162U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 163U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 164U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 165U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 166U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 167U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 168U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 169U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 170U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 171U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 172U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 173U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 174U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 175U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 176U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 177U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 178U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 179U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 180U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 181U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 182U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 183U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 184U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 185U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 186U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 187U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 188U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 189U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 190U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 191U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 192U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 193U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 194U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 195U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 196U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 197U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 198U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 199U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 200U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 201U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 202U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 203U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 204U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 205U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 206U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 207U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 208U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 209U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 210U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 211U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 212U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 213U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 214U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 215U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 216U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 217U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 218U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 219U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 220U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 221U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 222U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 223U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 224U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 225U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 226U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 227U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 228U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 229U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 230U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 231U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 232U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 233U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 234U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 235U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 236U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 237U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 238U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 239U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 240U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 241U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 242U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 243U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 244U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 245U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 246U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 247U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 248U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 249U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 250U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 251U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 252U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 253U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 254U, Polynomial, Chunk_8_Bits>::value,
table_entry<TAccumulator, 255U, Polynomial, Chunk_8_Bits>::value
};
return table;
}
};
template <typename TAccumulator, TAccumulator Polynomial>
struct crc_table<TAccumulator, Polynomial, 16>
{
static const TAccumulator* get_table()
{
static const TAccumulator table[16] =
{
table_entry<TAccumulator, 0U, Polynomial, Chunk_4_Bits>::value,
table_entry<TAccumulator, 1U, Polynomial, Chunk_4_Bits>::value,
table_entry<TAccumulator, 2U, Polynomial, Chunk_4_Bits>::value,
table_entry<TAccumulator, 3U, Polynomial, Chunk_4_Bits>::value,
table_entry<TAccumulator, 4U, Polynomial, Chunk_4_Bits>::value,
table_entry<TAccumulator, 5U, Polynomial, Chunk_4_Bits>::value,
table_entry<TAccumulator, 6U, Polynomial, Chunk_4_Bits>::value,
table_entry<TAccumulator, 7U, Polynomial, Chunk_4_Bits>::value,
table_entry<TAccumulator, 8U, Polynomial, Chunk_4_Bits>::value,
table_entry<TAccumulator, 9U, Polynomial, Chunk_4_Bits>::value,
table_entry<TAccumulator, 10U, Polynomial, Chunk_4_Bits>::value,
table_entry<TAccumulator, 11U, Polynomial, Chunk_4_Bits>::value,
table_entry<TAccumulator, 12U, Polynomial, Chunk_4_Bits>::value,
table_entry<TAccumulator, 13U, Polynomial, Chunk_4_Bits>::value,
table_entry<TAccumulator, 14U, Polynomial, Chunk_4_Bits>::value,
table_entry<TAccumulator, 15U, Polynomial, Chunk_4_Bits>::value
};
return table;
}
};
template <typename TAccumulator, TAccumulator Polynomial>
struct crc_table<TAccumulator, Polynomial, 4>
{
static const TAccumulator* get_table()
{
static const TAccumulator table[4] =
{
table_entry<TAccumulator, 0U, Polynomial, Chunk_2_Bits>::value,
table_entry<TAccumulator, 1U, Polynomial, Chunk_2_Bits>::value,
table_entry<TAccumulator, 2U, Polynomial, Chunk_2_Bits>::value,
table_entry<TAccumulator, 3U, Polynomial, Chunk_2_Bits>::value
};
return table;
}
};
//
// Define the CRC algorithm parameters
//
template <typename TAccumulator, TAccumulator Polynomial, TAccumulator Initial, TAccumulator Xor_Out, bool Reverse>
struct crc_algorithm
{
using accumulator_type = TAccumulator;
static constexpr TAccumulator polynomial = Polynomial;
static constexpr TAccumulator initial_value = Initial;
static constexpr TAccumulator xor_out_value = Xor_Out;
static constexpr bool reverse = Reverse;
};
//
// Define the basic traits we use in our CRC accumulators and Table Lookup
//
template <typename TAccumulator, const size_t Table_Size>
struct crc_traits {};
template <typename TAccumulator>
struct crc_traits<TAccumulator, size_t::tiny>
{
static constexpr std::size_t ACCUMULATOR_BITS = sizeof(TAccumulator) * 8;
static constexpr std::size_t CHUNK_BITS = 2;
static constexpr uint8_t CHUNK_MASK = 0x03u;
static constexpr std::size_t TABLE_ENTRIES = 1u << CHUNK_BITS;
using table_type = std::array<TAccumulator, TABLE_ENTRIES>;
};
template <typename TAccumulator>
struct crc_traits<TAccumulator, size_t::small>
{
static constexpr std::size_t ACCUMULATOR_BITS = sizeof(TAccumulator) * 8;
static constexpr std::size_t CHUNK_BITS = 4;
static constexpr uint8_t CHUNK_MASK = 0x0Fu;
static constexpr std::size_t TABLE_ENTRIES = 1u << CHUNK_BITS;
using table_type = std::array<TAccumulator, TABLE_ENTRIES>;
};
template <typename TAccumulator>
struct crc_traits<TAccumulator, size_t::large>
{
static constexpr std::size_t ACCUMULATOR_BITS = sizeof(TAccumulator) * 8;
static constexpr std::size_t CHUNK_BITS = 8;
static constexpr uint8_t CHUNK_MASK = 0xFFu;
static constexpr std::size_t TABLE_ENTRIES = 1u << CHUNK_BITS;
using table_type = std::array<TAccumulator, TABLE_ENTRIES>;
};
//
// CRC rotation policies.
//
// Forward rotation means that we clock in data MSB->LSB and rotate the Accumulator register left
// Reverse rotation means that we clock in data LSB->MSB and rotate the Accumulator register right
//
template <typename TAccumulator, const size_t Table_Size>
struct crc_forward_policy
{
using traits = crc_traits<TAccumulator, Table_Size>;
[[nodiscard]] static constexpr TAccumulator update_impl_tiny(
TAccumulator crc, uint8_t value, typename traits::table_type const& table)
{
crc = update_chunk(crc, (value >> (traits::CHUNK_BITS * 3)) & traits::CHUNK_MASK, table); // high chunk
crc = update_chunk(crc, (value >> (traits::CHUNK_BITS * 2)) & traits::CHUNK_MASK, table);
crc = update_chunk(crc, (value >> (traits::CHUNK_BITS * 1)) & traits::CHUNK_MASK, table);
crc = update_chunk(crc, value & traits::CHUNK_MASK, table); // low chunk
return crc;
}
[[nodiscard]] static constexpr TAccumulator update_impl_small(
TAccumulator crc, uint8_t value, typename traits::table_type const& table)
{
crc = update_chunk(crc, value >> traits::CHUNK_BITS, table); // high nibble
crc = update_chunk(crc, value & traits::CHUNK_MASK, table); // low nibble
return crc;
}
[[nodiscard]] static constexpr TAccumulator update_impl_large(
TAccumulator crc, uint8_t value, typename traits::table_type const& table)
{
crc = update_chunk(crc, value, table); // full byte
return crc;
}
[[nodiscard]] static constexpr TAccumulator update_chunk(
TAccumulator crc, uint8_t value, typename traits::table_type const& table)
{
// ensure we have only 4 bits
value &= traits::CHUNK_MASK;
// Extract the most significant nibble of the crc and xor with the value nibble
uint8_t t = (crc >> (traits::ACCUMULATOR_BITS - traits::CHUNK_BITS)) ^ value;
// special case for when chunk size is same as accumulator size.
if constexpr (traits::ACCUMULATOR_BITS > traits::CHUNK_BITS) {
// shit crc left the size of the nibble
crc <<= traits::CHUNK_BITS;
// xor in the table data
crc ^= table[t];
}
else {
crc = table[t];
}
return crc;
}
[[nodiscard]] static constexpr TAccumulator generate_entry(TAccumulator const polynomial, uint8_t const index)
{
// initialise with the register in the upper bits
TAccumulator entry = TAccumulator(index) << (traits::ACCUMULATOR_BITS - traits::CHUNK_BITS);
for (std::size_t i = 0; i < traits::CHUNK_BITS; i++)
{
// We are processing MSBs / rotating left so we need to check the high bit
if (entry & (TAccumulator(1u) << (traits::ACCUMULATOR_BITS - 1))) {
entry = (entry << 1) ^ polynomial;
}
else {
entry = (entry << 1);
}
}
return entry;
}
[[nodiscard]] static constexpr TAccumulator make_initial_value(TAccumulator init)
{
return init;
}
};
template <typename TAccumulator, const size_t Table_Size>
struct crc_reverse_policy
{
using traits = crc_traits<TAccumulator, Table_Size>;
[[nodiscard]] static constexpr TAccumulator update_impl_tiny(
TAccumulator crc, uint8_t value, typename traits::table_type const& table)
{
crc = update_chunk(crc, value & traits::CHUNK_MASK, table); // low chunk
crc = update_chunk(crc, (value >> (traits::CHUNK_BITS * 1)) & traits::CHUNK_MASK, table);
crc = update_chunk(crc, (value >> (traits::CHUNK_BITS * 2)) & traits::CHUNK_MASK, table);
crc = update_chunk(crc, (value >> (traits::CHUNK_BITS * 3)) & traits::CHUNK_MASK, table); // high chunk
return crc;
}
[[nodiscard]] static constexpr TAccumulator update_impl_small(
TAccumulator crc, uint8_t value, typename traits::table_type const& table)
{
crc = update_chunk(crc, value & traits::CHUNK_MASK, table); // low nibble
crc = update_chunk(crc, value >> traits::CHUNK_BITS, table); // high nibble
return crc;
}
[[nodiscard]] static constexpr TAccumulator update_impl_large(
TAccumulator crc, uint8_t value, typename traits::table_type const& table)
{
crc = update_chunk(crc, value, table); // full byte
return crc;
}
[[nodiscard]] static constexpr TAccumulator update_chunk(
TAccumulator crc, uint8_t value, typename traits::table_type const& table)
{
// ensure we have only 4 bits
value &= traits::CHUNK_MASK;
// Extract the least significant nibble of the crc and xor with the value nibble
uint8_t t = (crc & traits::CHUNK_MASK) ^ value;
// special case for when chunk size is same as accumulator size.
if constexpr (traits::ACCUMULATOR_BITS > traits::CHUNK_BITS) {
// shit crc right the size of a nibble
crc >>= traits::CHUNK_BITS;
// xor in the table data
crc ^= table[t];
}
else {
crc = table[t];
}
return crc;
}
[[nodiscard]] static constexpr TAccumulator generate_entry(TAccumulator const polynomial, uint8_t const index)
{
// initialise with the register in the lower bits
TAccumulator entry = TAccumulator(index);
for (std::size_t i = 0; i < traits::CHUNK_BITS; i++)
{
// we are processing LSBs/rotating right
if (entry & 0x1u) {
entry = (entry >> 1) ^ util::reverse_bits(polynomial);
}
else {
entry = (entry >> 1);
}
}
return entry;
}
[[nodiscard]] static constexpr TAccumulator make_initial_value(TAccumulator init)
{
return util::reverse_bits(init);
}
};
//
// A generic CRC lookup table sized for computing a nibble (4 bits) at a time.
//
// This is can be a large reduction of table space storage for embedded devices.
//
template <typename TAccumulator, TAccumulator Polynomial, bool Reverse, size_t Table_Size, typename = std::enable_if_t<std::is_unsigned<TAccumulator>::value>>
class crc_chunk_table
{
public:
using policy = typename std::conditional<Reverse, crc_reverse_policy<TAccumulator, Table_Size>, crc_forward_policy<TAccumulator, Table_Size>>::type;
using traits = typename policy::traits;
// update the given crc accumulator with the value
[[nodiscard]] static constexpr TAccumulator update(TAccumulator crc, uint8_t value)
{
if constexpr (Table_Size == size_t::tiny) {
return policy::update_impl_tiny(crc, value, m_Table);
}
else if constexpr (Table_Size == size_t::small) {
return policy::update_impl_small(crc, value, m_Table);
}
else if constexpr (Table_Size == size_t::large) {
return policy::update_impl_large(crc, value, m_Table);
}
else {
static_assert("Unknown size_t");
}
}
// the crc accumulator initial value may need to be modified by the policy
// to account for rotation direction
[[nodiscard]] static constexpr TAccumulator make_initial_value(TAccumulator init)
{
return policy::make_initial_value(init);
}
private:
};
//
// The generic CRC accumulator that is table driven
//
template <typename TAlgorithm, size_t Table_Size>
class crc
{
public:
using algorithm = TAlgorithm;
using accumulator_type = typename algorithm::accumulator_type;
//
// Update the accumulator with a new byte
//
void update(uint8_t value)
{
m_crc = table_impl::update(m_crc, value);
}
//
// Extract the final value of the accumulator.
//
[[nodiscard]] accumulator_type final() { return m_crc ^ algorithm::xor_out_value; }
//
// Reset the state of the accumulator back to the INITIAL value.
//
void reset() { m_crc = table_impl::make_initial_value(algorithm::initial_value); }
private:
using table_impl = crc_chunk_table<accumulator_type, algorithm::polynomial, algorithm::reverse, Table_Size>;
accumulator_type m_crc = table_impl::make_initial_value(algorithm::initial_value);
};

1259
test/test_crc_table16.cpp Normal file

File diff suppressed because it is too large Load Diff

1259
test/test_crc_table256.cpp Normal file

File diff suppressed because it is too large Load Diff

1259
test/test_crc_table4.cpp Normal file

File diff suppressed because it is too large Load Diff

View File

@ -1272,6 +1272,21 @@
<ClInclude Include="..\..\include\etl\cumulative_moving_average.h" />
<ClInclude Include="..\..\include\etl\delegate.h" />
<ClInclude Include="..\..\include\etl\delegate_service.h" />
<ClInclude Include="..\..\include\etl\experimental\crc16.h" />
<ClInclude Include="..\..\include\etl\experimental\crc16_aug_ccitt.h" />
<ClInclude Include="..\..\include\etl\experimental\crc16_ccitt.h" />
<ClInclude Include="..\..\include\etl\experimental\crc16_genibus.h" />
<ClInclude Include="..\..\include\etl\experimental\crc16_kermit.h" />
<ClInclude Include="..\..\include\etl\experimental\crc16_modbus.h" />
<ClInclude Include="..\..\include\etl\experimental\crc16_usb.h" />
<ClInclude Include="..\..\include\etl\experimental\crc16_x25.h" />
<ClInclude Include="..\..\include\etl\experimental\crc16_xmodem.h" />
<ClInclude Include="..\..\include\etl\experimental\crc32.h" />
<ClInclude Include="..\..\include\etl\experimental\crc64_ecma.h" />
<ClInclude Include="..\..\include\etl\experimental\crc8_rohc.h" />
<ClInclude Include="..\..\include\etl\experimental\crc8_ccitt.h" />
<ClInclude Include="..\..\include\etl\experimental\crc_implementation.h" />
<ClInclude Include="..\..\include\etl\experimental\crc_parameters.h" />
<ClInclude Include="..\..\include\etl\file_error_numbers.h" />
<ClInclude Include="..\..\include\etl\flags.h" />
<ClInclude Include="..\..\include\etl\format_spec.h" />
@ -3778,6 +3793,9 @@
<ClCompile Include="..\test_circular_buffer.cpp" />
<ClCompile Include="..\test_circular_buffer_external_buffer.cpp" />
<ClCompile Include="..\test_compiler_settings.cpp" />
<ClCompile Include="..\test_crc_table16.cpp" />
<ClCompile Include="..\test_crc_table256.cpp" />
<ClCompile Include="..\test_crc_table4.cpp" />
<ClCompile Include="..\test_cumulative_moving_average.cpp" />
<ClCompile Include="..\test_delegate.cpp" />
<ClCompile Include="..\test_delegate_service.cpp" />

View File

@ -106,6 +106,9 @@
<Filter Include="Source Files\Scripts">
<UniqueIdentifier>{562466b5-677d-4448-9e9e-f70805cd71ad}</UniqueIdentifier>
</Filter>
<Filter Include="ETL\Maths\Experimental">
<UniqueIdentifier>{016bd5a6-e277-4aba-8b28-28a9f1348473}</UniqueIdentifier>
</Filter>
</ItemGroup>
<ItemGroup>
<ClInclude Include="..\..\include\etl\enum_type.h">
@ -984,6 +987,51 @@
<ClInclude Include="..\sanity-check\c++17\etl_profile.h">
<Filter>Source Files\Sanity Checks\C++17</Filter>
</ClInclude>
<ClInclude Include="..\..\include\etl\experimental\crc8_ccitt.h">
<Filter>ETL\Maths\Experimental</Filter>
</ClInclude>
<ClInclude Include="..\..\include\etl\experimental\crc_implementation.h">
<Filter>ETL\Maths\Experimental</Filter>
</ClInclude>
<ClInclude Include="..\..\include\etl\experimental\crc8_rohc.h">
<Filter>ETL\Maths\Experimental</Filter>
</ClInclude>
<ClInclude Include="..\..\include\etl\experimental\crc16.h">
<Filter>ETL\Maths\Experimental</Filter>
</ClInclude>
<ClInclude Include="..\..\include\etl\experimental\crc32.h">
<Filter>ETL\Maths\Experimental</Filter>
</ClInclude>
<ClInclude Include="..\..\include\etl\experimental\crc16_aug_ccitt.h">
<Filter>ETL\Maths\Experimental</Filter>
</ClInclude>
<ClInclude Include="..\..\include\etl\experimental\crc16_ccitt.h">
<Filter>ETL\Maths\Experimental</Filter>
</ClInclude>
<ClInclude Include="..\..\include\etl\experimental\crc16_kermit.h">
<Filter>ETL\Maths\Experimental</Filter>
</ClInclude>
<ClInclude Include="..\..\include\etl\experimental\crc16_modbus.h">
<Filter>ETL\Maths\Experimental</Filter>
</ClInclude>
<ClInclude Include="..\..\include\etl\experimental\crc16_usb.h">
<Filter>ETL\Maths\Experimental</Filter>
</ClInclude>
<ClInclude Include="..\..\include\etl\experimental\crc64_ecma.h">
<Filter>ETL\Maths\Experimental</Filter>
</ClInclude>
<ClInclude Include="..\..\include\etl\experimental\crc16_genibus.h">
<Filter>ETL\Maths\Experimental</Filter>
</ClInclude>
<ClInclude Include="..\..\include\etl\experimental\crc16_x25.h">
<Filter>ETL\Maths\Experimental</Filter>
</ClInclude>
<ClInclude Include="..\..\include\etl\experimental\crc16_xmodem.h">
<Filter>ETL\Maths\Experimental</Filter>
</ClInclude>
<ClInclude Include="..\..\include\etl\experimental\crc_parameters.h">
<Filter>ETL\Maths\Experimental</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<ClCompile Include="..\main.cpp">
@ -2102,6 +2150,15 @@
<ClCompile Include="..\sanity-check\wstring_stream.h.t.cpp">
<Filter>Source Files\Sanity Checks</Filter>
</ClCompile>
<ClCompile Include="..\test_crc_table256.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\test_crc_table16.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\test_crc_table4.cpp">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<None Include="..\..\library.properties">