diff --git a/include/etl/binary.h b/include/etl/binary.h index cebaa91f..5260485f 100644 --- a/include/etl/binary.h +++ b/include/etl/binary.h @@ -472,6 +472,9 @@ namespace etl return second ^ ((second ^ first) & MASK); } + template + 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 + struct reverse_bits_const + { + 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 + struct reverse_bits_const + { + 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 + struct reverse_bits_const + { + 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 + struct reverse_bits_const + { + 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 + struct reverse_bits_const + { + 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 + struct reverse_bits_const + { + 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 + struct reverse_bits_const + { + 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 + struct reverse_bits_const + { + 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 //*************************************************************************** diff --git a/include/etl/experimental/crc.h b/include/etl/experimental/crc.h new file mode 100644 index 00000000..4948719d --- /dev/null +++ b/include/etl/experimental/crc.h @@ -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 + using crc8_ccitt_t = etl::private_crc::crc_type; +#else + template + class crc8_ccitt_t : public etl::private_crc::crc_type + { + 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 + 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 diff --git a/include/etl/experimental/crc16.h b/include/etl/experimental/crc16.h new file mode 100644 index 00000000..e09a1031 --- /dev/null +++ b/include/etl/experimental/crc16.h @@ -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 + class crc16_t : public etl::private_crc::crc_type + { + 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 + 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 diff --git a/include/etl/experimental/crc16_aug_ccitt.h b/include/etl/experimental/crc16_aug_ccitt.h new file mode 100644 index 00000000..13b49212 --- /dev/null +++ b/include/etl/experimental/crc16_aug_ccitt.h @@ -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 + class crc16_aug_ccitt_t : public etl::private_crc::crc_type + { + 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 + 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 diff --git a/include/etl/experimental/crc16_ccitt.h b/include/etl/experimental/crc16_ccitt.h new file mode 100644 index 00000000..e2f12d31 --- /dev/null +++ b/include/etl/experimental/crc16_ccitt.h @@ -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 + class crc16_ccitt_t : public etl::private_crc::crc_type + { + 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 + 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 diff --git a/include/etl/experimental/crc16_genibus.h b/include/etl/experimental/crc16_genibus.h new file mode 100644 index 00000000..72a5d1b7 --- /dev/null +++ b/include/etl/experimental/crc16_genibus.h @@ -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 + class crc16_genibus_t : public etl::private_crc::crc_type + { + 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 + 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 diff --git a/include/etl/experimental/crc16_kermit.h b/include/etl/experimental/crc16_kermit.h new file mode 100644 index 00000000..dcb026ca --- /dev/null +++ b/include/etl/experimental/crc16_kermit.h @@ -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 + class crc16_kermit_t : public etl::private_crc::crc_type + { + 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 + 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 diff --git a/include/etl/experimental/crc16_modbus.h b/include/etl/experimental/crc16_modbus.h new file mode 100644 index 00000000..cc62a179 --- /dev/null +++ b/include/etl/experimental/crc16_modbus.h @@ -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 + class crc16_modbus_t : public etl::private_crc::crc_type + { + 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 + 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 diff --git a/include/etl/experimental/crc16_usb.h b/include/etl/experimental/crc16_usb.h new file mode 100644 index 00000000..e1205999 --- /dev/null +++ b/include/etl/experimental/crc16_usb.h @@ -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 + class crc16_usb_t : public etl::private_crc::crc_type + { + 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 + 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 diff --git a/include/etl/experimental/crc16_x25.h b/include/etl/experimental/crc16_x25.h new file mode 100644 index 00000000..d423d342 --- /dev/null +++ b/include/etl/experimental/crc16_x25.h @@ -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 + class crc16_x25_t : public etl::private_crc::crc_type + { + 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 + 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 diff --git a/include/etl/experimental/crc16_xmodem.h b/include/etl/experimental/crc16_xmodem.h new file mode 100644 index 00000000..c0d1921b --- /dev/null +++ b/include/etl/experimental/crc16_xmodem.h @@ -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 + using crc16_xmodem_t = etl::private_crc::crc_type; +#else + template + class crc16_xmodem_t : public etl::private_crc::crc_type + { + 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 + 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 diff --git a/include/etl/experimental/crc32.h b/include/etl/experimental/crc32.h new file mode 100644 index 00000000..5fd6b37e --- /dev/null +++ b/include/etl/experimental/crc32.h @@ -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 + class crc32_t : public etl::private_crc::crc_type + { + 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 + 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 diff --git a/include/etl/experimental/crc64_ecma.h b/include/etl/experimental/crc64_ecma.h new file mode 100644 index 00000000..adb3980d --- /dev/null +++ b/include/etl/experimental/crc64_ecma.h @@ -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 + class crc64_ecma_t : public etl::private_crc::crc_type + { + 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 + 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 diff --git a/include/etl/experimental/crc8_ccitt.h b/include/etl/experimental/crc8_ccitt.h new file mode 100644 index 00000000..156944b4 --- /dev/null +++ b/include/etl/experimental/crc8_ccitt.h @@ -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 + class crc8_ccitt_t : public etl::private_crc::crc_type + { + 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 + 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 diff --git a/include/etl/experimental/crc8_rohc.h b/include/etl/experimental/crc8_rohc.h new file mode 100644 index 00000000..baa4a3a0 --- /dev/null +++ b/include/etl/experimental/crc8_rohc.h @@ -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 + class crc8_rohc_t : public etl::private_crc::crc_type + { + 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 + 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 diff --git a/include/etl/experimental/crc8_table16.h b/include/etl/experimental/crc8_table16.h new file mode 100644 index 00000000..e7ad5988 --- /dev/null +++ b/include/etl/experimental/crc8_table16.h @@ -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 + struct crc8_policy_table16; + + //***************************************************************************** + // Specialisation for Reflect = false + //***************************************************************************** + template + struct crc8_policy_table16 + { + static ETL_CONSTANT uint8_t Mask = 0x0FU; + static ETL_CONSTANT uint8_t Chunk_Size = 4U; + + typedef uint8_t value_type; + + //***************************************************************************** + template + class entry + { + public: + + static ETL_CONSTANT size_t Accumulator_Bits = etl::integral_limits::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 + class table_entry + { + public: + + static ETL_CONSTANT size_t Accumulator_Bits = entry::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::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::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 + struct crc8_policy_table16 + { + static ETL_CONSTANT uint8_t Mask = 0x0FU; + static ETL_CONSTANT uint8_t Chunk_Size = 4U; + + typedef uint8_t value_type; + + //***************************************************************************** + template + class entry + { + public: + + static ETL_CONSTANT size_t Accumulator_Bits = etl::integral_limits::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::value : (Entry >> 1U)); + }; + + //************************************************************************* + template + class table_entry + { + public: + + static ETL_CONSTANT size_t Accumulator_Bits = entry::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::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 + class crc8_table16 : public etl::frame_check_sequence > + { + public: + + //************************************************************************* + /// Default constructor. + //************************************************************************* + crc8_table16() + { + this->reset(); + } + + //************************************************************************* + /// Constructor from range. + /// \param begin Start of the range. + /// \param end End of the range. + //************************************************************************* + template + crc8_table16(TIterator begin, const TIterator end) + { + this->reset(); + this->add(begin, end); + } + }; + } +} diff --git a/include/etl/experimental/crc8_table256.h b/include/etl/experimental/crc8_table256.h new file mode 100644 index 00000000..bd9c187c --- /dev/null +++ b/include/etl/experimental/crc8_table256.h @@ -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 + 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::value, + etl::private_crc::table_entry::value, + etl::private_crc::table_entry::value, + etl::private_crc::table_entry::value, + etl::private_crc::table_entry::value, + etl::private_crc::table_entry::value, + etl::private_crc::table_entry::value, + etl::private_crc::table_entry::value, + etl::private_crc::table_entry::value, + etl::private_crc::table_entry::value, + etl::private_crc::table_entry::value, + etl::private_crc::table_entry::value, + etl::private_crc::table_entry::value, + etl::private_crc::table_entry::value, + etl::private_crc::table_entry::value, + etl::private_crc::table_entry::value, + etl::private_crc::table_entry::value, + etl::private_crc::table_entry::value, + etl::private_crc::table_entry::value, + etl::private_crc::table_entry::value, + etl::private_crc::table_entry::value, + etl::private_crc::table_entry::value, + etl::private_crc::table_entry::value, + etl::private_crc::table_entry::value, + etl::private_crc::table_entry::value, + etl::private_crc::table_entry::value, + etl::private_crc::table_entry::value, + etl::private_crc::table_entry::value, + etl::private_crc::table_entry::value, + etl::private_crc::table_entry::value, + etl::private_crc::table_entry::value, + etl::private_crc::table_entry::value, + etl::private_crc::table_entry::value, + etl::private_crc::table_entry::value, + etl::private_crc::table_entry::value, + etl::private_crc::table_entry::value, + etl::private_crc::table_entry::value, + etl::private_crc::table_entry::value, + etl::private_crc::table_entry::value, + etl::private_crc::table_entry::value, + etl::private_crc::table_entry::value, + etl::private_crc::table_entry::value, + etl::private_crc::table_entry::value, + etl::private_crc::table_entry::value, + etl::private_crc::table_entry::value, + etl::private_crc::table_entry::value, + etl::private_crc::table_entry::value, + etl::private_crc::table_entry::value, + etl::private_crc::table_entry::value, + etl::private_crc::table_entry::value, + etl::private_crc::table_entry::value, + etl::private_crc::table_entry::value, + etl::private_crc::table_entry::value, + etl::private_crc::table_entry::value, + etl::private_crc::table_entry::value, + etl::private_crc::table_entry::value, + etl::private_crc::table_entry::value, + etl::private_crc::table_entry::value, + etl::private_crc::table_entry::value, + etl::private_crc::table_entry::value, + etl::private_crc::table_entry::value, + etl::private_crc::table_entry::value, + etl::private_crc::table_entry::value, + etl::private_crc::table_entry::value, + etl::private_crc::table_entry::value, + etl::private_crc::table_entry::value, + etl::private_crc::table_entry::value, + etl::private_crc::table_entry::value, + etl::private_crc::table_entry::value, + etl::private_crc::table_entry::value, + etl::private_crc::table_entry::value, + etl::private_crc::table_entry::value, + etl::private_crc::table_entry::value, + etl::private_crc::table_entry::value, + etl::private_crc::table_entry::value, + etl::private_crc::table_entry::value, + etl::private_crc::table_entry::value, + etl::private_crc::table_entry::value, + etl::private_crc::table_entry::value, + etl::private_crc::table_entry::value, + etl::private_crc::table_entry::value, + etl::private_crc::table_entry::value, + etl::private_crc::table_entry::value, + etl::private_crc::table_entry::value, + etl::private_crc::table_entry::value, + etl::private_crc::table_entry::value, + etl::private_crc::table_entry::value, + etl::private_crc::table_entry::value, + etl::private_crc::table_entry::value, + etl::private_crc::table_entry::value, + etl::private_crc::table_entry::value, + etl::private_crc::table_entry::value, + etl::private_crc::table_entry::value, + etl::private_crc::table_entry::value, + etl::private_crc::table_entry::value, + etl::private_crc::table_entry::value, + etl::private_crc::table_entry::value, + etl::private_crc::table_entry::value, + etl::private_crc::table_entry::value, + etl::private_crc::table_entry::value, + etl::private_crc::table_entry::value, + etl::private_crc::table_entry::value, + etl::private_crc::table_entry::value, + etl::private_crc::table_entry::value, + etl::private_crc::table_entry::value, + etl::private_crc::table_entry::value, + etl::private_crc::table_entry::value, + etl::private_crc::table_entry::value, + etl::private_crc::table_entry::value, + etl::private_crc::table_entry::value, + etl::private_crc::table_entry::value, + etl::private_crc::table_entry::value, + etl::private_crc::table_entry::value, + etl::private_crc::table_entry::value, + etl::private_crc::table_entry::value, + etl::private_crc::table_entry::value, + etl::private_crc::table_entry::value, + etl::private_crc::table_entry::value, + etl::private_crc::table_entry::value, + etl::private_crc::table_entry::value, + etl::private_crc::table_entry::value, + etl::private_crc::table_entry::value, + etl::private_crc::table_entry::value, + etl::private_crc::table_entry::value, + etl::private_crc::table_entry::value, + etl::private_crc::table_entry::value, + etl::private_crc::table_entry::value, + etl::private_crc::table_entry::value, + etl::private_crc::table_entry::value, + etl::private_crc::table_entry::value, + etl::private_crc::table_entry::value, + etl::private_crc::table_entry::value, + etl::private_crc::table_entry::value, + etl::private_crc::table_entry::value, + etl::private_crc::table_entry::value, + etl::private_crc::table_entry::value, + etl::private_crc::table_entry::value, + etl::private_crc::table_entry::value, + etl::private_crc::table_entry::value, + etl::private_crc::table_entry::value, + etl::private_crc::table_entry::value, + etl::private_crc::table_entry::value, + etl::private_crc::table_entry::value, + etl::private_crc::table_entry::value, + etl::private_crc::table_entry::value, + etl::private_crc::table_entry::value, + etl::private_crc::table_entry::value, + etl::private_crc::table_entry::value, + etl::private_crc::table_entry::value, + etl::private_crc::table_entry::value, + etl::private_crc::table_entry::value, + etl::private_crc::table_entry::value, + etl::private_crc::table_entry::value, + etl::private_crc::table_entry::value, + etl::private_crc::table_entry::value, + etl::private_crc::table_entry::value, + etl::private_crc::table_entry::value, + etl::private_crc::table_entry::value, + etl::private_crc::table_entry::value, + etl::private_crc::table_entry::value, + etl::private_crc::table_entry::value, + etl::private_crc::table_entry::value, + etl::private_crc::table_entry::value, + etl::private_crc::table_entry::value, + etl::private_crc::table_entry::value, + etl::private_crc::table_entry::value, + etl::private_crc::table_entry::value, + etl::private_crc::table_entry::value, + etl::private_crc::table_entry::value, + etl::private_crc::table_entry::value, + etl::private_crc::table_entry::value, + etl::private_crc::table_entry::value, + etl::private_crc::table_entry::value, + etl::private_crc::table_entry::value, + etl::private_crc::table_entry::value, + etl::private_crc::table_entry::value, + etl::private_crc::table_entry::value, + etl::private_crc::table_entry::value, + etl::private_crc::table_entry::value, + etl::private_crc::table_entry::value, + etl::private_crc::table_entry::value, + etl::private_crc::table_entry::value, + etl::private_crc::table_entry::value, + etl::private_crc::table_entry::value, + etl::private_crc::table_entry::value, + etl::private_crc::table_entry::value, + etl::private_crc::table_entry::value, + etl::private_crc::table_entry::value, + etl::private_crc::table_entry::value, + etl::private_crc::table_entry::value, + etl::private_crc::table_entry::value, + etl::private_crc::table_entry::value, + etl::private_crc::table_entry::value, + etl::private_crc::table_entry::value, + etl::private_crc::table_entry::value, + etl::private_crc::table_entry::value, + etl::private_crc::table_entry::value, + etl::private_crc::table_entry::value, + etl::private_crc::table_entry::value, + etl::private_crc::table_entry::value, + etl::private_crc::table_entry::value, + etl::private_crc::table_entry::value, + etl::private_crc::table_entry::value, + etl::private_crc::table_entry::value, + etl::private_crc::table_entry::value, + etl::private_crc::table_entry::value, + etl::private_crc::table_entry::value, + etl::private_crc::table_entry::value, + etl::private_crc::table_entry::value, + etl::private_crc::table_entry::value, + etl::private_crc::table_entry::value, + etl::private_crc::table_entry::value, + etl::private_crc::table_entry::value, + etl::private_crc::table_entry::value, + etl::private_crc::table_entry::value, + etl::private_crc::table_entry::value, + etl::private_crc::table_entry::value, + etl::private_crc::table_entry::value, + etl::private_crc::table_entry::value, + etl::private_crc::table_entry::value, + etl::private_crc::table_entry::value, + etl::private_crc::table_entry::value, + etl::private_crc::table_entry::value, + etl::private_crc::table_entry::value, + etl::private_crc::table_entry::value, + etl::private_crc::table_entry::value, + etl::private_crc::table_entry::value, + etl::private_crc::table_entry::value, + etl::private_crc::table_entry::value, + etl::private_crc::table_entry::value, + etl::private_crc::table_entry::value, + etl::private_crc::table_entry::value, + etl::private_crc::table_entry::value, + etl::private_crc::table_entry::value, + etl::private_crc::table_entry::value, + etl::private_crc::table_entry::value, + etl::private_crc::table_entry::value, + etl::private_crc::table_entry::value, + etl::private_crc::table_entry::value, + etl::private_crc::table_entry::value, + etl::private_crc::table_entry::value, + etl::private_crc::table_entry::value, + etl::private_crc::table_entry::value, + etl::private_crc::table_entry::value, + etl::private_crc::table_entry::value, + etl::private_crc::table_entry::value, + etl::private_crc::table_entry::value, + etl::private_crc::table_entry::value, + etl::private_crc::table_entry::value, + etl::private_crc::table_entry::value, + etl::private_crc::table_entry::value, + etl::private_crc::table_entry::value, + etl::private_crc::table_entry::value, + etl::private_crc::table_entry::value, + etl::private_crc::table_entry::value, + etl::private_crc::table_entry::value + }; + + crc = update_chunk(crc, value, table); + + return crc; + } + + //************************************************************************* + uint8_t final(uint8_t crc) const + { + return crc ^ Xor_Out; + } + }; + + //***************************************************************************** + // + //***************************************************************************** + template + class crc8_table256 : public etl::frame_check_sequence > + { + public: + + //************************************************************************* + /// Default constructor. + //************************************************************************* + crc8_table256() + { + this->reset(); + } + + //************************************************************************* + /// Constructor from range. + /// \param begin Start of the range. + /// \param end End of the range. + //************************************************************************* + template + crc8_table256(TIterator begin, const TIterator end) + { + this->reset(); + this->add(begin, end); + } + }; + } +} diff --git a/include/etl/experimental/crc8_table4.h b/include/etl/experimental/crc8_table4.h new file mode 100644 index 00000000..e69e815e --- /dev/null +++ b/include/etl/experimental/crc8_table4.h @@ -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 + struct crc8_policy_table4; + + //***************************************************************************** + // Specialisation for Reflect = false + //***************************************************************************** + template + struct crc8_policy_table4 + { + static ETL_CONSTANT uint8_t Mask = 0x03U; + static ETL_CONSTANT uint8_t Chunk_Size = 2U; + + typedef uint8_t value_type; + + //***************************************************************************** + template + class entry + { + public: + + static ETL_CONSTANT size_t Accumulator_Bits = etl::integral_limits::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 + class table_entry + { + public: + + static ETL_CONSTANT size_t Accumulator_Bits = entry::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::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::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 + struct crc8_policy_table4 + { + static ETL_CONSTANT uint8_t Mask = 0x03; + static ETL_CONSTANT uint8_t Chunk_Size = 2U; + + typedef uint8_t value_type; + + //***************************************************************************** + template + class entry + { + public: + + static ETL_CONSTANT size_t Accumulator_Bits = etl::integral_limits::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::value : (Entry >> 1U)); + }; + + //************************************************************************* + template + class table_entry + { + public: + + static ETL_CONSTANT size_t Accumulator_Bits = entry::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::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 + class crc8_table4 : public etl::frame_check_sequence > + { + public: + + //************************************************************************* + /// Default constructor. + //************************************************************************* + crc8_table4() + { + this->reset(); + } + + //************************************************************************* + /// Constructor from range. + /// \param begin Start of the range. + /// \param end End of the range. + //************************************************************************* + template + crc8_table4(TIterator begin, const TIterator end) + { + this->reset(); + this->add(begin, end); + } + }; + } +} diff --git a/include/etl/experimental/crc_implementation.h b/include/etl/experimental/crc_implementation.h new file mode 100644 index 00000000..2935cda6 --- /dev/null +++ b/include/etl/experimental/crc_implementation.h @@ -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 + 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 + class crc_entry; + + //********************************* + // Not reflected + template + class crc_entry + { + private: + + static ETL_CONSTANT size_t Accumulator_Bits = etl::integral_limits::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 + class crc_entry + { + private: + + static ETL_CONSTANT size_t Accumulator_Bits = etl::integral_limits::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::value : (Entry >> 1U)); + }; + + //***************************************************************************** + /// CRC Table Entry + //***************************************************************************** + template + 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 + class crc_table_entry + { + public: + + static ETL_CONSTANT size_t Accumulator_Bits = etl::integral_limits::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::value>::value>::value>::value>::value>::value>::value>::value; + }; + + //********************************* + // Chunk bit size of 4. + template + class crc_table_entry + { + public: + + static ETL_CONSTANT size_t Accumulator_Bits = etl::integral_limits::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::value>::value>::value>::value; + }; + + //********************************* + // Chunk bit size of 2. + template + class crc_table_entry + { + public: + + static ETL_CONSTANT size_t Accumulator_Bits = etl::integral_limits::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::value>::value; + }; + + //************************************************************************* + // Accumulator_Bits > Chunk_Bits and not reflected + template + 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 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 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 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 + struct crc_policy + { + ETL_STATIC_ASSERT((Table_Size == 4U) || (Table_Size == 16U) || (Table_Size == 256U), "Table size must be 4, 16 or 256"); + }; + + //********************************* + template + struct crc_policy + { + static ETL_CONSTANT size_t Table_Size = 256U; + static ETL_CONSTANT uint8_t Chunk_Mask = crc_traits::Chunk_Mask; + static ETL_CONSTANT uint8_t Chunk_Bits = crc_traits::Chunk_Bits; + static ETL_CONSTANT size_t Accumulator_Bits = etl::integral_limits::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::value, + crc_table_entry::value, + crc_table_entry::value, + crc_table_entry::value, + crc_table_entry::value, + crc_table_entry::value, + crc_table_entry::value, + crc_table_entry::value, + crc_table_entry::value, + crc_table_entry::value, + crc_table_entry::value, + crc_table_entry::value, + crc_table_entry::value, + crc_table_entry::value, + crc_table_entry::value, + crc_table_entry::value, + crc_table_entry::value, + crc_table_entry::value, + crc_table_entry::value, + crc_table_entry::value, + crc_table_entry::value, + crc_table_entry::value, + crc_table_entry::value, + crc_table_entry::value, + crc_table_entry::value, + crc_table_entry::value, + crc_table_entry::value, + crc_table_entry::value, + crc_table_entry::value, + crc_table_entry::value, + crc_table_entry::value, + crc_table_entry::value, + crc_table_entry::value, + crc_table_entry::value, + crc_table_entry::value, + crc_table_entry::value, + crc_table_entry::value, + crc_table_entry::value, + crc_table_entry::value, + crc_table_entry::value, + crc_table_entry::value, + crc_table_entry::value, + crc_table_entry::value, + crc_table_entry::value, + crc_table_entry::value, + crc_table_entry::value, + crc_table_entry::value, + crc_table_entry::value, + crc_table_entry::value, + crc_table_entry::value, + crc_table_entry::value, + crc_table_entry::value, + crc_table_entry::value, + crc_table_entry::value, + crc_table_entry::value, + crc_table_entry::value, + crc_table_entry::value, + crc_table_entry::value, + crc_table_entry::value, + crc_table_entry::value, + crc_table_entry::value, + crc_table_entry::value, + crc_table_entry::value, + crc_table_entry::value, + crc_table_entry::value, + crc_table_entry::value, + crc_table_entry::value, + crc_table_entry::value, + crc_table_entry::value, + crc_table_entry::value, + crc_table_entry::value, + crc_table_entry::value, + crc_table_entry::value, + crc_table_entry::value, + crc_table_entry::value, + crc_table_entry::value, + crc_table_entry::value, + crc_table_entry::value, + crc_table_entry::value, + crc_table_entry::value, + crc_table_entry::value, + crc_table_entry::value, + crc_table_entry::value, + crc_table_entry::value, + crc_table_entry::value, + crc_table_entry::value, + crc_table_entry::value, + crc_table_entry::value, + crc_table_entry::value, + crc_table_entry::value, + crc_table_entry::value, + crc_table_entry::value, + crc_table_entry::value, + crc_table_entry::value, + crc_table_entry::value, + crc_table_entry::value, + crc_table_entry::value, + crc_table_entry::value, + crc_table_entry::value, + crc_table_entry::value, + crc_table_entry::value, + crc_table_entry::value, + crc_table_entry::value, + crc_table_entry::value, + crc_table_entry::value, + crc_table_entry::value, + crc_table_entry::value, + crc_table_entry::value, + crc_table_entry::value, + crc_table_entry::value, + crc_table_entry::value, + crc_table_entry::value, + crc_table_entry::value, + crc_table_entry::value, + crc_table_entry::value, + crc_table_entry::value, + crc_table_entry::value, + crc_table_entry::value, + crc_table_entry::value, + crc_table_entry::value, + crc_table_entry::value, + crc_table_entry::value, + crc_table_entry::value, + crc_table_entry::value, + crc_table_entry::value, + crc_table_entry::value, + crc_table_entry::value, + crc_table_entry::value, + crc_table_entry::value, + crc_table_entry::value, + crc_table_entry::value, + crc_table_entry::value, + crc_table_entry::value, + crc_table_entry::value, + crc_table_entry::value, + crc_table_entry::value, + crc_table_entry::value, + crc_table_entry::value, + crc_table_entry::value, + crc_table_entry::value, + crc_table_entry::value, + crc_table_entry::value, + crc_table_entry::value, + crc_table_entry::value, + crc_table_entry::value, + crc_table_entry::value, + crc_table_entry::value, + crc_table_entry::value, + crc_table_entry::value, + crc_table_entry::value, + crc_table_entry::value, + crc_table_entry::value, + crc_table_entry::value, + crc_table_entry::value, + crc_table_entry::value, + crc_table_entry::value, + crc_table_entry::value, + crc_table_entry::value, + crc_table_entry::value, + crc_table_entry::value, + crc_table_entry::value, + crc_table_entry::value, + crc_table_entry::value, + crc_table_entry::value, + crc_table_entry::value, + crc_table_entry::value, + crc_table_entry::value, + crc_table_entry::value, + crc_table_entry::value, + crc_table_entry::value, + crc_table_entry::value, + crc_table_entry::value, + crc_table_entry::value, + crc_table_entry::value, + crc_table_entry::value, + crc_table_entry::value, + crc_table_entry::value, + crc_table_entry::value, + crc_table_entry::value, + crc_table_entry::value, + crc_table_entry::value, + crc_table_entry::value, + crc_table_entry::value, + crc_table_entry::value, + crc_table_entry::value, + crc_table_entry::value, + crc_table_entry::value, + crc_table_entry::value, + crc_table_entry::value, + crc_table_entry::value, + crc_table_entry::value, + crc_table_entry::value, + crc_table_entry::value, + crc_table_entry::value, + crc_table_entry::value, + crc_table_entry::value, + crc_table_entry::value, + crc_table_entry::value, + crc_table_entry::value, + crc_table_entry::value, + crc_table_entry::value, + crc_table_entry::value, + crc_table_entry::value, + crc_table_entry::value, + crc_table_entry::value, + crc_table_entry::value, + crc_table_entry::value, + crc_table_entry::value, + crc_table_entry::value, + crc_table_entry::value, + crc_table_entry::value, + crc_table_entry::value, + crc_table_entry::value, + crc_table_entry::value, + crc_table_entry::value, + crc_table_entry::value, + crc_table_entry::value, + crc_table_entry::value, + crc_table_entry::value, + crc_table_entry::value, + crc_table_entry::value, + crc_table_entry::value, + crc_table_entry::value, + crc_table_entry::value, + crc_table_entry::value, + crc_table_entry::value, + crc_table_entry::value, + crc_table_entry::value, + crc_table_entry::value, + crc_table_entry::value, + crc_table_entry::value, + crc_table_entry::value, + crc_table_entry::value, + crc_table_entry::value, + crc_table_entry::value, + crc_table_entry::value, + crc_table_entry::value, + crc_table_entry::value, + crc_table_entry::value, + crc_table_entry::value, + crc_table_entry::value, + crc_table_entry::value, + crc_table_entry::value, + crc_table_entry::value, + crc_table_entry::value, + crc_table_entry::value, + crc_table_entry::value, + crc_table_entry::value, + crc_table_entry::value, + crc_table_entry::value, + crc_table_entry::value, + crc_table_entry::value, + crc_table_entry::value, + crc_table_entry::value, + crc_table_entry::value, + crc_table_entry::value + }; + + crc = crc_update_chunk(crc, value, table); + + return crc; + } + + //************************************************************************* + TAccumulator final(TAccumulator crc) const + { + return crc ^ Xor_Out; + } + }; + + //********************************* + template + struct crc_policy + { + static ETL_CONSTANT size_t Table_Size = 16U; + static ETL_CONSTANT uint8_t Chunk_Mask = crc_traits::Chunk_Mask; + static ETL_CONSTANT uint8_t Chunk_Bits = crc_traits::Chunk_Bits; + static ETL_CONSTANT size_t Accumulator_Bits = etl::integral_limits::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::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::value, + crc_table_entry::value, + crc_table_entry::value, + crc_table_entry::value, + crc_table_entry::value, + crc_table_entry::value, + crc_table_entry::value, + crc_table_entry::value, + crc_table_entry::value, + crc_table_entry::value, + crc_table_entry::value, + crc_table_entry::value, + crc_table_entry::value, + crc_table_entry::value, + crc_table_entry::value, + crc_table_entry::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 + struct crc_policy + { + static ETL_CONSTANT size_t Table_Size = 4U; + static ETL_CONSTANT uint8_t Chunk_Mask = crc_traits::Chunk_Mask; + static ETL_CONSTANT uint8_t Chunk_Bits = crc_traits::Chunk_Bits; + static ETL_CONSTANT size_t Accumulator_Bits = etl::integral_limits::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::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::value, + crc_table_entry::value, + crc_table_entry::value, + crc_table_entry::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 + class crc_type : public etl::frame_check_sequence > + { + 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 + crc_type(TIterator begin, const TIterator end) + { + this->reset(); + this->add(begin, end); + } + }; + } +} diff --git a/include/etl/experimental/crc_parameters.h b/include/etl/experimental/crc_parameters.h new file mode 100644 index 00000000..309dbdf4 --- /dev/null +++ b/include/etl/experimental/crc_parameters.h @@ -0,0 +1,42 @@ +#pragma once + +#include "../platform.h" + +namespace etl +{ + namespace private_crc + { + template + 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 crc8_ccitt_parameters; + typedef crc_parameters crc8_rohc_parameters; + + // 16 bit. + typedef crc_parameters crc16_parameters; + typedef crc_parameters crc16_ccitt_parameters; + typedef crc_parameters crc16_aug_ccitt_parameters; + typedef crc_parameters crc16_genibus_parameters; + typedef crc_parameters crc16_kermit_parameters; + typedef crc_parameters crc16_modbus_parameters; + typedef crc_parameters crc16_usb_parameters; + typedef crc_parameters crc16_x25_parameters; + typedef crc_parameters crc16_xmodem_parameters; + + // 32 bit. + typedef crc_parameters crc32_parameters; + + // 64 bit. + typedef crc_parameters crc64_ecma_parameters; + } +} + + diff --git a/include/etl/experimental/crc_table_16.h b/include/etl/experimental/crc_table_16.h new file mode 100644 index 00000000..05cb77f8 --- /dev/null +++ b/include/etl/experimental/crc_table_16.h @@ -0,0 +1,701 @@ + +#pragma once + +#include +#include + +//***************************************************************************** +template +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 +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::value>::value>::value>::value>::value>::value>::value>::value; +}; + +//***************************************************************************** +/// 4 bit chunks +//***************************************************************************** +template +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::value>::value>::value>::value; +}; + +//***************************************************************************** +/// 2 bit chunks +//***************************************************************************** +template +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::value>::value; +}; + +//***************************************************************************** +template +struct crc_table; + +template +struct crc_table +{ + static const TAccumulator* get_table() + { + static const TAccumulator table[256] = + { + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value + }; + + return table; + } +}; + +template +struct crc_table +{ + static const TAccumulator* get_table() + { + static const TAccumulator table[16] = + { + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value + }; + + return table; + } +}; + +template +struct crc_table +{ + static const TAccumulator* get_table() + { + static const TAccumulator table[4] = + { + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value + }; + + return table; + } +}; + + +// +// Define the CRC algorithm parameters +// +template +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 +struct crc_traits {}; + +template +struct crc_traits +{ + 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; +}; + +template +struct crc_traits +{ + 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; +}; + +template +struct crc_traits +{ + 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; +}; + +// +// 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 +struct crc_forward_policy +{ + using traits = crc_traits; + + + [[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 +struct crc_reverse_policy +{ + using traits = crc_traits; + + + [[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 ::value>> +class crc_chunk_table +{ +public: + + using policy = typename std::conditional, crc_forward_policy>::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 +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 m_crc = table_impl::make_initial_value(algorithm::initial_value); +}; \ No newline at end of file diff --git a/include/etl/experimental/crc_table_256.h b/include/etl/experimental/crc_table_256.h new file mode 100644 index 00000000..bb6e45e8 --- /dev/null +++ b/include/etl/experimental/crc_table_256.h @@ -0,0 +1,519 @@ + +#pragma once + +#include +#include + +#include "../binary.h" +#include "../integral_limits.h" + +//***************************************************************************** +template +class entry +{ +private: + + static ETL_CONSTANT size_t Accumulator_Bits = etl::integral_limits::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 +class table_entry_8 +{ +//private: +public: + + static const size_t Accumulator_Bits = entry::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::value>::value>::value>::value>::value>::value>::value>::value; +}; + +//***************************************************************************** +template +struct crc_table_256 +{ + static const TAccumulator* get_table() + { + static const TAccumulator table[256] = + { + table_entry_8::value, + table_entry_8::value, + table_entry_8::value, + table_entry_8::value, + table_entry_8::value, + table_entry_8::value, + table_entry_8::value, + table_entry_8::value, + table_entry_8::value, + table_entry_8::value, + table_entry_8::value, + table_entry_8::value, + table_entry_8::value, + table_entry_8::value, + table_entry_8::value, + table_entry_8::value, + table_entry_8::value, + table_entry_8::value, + table_entry_8::value, + table_entry_8::value, + table_entry_8::value, + table_entry_8::value, + table_entry_8::value, + table_entry_8::value, + table_entry_8::value, + table_entry_8::value, + table_entry_8::value, + table_entry_8::value, + table_entry_8::value, + table_entry_8::value, + table_entry_8::value, + table_entry_8::value, + table_entry_8::value, + table_entry_8::value, + table_entry_8::value, + table_entry_8::value, + table_entry_8::value, + table_entry_8::value, + table_entry_8::value, + table_entry_8::value, + table_entry_8::value, + table_entry_8::value, + table_entry_8::value, + table_entry_8::value, + table_entry_8::value, + table_entry_8::value, + table_entry_8::value, + table_entry_8::value, + table_entry_8::value, + table_entry_8::value, + table_entry_8::value, + table_entry_8::value, + table_entry_8::value, + table_entry_8::value, + table_entry_8::value, + table_entry_8::value, + table_entry_8::value, + table_entry_8::value, + table_entry_8::value, + table_entry_8::value, + table_entry_8::value, + table_entry_8::value, + table_entry_8::value, + table_entry_8::value, + table_entry_8::value, + table_entry_8::value, + table_entry_8::value, + table_entry_8::value, + table_entry_8::value, + table_entry_8::value, + table_entry_8::value, + table_entry_8::value, + table_entry_8::value, + table_entry_8::value, + table_entry_8::value, + table_entry_8::value, + table_entry_8::value, + table_entry_8::value, + table_entry_8::value, + table_entry_8::value, + table_entry_8::value, + table_entry_8::value, + table_entry_8::value, + table_entry_8::value, + table_entry_8::value, + table_entry_8::value, + table_entry_8::value, + table_entry_8::value, + table_entry_8::value, + table_entry_8::value, + table_entry_8::value, + table_entry_8::value, + table_entry_8::value, + table_entry_8::value, + table_entry_8::value, + table_entry_8::value, + table_entry_8::value, + table_entry_8::value, + table_entry_8::value, + table_entry_8::value, + table_entry_8::value, + table_entry_8::value, + table_entry_8::value, + table_entry_8::value, + table_entry_8::value, + table_entry_8::value, + table_entry_8::value, + table_entry_8::value, + table_entry_8::value, + table_entry_8::value, + table_entry_8::value, + table_entry_8::value, + table_entry_8::value, + table_entry_8::value, + table_entry_8::value, + table_entry_8::value, + table_entry_8::value, + table_entry_8::value, + table_entry_8::value, + table_entry_8::value, + table_entry_8::value, + table_entry_8::value, + table_entry_8::value, + table_entry_8::value, + table_entry_8::value, + table_entry_8::value, + table_entry_8::value, + table_entry_8::value, + table_entry_8::value, + table_entry_8::value, + table_entry_8::value, + table_entry_8::value, + table_entry_8::value, + table_entry_8::value, + table_entry_8::value, + table_entry_8::value, + table_entry_8::value, + table_entry_8::value, + table_entry_8::value, + table_entry_8::value, + table_entry_8::value, + table_entry_8::value, + table_entry_8::value, + table_entry_8::value, + table_entry_8::value, + table_entry_8::value, + table_entry_8::value, + table_entry_8::value, + table_entry_8::value, + table_entry_8::value, + table_entry_8::value, + table_entry_8::value, + table_entry_8::value, + table_entry_8::value, + table_entry_8::value, + table_entry_8::value, + table_entry_8::value, + table_entry_8::value, + table_entry_8::value, + table_entry_8::value, + table_entry_8::value, + table_entry_8::value, + table_entry_8::value, + table_entry_8::value, + table_entry_8::value, + table_entry_8::value, + table_entry_8::value, + table_entry_8::value, + table_entry_8::value, + table_entry_8::value, + table_entry_8::value, + table_entry_8::value, + table_entry_8::value, + table_entry_8::value, + table_entry_8::value, + table_entry_8::value, + table_entry_8::value, + table_entry_8::value, + table_entry_8::value, + table_entry_8::value, + table_entry_8::value, + table_entry_8::value, + table_entry_8::value, + table_entry_8::value, + table_entry_8::value, + table_entry_8::value, + table_entry_8::value, + table_entry_8::value, + table_entry_8::value, + table_entry_8::value, + table_entry_8::value, + table_entry_8::value, + table_entry_8::value, + table_entry_8::value, + table_entry_8::value, + table_entry_8::value, + table_entry_8::value, + table_entry_8::value, + table_entry_8::value, + table_entry_8::value, + table_entry_8::value, + table_entry_8::value, + table_entry_8::value, + table_entry_8::value, + table_entry_8::value, + table_entry_8::value, + table_entry_8::value, + table_entry_8::value, + table_entry_8::value, + table_entry_8::value, + table_entry_8::value, + table_entry_8::value, + table_entry_8::value, + table_entry_8::value, + table_entry_8::value, + table_entry_8::value, + table_entry_8::value, + table_entry_8::value, + table_entry_8::value, + table_entry_8::value, + table_entry_8::value, + table_entry_8::value, + table_entry_8::value, + table_entry_8::value, + table_entry_8::value, + table_entry_8::value, + table_entry_8::value, + table_entry_8::value, + table_entry_8::value, + table_entry_8::value, + table_entry_8::value, + table_entry_8::value, + table_entry_8::value, + table_entry_8::value, + table_entry_8::value, + table_entry_8::value, + table_entry_8::value, + table_entry_8::value, + table_entry_8::value, + table_entry_8::value, + table_entry_8::value, + table_entry_8::value, + table_entry_8::value, + table_entry_8::value, + table_entry_8::value, + table_entry_8::value, + table_entry_8::value, + table_entry_8::value, + table_entry_8::value, + table_entry_8::value, + table_entry_8::value, + table_entry_8::value, + table_entry_8::value, + table_entry_8::value, + table_entry_8::value, + table_entry_8::value + }; + + return table; + } +}; +// +//// +//// Define the CRC algorithm parameters +//// +//template +//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 +//struct crc_traits {}; +// +//template +//struct crc_traits_256 +//{ +// static constexpr std::size_t ACCUMULATOR_BITS = etl::integral_limits::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; +//}; +// +//// +//// 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 +//struct crc_forward_policy_256 +//{ +// typedef crc_traits_256 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 +//struct crc_reverse_policy_256 +//{ +// typedef crc_traits_256 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 ::value>> +//class crc_chunk_table +//{ +//public: +// +// using policy = typename std::conditional, crc_forward_policy>::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 +//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 m_crc = table_impl::make_initial_value(algorithm::initial_value); +//}; \ No newline at end of file diff --git a/include/etl/experimental/crc_table_4.h b/include/etl/experimental/crc_table_4.h new file mode 100644 index 00000000..a44bed84 --- /dev/null +++ b/include/etl/experimental/crc_table_4.h @@ -0,0 +1,698 @@ + +#pragma once + +#include +#include + +//***************************************************************************** +template +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 +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::value>::value>::value>::value>::value>::value>::value>::value; +}; + +//***************************************************************************** +/// 4 bit chunks +//***************************************************************************** +template +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::value>::value>::value>::value; +}; + +//***************************************************************************** +/// 2 bit chunks +//***************************************************************************** +template +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::value>::value; +}; + +//***************************************************************************** +template +struct crc_table +{ + static const TAccumulator* get_table() + { + static const TAccumulator table[256] = + { + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value + }; + + return table; + } +}; + +template +struct crc_table +{ + static const TAccumulator* get_table() + { + static const TAccumulator table[16] = + { + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value + }; + + return table; + } +}; + +template +struct crc_table +{ + static const TAccumulator* get_table() + { + static const TAccumulator table[4] = + { + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value + }; + + return table; + } +}; + + +// +// Define the CRC algorithm parameters +// +template +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 +struct crc_traits {}; + +template +struct crc_traits +{ + 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; +}; + +template +struct crc_traits +{ + 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; +}; + +template +struct crc_traits +{ + 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; +}; + +// +// 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 +struct crc_forward_policy +{ + using traits = crc_traits; + + + [[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 +struct crc_reverse_policy +{ + using traits = crc_traits; + + + [[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 ::value>> +class crc_chunk_table +{ +public: + + using policy = typename std::conditional, crc_forward_policy>::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 +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 m_crc = table_impl::make_initial_value(algorithm::initial_value); +}; \ No newline at end of file diff --git a/include/etl/experimental/crc_table_generator.h b/include/etl/experimental/crc_table_generator.h new file mode 100644 index 00000000..0d5c514a --- /dev/null +++ b/include/etl/experimental/crc_table_generator.h @@ -0,0 +1,712 @@ + +#pragma once + +#include +#include + +enum +{ + Chunk_8_Bits = 8, + Chunk_4_Bits = 4, + Chunk_2_Bits = 2 +}; + +//***************************************************************************** +template +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 +class table_entry; + +//***************************************************************************** +/// 8 bit chunks +//***************************************************************************** +template +class table_entry +{ +//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::value>::value>::value>::value>::value>::value>::value>::value; +}; + +//***************************************************************************** +/// 4 bit chunks +//***************************************************************************** +template +class table_entry +{ +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::value>::value>::value>::value; +}; + +//***************************************************************************** +/// 2 bit chunks +//***************************************************************************** +template +class table_entry +{ +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::value>::value; +}; + +//***************************************************************************** +template +struct crc_table; + +template +struct crc_table +{ + static const TAccumulator* get_table() + { + static const TAccumulator table[256] = + { + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value + }; + + return table; + } +}; + +template +struct crc_table +{ + static const TAccumulator* get_table() + { + static const TAccumulator table[16] = + { + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value + }; + + return table; + } +}; + +template +struct crc_table +{ + static const TAccumulator* get_table() + { + static const TAccumulator table[4] = + { + table_entry::value, + table_entry::value, + table_entry::value, + table_entry::value + }; + + return table; + } +}; + + +// +// Define the CRC algorithm parameters +// +template +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 +struct crc_traits {}; + +template +struct crc_traits +{ + 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; +}; + +template +struct crc_traits +{ + 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; +}; + +template +struct crc_traits +{ + 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; +}; + +// +// 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 +struct crc_forward_policy +{ + using traits = crc_traits; + + + [[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 +struct crc_reverse_policy +{ + using traits = crc_traits; + + + [[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 ::value>> +class crc_chunk_table +{ +public: + + using policy = typename std::conditional, crc_forward_policy>::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 +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 m_crc = table_impl::make_initial_value(algorithm::initial_value); +}; \ No newline at end of file diff --git a/test/test_crc_table16.cpp b/test/test_crc_table16.cpp new file mode 100644 index 00000000..da46a9e5 --- /dev/null +++ b/test/test_crc_table16.cpp @@ -0,0 +1,1259 @@ +/****************************************************************************** +The MIT License(MIT) + +Embedded Template Library. +https://github.com/ETLCPP/etl +https://www.etlcpp.com + +Copyright(c) 2014 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. +******************************************************************************/ + +#include "unit_test_framework.h" + +#include +#include +#include +#include + +#include "etl/experimental/crc8_ccitt.h" +#include "etl/experimental/crc8_rohc.h" +//#include "etl/experimental/crc16.h" +//#include "etl/crc16.h" +//#include "etl/crc16_ccitt.h" +//#include "etl/crc16_aug_ccitt.h" +//#include "etl/crc16_kermit.h" +//#include "etl/crc16_modbus.h" +//#include "etl/crc16_usb.h" +//#include "etl/crc16_xmodem.h" +//#include "etl/crc16_genibus.h" +//#include "etl/crc16_x25.h" +//#include "etl/crc32.h" +//#include "etl/crc32_c.h" +//#include "etl/crc32_bzip2.h" +//#include "etl/crc32_mpeg2.h" +//#include "etl/crc32_posix.h" +//#include "etl/crc64_ecma.h" + +//***************************************************************************** +// The results for these tests were created from https://crccalc.com/ +//***************************************************************************** + +namespace +{ + SUITE(test_crc_experimental) + { + ////************************************************************************* + //TEST(test_crc8_ccitt_constructor) + //{ + // std::string data("123456789"); + + // uint8_t crc = etl::crc::crc8_ccitt_t16(data.begin(), data.end()); + + // CHECK_EQUAL(0xF4, int(crc)); + //} + + ////************************************************************************* + //TEST(test_crc8_ccitt_add_values) + //{ + // std::string data("123456789"); + + // etl::crc::crc8_ccitt_t16 crc_calculator; + + // for (size_t i = 0; i < data.size(); ++i) + // { + // crc_calculator.add(data[i]); + // } + + // uint8_t crc = crc_calculator; + + // CHECK_EQUAL(0xF4, int(crc)); + //} + + ////************************************************************************* + //TEST(test_crc8_ccitt_add_range) + //{ + // std::string data("123456789"); + + // etl::crc::crc8_ccitt_t16 crc_calculator; + + // crc_calculator.add(data.begin(), data.end()); + + // uint8_t crc = crc_calculator.value(); + + // CHECK_EQUAL(0xF4, int(crc)); + //} + + ////************************************************************************* + //TEST(test_crc8_ccitt_add_range_via_iterator) + //{ + // std::string data("123456789"); + + // etl::crc::crc8_ccitt_t16 crc_calculator; + + // std::copy(data.begin(), data.end(), crc_calculator.input()); + + // uint8_t crc = crc_calculator.value(); + + // CHECK_EQUAL(0xF4, int(crc)); + //} + + ////************************************************************************* + //TEST(test_crc8_ccitt_add_range_endian) + //{ + // std::vector data1 = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08 }; + // std::vector data2 = { 0x04030201, 0x08070605 }; + // std::vector data3 = { 0x08, 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01 }; + + // uint8_t crc1 = etl::crc32(data1.begin(), data1.end()); + // uint8_t crc2 = etl::crc32((uint8_t*)&data2[0], (uint8_t*)(&data2[0] + data2.size())); + // CHECK_EQUAL(int(crc1), int(crc2)); + + // uint8_t crc3 = etl::crc32(data3.rbegin(), data3.rend()); + // CHECK_EQUAL(int(crc1), int(crc3)); + //} + + ////************************************************************************* + //TEST(test_crc8_rohc_constructor) + //{ + // std::string data("123456789"); + + // uint8_t crc = etl::crc::crc8_rohc(data.begin(), data.end()); + + // CHECK_EQUAL(0xD0, int(crc)); + //} + + ////************************************************************************* + //TEST(test_crc8_rohc_add_values) + //{ + // std::string data("123456789"); + + // etl::crc::crc8_rohc crc_calculator; + + // for (size_t i = 0; i < data.size(); ++i) + // { + // crc_calculator.add(data[i]); + // } + + // uint8_t crc = crc_calculator; + + // CHECK_EQUAL(0xD0, int(crc)); + //} + + ////************************************************************************* + //TEST(test_crc8_rohc_add_range) + //{ + // std::string data("123456789"); + + // etl::crc::crc8_rohc crc_calculator; + + // crc_calculator.add(data.begin(), data.end()); + + // uint8_t crc = crc_calculator.value(); + + // CHECK_EQUAL(0xD0, int(crc)); + //} + + ////************************************************************************* + //TEST(test_crc8_rohc_add_range_via_iterator) + //{ + // std::string data("123456789"); + + // etl::crc::crc8_rohc crc_calculator; + + // std::copy(data.begin(), data.end(), crc_calculator.input()); + + // uint8_t crc = crc_calculator.value(); + + // CHECK_EQUAL(0xD0, int(crc)); + //} + + ////************************************************************************* + //TEST(test_crc8_rohc_add_range_endian) + //{ + // std::vector data1 = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08 }; + // std::vector data2 = { 0x04030201, 0x08070605 }; + // std::vector data3 = { 0x08, 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01 }; + + // uint8_t crc1 = etl::crc32(data1.begin(), data1.end()); + // uint8_t crc2 = etl::crc32((uint8_t*)&data2[0], (uint8_t*)(&data2[0] + data2.size())); + // CHECK_EQUAL(int(crc1), int(crc2)); + + // uint8_t crc3 = etl::crc32(data3.rbegin(), data3.rend()); + // CHECK_EQUAL(int(crc1), int(crc3)); + //} + + ////************************************************************************* + //TEST(test_crc16) + //{ + // std::string data("123456789"); + + // uint16_t crc = etl::crc::crc16(data.begin(), data.end()); + + // CHECK_EQUAL(0xBB3D, crc); + //} + + ////************************************************************************* + //TEST(test_crc16_add_values) + //{ + // std::string data("123456789"); + + // etl::crc::crc16 crc_calculator; + + // for (size_t i = 0; i < data.size(); ++i) + // { + // crc_calculator.add(data[i]); + // } + + // uint16_t crc = crc_calculator; + + // CHECK_EQUAL(0xBB3D, crc); + //} + + ////************************************************************************* + //TEST(test_crc16_add_range) + //{ + // std::string data("123456789"); + + // etl::crc::crc16 crc_calculator; + + // crc_calculator.add(data.begin(), data.end()); + + // uint16_t crc = crc_calculator.value(); + + // CHECK_EQUAL(0xBB3D, crc); + //} + + ////************************************************************************* + //TEST(test_crc16_add_range_via_iterator) + //{ + // std::string data("123456789"); + + // etl::crc::crc16 crc_calculator; + + // std::copy(data.begin(), data.end(), crc_calculator.input()); + + // uint16_t crc = crc_calculator.value(); + + // CHECK_EQUAL(0xBB3D, crc); + //} + + ////************************************************************************* + //TEST(test_crc16_add_range_endian) + //{ + // std::vector data1 = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08 }; + // std::vector data2 = { 0x04030201, 0x08070605 }; + // std::vector data3 = { 0x08, 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01 }; + + // uint16_t crc1 = etl::crc16(data1.begin(), data1.end()); + // uint16_t crc2 = etl::crc16((uint8_t*)&data2[0], (uint8_t*)(&data2[0] + data2.size())); + // CHECK_EQUAL(crc1, crc2); + + // uint16_t crc3 = etl::crc16(data3.rbegin(), data3.rend()); + // CHECK_EQUAL(crc1, crc3); + //} + + ////************************************************************************* + //TEST(test_crc16_ccitt) + //{ + // std::string data("123456789"); + + // uint16_t crc = etl::crc16_ccitt(data.begin(), data.end()); + + // CHECK_EQUAL(0x29B1, crc); + //} + + ////************************************************************************* + //TEST(test_crc16_ccitt_add_values) + //{ + // std::string data("123456789"); + + // etl::crc16_ccitt crc_calculator; + + // for (size_t i = 0; i < data.size(); ++i) + // { + // crc_calculator.add(data[i]); + // } + + // uint16_t crc = crc_calculator; + + // CHECK_EQUAL(0x29B1, crc); + //} + + ////************************************************************************* + //TEST(test_crc16_ccitt_add_range) + //{ + // std::string data("123456789"); + + // etl::crc16_ccitt crc_calculator; + + // crc_calculator.add(data.begin(), data.end()); + + // uint16_t crc = crc_calculator.value(); + + // CHECK_EQUAL(0x29B1, crc); + //} + + ////************************************************************************* + //TEST(test_crc16_ccitt_add_range_via_iterator) + //{ + // std::string data("123456789"); + + // etl::crc16_ccitt crc_calculator; + + // std::copy(data.begin(), data.end(), crc_calculator.input()); + + // uint16_t crc = crc_calculator.value(); + + // CHECK_EQUAL(0x29B1, crc); + //} + + ////************************************************************************* + //TEST(test_crc16_ccitt_add_range_endian) + //{ + // std::vector data1 = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08 }; + // std::vector data2 = { 0x04030201, 0x08070605 }; + // std::vector data3 = { 0x08, 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01 }; + + // uint16_t crc1 = etl::crc16_ccitt(data1.begin(), data1.end()); + // uint16_t crc2 = etl::crc16_ccitt((uint8_t*)&data2[0], (uint8_t*)(&data2[0] + data2.size())); + // CHECK_EQUAL(crc1, crc2); + + // uint16_t crc3 = etl::crc16_ccitt(data3.rbegin(), data3.rend()); + // CHECK_EQUAL(crc1, crc3); + //} + + ////************************************************************************* + //TEST(test_crc16_kermit) + //{ + // std::string data("123456789"); + + // uint16_t crc = etl::crc16_kermit(data.begin(), data.end()); + + // CHECK_EQUAL(0x2189, crc); + //} + + ////************************************************************************* + //TEST(test_crc16_kermit_add_values) + //{ + // std::string data("123456789"); + + // etl::crc16_kermit crc_calculator; + + // for (size_t i = 0; i < data.size(); ++i) + // { + // crc_calculator.add(data[i]); + // } + + // uint16_t crc = crc_calculator; + + // CHECK_EQUAL(0x2189, crc); + //} + + ////************************************************************************* + //TEST(test_crc16_kermit_add_range) + //{ + // std::string data("123456789"); + + // etl::crc16_kermit crc_calculator; + + // crc_calculator.add(data.begin(), data.end()); + + // uint16_t crc = crc_calculator.value(); + + // CHECK_EQUAL(0x2189, crc); + //} + + ////************************************************************************* + //TEST(test_crc16_kermit_add_range_via_iterator) + //{ + // std::string data("123456789"); + + // etl::crc16_kermit crc_calculator; + + // std::copy(data.begin(), data.end(), crc_calculator.input()); + + // uint16_t crc = crc_calculator.value(); + + // CHECK_EQUAL(0x2189, crc); + //} + + ////************************************************************************* + //TEST(test_crc16_kermit_add_range_endian) + //{ + // std::vector data1 = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08 }; + // std::vector data2 = { 0x04030201, 0x08070605 }; + // std::vector data3 = { 0x08, 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01 }; + + // uint16_t crc1 = etl::crc16_kermit(data1.begin(), data1.end()); + // uint16_t crc2 = etl::crc16_kermit((uint8_t*)&data2[0], (uint8_t*)(&data2[0] + data2.size())); + // CHECK_EQUAL(crc1, crc2); + + // uint16_t crc3 = etl::crc16_kermit(data3.rbegin(), data3.rend()); + // CHECK_EQUAL(crc1, crc3); + //} + + ////************************************************************************* + //TEST(test_crc16_modbus) + //{ + // std::string data("123456789"); + + // uint16_t crc = etl::crc16_modbus(data.begin(), data.end()); + + // CHECK_EQUAL(0x4B37, crc); + //} + + ////************************************************************************* + //TEST(test_crc16_modbus_add_values) + //{ + // std::string data("123456789"); + + // etl::crc16_modbus crc_calculator; + + // for (size_t i = 0; i < data.size(); ++i) + // { + // crc_calculator.add(data[i]); + // } + + // uint16_t crc = crc_calculator; + + // CHECK_EQUAL(0x4B37, crc); + //} + + ////************************************************************************* + //TEST(test_crc16_modbus_add_range) + //{ + // std::string data("123456789"); + + // etl::crc16_modbus crc_calculator; + + // crc_calculator.add(data.begin(), data.end()); + + // uint16_t crc = crc_calculator.value(); + + // CHECK_EQUAL(0x4B37, crc); + //} + + ////************************************************************************* + //TEST(test_crc16_modbus_add_range_via_iterator) + //{ + // std::string data("123456789"); + + // etl::crc16_modbus crc_calculator; + + // std::copy(data.begin(), data.end(), crc_calculator.input()); + + // uint16_t crc = crc_calculator.value(); + + // CHECK_EQUAL(0x4B37, crc); + //} + + ////************************************************************************* + //TEST(test_crc16_modbus_add_range_endian) + //{ + // std::vector data1 = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08 }; + // std::vector data2 = { 0x04030201, 0x08070605 }; + // std::vector data3 = { 0x08, 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01 }; + + // uint16_t crc1 = etl::crc16_modbus(data1.begin(), data1.end()); + // uint16_t crc2 = etl::crc16_modbus((uint8_t*)&data2[0], (uint8_t*)(&data2[0] + data2.size())); + // CHECK_EQUAL(crc1, crc2); + + // uint16_t crc3 = etl::crc16_modbus(data3.rbegin(), data3.rend()); + // CHECK_EQUAL(crc1, crc3); + //} + + ////************************************************************************* + //TEST(test_crc16_usb) + //{ + // std::string data("123456789"); + + // uint16_t crc = etl::crc16_usb(data.begin(), data.end()); + + // CHECK_EQUAL(0xB4C8, crc); + //} + + ////************************************************************************* + //TEST(test_crc16_usb_add_values) + //{ + // std::string data("123456789"); + + // etl::crc16_usb crc_calculator; + + // for (size_t i = 0; i < data.size(); ++i) + // { + // crc_calculator.add(data[i]); + // } + + // uint16_t crc = crc_calculator; + + // CHECK_EQUAL(0xB4C8, crc); + //} + + ////************************************************************************* + //TEST(test_crc16_usb_add_range) + //{ + // std::string data("123456789"); + + // etl::crc16_usb crc_calculator; + + // crc_calculator.add(data.begin(), data.end()); + + // uint16_t crc = crc_calculator.value(); + + // CHECK_EQUAL(0xB4C8, crc); + //} + + ////************************************************************************* + //TEST(test_crc16_usb_add_range_via_iterator) + //{ + // std::string data("123456789"); + + // etl::crc16_usb crc_calculator; + + // std::copy(data.begin(), data.end(), crc_calculator.input()); + + // uint16_t crc = crc_calculator.value(); + + // CHECK_EQUAL(0xB4C8, crc); + //} + + ////************************************************************************* + //TEST(test_crc16_usb_add_range_endian) + //{ + // std::vector data1 = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08 }; + // std::vector data2 = { 0x04030201, 0x08070605 }; + // std::vector data3 = { 0x08, 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01 }; + + // uint16_t crc1 = etl::crc16_usb(data1.begin(), data1.end()); + // uint16_t crc2 = etl::crc16_usb((uint8_t*)&data2[0], (uint8_t*)(&data2[0] + data2.size())); + // CHECK_EQUAL(crc1, crc2); + + // uint16_t crc3 = etl::crc16_usb(data3.rbegin(), data3.rend()); + // CHECK_EQUAL(crc1, crc3); + //} + + ////************************************************************************* + //TEST(test_crc16_xmodem) + //{ + // std::string data("123456789"); + + // uint16_t crc = etl::crc16_xmodem(data.begin(), data.end()); + + // CHECK_EQUAL(0x31C3, crc); + //} + + ////************************************************************************* + //TEST(test_crc16_xmodem_add_values) + //{ + // std::string data("123456789"); + + // etl::crc16_xmodem crc_calculator; + + // for (size_t i = 0; i < data.size(); ++i) + // { + // crc_calculator.add(data[i]); + // } + + // uint16_t crc = crc_calculator; + + // CHECK_EQUAL(0x31C3, crc); + //} + + ////************************************************************************* + //TEST(test_crc16_xmodem_add_range) + //{ + // std::string data("123456789"); + + // etl::crc16_xmodem crc_calculator; + + // crc_calculator.add(data.begin(), data.end()); + + // uint16_t crc = crc_calculator.value(); + + // CHECK_EQUAL(0x31C3, crc); + //} + + ////************************************************************************* + //TEST(test_crc16_xmodem_add_range_via_iterator) + //{ + // std::string data("123456789"); + + // etl::crc16_xmodem crc_calculator; + + // std::copy(data.begin(), data.end(), crc_calculator.input()); + + // uint16_t crc = crc_calculator.value(); + + // CHECK_EQUAL(0x31C3, crc); + //} + + ////************************************************************************* + //TEST(test_crc16_xmodem_add_range_endian) + //{ + // std::vector data1 = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08 }; + // std::vector data2 = { 0x04030201, 0x08070605 }; + // std::vector data3 = { 0x08, 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01 }; + + // uint16_t crc1 = etl::crc16_xmodem(data1.begin(), data1.end()); + // uint16_t crc2 = etl::crc16_xmodem((uint8_t*)&data2[0], (uint8_t*)(&data2[0] + data2.size())); + // CHECK_EQUAL(crc1, crc2); + + // uint16_t crc3 = etl::crc16_xmodem(data3.rbegin(), data3.rend()); + // CHECK_EQUAL(crc1, crc3); + //} + + ////************************************************************************* + //TEST(test_crc16_aug_ccitt) + //{ + // std::string data("123456789"); + + // uint16_t crc = etl::crc16_aug_ccitt(data.begin(), data.end()); + + // CHECK_EQUAL(0xE5CC, crc); + //} + + ////************************************************************************* + //TEST(test_crc16_aug_ccitt_add_values) + //{ + // std::string data("123456789"); + + // etl::crc16_aug_ccitt crc_calculator; + + // for (size_t i = 0; i < data.size(); ++i) + // { + // crc_calculator.add(data[i]); + // } + + // uint16_t crc = crc_calculator; + + // CHECK_EQUAL(0xE5CC, crc); + //} + + ////************************************************************************* + //TEST(test_crc16_aug_ccitt_add_range) + //{ + // std::string data("123456789"); + + // etl::crc16_aug_ccitt crc_calculator; + + // crc_calculator.add(data.begin(), data.end()); + + // uint16_t crc = crc_calculator.value(); + + // CHECK_EQUAL(0xE5CC, crc); + //} + + ////************************************************************************* + //TEST(test_crc16_aug_ccitt_add_range_via_iterator) + //{ + // std::string data("123456789"); + + // etl::crc16_aug_ccitt crc_calculator; + + // std::copy(data.begin(), data.end(), crc_calculator.input()); + + // uint16_t crc = crc_calculator.value(); + + // CHECK_EQUAL(0xE5CC, crc); + //} + + ////************************************************************************* + //TEST(test_crc16_aug_ccitt_add_range_endian) + //{ + // std::vector data1 = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08 }; + // std::vector data2 = { 0x04030201, 0x08070605 }; + // std::vector data3 = { 0x08, 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01 }; + + // uint16_t crc1 = etl::crc16_aug_ccitt(data1.begin(), data1.end()); + // uint16_t crc2 = etl::crc16_aug_ccitt((uint8_t*)&data2[0], (uint8_t*)(&data2[0] + data2.size())); + // CHECK_EQUAL(crc1, crc2); + + // uint16_t crc3 = etl::crc16_aug_ccitt(data3.rbegin(), data3.rend()); + // CHECK_EQUAL(crc1, crc3); + //} + + ////************************************************************************* + //TEST(test_crc16_genibus) + //{ + // std::string data("123456789"); + + // uint16_t crc = etl::crc16_genibus(data.begin(), data.end()); + + // CHECK_EQUAL(0xD64E, crc); + //} + + ////************************************************************************* + //TEST(test_crc16_genibus_add_values) + //{ + // std::string data("123456789"); + + // etl::crc16_genibus crc_calculator; + + // for (size_t i = 0; i < data.size(); ++i) + // { + // crc_calculator.add(data[i]); + // } + + // uint16_t crc = crc_calculator; + + // CHECK_EQUAL(0xD64E, crc); + //} + + ////************************************************************************* + //TEST(test_crc16_genibus_add_range) + //{ + // std::string data("123456789"); + + // etl::crc16_genibus crc_calculator; + + // crc_calculator.add(data.begin(), data.end()); + + // uint16_t crc = crc_calculator.value(); + + // CHECK_EQUAL(0xD64E, crc); + //} + + ////************************************************************************* + //TEST(test_crc16_genibus_add_range_via_iterator) + //{ + // std::string data("123456789"); + + // etl::crc16_genibus crc_calculator; + + // std::copy(data.begin(), data.end(), crc_calculator.input()); + + // uint16_t crc = crc_calculator.value(); + + // CHECK_EQUAL(0xD64E, crc); + //} + + ////************************************************************************* + //TEST(test_crc16_genibus_add_range_endian) + //{ + // std::vector data1 = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08 }; + // std::vector data2 = { 0x04030201, 0x08070605 }; + // std::vector data3 = { 0x08, 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01 }; + + // uint16_t crc1 = etl::crc16_genibus(data1.begin(), data1.end()); + // uint16_t crc2 = etl::crc16_genibus((uint8_t*)&data2[0], (uint8_t*)(&data2[0] + data2.size())); + // CHECK_EQUAL(crc1, crc2); + + // uint16_t crc3 = etl::crc16_genibus(data3.rbegin(), data3.rend()); + // CHECK_EQUAL(crc1, crc3); + //} + + ////************************************************************************* + //TEST(test_crc16_x25) + //{ + // std::string data("123456789"); + + // uint16_t crc = etl::crc16_x25(data.begin(), data.end()); + + // CHECK_EQUAL(0x906E, crc); + //} + + ////************************************************************************* + //TEST(test_crc16_x25_add_values) + //{ + // std::string data("123456789"); + + // etl::crc16_x25 crc_calculator; + + // for (size_t i = 0; i < data.size(); ++i) + // { + // crc_calculator.add(data[i]); + // } + + // uint16_t crc = crc_calculator; + + // CHECK_EQUAL(0x906E, crc); + //} + + ////************************************************************************* + //TEST(test_crc16_x25_add_range) + //{ + // std::string data("123456789"); + + // etl::crc16_x25 crc_calculator; + + // crc_calculator.add(data.begin(), data.end()); + + // uint16_t crc = crc_calculator.value(); + + // CHECK_EQUAL(0x906E, crc); + //} + + ////************************************************************************* + //TEST(test_crc16_x25_add_range_via_iterator) + //{ + // std::string data("123456789"); + + // etl::crc16_x25 crc_calculator; + + // std::copy(data.begin(), data.end(), crc_calculator.input()); + + // uint16_t crc = crc_calculator.value(); + + // CHECK_EQUAL(0x906E, crc); + //} + + ////************************************************************************* + //TEST(test_crc16_x25_add_range_endian) + //{ + // std::vector data1 = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08 }; + // std::vector data2 = { 0x04030201, 0x08070605 }; + // std::vector data3 = { 0x08, 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01 }; + + // uint16_t crc1 = etl::crc16_x25(data1.begin(), data1.end()); + // uint16_t crc2 = etl::crc16_x25((uint8_t*)&data2[0], (uint8_t*)(&data2[0] + data2.size())); + // CHECK_EQUAL(crc1, crc2); + + // uint16_t crc3 = etl::crc16_x25(data3.rbegin(), data3.rend()); + // CHECK_EQUAL(crc1, crc3); + //} + + ////************************************************************************* + //TEST(test_crc32) + //{ + // std::string data("123456789"); + + // uint32_t crc = etl::crc32(data.begin(), data.end()); + + // CHECK_EQUAL(0xCBF43926, crc); + //} + + ////************************************************************************* + //TEST(test_crc32_add_values) + //{ + // std::string data("123456789"); + + // etl::crc32 crc_calculator; + + // for (size_t i = 0; i < data.size(); ++i) + // { + // crc_calculator.add(data[i]); + // } + + // uint32_t crc = crc_calculator; + + + // CHECK_EQUAL(0xCBF43926, crc); + //} + + ////************************************************************************* + //TEST(test_crc32_add_range) + //{ + // std::string data("123456789"); + + // etl::crc32 crc_calculator; + + // crc_calculator.add(data.begin(), data.end()); + + // uint32_t crc = crc_calculator.value(); + + // CHECK_EQUAL(0xCBF43926, crc); + //} + + ////************************************************************************* + //TEST(test_crc32_add_range_via_iterator) + //{ + // std::string data("123456789"); + + // etl::crc32 crc_calculator; + + // std::copy(data.begin(), data.end(), crc_calculator.input()); + + // uint32_t crc = crc_calculator.value(); + + // CHECK_EQUAL(0xCBF43926, crc); + //} + + ////************************************************************************* + //TEST(test_crc32_add_range_endian) + //{ + // std::vector data1 = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08 }; + // std::vector data2 = { 0x04030201, 0x08070605 }; + // std::vector data3 = { 0x08, 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01 }; + + // uint32_t crc1 = etl::crc32(data1.begin(), data1.end()); + // uint32_t crc2 = etl::crc32((uint8_t*)&data2[0], (uint8_t*)(&data2[0] + data2.size())); + // CHECK_EQUAL(crc1, crc2); + + // uint32_t crc3 = etl::crc32(data3.rbegin(), data3.rend()); + // CHECK_EQUAL(crc1, crc3); + //} + + ////************************************************************************* + //TEST(test_crc32_c) + //{ + // std::string data("123456789"); + + // uint32_t crc = etl::crc32_c(data.begin(), data.end()); + + // CHECK_EQUAL(0xE3069283, crc); + //} + + ////************************************************************************* + //TEST(test_crc32_c_add_values) + //{ + // std::string data("123456789"); + + // etl::crc32_c crc_calculator; + + // for (size_t i = 0; i < data.size(); ++i) + // { + // crc_calculator.add(data[i]); + // } + + // uint32_t crc = crc_calculator; + + + // CHECK_EQUAL(0xE3069283, crc); + //} + + ////************************************************************************* + //TEST(test_crc32_c_add_range) + //{ + // std::string data("123456789"); + + // etl::crc32_c crc_calculator; + + // crc_calculator.add(data.begin(), data.end()); + + // uint32_t crc = crc_calculator.value(); + + // CHECK_EQUAL(0xE3069283, crc); + //} + + ////************************************************************************* + //TEST(test_crc32_c_add_range_via_iterator) + //{ + // std::string data("123456789"); + + // etl::crc32_c crc_calculator; + + // std::copy(data.begin(), data.end(), crc_calculator.input()); + + // uint32_t crc = crc_calculator.value(); + + // CHECK_EQUAL(0xE3069283, crc); + //} + + ////************************************************************************* + //TEST(test_crc32_c_add_range_endian) + //{ + // std::vector data1 = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08 }; + // std::vector data2 = { 0x04030201, 0x08070605 }; + // std::vector data3 = { 0x08, 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01 }; + + // uint32_t crc1 = etl::crc32_c(data1.begin(), data1.end()); + // uint32_t crc2 = etl::crc32_c((uint8_t*)&data2[0], (uint8_t*)(&data2[0] + data2.size())); + // CHECK_EQUAL(crc1, crc2); + + // uint32_t crc3 = etl::crc32_c(data3.rbegin(), data3.rend()); + // CHECK_EQUAL(crc1, crc3); + //} + + ////************************************************************************* + //TEST(test_crc32_bzip2) + //{ + // std::string data("123456789"); + + // uint32_t crc = etl::crc32_bzip2(data.begin(), data.end()); + + // CHECK_EQUAL(0xFC891918, crc); + //} + + ////************************************************************************* + //TEST(test_crc32_bzip2_add_values) + //{ + // std::string data("123456789"); + + // etl::crc32_bzip2 crc_calculator; + + // for (size_t i = 0; i < data.size(); ++i) + // { + // crc_calculator.add(data[i]); + // } + + // uint32_t crc = crc_calculator; + + + // CHECK_EQUAL(0xFC891918, crc); + //} + + ////************************************************************************* + //TEST(test_crc32_bzip2_add_range) + //{ + // std::string data("123456789"); + + // etl::crc32_bzip2 crc_calculator; + + // crc_calculator.add(data.begin(), data.end()); + + // uint32_t crc = crc_calculator.value(); + + // CHECK_EQUAL(0xFC891918, crc); + //} + + ////************************************************************************* + //TEST(test_crc32_bzip2_add_range_via_iterator) + //{ + // std::string data("123456789"); + + // etl::crc32_bzip2 crc_calculator; + + // std::copy(data.begin(), data.end(), crc_calculator.input()); + + // uint32_t crc = crc_calculator.value(); + + // CHECK_EQUAL(0xFC891918, crc); + //} + + ////************************************************************************* + //TEST(test_crc32_bzip2_add_range_endian) + //{ + // std::vector data1 = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08 }; + // std::vector data2 = { 0x04030201, 0x08070605 }; + // std::vector data3 = { 0x08, 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01 }; + + // uint32_t crc1 = etl::crc32_bzip2(data1.begin(), data1.end()); + // uint32_t crc2 = etl::crc32_bzip2((uint8_t*)&data2[0], (uint8_t*)(&data2[0] + data2.size())); + // CHECK_EQUAL(crc1, crc2); + + // uint32_t crc3 = etl::crc32_bzip2(data3.rbegin(), data3.rend()); + // CHECK_EQUAL(crc1, crc3); + //} + + ////************************************************************************* + //TEST(test_crc32_posix) + //{ + // std::string data("123456789"); + + // uint32_t crc = etl::crc32_posix(data.begin(), data.end()); + + // CHECK_EQUAL(0x765E7680, crc); + //} + + ////************************************************************************* + //TEST(test_crc32_posix_add_values) + //{ + // std::string data("123456789"); + + // etl::crc32_posix crc_calculator; + + // for (size_t i = 0; i < data.size(); ++i) + // { + // crc_calculator.add(data[i]); + // } + + // uint32_t crc = crc_calculator; + + + // CHECK_EQUAL(0x765E7680, crc); + //} + + ////************************************************************************* + //TEST(test_crc32_posix_add_range) + //{ + // std::string data("123456789"); + + // etl::crc32_posix crc_calculator; + + // crc_calculator.add(data.begin(), data.end()); + + // uint32_t crc = crc_calculator.value(); + + // CHECK_EQUAL(0x765E7680, crc); + //} + + ////************************************************************************* + //TEST(test_crc32_posix_add_range_via_iterator) + //{ + // std::string data("123456789"); + + // etl::crc32_posix crc_calculator; + + // std::copy(data.begin(), data.end(), crc_calculator.input()); + + // uint32_t crc = crc_calculator.value(); + + // CHECK_EQUAL(0x765E7680, crc); + //} + + ////************************************************************************* + //TEST(test_crc32_posix_add_range_endian) + //{ + // std::vector data1 = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08 }; + // std::vector data2 = { 0x04030201, 0x08070605 }; + // std::vector data3 = { 0x08, 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01 }; + + // uint32_t crc1 = etl::crc32_posix(data1.begin(), data1.end()); + // uint32_t crc2 = etl::crc32_posix((uint8_t*)&data2[0], (uint8_t*)(&data2[0] + data2.size())); + // CHECK_EQUAL(crc1, crc2); + + // uint32_t crc3 = etl::crc32_posix(data3.rbegin(), data3.rend()); + // CHECK_EQUAL(crc1, crc3); + //} + + ////************************************************************************* + //TEST(test_crc32_mpeg2) + //{ + // std::string data("123456789"); + + // uint32_t crc = etl::crc32_mpeg2(data.begin(), data.end()); + + // CHECK_EQUAL(0x0376E6E7, crc); + //} + + ////************************************************************************* + //TEST(test_crc32_mpeg2_add_values) + //{ + // std::string data("123456789"); + + // etl::crc32_mpeg2 crc_calculator; + + // for (size_t i = 0; i < data.size(); ++i) + // { + // crc_calculator.add(data[i]); + // } + + // uint32_t crc = crc_calculator; + + + // CHECK_EQUAL(0x0376E6E7, crc); + //} + + ////************************************************************************* + //TEST(test_crc32_mpeg2_add_range) + //{ + // std::string data("123456789"); + + // etl::crc32_mpeg2 crc_calculator; + + // crc_calculator.add(data.begin(), data.end()); + + // uint32_t crc = crc_calculator.value(); + + // CHECK_EQUAL(0x0376E6E7, crc); + //} + + ////************************************************************************* + //TEST(test_crc32_mpeg2_add_range_via_iterator) + //{ + // std::string data("123456789"); + + // etl::crc32_mpeg2 crc_calculator; + + // std::copy(data.begin(), data.end(), crc_calculator.input()); + + // uint32_t crc = crc_calculator.value(); + + // CHECK_EQUAL(0x0376E6E7, crc); + //} + + ////************************************************************************* + //TEST(test_crc32_mpeg2_add_range_endian) + //{ + // std::vector data1 = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08 }; + // std::vector data2 = { 0x04030201, 0x08070605 }; + // std::vector data3 = { 0x08, 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01 }; + + // uint32_t crc1 = etl::crc32_mpeg2(data1.begin(), data1.end()); + // uint32_t crc2 = etl::crc32_mpeg2((uint8_t*)&data2[0], (uint8_t*)(&data2[0] + data2.size())); + // CHECK_EQUAL(crc1, crc2); + + // uint32_t crc3 = etl::crc32_mpeg2(data3.rbegin(), data3.rend()); + // CHECK_EQUAL(crc1, crc3); + //} + + ////************************************************************************* + //TEST(test_crc64_ecma) + //{ + // std::string data("123456789"); + + // uint64_t crc = etl::crc64_ecma(data.begin(), data.end()); + + // CHECK_EQUAL(0x6C40DF5F0B497347U, crc); + //} + + ////************************************************************************* + //TEST(test_crc64_ecma_add_values) + //{ + // std::string data("123456789"); + + // etl::crc64_ecma crc_calculator; + + // for (size_t i = 0; i < data.size(); ++i) + // { + // crc_calculator.add(data[i]); + // } + + // uint64_t crc = crc_calculator; + + // CHECK_EQUAL(0x6C40DF5F0B497347U, crc); + //} + + ////************************************************************************* + //TEST(test_crc64_ecma_add_range) + //{ + // std::string data("123456789"); + + // etl::crc64_ecma crc_calculator; + + // crc_calculator.add(data.begin(), data.end()); + + // uint64_t crc = crc_calculator.value(); + + // CHECK_EQUAL(0x6C40DF5F0B497347U, crc); + //} + + ////************************************************************************* + //TEST(test_crc64_ecma_add_range_via_iterator) + //{ + // std::string data("123456789"); + + // etl::crc64_ecma crc_calculator; + + // std::copy(data.begin(), data.end(), crc_calculator.input()); + + // uint64_t crc = crc_calculator.value(); + + // CHECK_EQUAL(0x6C40DF5F0B497347U, crc); + //} + + ////************************************************************************* + //TEST(test_crc64_ecma_add_range_endian) + //{ + // std::vector data1 = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08 }; + // std::vector data2 = { 0x04030201, 0x08070605 }; + // std::vector data3 = { 0x08, 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01 }; + + // uint64_t crc1 = etl::crc64_ecma(data1.begin(), data1.end()); + // uint64_t crc2 = etl::crc64_ecma((uint8_t*)&data2[0], (uint8_t*)(&data2[0] + data2.size())); + // CHECK_EQUAL(crc1, crc2); + + // uint64_t crc3 = etl::crc64_ecma(data3.rbegin(), data3.rend()); + // CHECK_EQUAL(crc1, crc3); + //} + }; +} + diff --git a/test/test_crc_table256.cpp b/test/test_crc_table256.cpp new file mode 100644 index 00000000..31c0b68f --- /dev/null +++ b/test/test_crc_table256.cpp @@ -0,0 +1,1259 @@ +/****************************************************************************** +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. +******************************************************************************/ + +#include "unit_test_framework.h" + +#include +#include +#include +#include + +#include "etl/experimental/crc8_ccitt.h" +#include "etl/experimental/crc8_rohc.h" +#include "etl/experimental/crc16.h" +#include "etl/experimental/crc16_aug_ccitt.h" +#include "etl/experimental/crc16_ccitt.h" +#include "etl/experimental/crc16_kermit.h" +#include "etl/experimental/crc16_modbus.h" +#include "etl/experimental/crc16_usb.h" +#include "etl/experimental/crc16_genibus.h" +#include "etl/experimental/crc16_x25.h" +#include "etl/experimental/crc16_xmodem.h" +#include "etl/experimental/crc32.h" +#include "etl/experimental/crc64_ecma.h" + +//#include "etl/crc32_c.h" +//#include "etl/crc32_bzip2.h" +//#include "etl/crc32_mpeg2.h" +//#include "etl/crc32_posix.h" + +//***************************************************************************** +// The results for these tests were created from https://crccalc.com/ +//***************************************************************************** + +namespace +{ + SUITE(test_crc_experimental) + { + //************************************************************************* + TEST(test_crc8_ccitt_constructor) + { + std::string data("123456789"); + + uint8_t crc = etl::crc::crc8_ccitt(data.begin(), data.end()); + + CHECK_EQUAL(0xF4, int(crc)); + } + + //************************************************************************* + TEST(test_crc8_ccitt_add_values) + { + std::string data("123456789"); + + etl::crc::crc8_ccitt crc_calculator; + + for (size_t i = 0; i < data.size(); ++i) + { + crc_calculator.add(data[i]); + } + + uint8_t crc = crc_calculator; + + CHECK_EQUAL(0xF4, int(crc)); + } + + //************************************************************************* + TEST(test_crc8_ccitt_add_range) + { + std::string data("123456789"); + + etl::crc::crc8_ccitt crc_calculator; + + crc_calculator.add(data.begin(), data.end()); + + uint8_t crc = crc_calculator.value(); + + CHECK_EQUAL(0xF4, int(crc)); + } + + //************************************************************************* + TEST(test_crc8_ccitt_add_range_via_iterator) + { + std::string data("123456789"); + + etl::crc::crc8_ccitt crc_calculator; + + std::copy(data.begin(), data.end(), crc_calculator.input()); + + uint8_t crc = crc_calculator.value(); + + CHECK_EQUAL(0xF4, int(crc)); + } + + //************************************************************************* + TEST(test_crc8_ccitt_add_range_endian) + { + std::vector data1 = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08 }; + std::vector data2 = { 0x04030201, 0x08070605 }; + std::vector data3 = { 0x08, 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01 }; + + uint8_t crc1 = etl::crc::crc8_ccitt(data1.begin(), data1.end()); + uint8_t crc2 = etl::crc::crc8_ccitt((uint8_t*)&data2[0], (uint8_t*)(&data2[0] + data2.size())); + CHECK_EQUAL(int(crc1), int(crc2)); + + uint8_t crc3 = etl::crc::crc8_ccitt(data3.rbegin(), data3.rend()); + CHECK_EQUAL(int(crc1), int(crc3)); + } + + //************************************************************************* + TEST(test_crc8_rohc_constructor) + { + std::string data("123456789"); + + uint8_t crc = etl::crc::crc8_rohc(data.begin(), data.end()); + + CHECK_EQUAL(0xD0, int(crc)); + } + + //************************************************************************* + TEST(test_crc8_rohc_add_values) + { + std::string data("123456789"); + + etl::crc::crc8_rohc crc_calculator; + + for (size_t i = 0; i < data.size(); ++i) + { + crc_calculator.add(data[i]); + } + + uint8_t crc = crc_calculator; + + CHECK_EQUAL(0xD0, int(crc)); + } + + //************************************************************************* + TEST(test_crc8_rohc_add_range) + { + std::string data("123456789"); + + etl::crc::crc8_rohc crc_calculator; + + crc_calculator.add(data.begin(), data.end()); + + uint8_t crc = crc_calculator.value(); + + CHECK_EQUAL(0xD0, int(crc)); + } + + //************************************************************************* + TEST(test_crc8_rohc_add_range_via_iterator) + { + std::string data("123456789"); + + etl::crc::crc8_rohc crc_calculator; + + std::copy(data.begin(), data.end(), crc_calculator.input()); + + uint8_t crc = crc_calculator.value(); + + CHECK_EQUAL(0xD0, int(crc)); + } + + //************************************************************************* + TEST(test_crc8_rohc_add_range_endian) + { + std::vector data1 = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08 }; + std::vector data2 = { 0x04030201, 0x08070605 }; + std::vector data3 = { 0x08, 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01 }; + + uint8_t crc1 = etl::crc::crc8_rohc(data1.begin(), data1.end()); + uint8_t crc2 = etl::crc::crc8_rohc((uint8_t*)&data2[0], (uint8_t*)(&data2[0] + data2.size())); + CHECK_EQUAL(int(crc1), int(crc2)); + + uint8_t crc3 = etl::crc::crc8_rohc(data3.rbegin(), data3.rend()); + CHECK_EQUAL(int(crc1), int(crc3)); + } + + //************************************************************************* + TEST(test_crc16) + { + std::string data("123456789"); + + uint16_t crc = etl::crc::crc16(data.begin(), data.end()); + + CHECK_EQUAL(0xBB3D, crc); + } + + ////************************************************************************* + //TEST(test_crc16_add_values) + //{ + // std::string data("123456789"); + + // etl::crc::crc16 crc_calculator; + + // for (size_t i = 0; i < data.size(); ++i) + // { + // crc_calculator.add(data[i]); + // } + + // uint16_t crc = crc_calculator; + + // CHECK_EQUAL(0xBB3D, crc); + //} + + ////************************************************************************* + //TEST(test_crc16_add_range) + //{ + // std::string data("123456789"); + + // etl::crc::crc16 crc_calculator; + + // crc_calculator.add(data.begin(), data.end()); + + // uint16_t crc = crc_calculator.value(); + + // CHECK_EQUAL(0xBB3D, crc); + //} + + ////************************************************************************* + //TEST(test_crc16_add_range_via_iterator) + //{ + // std::string data("123456789"); + + // etl::crc::crc16 crc_calculator; + + // std::copy(data.begin(), data.end(), crc_calculator.input()); + + // uint16_t crc = crc_calculator.value(); + + // CHECK_EQUAL(0xBB3D, crc); + //} + + ////************************************************************************* + //TEST(test_crc16_add_range_endian) + //{ + // std::vector data1 = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08 }; + // std::vector data2 = { 0x04030201, 0x08070605 }; + // std::vector data3 = { 0x08, 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01 }; + + // uint16_t crc1 = etl::crc16(data1.begin(), data1.end()); + // uint16_t crc2 = etl::crc16((uint8_t*)&data2[0], (uint8_t*)(&data2[0] + data2.size())); + // CHECK_EQUAL(crc1, crc2); + + // uint16_t crc3 = etl::crc16(data3.rbegin(), data3.rend()); + // CHECK_EQUAL(crc1, crc3); + //} + + //************************************************************************* + TEST(test_crc16_ccitt) + { + std::string data("123456789"); + + uint16_t crc = etl::crc::crc16_ccitt(data.begin(), data.end()); + + CHECK_EQUAL(0x29B1, crc); + } + + //************************************************************************* + TEST(test_crc16_ccitt_add_values) + { + std::string data("123456789"); + + etl::crc::crc16_ccitt crc_calculator; + + for (size_t i = 0; i < data.size(); ++i) + { + crc_calculator.add(data[i]); + } + + uint16_t crc = crc_calculator; + + CHECK_EQUAL(0x29B1, crc); + } + + //************************************************************************* + TEST(test_crc16_ccitt_add_range) + { + std::string data("123456789"); + + etl::crc::crc16_ccitt crc_calculator; + + crc_calculator.add(data.begin(), data.end()); + + uint16_t crc = crc_calculator.value(); + + CHECK_EQUAL(0x29B1, crc); + } + + //************************************************************************* + TEST(test_crc16_ccitt_add_range_via_iterator) + { + std::string data("123456789"); + + etl::crc::crc16_ccitt crc_calculator; + + std::copy(data.begin(), data.end(), crc_calculator.input()); + + uint16_t crc = crc_calculator.value(); + + CHECK_EQUAL(0x29B1, crc); + } + + //************************************************************************* + TEST(test_crc16_ccitt_add_range_endian) + { + std::vector data1 = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08 }; + std::vector data2 = { 0x04030201, 0x08070605 }; + std::vector data3 = { 0x08, 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01 }; + + uint16_t crc1 = etl::crc::crc16_ccitt(data1.begin(), data1.end()); + uint16_t crc2 = etl::crc::crc16_ccitt((uint8_t*)&data2[0], (uint8_t*)(&data2[0] + data2.size())); + CHECK_EQUAL(crc1, crc2); + + uint16_t crc3 = etl::crc::crc16_ccitt(data3.rbegin(), data3.rend()); + CHECK_EQUAL(crc1, crc3); + } + + //************************************************************************* + TEST(test_crc16_kermit) + { + std::string data("123456789"); + + uint16_t crc = etl::crc::crc16_kermit(data.begin(), data.end()); + + CHECK_EQUAL(0x2189, crc); + } + + //************************************************************************* + TEST(test_crc16_kermit_add_values) + { + std::string data("123456789"); + + etl::crc::crc16_kermit crc_calculator; + + for (size_t i = 0; i < data.size(); ++i) + { + crc_calculator.add(data[i]); + } + + uint16_t crc = crc_calculator; + + CHECK_EQUAL(0x2189, crc); + } + + //************************************************************************* + TEST(test_crc16_kermit_add_range) + { + std::string data("123456789"); + + etl::crc::crc16_kermit crc_calculator; + + crc_calculator.add(data.begin(), data.end()); + + uint16_t crc = crc_calculator.value(); + + CHECK_EQUAL(0x2189, crc); + } + + //************************************************************************* + TEST(test_crc16_kermit_add_range_via_iterator) + { + std::string data("123456789"); + + etl::crc::crc16_kermit crc_calculator; + + std::copy(data.begin(), data.end(), crc_calculator.input()); + + uint16_t crc = crc_calculator.value(); + + CHECK_EQUAL(0x2189, crc); + } + + //************************************************************************* + TEST(test_crc16_kermit_add_range_endian) + { + std::vector data1 = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08 }; + std::vector data2 = { 0x04030201, 0x08070605 }; + std::vector data3 = { 0x08, 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01 }; + + uint16_t crc1 = etl::crc::crc16_kermit(data1.begin(), data1.end()); + uint16_t crc2 = etl::crc::crc16_kermit((uint8_t*)&data2[0], (uint8_t*)(&data2[0] + data2.size())); + CHECK_EQUAL(crc1, crc2); + + uint16_t crc3 = etl::crc::crc16_kermit(data3.rbegin(), data3.rend()); + CHECK_EQUAL(crc1, crc3); + } + + //************************************************************************* + TEST(test_crc16_modbus) + { + std::string data("123456789"); + + uint16_t crc = etl::crc::crc16_modbus(data.begin(), data.end()); + + CHECK_EQUAL(0x4B37, crc); + } + + //************************************************************************* + TEST(test_crc16_modbus_add_values) + { + std::string data("123456789"); + + etl::crc::crc16_modbus crc_calculator; + + for (size_t i = 0; i < data.size(); ++i) + { + crc_calculator.add(data[i]); + } + + uint16_t crc = crc_calculator; + + CHECK_EQUAL(0x4B37, crc); + } + + //************************************************************************* + TEST(test_crc16_modbus_add_range) + { + std::string data("123456789"); + + etl::crc::crc16_modbus crc_calculator; + + crc_calculator.add(data.begin(), data.end()); + + uint16_t crc = crc_calculator.value(); + + CHECK_EQUAL(0x4B37, crc); + } + + //************************************************************************* + TEST(test_crc16_modbus_add_range_via_iterator) + { + std::string data("123456789"); + + etl::crc::crc16_modbus crc_calculator; + + std::copy(data.begin(), data.end(), crc_calculator.input()); + + uint16_t crc = crc_calculator.value(); + + CHECK_EQUAL(0x4B37, crc); + } + + //************************************************************************* + TEST(test_crc16_modbus_add_range_endian) + { + std::vector data1 = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08 }; + std::vector data2 = { 0x04030201, 0x08070605 }; + std::vector data3 = { 0x08, 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01 }; + + uint16_t crc1 = etl::crc::crc16_modbus(data1.begin(), data1.end()); + uint16_t crc2 = etl::crc::crc16_modbus((uint8_t*)&data2[0], (uint8_t*)(&data2[0] + data2.size())); + CHECK_EQUAL(crc1, crc2); + + uint16_t crc3 = etl::crc::crc16_modbus(data3.rbegin(), data3.rend()); + CHECK_EQUAL(crc1, crc3); + } + + //************************************************************************* + TEST(test_crc16_usb) + { + std::string data("123456789"); + + uint16_t crc = etl::crc::crc16_usb(data.begin(), data.end()); + + CHECK_EQUAL(0xB4C8, crc); + } + + //************************************************************************* + TEST(test_crc16_usb_add_values) + { + std::string data("123456789"); + + etl::crc::crc16_usb crc_calculator; + + for (size_t i = 0; i < data.size(); ++i) + { + crc_calculator.add(data[i]); + } + + uint16_t crc = crc_calculator; + + CHECK_EQUAL(0xB4C8, crc); + } + + //************************************************************************* + TEST(test_crc16_usb_add_range) + { + std::string data("123456789"); + + etl::crc::crc16_usb crc_calculator; + + crc_calculator.add(data.begin(), data.end()); + + uint16_t crc = crc_calculator.value(); + + CHECK_EQUAL(0xB4C8, crc); + } + + //************************************************************************* + TEST(test_crc16_usb_add_range_via_iterator) + { + std::string data("123456789"); + + etl::crc::crc16_usb crc_calculator; + + std::copy(data.begin(), data.end(), crc_calculator.input()); + + uint16_t crc = crc_calculator.value(); + + CHECK_EQUAL(0xB4C8, crc); + } + + //************************************************************************* + TEST(test_crc16_usb_add_range_endian) + { + std::vector data1 = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08 }; + std::vector data2 = { 0x04030201, 0x08070605 }; + std::vector data3 = { 0x08, 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01 }; + + uint16_t crc1 = etl::crc::crc16_usb(data1.begin(), data1.end()); + uint16_t crc2 = etl::crc::crc16_usb((uint8_t*)&data2[0], (uint8_t*)(&data2[0] + data2.size())); + CHECK_EQUAL(crc1, crc2); + + uint16_t crc3 = etl::crc::crc16_usb(data3.rbegin(), data3.rend()); + CHECK_EQUAL(crc1, crc3); + } + + //************************************************************************* + TEST(test_crc16_xmodem) + { + std::string data("123456789"); + + uint16_t crc = etl::crc::crc16_xmodem(data.begin(), data.end()); + + CHECK_EQUAL(0x31C3, crc); + } + + //************************************************************************* + TEST(test_crc16_xmodem_add_values) + { + std::string data("123456789"); + + etl::crc::crc16_xmodem crc_calculator; + + for (size_t i = 0; i < data.size(); ++i) + { + crc_calculator.add(data[i]); + } + + uint16_t crc = crc_calculator; + + CHECK_EQUAL(0x31C3, crc); + } + + //************************************************************************* + TEST(test_crc16_xmodem_add_range) + { + std::string data("123456789"); + + etl::crc::crc16_xmodem crc_calculator; + + crc_calculator.add(data.begin(), data.end()); + + uint16_t crc = crc_calculator.value(); + + CHECK_EQUAL(0x31C3, crc); + } + + //************************************************************************* + TEST(test_crc16_xmodem_add_range_via_iterator) + { + std::string data("123456789"); + + etl::crc::crc16_xmodem crc_calculator; + + std::copy(data.begin(), data.end(), crc_calculator.input()); + + uint16_t crc = crc_calculator.value(); + + CHECK_EQUAL(0x31C3, crc); + } + + //************************************************************************* + TEST(test_crc16_xmodem_add_range_endian) + { + std::vector data1 = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08 }; + std::vector data2 = { 0x04030201, 0x08070605 }; + std::vector data3 = { 0x08, 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01 }; + + uint16_t crc1 = etl::crc::crc16_xmodem(data1.begin(), data1.end()); + uint16_t crc2 = etl::crc::crc16_xmodem((uint8_t*)&data2[0], (uint8_t*)(&data2[0] + data2.size())); + CHECK_EQUAL(crc1, crc2); + + uint16_t crc3 = etl::crc::crc16_xmodem(data3.rbegin(), data3.rend()); + CHECK_EQUAL(crc1, crc3); + } + + //************************************************************************* + TEST(test_crc16_aug_ccitt) + { + std::string data("123456789"); + + uint16_t crc = etl::crc::crc16_aug_ccitt(data.begin(), data.end()); + + CHECK_EQUAL(0xE5CC, crc); + } + + //************************************************************************* + TEST(test_crc16_aug_ccitt_add_values) + { + std::string data("123456789"); + + etl::crc::crc16_aug_ccitt crc_calculator; + + for (size_t i = 0; i < data.size(); ++i) + { + crc_calculator.add(data[i]); + } + + uint16_t crc = crc_calculator; + + CHECK_EQUAL(0xE5CC, crc); + } + + //************************************************************************* + TEST(test_crc16_aug_ccitt_add_range) + { + std::string data("123456789"); + + etl::crc::crc16_aug_ccitt crc_calculator; + + crc_calculator.add(data.begin(), data.end()); + + uint16_t crc = crc_calculator.value(); + + CHECK_EQUAL(0xE5CC, crc); + } + + //************************************************************************* + TEST(test_crc16_aug_ccitt_add_range_via_iterator) + { + std::string data("123456789"); + + etl::crc::crc16_aug_ccitt crc_calculator; + + std::copy(data.begin(), data.end(), crc_calculator.input()); + + uint16_t crc = crc_calculator.value(); + + CHECK_EQUAL(0xE5CC, crc); + } + + //************************************************************************* + TEST(test_crc16_aug_ccitt_add_range_endian) + { + std::vector data1 = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08 }; + std::vector data2 = { 0x04030201, 0x08070605 }; + std::vector data3 = { 0x08, 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01 }; + + uint16_t crc1 = etl::crc::crc16_aug_ccitt(data1.begin(), data1.end()); + uint16_t crc2 = etl::crc::crc16_aug_ccitt((uint8_t*)&data2[0], (uint8_t*)(&data2[0] + data2.size())); + CHECK_EQUAL(crc1, crc2); + + uint16_t crc3 = etl::crc::crc16_aug_ccitt(data3.rbegin(), data3.rend()); + CHECK_EQUAL(crc1, crc3); + } + + //************************************************************************* + TEST(test_crc16_genibus) + { + std::string data("123456789"); + + uint16_t crc = etl::crc::crc16_genibus(data.begin(), data.end()); + + CHECK_EQUAL(0xD64E, crc); + } + + //************************************************************************* + TEST(test_crc16_genibus_add_values) + { + std::string data("123456789"); + + etl::crc::crc16_genibus crc_calculator; + + for (size_t i = 0; i < data.size(); ++i) + { + crc_calculator.add(data[i]); + } + + uint16_t crc = crc_calculator; + + CHECK_EQUAL(0xD64E, crc); + } + + //************************************************************************* + TEST(test_crc16_genibus_add_range) + { + std::string data("123456789"); + + etl::crc::crc16_genibus crc_calculator; + + crc_calculator.add(data.begin(), data.end()); + + uint16_t crc = crc_calculator.value(); + + CHECK_EQUAL(0xD64E, crc); + } + + //************************************************************************* + TEST(test_crc16_genibus_add_range_via_iterator) + { + std::string data("123456789"); + + etl::crc::crc16_genibus crc_calculator; + + std::copy(data.begin(), data.end(), crc_calculator.input()); + + uint16_t crc = crc_calculator.value(); + + CHECK_EQUAL(0xD64E, crc); + } + + //************************************************************************* + TEST(test_crc16_genibus_add_range_endian) + { + std::vector data1 = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08 }; + std::vector data2 = { 0x04030201, 0x08070605 }; + std::vector data3 = { 0x08, 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01 }; + + uint16_t crc1 = etl::crc::crc16_genibus(data1.begin(), data1.end()); + uint16_t crc2 = etl::crc::crc16_genibus((uint8_t*)&data2[0], (uint8_t*)(&data2[0] + data2.size())); + CHECK_EQUAL(crc1, crc2); + + uint16_t crc3 = etl::crc::crc16_genibus(data3.rbegin(), data3.rend()); + CHECK_EQUAL(crc1, crc3); + } + + //************************************************************************* + TEST(test_crc16_x25) + { + std::string data("123456789"); + + uint16_t crc = etl::crc::crc16_x25(data.begin(), data.end()); + + CHECK_EQUAL(0x906E, crc); + } + + //************************************************************************* + TEST(test_crc16_x25_add_values) + { + std::string data("123456789"); + + etl::crc::crc16_x25 crc_calculator; + + for (size_t i = 0; i < data.size(); ++i) + { + crc_calculator.add(data[i]); + } + + uint16_t crc = crc_calculator; + + CHECK_EQUAL(0x906E, crc); + } + + //************************************************************************* + TEST(test_crc16_x25_add_range) + { + std::string data("123456789"); + + etl::crc::crc16_x25 crc_calculator; + + crc_calculator.add(data.begin(), data.end()); + + uint16_t crc = crc_calculator.value(); + + CHECK_EQUAL(0x906E, crc); + } + + //************************************************************************* + TEST(test_crc16_x25_add_range_via_iterator) + { + std::string data("123456789"); + + etl::crc::crc16_x25 crc_calculator; + + std::copy(data.begin(), data.end(), crc_calculator.input()); + + uint16_t crc = crc_calculator.value(); + + CHECK_EQUAL(0x906E, crc); + } + + //************************************************************************* + TEST(test_crc16_x25_add_range_endian) + { + std::vector data1 = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08 }; + std::vector data2 = { 0x04030201, 0x08070605 }; + std::vector data3 = { 0x08, 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01 }; + + uint16_t crc1 = etl::crc::crc16_x25(data1.begin(), data1.end()); + uint16_t crc2 = etl::crc::crc16_x25((uint8_t*)&data2[0], (uint8_t*)(&data2[0] + data2.size())); + CHECK_EQUAL(crc1, crc2); + + uint16_t crc3 = etl::crc::crc16_x25(data3.rbegin(), data3.rend()); + CHECK_EQUAL(crc1, crc3); + } + + //************************************************************************* + TEST(test_crc32) + { + std::string data("123456789"); + + uint32_t crc = etl::crc::crc32(data.begin(), data.end()); + + CHECK_EQUAL(0xCBF43926, crc); + } + + //************************************************************************* + TEST(test_crc32_add_values) + { + std::string data("123456789"); + + etl::crc::crc32 crc_calculator; + + for (size_t i = 0; i < data.size(); ++i) + { + crc_calculator.add(data[i]); + } + + uint32_t crc = crc_calculator; + + + CHECK_EQUAL(0xCBF43926, crc); + } + + //************************************************************************* + TEST(test_crc32_add_range) + { + std::string data("123456789"); + + etl::crc::crc32 crc_calculator; + + crc_calculator.add(data.begin(), data.end()); + + uint32_t crc = crc_calculator.value(); + + CHECK_EQUAL(0xCBF43926, crc); + } + + //************************************************************************* + TEST(test_crc32_add_range_via_iterator) + { + std::string data("123456789"); + + etl::crc::crc32 crc_calculator; + + std::copy(data.begin(), data.end(), crc_calculator.input()); + + uint32_t crc = crc_calculator.value(); + + CHECK_EQUAL(0xCBF43926, crc); + } + + //************************************************************************* + TEST(test_crc32_add_range_endian) + { + std::vector data1 = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08 }; + std::vector data2 = { 0x04030201, 0x08070605 }; + std::vector data3 = { 0x08, 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01 }; + + uint32_t crc1 = etl::crc::crc32(data1.begin(), data1.end()); + uint32_t crc2 = etl::crc::crc32((uint8_t*)&data2[0], (uint8_t*)(&data2[0] + data2.size())); + CHECK_EQUAL(crc1, crc2); + + uint32_t crc3 = etl::crc::crc32(data3.rbegin(), data3.rend()); + CHECK_EQUAL(crc1, crc3); + } + + ////************************************************************************* + //TEST(test_crc32_c) + //{ + // std::string data("123456789"); + + // uint32_t crc = etl::crc32_c(data.begin(), data.end()); + + // CHECK_EQUAL(0xE3069283, crc); + //} + + ////************************************************************************* + //TEST(test_crc32_c_add_values) + //{ + // std::string data("123456789"); + + // etl::crc32_c crc_calculator; + + // for (size_t i = 0; i < data.size(); ++i) + // { + // crc_calculator.add(data[i]); + // } + + // uint32_t crc = crc_calculator; + + + // CHECK_EQUAL(0xE3069283, crc); + //} + + ////************************************************************************* + //TEST(test_crc32_c_add_range) + //{ + // std::string data("123456789"); + + // etl::crc32_c crc_calculator; + + // crc_calculator.add(data.begin(), data.end()); + + // uint32_t crc = crc_calculator.value(); + + // CHECK_EQUAL(0xE3069283, crc); + //} + + ////************************************************************************* + //TEST(test_crc32_c_add_range_via_iterator) + //{ + // std::string data("123456789"); + + // etl::crc32_c crc_calculator; + + // std::copy(data.begin(), data.end(), crc_calculator.input()); + + // uint32_t crc = crc_calculator.value(); + + // CHECK_EQUAL(0xE3069283, crc); + //} + + ////************************************************************************* + //TEST(test_crc32_c_add_range_endian) + //{ + // std::vector data1 = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08 }; + // std::vector data2 = { 0x04030201, 0x08070605 }; + // std::vector data3 = { 0x08, 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01 }; + + // uint32_t crc1 = etl::crc32_c(data1.begin(), data1.end()); + // uint32_t crc2 = etl::crc32_c((uint8_t*)&data2[0], (uint8_t*)(&data2[0] + data2.size())); + // CHECK_EQUAL(crc1, crc2); + + // uint32_t crc3 = etl::crc32_c(data3.rbegin(), data3.rend()); + // CHECK_EQUAL(crc1, crc3); + //} + + ////************************************************************************* + //TEST(test_crc32_bzip2) + //{ + // std::string data("123456789"); + + // uint32_t crc = etl::crc32_bzip2(data.begin(), data.end()); + + // CHECK_EQUAL(0xFC891918, crc); + //} + + ////************************************************************************* + //TEST(test_crc32_bzip2_add_values) + //{ + // std::string data("123456789"); + + // etl::crc32_bzip2 crc_calculator; + + // for (size_t i = 0; i < data.size(); ++i) + // { + // crc_calculator.add(data[i]); + // } + + // uint32_t crc = crc_calculator; + + + // CHECK_EQUAL(0xFC891918, crc); + //} + + ////************************************************************************* + //TEST(test_crc32_bzip2_add_range) + //{ + // std::string data("123456789"); + + // etl::crc32_bzip2 crc_calculator; + + // crc_calculator.add(data.begin(), data.end()); + + // uint32_t crc = crc_calculator.value(); + + // CHECK_EQUAL(0xFC891918, crc); + //} + + ////************************************************************************* + //TEST(test_crc32_bzip2_add_range_via_iterator) + //{ + // std::string data("123456789"); + + // etl::crc32_bzip2 crc_calculator; + + // std::copy(data.begin(), data.end(), crc_calculator.input()); + + // uint32_t crc = crc_calculator.value(); + + // CHECK_EQUAL(0xFC891918, crc); + //} + + ////************************************************************************* + //TEST(test_crc32_bzip2_add_range_endian) + //{ + // std::vector data1 = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08 }; + // std::vector data2 = { 0x04030201, 0x08070605 }; + // std::vector data3 = { 0x08, 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01 }; + + // uint32_t crc1 = etl::crc32_bzip2(data1.begin(), data1.end()); + // uint32_t crc2 = etl::crc32_bzip2((uint8_t*)&data2[0], (uint8_t*)(&data2[0] + data2.size())); + // CHECK_EQUAL(crc1, crc2); + + // uint32_t crc3 = etl::crc32_bzip2(data3.rbegin(), data3.rend()); + // CHECK_EQUAL(crc1, crc3); + //} + + ////************************************************************************* + //TEST(test_crc32_posix) + //{ + // std::string data("123456789"); + + // uint32_t crc = etl::crc32_posix(data.begin(), data.end()); + + // CHECK_EQUAL(0x765E7680, crc); + //} + + ////************************************************************************* + //TEST(test_crc32_posix_add_values) + //{ + // std::string data("123456789"); + + // etl::crc32_posix crc_calculator; + + // for (size_t i = 0; i < data.size(); ++i) + // { + // crc_calculator.add(data[i]); + // } + + // uint32_t crc = crc_calculator; + + + // CHECK_EQUAL(0x765E7680, crc); + //} + + ////************************************************************************* + //TEST(test_crc32_posix_add_range) + //{ + // std::string data("123456789"); + + // etl::crc32_posix crc_calculator; + + // crc_calculator.add(data.begin(), data.end()); + + // uint32_t crc = crc_calculator.value(); + + // CHECK_EQUAL(0x765E7680, crc); + //} + + ////************************************************************************* + //TEST(test_crc32_posix_add_range_via_iterator) + //{ + // std::string data("123456789"); + + // etl::crc32_posix crc_calculator; + + // std::copy(data.begin(), data.end(), crc_calculator.input()); + + // uint32_t crc = crc_calculator.value(); + + // CHECK_EQUAL(0x765E7680, crc); + //} + + ////************************************************************************* + //TEST(test_crc32_posix_add_range_endian) + //{ + // std::vector data1 = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08 }; + // std::vector data2 = { 0x04030201, 0x08070605 }; + // std::vector data3 = { 0x08, 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01 }; + + // uint32_t crc1 = etl::crc32_posix(data1.begin(), data1.end()); + // uint32_t crc2 = etl::crc32_posix((uint8_t*)&data2[0], (uint8_t*)(&data2[0] + data2.size())); + // CHECK_EQUAL(crc1, crc2); + + // uint32_t crc3 = etl::crc32_posix(data3.rbegin(), data3.rend()); + // CHECK_EQUAL(crc1, crc3); + //} + + ////************************************************************************* + //TEST(test_crc32_mpeg2) + //{ + // std::string data("123456789"); + + // uint32_t crc = etl::crc32_mpeg2(data.begin(), data.end()); + + // CHECK_EQUAL(0x0376E6E7, crc); + //} + + ////************************************************************************* + //TEST(test_crc32_mpeg2_add_values) + //{ + // std::string data("123456789"); + + // etl::crc32_mpeg2 crc_calculator; + + // for (size_t i = 0; i < data.size(); ++i) + // { + // crc_calculator.add(data[i]); + // } + + // uint32_t crc = crc_calculator; + + + // CHECK_EQUAL(0x0376E6E7, crc); + //} + + ////************************************************************************* + //TEST(test_crc32_mpeg2_add_range) + //{ + // std::string data("123456789"); + + // etl::crc32_mpeg2 crc_calculator; + + // crc_calculator.add(data.begin(), data.end()); + + // uint32_t crc = crc_calculator.value(); + + // CHECK_EQUAL(0x0376E6E7, crc); + //} + + ////************************************************************************* + //TEST(test_crc32_mpeg2_add_range_via_iterator) + //{ + // std::string data("123456789"); + + // etl::crc32_mpeg2 crc_calculator; + + // std::copy(data.begin(), data.end(), crc_calculator.input()); + + // uint32_t crc = crc_calculator.value(); + + // CHECK_EQUAL(0x0376E6E7, crc); + //} + + ////************************************************************************* + //TEST(test_crc32_mpeg2_add_range_endian) + //{ + // std::vector data1 = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08 }; + // std::vector data2 = { 0x04030201, 0x08070605 }; + // std::vector data3 = { 0x08, 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01 }; + + // uint32_t crc1 = etl::crc32_mpeg2(data1.begin(), data1.end()); + // uint32_t crc2 = etl::crc32_mpeg2((uint8_t*)&data2[0], (uint8_t*)(&data2[0] + data2.size())); + // CHECK_EQUAL(crc1, crc2); + + // uint32_t crc3 = etl::crc32_mpeg2(data3.rbegin(), data3.rend()); + // CHECK_EQUAL(crc1, crc3); + //} + + //************************************************************************* + TEST(test_crc64_ecma) + { + std::string data("123456789"); + + uint64_t crc = etl::crc::crc64_ecma(data.begin(), data.end()); + + CHECK_EQUAL(0x6C40DF5F0B497347U, crc); + } + + //************************************************************************* + TEST(test_crc64_ecma_add_values) + { + std::string data("123456789"); + + etl::crc::crc64_ecma crc_calculator; + + for (size_t i = 0; i < data.size(); ++i) + { + crc_calculator.add(data[i]); + } + + uint64_t crc = crc_calculator; + + CHECK_EQUAL(0x6C40DF5F0B497347U, crc); + } + + //************************************************************************* + TEST(test_crc64_ecma_add_range) + { + std::string data("123456789"); + + etl::crc::crc64_ecma crc_calculator; + + crc_calculator.add(data.begin(), data.end()); + + uint64_t crc = crc_calculator.value(); + + CHECK_EQUAL(0x6C40DF5F0B497347U, crc); + } + + //************************************************************************* + TEST(test_crc64_ecma_add_range_via_iterator) + { + std::string data("123456789"); + + etl::crc::crc64_ecma crc_calculator; + + std::copy(data.begin(), data.end(), crc_calculator.input()); + + uint64_t crc = crc_calculator.value(); + + CHECK_EQUAL(0x6C40DF5F0B497347U, crc); + } + + //************************************************************************* + TEST(test_crc64_ecma_add_range_endian) + { + std::vector data1 = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08 }; + std::vector data2 = { 0x04030201, 0x08070605 }; + std::vector data3 = { 0x08, 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01 }; + + uint64_t crc1 = etl::crc::crc64_ecma(data1.begin(), data1.end()); + uint64_t crc2 = etl::crc::crc64_ecma((uint8_t*)&data2[0], (uint8_t*)(&data2[0] + data2.size())); + CHECK_EQUAL(crc1, crc2); + + uint64_t crc3 = etl::crc::crc64_ecma(data3.rbegin(), data3.rend()); + CHECK_EQUAL(crc1, crc3); + } + }; +} + diff --git a/test/test_crc_table4.cpp b/test/test_crc_table4.cpp new file mode 100644 index 00000000..de65d3a2 --- /dev/null +++ b/test/test_crc_table4.cpp @@ -0,0 +1,1259 @@ +/****************************************************************************** +The MIT License(MIT) + +Embedded Template Library. +https://github.com/ETLCPP/etl +https://www.etlcpp.com + +Copyright(c) 2014 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. +******************************************************************************/ + +#include "unit_test_framework.h" + +#include +#include +#include +#include + +#include "etl/experimental/crc8_ccitt.h" +#include "etl/experimental/crc8_rohc.h" +//#include "etl/experimental/crc16.h" +//#include "etl/crc16.h" +//#include "etl/crc16_ccitt.h" +//#include "etl/crc16_aug_ccitt.h" +//#include "etl/crc16_kermit.h" +//#include "etl/crc16_modbus.h" +//#include "etl/crc16_usb.h" +//#include "etl/crc16_xmodem.h" +//#include "etl/crc16_genibus.h" +//#include "etl/crc16_x25.h" +//#include "etl/crc32.h" +//#include "etl/crc32_c.h" +//#include "etl/crc32_bzip2.h" +//#include "etl/crc32_mpeg2.h" +//#include "etl/crc32_posix.h" +//#include "etl/crc64_ecma.h" + +//***************************************************************************** +// The results for these tests were created from https://crccalc.com/ +//***************************************************************************** + +namespace +{ + SUITE(test_crc_experimental) + { + ////************************************************************************* + //TEST(test_crc8_ccitt_constructor) + //{ + // std::string data("123456789"); + + // uint8_t crc = etl::crc::crc8_ccitt_t4(data.begin(), data.end()); + + // CHECK_EQUAL(0xF4, int(crc)); + //} + + ////************************************************************************* + //TEST(test_crc8_ccitt_add_values) + //{ + // std::string data("123456789"); + + // etl::crc::crc8_ccitt_t4 crc_calculator; + + // for (size_t i = 0; i < data.size(); ++i) + // { + // crc_calculator.add(data[i]); + // } + + // uint8_t crc = crc_calculator; + + // CHECK_EQUAL(0xF4, int(crc)); + //} + + ////************************************************************************* + //TEST(test_crc8_ccitt_add_range) + //{ + // std::string data("123456789"); + + // etl::crc::crc8_ccitt_t4 crc_calculator; + + // crc_calculator.add(data.begin(), data.end()); + + // uint8_t crc = crc_calculator.value(); + + // CHECK_EQUAL(0xF4, int(crc)); + //} + + ////************************************************************************* + //TEST(test_crc8_ccitt_add_range_via_iterator) + //{ + // std::string data("123456789"); + + // etl::crc::crc8_ccitt_t4 crc_calculator; + + // std::copy(data.begin(), data.end(), crc_calculator.input()); + + // uint8_t crc = crc_calculator.value(); + + // CHECK_EQUAL(0xF4, int(crc)); + //} + + ////************************************************************************* + //TEST(test_crc8_ccitt_add_range_endian) + //{ + // std::vector data1 = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08 }; + // std::vector data2 = { 0x04030201, 0x08070605 }; + // std::vector data3 = { 0x08, 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01 }; + + // uint8_t crc1 = etl::crc32(data1.begin(), data1.end()); + // uint8_t crc2 = etl::crc32((uint8_t*)&data2[0], (uint8_t*)(&data2[0] + data2.size())); + // CHECK_EQUAL(int(crc1), int(crc2)); + + // uint8_t crc3 = etl::crc32(data3.rbegin(), data3.rend()); + // CHECK_EQUAL(int(crc1), int(crc3)); + //} + + ////************************************************************************* + //TEST(test_crc8_rohc_constructor) + //{ + // std::string data("123456789"); + + // uint8_t crc = etl::crc::crc8_rohc(data.begin(), data.end()); + + // CHECK_EQUAL(0xD0, int(crc)); + //} + + ////************************************************************************* + //TEST(test_crc8_rohc_add_values) + //{ + // std::string data("123456789"); + + // etl::crc::crc8_rohc crc_calculator; + + // for (size_t i = 0; i < data.size(); ++i) + // { + // crc_calculator.add(data[i]); + // } + + // uint8_t crc = crc_calculator; + + // CHECK_EQUAL(0xD0, int(crc)); + //} + + ////************************************************************************* + //TEST(test_crc8_rohc_add_range) + //{ + // std::string data("123456789"); + + // etl::crc::crc8_rohc crc_calculator; + + // crc_calculator.add(data.begin(), data.end()); + + // uint8_t crc = crc_calculator.value(); + + // CHECK_EQUAL(0xD0, int(crc)); + //} + + ////************************************************************************* + //TEST(test_crc8_rohc_add_range_via_iterator) + //{ + // std::string data("123456789"); + + // etl::crc::crc8_rohc crc_calculator; + + // std::copy(data.begin(), data.end(), crc_calculator.input()); + + // uint8_t crc = crc_calculator.value(); + + // CHECK_EQUAL(0xD0, int(crc)); + //} + + ////************************************************************************* + //TEST(test_crc8_rohc_add_range_endian) + //{ + // std::vector data1 = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08 }; + // std::vector data2 = { 0x04030201, 0x08070605 }; + // std::vector data3 = { 0x08, 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01 }; + + // uint8_t crc1 = etl::crc32(data1.begin(), data1.end()); + // uint8_t crc2 = etl::crc32((uint8_t*)&data2[0], (uint8_t*)(&data2[0] + data2.size())); + // CHECK_EQUAL(int(crc1), int(crc2)); + + // uint8_t crc3 = etl::crc32(data3.rbegin(), data3.rend()); + // CHECK_EQUAL(int(crc1), int(crc3)); + //} + + ////************************************************************************* + //TEST(test_crc16) + //{ + // std::string data("123456789"); + + // uint16_t crc = etl::crc::crc16(data.begin(), data.end()); + + // CHECK_EQUAL(0xBB3D, crc); + //} + + ////************************************************************************* + //TEST(test_crc16_add_values) + //{ + // std::string data("123456789"); + + // etl::crc::crc16 crc_calculator; + + // for (size_t i = 0; i < data.size(); ++i) + // { + // crc_calculator.add(data[i]); + // } + + // uint16_t crc = crc_calculator; + + // CHECK_EQUAL(0xBB3D, crc); + //} + + ////************************************************************************* + //TEST(test_crc16_add_range) + //{ + // std::string data("123456789"); + + // etl::crc::crc16 crc_calculator; + + // crc_calculator.add(data.begin(), data.end()); + + // uint16_t crc = crc_calculator.value(); + + // CHECK_EQUAL(0xBB3D, crc); + //} + + ////************************************************************************* + //TEST(test_crc16_add_range_via_iterator) + //{ + // std::string data("123456789"); + + // etl::crc::crc16 crc_calculator; + + // std::copy(data.begin(), data.end(), crc_calculator.input()); + + // uint16_t crc = crc_calculator.value(); + + // CHECK_EQUAL(0xBB3D, crc); + //} + + ////************************************************************************* + //TEST(test_crc16_add_range_endian) + //{ + // std::vector data1 = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08 }; + // std::vector data2 = { 0x04030201, 0x08070605 }; + // std::vector data3 = { 0x08, 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01 }; + + // uint16_t crc1 = etl::crc16(data1.begin(), data1.end()); + // uint16_t crc2 = etl::crc16((uint8_t*)&data2[0], (uint8_t*)(&data2[0] + data2.size())); + // CHECK_EQUAL(crc1, crc2); + + // uint16_t crc3 = etl::crc16(data3.rbegin(), data3.rend()); + // CHECK_EQUAL(crc1, crc3); + //} + + ////************************************************************************* + //TEST(test_crc16_ccitt) + //{ + // std::string data("123456789"); + + // uint16_t crc = etl::crc16_ccitt(data.begin(), data.end()); + + // CHECK_EQUAL(0x29B1, crc); + //} + + ////************************************************************************* + //TEST(test_crc16_ccitt_add_values) + //{ + // std::string data("123456789"); + + // etl::crc16_ccitt crc_calculator; + + // for (size_t i = 0; i < data.size(); ++i) + // { + // crc_calculator.add(data[i]); + // } + + // uint16_t crc = crc_calculator; + + // CHECK_EQUAL(0x29B1, crc); + //} + + ////************************************************************************* + //TEST(test_crc16_ccitt_add_range) + //{ + // std::string data("123456789"); + + // etl::crc16_ccitt crc_calculator; + + // crc_calculator.add(data.begin(), data.end()); + + // uint16_t crc = crc_calculator.value(); + + // CHECK_EQUAL(0x29B1, crc); + //} + + ////************************************************************************* + //TEST(test_crc16_ccitt_add_range_via_iterator) + //{ + // std::string data("123456789"); + + // etl::crc16_ccitt crc_calculator; + + // std::copy(data.begin(), data.end(), crc_calculator.input()); + + // uint16_t crc = crc_calculator.value(); + + // CHECK_EQUAL(0x29B1, crc); + //} + + ////************************************************************************* + //TEST(test_crc16_ccitt_add_range_endian) + //{ + // std::vector data1 = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08 }; + // std::vector data2 = { 0x04030201, 0x08070605 }; + // std::vector data3 = { 0x08, 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01 }; + + // uint16_t crc1 = etl::crc16_ccitt(data1.begin(), data1.end()); + // uint16_t crc2 = etl::crc16_ccitt((uint8_t*)&data2[0], (uint8_t*)(&data2[0] + data2.size())); + // CHECK_EQUAL(crc1, crc2); + + // uint16_t crc3 = etl::crc16_ccitt(data3.rbegin(), data3.rend()); + // CHECK_EQUAL(crc1, crc3); + //} + + ////************************************************************************* + //TEST(test_crc16_kermit) + //{ + // std::string data("123456789"); + + // uint16_t crc = etl::crc16_kermit(data.begin(), data.end()); + + // CHECK_EQUAL(0x2189, crc); + //} + + ////************************************************************************* + //TEST(test_crc16_kermit_add_values) + //{ + // std::string data("123456789"); + + // etl::crc16_kermit crc_calculator; + + // for (size_t i = 0; i < data.size(); ++i) + // { + // crc_calculator.add(data[i]); + // } + + // uint16_t crc = crc_calculator; + + // CHECK_EQUAL(0x2189, crc); + //} + + ////************************************************************************* + //TEST(test_crc16_kermit_add_range) + //{ + // std::string data("123456789"); + + // etl::crc16_kermit crc_calculator; + + // crc_calculator.add(data.begin(), data.end()); + + // uint16_t crc = crc_calculator.value(); + + // CHECK_EQUAL(0x2189, crc); + //} + + ////************************************************************************* + //TEST(test_crc16_kermit_add_range_via_iterator) + //{ + // std::string data("123456789"); + + // etl::crc16_kermit crc_calculator; + + // std::copy(data.begin(), data.end(), crc_calculator.input()); + + // uint16_t crc = crc_calculator.value(); + + // CHECK_EQUAL(0x2189, crc); + //} + + ////************************************************************************* + //TEST(test_crc16_kermit_add_range_endian) + //{ + // std::vector data1 = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08 }; + // std::vector data2 = { 0x04030201, 0x08070605 }; + // std::vector data3 = { 0x08, 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01 }; + + // uint16_t crc1 = etl::crc16_kermit(data1.begin(), data1.end()); + // uint16_t crc2 = etl::crc16_kermit((uint8_t*)&data2[0], (uint8_t*)(&data2[0] + data2.size())); + // CHECK_EQUAL(crc1, crc2); + + // uint16_t crc3 = etl::crc16_kermit(data3.rbegin(), data3.rend()); + // CHECK_EQUAL(crc1, crc3); + //} + + ////************************************************************************* + //TEST(test_crc16_modbus) + //{ + // std::string data("123456789"); + + // uint16_t crc = etl::crc16_modbus(data.begin(), data.end()); + + // CHECK_EQUAL(0x4B37, crc); + //} + + ////************************************************************************* + //TEST(test_crc16_modbus_add_values) + //{ + // std::string data("123456789"); + + // etl::crc16_modbus crc_calculator; + + // for (size_t i = 0; i < data.size(); ++i) + // { + // crc_calculator.add(data[i]); + // } + + // uint16_t crc = crc_calculator; + + // CHECK_EQUAL(0x4B37, crc); + //} + + ////************************************************************************* + //TEST(test_crc16_modbus_add_range) + //{ + // std::string data("123456789"); + + // etl::crc16_modbus crc_calculator; + + // crc_calculator.add(data.begin(), data.end()); + + // uint16_t crc = crc_calculator.value(); + + // CHECK_EQUAL(0x4B37, crc); + //} + + ////************************************************************************* + //TEST(test_crc16_modbus_add_range_via_iterator) + //{ + // std::string data("123456789"); + + // etl::crc16_modbus crc_calculator; + + // std::copy(data.begin(), data.end(), crc_calculator.input()); + + // uint16_t crc = crc_calculator.value(); + + // CHECK_EQUAL(0x4B37, crc); + //} + + ////************************************************************************* + //TEST(test_crc16_modbus_add_range_endian) + //{ + // std::vector data1 = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08 }; + // std::vector data2 = { 0x04030201, 0x08070605 }; + // std::vector data3 = { 0x08, 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01 }; + + // uint16_t crc1 = etl::crc16_modbus(data1.begin(), data1.end()); + // uint16_t crc2 = etl::crc16_modbus((uint8_t*)&data2[0], (uint8_t*)(&data2[0] + data2.size())); + // CHECK_EQUAL(crc1, crc2); + + // uint16_t crc3 = etl::crc16_modbus(data3.rbegin(), data3.rend()); + // CHECK_EQUAL(crc1, crc3); + //} + + ////************************************************************************* + //TEST(test_crc16_usb) + //{ + // std::string data("123456789"); + + // uint16_t crc = etl::crc16_usb(data.begin(), data.end()); + + // CHECK_EQUAL(0xB4C8, crc); + //} + + ////************************************************************************* + //TEST(test_crc16_usb_add_values) + //{ + // std::string data("123456789"); + + // etl::crc16_usb crc_calculator; + + // for (size_t i = 0; i < data.size(); ++i) + // { + // crc_calculator.add(data[i]); + // } + + // uint16_t crc = crc_calculator; + + // CHECK_EQUAL(0xB4C8, crc); + //} + + ////************************************************************************* + //TEST(test_crc16_usb_add_range) + //{ + // std::string data("123456789"); + + // etl::crc16_usb crc_calculator; + + // crc_calculator.add(data.begin(), data.end()); + + // uint16_t crc = crc_calculator.value(); + + // CHECK_EQUAL(0xB4C8, crc); + //} + + ////************************************************************************* + //TEST(test_crc16_usb_add_range_via_iterator) + //{ + // std::string data("123456789"); + + // etl::crc16_usb crc_calculator; + + // std::copy(data.begin(), data.end(), crc_calculator.input()); + + // uint16_t crc = crc_calculator.value(); + + // CHECK_EQUAL(0xB4C8, crc); + //} + + ////************************************************************************* + //TEST(test_crc16_usb_add_range_endian) + //{ + // std::vector data1 = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08 }; + // std::vector data2 = { 0x04030201, 0x08070605 }; + // std::vector data3 = { 0x08, 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01 }; + + // uint16_t crc1 = etl::crc16_usb(data1.begin(), data1.end()); + // uint16_t crc2 = etl::crc16_usb((uint8_t*)&data2[0], (uint8_t*)(&data2[0] + data2.size())); + // CHECK_EQUAL(crc1, crc2); + + // uint16_t crc3 = etl::crc16_usb(data3.rbegin(), data3.rend()); + // CHECK_EQUAL(crc1, crc3); + //} + + ////************************************************************************* + //TEST(test_crc16_xmodem) + //{ + // std::string data("123456789"); + + // uint16_t crc = etl::crc16_xmodem(data.begin(), data.end()); + + // CHECK_EQUAL(0x31C3, crc); + //} + + ////************************************************************************* + //TEST(test_crc16_xmodem_add_values) + //{ + // std::string data("123456789"); + + // etl::crc16_xmodem crc_calculator; + + // for (size_t i = 0; i < data.size(); ++i) + // { + // crc_calculator.add(data[i]); + // } + + // uint16_t crc = crc_calculator; + + // CHECK_EQUAL(0x31C3, crc); + //} + + ////************************************************************************* + //TEST(test_crc16_xmodem_add_range) + //{ + // std::string data("123456789"); + + // etl::crc16_xmodem crc_calculator; + + // crc_calculator.add(data.begin(), data.end()); + + // uint16_t crc = crc_calculator.value(); + + // CHECK_EQUAL(0x31C3, crc); + //} + + ////************************************************************************* + //TEST(test_crc16_xmodem_add_range_via_iterator) + //{ + // std::string data("123456789"); + + // etl::crc16_xmodem crc_calculator; + + // std::copy(data.begin(), data.end(), crc_calculator.input()); + + // uint16_t crc = crc_calculator.value(); + + // CHECK_EQUAL(0x31C3, crc); + //} + + ////************************************************************************* + //TEST(test_crc16_xmodem_add_range_endian) + //{ + // std::vector data1 = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08 }; + // std::vector data2 = { 0x04030201, 0x08070605 }; + // std::vector data3 = { 0x08, 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01 }; + + // uint16_t crc1 = etl::crc16_xmodem(data1.begin(), data1.end()); + // uint16_t crc2 = etl::crc16_xmodem((uint8_t*)&data2[0], (uint8_t*)(&data2[0] + data2.size())); + // CHECK_EQUAL(crc1, crc2); + + // uint16_t crc3 = etl::crc16_xmodem(data3.rbegin(), data3.rend()); + // CHECK_EQUAL(crc1, crc3); + //} + + ////************************************************************************* + //TEST(test_crc16_aug_ccitt) + //{ + // std::string data("123456789"); + + // uint16_t crc = etl::crc16_aug_ccitt(data.begin(), data.end()); + + // CHECK_EQUAL(0xE5CC, crc); + //} + + ////************************************************************************* + //TEST(test_crc16_aug_ccitt_add_values) + //{ + // std::string data("123456789"); + + // etl::crc16_aug_ccitt crc_calculator; + + // for (size_t i = 0; i < data.size(); ++i) + // { + // crc_calculator.add(data[i]); + // } + + // uint16_t crc = crc_calculator; + + // CHECK_EQUAL(0xE5CC, crc); + //} + + ////************************************************************************* + //TEST(test_crc16_aug_ccitt_add_range) + //{ + // std::string data("123456789"); + + // etl::crc16_aug_ccitt crc_calculator; + + // crc_calculator.add(data.begin(), data.end()); + + // uint16_t crc = crc_calculator.value(); + + // CHECK_EQUAL(0xE5CC, crc); + //} + + ////************************************************************************* + //TEST(test_crc16_aug_ccitt_add_range_via_iterator) + //{ + // std::string data("123456789"); + + // etl::crc16_aug_ccitt crc_calculator; + + // std::copy(data.begin(), data.end(), crc_calculator.input()); + + // uint16_t crc = crc_calculator.value(); + + // CHECK_EQUAL(0xE5CC, crc); + //} + + ////************************************************************************* + //TEST(test_crc16_aug_ccitt_add_range_endian) + //{ + // std::vector data1 = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08 }; + // std::vector data2 = { 0x04030201, 0x08070605 }; + // std::vector data3 = { 0x08, 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01 }; + + // uint16_t crc1 = etl::crc16_aug_ccitt(data1.begin(), data1.end()); + // uint16_t crc2 = etl::crc16_aug_ccitt((uint8_t*)&data2[0], (uint8_t*)(&data2[0] + data2.size())); + // CHECK_EQUAL(crc1, crc2); + + // uint16_t crc3 = etl::crc16_aug_ccitt(data3.rbegin(), data3.rend()); + // CHECK_EQUAL(crc1, crc3); + //} + + ////************************************************************************* + //TEST(test_crc16_genibus) + //{ + // std::string data("123456789"); + + // uint16_t crc = etl::crc16_genibus(data.begin(), data.end()); + + // CHECK_EQUAL(0xD64E, crc); + //} + + ////************************************************************************* + //TEST(test_crc16_genibus_add_values) + //{ + // std::string data("123456789"); + + // etl::crc16_genibus crc_calculator; + + // for (size_t i = 0; i < data.size(); ++i) + // { + // crc_calculator.add(data[i]); + // } + + // uint16_t crc = crc_calculator; + + // CHECK_EQUAL(0xD64E, crc); + //} + + ////************************************************************************* + //TEST(test_crc16_genibus_add_range) + //{ + // std::string data("123456789"); + + // etl::crc16_genibus crc_calculator; + + // crc_calculator.add(data.begin(), data.end()); + + // uint16_t crc = crc_calculator.value(); + + // CHECK_EQUAL(0xD64E, crc); + //} + + ////************************************************************************* + //TEST(test_crc16_genibus_add_range_via_iterator) + //{ + // std::string data("123456789"); + + // etl::crc16_genibus crc_calculator; + + // std::copy(data.begin(), data.end(), crc_calculator.input()); + + // uint16_t crc = crc_calculator.value(); + + // CHECK_EQUAL(0xD64E, crc); + //} + + ////************************************************************************* + //TEST(test_crc16_genibus_add_range_endian) + //{ + // std::vector data1 = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08 }; + // std::vector data2 = { 0x04030201, 0x08070605 }; + // std::vector data3 = { 0x08, 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01 }; + + // uint16_t crc1 = etl::crc16_genibus(data1.begin(), data1.end()); + // uint16_t crc2 = etl::crc16_genibus((uint8_t*)&data2[0], (uint8_t*)(&data2[0] + data2.size())); + // CHECK_EQUAL(crc1, crc2); + + // uint16_t crc3 = etl::crc16_genibus(data3.rbegin(), data3.rend()); + // CHECK_EQUAL(crc1, crc3); + //} + + ////************************************************************************* + //TEST(test_crc16_x25) + //{ + // std::string data("123456789"); + + // uint16_t crc = etl::crc16_x25(data.begin(), data.end()); + + // CHECK_EQUAL(0x906E, crc); + //} + + ////************************************************************************* + //TEST(test_crc16_x25_add_values) + //{ + // std::string data("123456789"); + + // etl::crc16_x25 crc_calculator; + + // for (size_t i = 0; i < data.size(); ++i) + // { + // crc_calculator.add(data[i]); + // } + + // uint16_t crc = crc_calculator; + + // CHECK_EQUAL(0x906E, crc); + //} + + ////************************************************************************* + //TEST(test_crc16_x25_add_range) + //{ + // std::string data("123456789"); + + // etl::crc16_x25 crc_calculator; + + // crc_calculator.add(data.begin(), data.end()); + + // uint16_t crc = crc_calculator.value(); + + // CHECK_EQUAL(0x906E, crc); + //} + + ////************************************************************************* + //TEST(test_crc16_x25_add_range_via_iterator) + //{ + // std::string data("123456789"); + + // etl::crc16_x25 crc_calculator; + + // std::copy(data.begin(), data.end(), crc_calculator.input()); + + // uint16_t crc = crc_calculator.value(); + + // CHECK_EQUAL(0x906E, crc); + //} + + ////************************************************************************* + //TEST(test_crc16_x25_add_range_endian) + //{ + // std::vector data1 = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08 }; + // std::vector data2 = { 0x04030201, 0x08070605 }; + // std::vector data3 = { 0x08, 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01 }; + + // uint16_t crc1 = etl::crc16_x25(data1.begin(), data1.end()); + // uint16_t crc2 = etl::crc16_x25((uint8_t*)&data2[0], (uint8_t*)(&data2[0] + data2.size())); + // CHECK_EQUAL(crc1, crc2); + + // uint16_t crc3 = etl::crc16_x25(data3.rbegin(), data3.rend()); + // CHECK_EQUAL(crc1, crc3); + //} + + ////************************************************************************* + //TEST(test_crc32) + //{ + // std::string data("123456789"); + + // uint32_t crc = etl::crc32(data.begin(), data.end()); + + // CHECK_EQUAL(0xCBF43926, crc); + //} + + ////************************************************************************* + //TEST(test_crc32_add_values) + //{ + // std::string data("123456789"); + + // etl::crc32 crc_calculator; + + // for (size_t i = 0; i < data.size(); ++i) + // { + // crc_calculator.add(data[i]); + // } + + // uint32_t crc = crc_calculator; + + + // CHECK_EQUAL(0xCBF43926, crc); + //} + + ////************************************************************************* + //TEST(test_crc32_add_range) + //{ + // std::string data("123456789"); + + // etl::crc32 crc_calculator; + + // crc_calculator.add(data.begin(), data.end()); + + // uint32_t crc = crc_calculator.value(); + + // CHECK_EQUAL(0xCBF43926, crc); + //} + + ////************************************************************************* + //TEST(test_crc32_add_range_via_iterator) + //{ + // std::string data("123456789"); + + // etl::crc32 crc_calculator; + + // std::copy(data.begin(), data.end(), crc_calculator.input()); + + // uint32_t crc = crc_calculator.value(); + + // CHECK_EQUAL(0xCBF43926, crc); + //} + + ////************************************************************************* + //TEST(test_crc32_add_range_endian) + //{ + // std::vector data1 = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08 }; + // std::vector data2 = { 0x04030201, 0x08070605 }; + // std::vector data3 = { 0x08, 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01 }; + + // uint32_t crc1 = etl::crc32(data1.begin(), data1.end()); + // uint32_t crc2 = etl::crc32((uint8_t*)&data2[0], (uint8_t*)(&data2[0] + data2.size())); + // CHECK_EQUAL(crc1, crc2); + + // uint32_t crc3 = etl::crc32(data3.rbegin(), data3.rend()); + // CHECK_EQUAL(crc1, crc3); + //} + + ////************************************************************************* + //TEST(test_crc32_c) + //{ + // std::string data("123456789"); + + // uint32_t crc = etl::crc32_c(data.begin(), data.end()); + + // CHECK_EQUAL(0xE3069283, crc); + //} + + ////************************************************************************* + //TEST(test_crc32_c_add_values) + //{ + // std::string data("123456789"); + + // etl::crc32_c crc_calculator; + + // for (size_t i = 0; i < data.size(); ++i) + // { + // crc_calculator.add(data[i]); + // } + + // uint32_t crc = crc_calculator; + + + // CHECK_EQUAL(0xE3069283, crc); + //} + + ////************************************************************************* + //TEST(test_crc32_c_add_range) + //{ + // std::string data("123456789"); + + // etl::crc32_c crc_calculator; + + // crc_calculator.add(data.begin(), data.end()); + + // uint32_t crc = crc_calculator.value(); + + // CHECK_EQUAL(0xE3069283, crc); + //} + + ////************************************************************************* + //TEST(test_crc32_c_add_range_via_iterator) + //{ + // std::string data("123456789"); + + // etl::crc32_c crc_calculator; + + // std::copy(data.begin(), data.end(), crc_calculator.input()); + + // uint32_t crc = crc_calculator.value(); + + // CHECK_EQUAL(0xE3069283, crc); + //} + + ////************************************************************************* + //TEST(test_crc32_c_add_range_endian) + //{ + // std::vector data1 = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08 }; + // std::vector data2 = { 0x04030201, 0x08070605 }; + // std::vector data3 = { 0x08, 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01 }; + + // uint32_t crc1 = etl::crc32_c(data1.begin(), data1.end()); + // uint32_t crc2 = etl::crc32_c((uint8_t*)&data2[0], (uint8_t*)(&data2[0] + data2.size())); + // CHECK_EQUAL(crc1, crc2); + + // uint32_t crc3 = etl::crc32_c(data3.rbegin(), data3.rend()); + // CHECK_EQUAL(crc1, crc3); + //} + + ////************************************************************************* + //TEST(test_crc32_bzip2) + //{ + // std::string data("123456789"); + + // uint32_t crc = etl::crc32_bzip2(data.begin(), data.end()); + + // CHECK_EQUAL(0xFC891918, crc); + //} + + ////************************************************************************* + //TEST(test_crc32_bzip2_add_values) + //{ + // std::string data("123456789"); + + // etl::crc32_bzip2 crc_calculator; + + // for (size_t i = 0; i < data.size(); ++i) + // { + // crc_calculator.add(data[i]); + // } + + // uint32_t crc = crc_calculator; + + + // CHECK_EQUAL(0xFC891918, crc); + //} + + ////************************************************************************* + //TEST(test_crc32_bzip2_add_range) + //{ + // std::string data("123456789"); + + // etl::crc32_bzip2 crc_calculator; + + // crc_calculator.add(data.begin(), data.end()); + + // uint32_t crc = crc_calculator.value(); + + // CHECK_EQUAL(0xFC891918, crc); + //} + + ////************************************************************************* + //TEST(test_crc32_bzip2_add_range_via_iterator) + //{ + // std::string data("123456789"); + + // etl::crc32_bzip2 crc_calculator; + + // std::copy(data.begin(), data.end(), crc_calculator.input()); + + // uint32_t crc = crc_calculator.value(); + + // CHECK_EQUAL(0xFC891918, crc); + //} + + ////************************************************************************* + //TEST(test_crc32_bzip2_add_range_endian) + //{ + // std::vector data1 = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08 }; + // std::vector data2 = { 0x04030201, 0x08070605 }; + // std::vector data3 = { 0x08, 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01 }; + + // uint32_t crc1 = etl::crc32_bzip2(data1.begin(), data1.end()); + // uint32_t crc2 = etl::crc32_bzip2((uint8_t*)&data2[0], (uint8_t*)(&data2[0] + data2.size())); + // CHECK_EQUAL(crc1, crc2); + + // uint32_t crc3 = etl::crc32_bzip2(data3.rbegin(), data3.rend()); + // CHECK_EQUAL(crc1, crc3); + //} + + ////************************************************************************* + //TEST(test_crc32_posix) + //{ + // std::string data("123456789"); + + // uint32_t crc = etl::crc32_posix(data.begin(), data.end()); + + // CHECK_EQUAL(0x765E7680, crc); + //} + + ////************************************************************************* + //TEST(test_crc32_posix_add_values) + //{ + // std::string data("123456789"); + + // etl::crc32_posix crc_calculator; + + // for (size_t i = 0; i < data.size(); ++i) + // { + // crc_calculator.add(data[i]); + // } + + // uint32_t crc = crc_calculator; + + + // CHECK_EQUAL(0x765E7680, crc); + //} + + ////************************************************************************* + //TEST(test_crc32_posix_add_range) + //{ + // std::string data("123456789"); + + // etl::crc32_posix crc_calculator; + + // crc_calculator.add(data.begin(), data.end()); + + // uint32_t crc = crc_calculator.value(); + + // CHECK_EQUAL(0x765E7680, crc); + //} + + ////************************************************************************* + //TEST(test_crc32_posix_add_range_via_iterator) + //{ + // std::string data("123456789"); + + // etl::crc32_posix crc_calculator; + + // std::copy(data.begin(), data.end(), crc_calculator.input()); + + // uint32_t crc = crc_calculator.value(); + + // CHECK_EQUAL(0x765E7680, crc); + //} + + ////************************************************************************* + //TEST(test_crc32_posix_add_range_endian) + //{ + // std::vector data1 = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08 }; + // std::vector data2 = { 0x04030201, 0x08070605 }; + // std::vector data3 = { 0x08, 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01 }; + + // uint32_t crc1 = etl::crc32_posix(data1.begin(), data1.end()); + // uint32_t crc2 = etl::crc32_posix((uint8_t*)&data2[0], (uint8_t*)(&data2[0] + data2.size())); + // CHECK_EQUAL(crc1, crc2); + + // uint32_t crc3 = etl::crc32_posix(data3.rbegin(), data3.rend()); + // CHECK_EQUAL(crc1, crc3); + //} + + ////************************************************************************* + //TEST(test_crc32_mpeg2) + //{ + // std::string data("123456789"); + + // uint32_t crc = etl::crc32_mpeg2(data.begin(), data.end()); + + // CHECK_EQUAL(0x0376E6E7, crc); + //} + + ////************************************************************************* + //TEST(test_crc32_mpeg2_add_values) + //{ + // std::string data("123456789"); + + // etl::crc32_mpeg2 crc_calculator; + + // for (size_t i = 0; i < data.size(); ++i) + // { + // crc_calculator.add(data[i]); + // } + + // uint32_t crc = crc_calculator; + + + // CHECK_EQUAL(0x0376E6E7, crc); + //} + + ////************************************************************************* + //TEST(test_crc32_mpeg2_add_range) + //{ + // std::string data("123456789"); + + // etl::crc32_mpeg2 crc_calculator; + + // crc_calculator.add(data.begin(), data.end()); + + // uint32_t crc = crc_calculator.value(); + + // CHECK_EQUAL(0x0376E6E7, crc); + //} + + ////************************************************************************* + //TEST(test_crc32_mpeg2_add_range_via_iterator) + //{ + // std::string data("123456789"); + + // etl::crc32_mpeg2 crc_calculator; + + // std::copy(data.begin(), data.end(), crc_calculator.input()); + + // uint32_t crc = crc_calculator.value(); + + // CHECK_EQUAL(0x0376E6E7, crc); + //} + + ////************************************************************************* + //TEST(test_crc32_mpeg2_add_range_endian) + //{ + // std::vector data1 = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08 }; + // std::vector data2 = { 0x04030201, 0x08070605 }; + // std::vector data3 = { 0x08, 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01 }; + + // uint32_t crc1 = etl::crc32_mpeg2(data1.begin(), data1.end()); + // uint32_t crc2 = etl::crc32_mpeg2((uint8_t*)&data2[0], (uint8_t*)(&data2[0] + data2.size())); + // CHECK_EQUAL(crc1, crc2); + + // uint32_t crc3 = etl::crc32_mpeg2(data3.rbegin(), data3.rend()); + // CHECK_EQUAL(crc1, crc3); + //} + + ////************************************************************************* + //TEST(test_crc64_ecma) + //{ + // std::string data("123456789"); + + // uint64_t crc = etl::crc64_ecma(data.begin(), data.end()); + + // CHECK_EQUAL(0x6C40DF5F0B497347U, crc); + //} + + ////************************************************************************* + //TEST(test_crc64_ecma_add_values) + //{ + // std::string data("123456789"); + + // etl::crc64_ecma crc_calculator; + + // for (size_t i = 0; i < data.size(); ++i) + // { + // crc_calculator.add(data[i]); + // } + + // uint64_t crc = crc_calculator; + + // CHECK_EQUAL(0x6C40DF5F0B497347U, crc); + //} + + ////************************************************************************* + //TEST(test_crc64_ecma_add_range) + //{ + // std::string data("123456789"); + + // etl::crc64_ecma crc_calculator; + + // crc_calculator.add(data.begin(), data.end()); + + // uint64_t crc = crc_calculator.value(); + + // CHECK_EQUAL(0x6C40DF5F0B497347U, crc); + //} + + ////************************************************************************* + //TEST(test_crc64_ecma_add_range_via_iterator) + //{ + // std::string data("123456789"); + + // etl::crc64_ecma crc_calculator; + + // std::copy(data.begin(), data.end(), crc_calculator.input()); + + // uint64_t crc = crc_calculator.value(); + + // CHECK_EQUAL(0x6C40DF5F0B497347U, crc); + //} + + ////************************************************************************* + //TEST(test_crc64_ecma_add_range_endian) + //{ + // std::vector data1 = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08 }; + // std::vector data2 = { 0x04030201, 0x08070605 }; + // std::vector data3 = { 0x08, 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01 }; + + // uint64_t crc1 = etl::crc64_ecma(data1.begin(), data1.end()); + // uint64_t crc2 = etl::crc64_ecma((uint8_t*)&data2[0], (uint8_t*)(&data2[0] + data2.size())); + // CHECK_EQUAL(crc1, crc2); + + // uint64_t crc3 = etl::crc64_ecma(data3.rbegin(), data3.rend()); + // CHECK_EQUAL(crc1, crc3); + //} + }; +} + diff --git a/test/vs2019/etl.vcxproj b/test/vs2019/etl.vcxproj index 35a7056c..05687816 100644 --- a/test/vs2019/etl.vcxproj +++ b/test/vs2019/etl.vcxproj @@ -1272,6 +1272,21 @@ + + + + + + + + + + + + + + + @@ -3778,6 +3793,9 @@ + + + diff --git a/test/vs2019/etl.vcxproj.filters b/test/vs2019/etl.vcxproj.filters index e37ddcd2..feb6f6c8 100644 --- a/test/vs2019/etl.vcxproj.filters +++ b/test/vs2019/etl.vcxproj.filters @@ -106,6 +106,9 @@ {562466b5-677d-4448-9e9e-f70805cd71ad} + + {016bd5a6-e277-4aba-8b28-28a9f1348473} + @@ -984,6 +987,51 @@ Source Files\Sanity Checks\C++17 + + ETL\Maths\Experimental + + + ETL\Maths\Experimental + + + ETL\Maths\Experimental + + + ETL\Maths\Experimental + + + ETL\Maths\Experimental + + + ETL\Maths\Experimental + + + ETL\Maths\Experimental + + + ETL\Maths\Experimental + + + ETL\Maths\Experimental + + + ETL\Maths\Experimental + + + ETL\Maths\Experimental + + + ETL\Maths\Experimental + + + ETL\Maths\Experimental + + + ETL\Maths\Experimental + + + ETL\Maths\Experimental + @@ -2102,6 +2150,15 @@ Source Files\Sanity Checks + + Source Files + + + Source Files + + + Source Files +