31#ifndef ETL_CRC_IMPLEMENTATION_INCLUDED
32#define ETL_CRC_IMPLEMENTATION_INCLUDED
34#include "../platform.h"
35#include "../frame_check_sequence.h"
36#include "../static_assert.h"
38#include "../type_traits.h"
44#if defined(ETL_COMPILER_KEIL)
45#pragma diag_suppress 1300
55 template <
typename TAccumulator,
size_t Accumulator_Bits, TAccumulator Polynomial,
bool Reflect, TAccumulator Entry>
60 static ETL_CONSTANT
bool Do_Poly = Reflect ? (Entry & TAccumulator(1U)) != 0U
61 : (Entry & (TAccumulator(1U) << (Accumulator_Bits - 1U))) != 0U;
66 : TAccumulator(Do_Poly ? (Entry << 1U) ^ Polynomial : (Entry << 1U));
69 template <
typename TAccumulator,
size_t Accumulator_Bits, TAccumulator Polynomial,
bool Reflect, TAccumulator Entry>
75 template <
typename TAccumulator,
size_t Accumulator_Bits, TAccumulator Polynomial,
bool Reflect,
size_t Index, u
int8_t Chunk_Bits>
78 ETL_STATIC_ASSERT((Chunk_Bits == 2U) || (Chunk_Bits == 4U) || (Chunk_Bits == 8U),
"Chunk bits must be 2, 4 or 8");
83 template <
typename TAccumulator,
size_t Accumulator_Bits, TAccumulator Polynomial,
bool Reflect,
size_t Index>
84 class crc_table_entry<TAccumulator, Accumulator_Bits, Polynomial, Reflect, Index, 2U>
88 static ETL_CONSTANT
size_t Shift_Bits = size_t(Accumulator_Bits - 2U);
89 static ETL_CONSTANT TAccumulator Entry = Reflect ? TAccumulator(Index) : TAccumulator(TAccumulator(Index) << Shift_Bits);
91 static ETL_CONSTANT TAccumulator value =
crc_partial_table_entry<TAccumulator, Accumulator_Bits, Polynomial, Reflect,
95 template <
typename TAccumulator,
size_t Accumulator_Bits, TAccumulator Polynomial,
bool Reflect,
size_t Index>
98 template <
typename TAccumulator,
size_t Accumulator_Bits, TAccumulator Polynomial,
bool Reflect,
size_t Index>
101 template <
typename TAccumulator,
size_t Accumulator_Bits, TAccumulator Polynomial,
bool Reflect,
size_t Index>
106 template <
typename TAccumulator,
size_t Accumulator_Bits, TAccumulator Polynomial,
bool Reflect,
size_t Index>
111 static ETL_CONSTANT
size_t Shift_Bits = size_t(Accumulator_Bits - 4U);
112 static ETL_CONSTANT TAccumulator Entry = Reflect ? TAccumulator(Index) : TAccumulator(TAccumulator(Index) << Shift_Bits);
114 static ETL_CONSTANT TAccumulator value =
crc_partial_table_entry<TAccumulator, Accumulator_Bits, Polynomial, Reflect,
120 template <
typename TAccumulator,
size_t Accumulator_Bits, TAccumulator Polynomial,
bool Reflect,
size_t Index>
123 template <
typename TAccumulator,
size_t Accumulator_Bits, TAccumulator Polynomial,
bool Reflect,
size_t Index>
126 template <
typename TAccumulator,
size_t Accumulator_Bits, TAccumulator Polynomial,
bool Reflect,
size_t Index>
131 template <
typename TAccumulator,
size_t Accumulator_Bits, TAccumulator Polynomial,
bool Reflect,
size_t Index>
136 static ETL_CONSTANT
size_t Shift_Bits = size_t(Accumulator_Bits - 8U);
137 static ETL_CONSTANT TAccumulator Entry = Reflect ? TAccumulator(Index) : TAccumulator(TAccumulator(Index) << Shift_Bits);
139 static ETL_CONSTANT TAccumulator value =
crc_partial_table_entry<TAccumulator, Accumulator_Bits, Polynomial, Reflect,
149 template <
typename TAccumulator,
size_t Accumulator_Bits, TAccumulator Polynomial,
bool Reflect,
size_t Index>
152 template <
typename TAccumulator,
size_t Accumulator_Bits, TAccumulator Polynomial,
bool Reflect,
size_t Index>
155 template <
typename TAccumulator,
size_t Accumulator_Bits, TAccumulator Polynomial,
bool Reflect,
size_t Index>
165 template <
typename TAccumulator,
size_t Accumulator_Bits,
size_t Chunk_Bits, u
int8_t Chunk_Mask,
bool Reflect>
167 typename etl::enable_if<(Accumulator_Bits > Chunk_Bits) && !Reflect, TAccumulator>::type
168 crc_update_chunk(TAccumulator crc, uint8_t value,
const TAccumulator table[])
172 uint8_t index = (crc >> (Accumulator_Bits - Chunk_Bits)) ^ value;
183 template <
typename TAccumulator,
size_t Accumulator_Bits,
size_t Chunk_Bits, u
int8_t Chunk_Mask,
bool Reflect>
185 typename etl::enable_if<(Accumulator_Bits > Chunk_Bits) && Reflect, TAccumulator>::type
186 crc_update_chunk(TAccumulator crc, uint8_t value,
const TAccumulator table[])
190 uint8_t index = (crc & Chunk_Mask) ^ value;
201 template <
typename TAccumulator,
size_t Accumulator_Bits,
size_t Chunk_Bits, u
int8_t Chunk_Mask,
bool Reflect>
203 typename etl::enable_if<(Accumulator_Bits == Chunk_Bits) && !Reflect, TAccumulator>::type
204 crc_update_chunk(TAccumulator crc, uint8_t value,
const TAccumulator table[])
208 uint8_t index = (crc >> (Accumulator_Bits - Chunk_Bits)) ^ value;
218 template <
typename TAccumulator,
size_t Accumulator_Bits,
size_t Chunk_Bits, u
int8_t Chunk_Mask,
bool Reflect>
220 typename etl::enable_if<(Accumulator_Bits == Chunk_Bits) && Reflect, TAccumulator>::type
221 crc_update_chunk(TAccumulator crc, uint8_t value,
const TAccumulator table[])
225 uint8_t index = (crc & Chunk_Mask) ^ value;
235 template <
typename TAccumulator,
size_t Accumulator_Bits,
size_t Chunk_Bits, u
int8_t Chunk_Mask, TAccumulator Polynomial,
bool Reflect,
size_t Table_Size>
240 template <
typename TAccumulator,
size_t Accumulator_Bits,
size_t Chunk_Bits, u
int8_t Chunk_Mask, TAccumulator Polynomial,
bool Reflect>
241 struct crc_table<TAccumulator, Accumulator_Bits, Chunk_Bits, Chunk_Mask, Polynomial, Reflect, 4U>
244 TAccumulator add(TAccumulator crc, uint8_t value)
const
246 static ETL_CONSTANT TAccumulator table[4U] =
254 if ETL_IF_CONSTEXPR(Reflect)
256 crc = crc_update_chunk<TAccumulator, Accumulator_Bits, Chunk_Bits, Chunk_Mask, Reflect>(crc, value, table);
257 crc = crc_update_chunk<TAccumulator, Accumulator_Bits, Chunk_Bits, Chunk_Mask, Reflect>(crc, (value >> (Chunk_Bits * 1U)), table);
258 crc = crc_update_chunk<TAccumulator, Accumulator_Bits, Chunk_Bits, Chunk_Mask, Reflect>(crc, (value >> (Chunk_Bits * 2U)), table);
259 crc = crc_update_chunk<TAccumulator, Accumulator_Bits, Chunk_Bits, Chunk_Mask, Reflect>(crc, (value >> (Chunk_Bits * 3U)), table);
263 crc = crc_update_chunk<TAccumulator, Accumulator_Bits, Chunk_Bits, Chunk_Mask, Reflect>(crc, (value >> (Chunk_Bits * 3U)), table);
264 crc = crc_update_chunk<TAccumulator, Accumulator_Bits, Chunk_Bits, Chunk_Mask, Reflect>(crc, (value >> (Chunk_Bits * 2U)), table);
265 crc = crc_update_chunk<TAccumulator, Accumulator_Bits, Chunk_Bits, Chunk_Mask, Reflect>(crc, (value >> (Chunk_Bits * 1U)), table);
266 crc = crc_update_chunk<TAccumulator, Accumulator_Bits, Chunk_Bits, Chunk_Mask, Reflect>(crc, value, table);
275 template <
typename TAccumulator,
size_t Accumulator_Bits,
size_t Chunk_Bits, u
int8_t Chunk_Mask, TAccumulator Polynomial,
bool Reflect>
276 struct crc_table<TAccumulator, Accumulator_Bits, Chunk_Bits, Chunk_Mask, Polynomial, Reflect, 16U>
279 TAccumulator add(TAccumulator crc, uint8_t value)
const
281 static ETL_CONSTANT TAccumulator table[16U] =
301 if ETL_IF_CONSTEXPR(Reflect)
303 crc = crc_update_chunk<TAccumulator, Accumulator_Bits, Chunk_Bits, Chunk_Mask, Reflect>(crc, value, table);
304 crc = crc_update_chunk<TAccumulator, Accumulator_Bits, Chunk_Bits, Chunk_Mask, Reflect>(crc, value >> Chunk_Bits, table);
308 crc = crc_update_chunk<TAccumulator, Accumulator_Bits, Chunk_Bits, Chunk_Mask, Reflect>(crc, value >> Chunk_Bits, table);
309 crc = crc_update_chunk<TAccumulator, Accumulator_Bits, Chunk_Bits, Chunk_Mask, Reflect>(crc, value, table);
318 template <
typename TAccumulator,
size_t Accumulator_Bits,
size_t Chunk_Bits, u
int8_t Chunk_Mask, TAccumulator Polynomial,
bool Reflect>
319 struct crc_table<TAccumulator, Accumulator_Bits, Chunk_Bits, Chunk_Mask, Polynomial, Reflect, 256U>
322 TAccumulator add(TAccumulator crc, uint8_t value)
const
324 static ETL_CONSTANT TAccumulator table[256U] =
584 crc = crc_update_chunk<TAccumulator, Accumulator_Bits, Chunk_Bits, Chunk_Mask, Reflect>(crc, value, table);
593 template <
typename TCrcParameters,
size_t Table_Size>
598 template <
typename TCrcParameters>
600 TCrcParameters::Accumulator_Bits,
603 TCrcParameters::Polynomial,
604 TCrcParameters::Reflect,
607 typedef typename TCrcParameters::accumulator_type accumulator_type;
608 typedef accumulator_type value_type;
611 ETL_CONSTEXPR accumulator_type initial()
const
614 : TCrcParameters::Initial;
618 accumulator_type
final(accumulator_type crc)
const
620 return crc ^ TCrcParameters::Xor_Out;
626 template <
typename TCrcParameters>
628 TCrcParameters::Accumulator_Bits,
631 TCrcParameters::Polynomial,
632 TCrcParameters::Reflect,
635 typedef typename TCrcParameters::accumulator_type accumulator_type;
636 typedef accumulator_type value_type;
639 ETL_CONSTEXPR accumulator_type initial()
const
642 : TCrcParameters::Initial;
646 accumulator_type
final(accumulator_type crc)
const
648 return crc ^ TCrcParameters::Xor_Out;
654 template <
typename TCrcParameters>
656 TCrcParameters::Accumulator_Bits,
659 TCrcParameters::Polynomial,
660 TCrcParameters::Reflect,
663 typedef typename TCrcParameters::accumulator_type accumulator_type;
664 typedef accumulator_type value_type;
667 ETL_CONSTEXPR accumulator_type initial()
const
670 : TCrcParameters::Initial;
674 accumulator_type
final(accumulator_type crc)
const
676 return crc ^ TCrcParameters::Xor_Out;
684 template <
typename TCrcParameters,
size_t Table_Size>
689 ETL_STATIC_ASSERT((Table_Size == 4U) || (Table_Size == 16U) || (Table_Size == 256U),
"Table size must be 4, 16 or 256");
704 template<
typename TIterator>
Basic parameterised CRC type.
Definition: crc_implementation.h:686
crc_type(TIterator begin, const TIterator end)
Definition: crc_implementation.h:705
crc_type()
Default constructor.
Definition: crc_implementation.h:694
CRC Partial Table Entry.
Definition: crc_implementation.h:57
CRC Table Entry.
Definition: crc_implementation.h:77
void reset()
Resets the FCS to the initial state.
Definition: frame_check_sequence.h:134
void add(TIterator begin, const TIterator end)
Definition: frame_check_sequence.h:145
Definition: frame_check_sequence.h:100
enable_if
Definition: type_traits_generator.h:1191
bitset_ext
Definition: absolute.h:38
ETL_CONSTEXPR TContainer::iterator begin(TContainer &container)
Definition: iterator.h:931
ETL_CONSTEXPR TContainer::iterator end(TContainer &container)
Definition: iterator.h:961
Definition: crc_implementation.h:594
Definition: crc_implementation.h:236