Embedded Template Library 1.0
Loading...
Searching...
No Matches
crc_implementation.h
Go to the documentation of this file.
1
2
3/******************************************************************************
4The MIT License(MIT)
5
6Embedded Template Library.
7https://github.com/ETLCPP/etl
8https://www.etlcpp.com
9
10Copyright(c) 2021 John Wellbelove
11
12Permission is hereby granted, free of charge, to any person obtaining a copy
13of this software and associated documentation files(the "Software"), to deal
14in the Software without restriction, including without limitation the rights
15to use, copy, modify, merge, publish, distribute, sublicense, and / or sell
16copies of the Software, and to permit persons to whom the Software is
17furnished to do so, subject to the following conditions :
18
19The above copyright notice and this permission notice shall be included in all
20copies or substantial portions of the Software.
21
22THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
23IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
24FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE
25AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
26LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
27OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
28SOFTWARE.
29******************************************************************************/
30
31#ifndef ETL_CRC_IMPLEMENTATION_INCLUDED
32#define ETL_CRC_IMPLEMENTATION_INCLUDED
33
34#include "../platform.h"
35#include "../frame_check_sequence.h"
36#include "../static_assert.h"
37#include "../binary.h"
38#include "../type_traits.h"
39
40#include "stdint.h"
41
42#include "crc_parameters.h"
43
44#if defined(ETL_COMPILER_KEIL)
45#pragma diag_suppress 1300
46#endif
47
48namespace etl
49{
50 namespace private_crc
51 {
52 //*****************************************************************************
54 //*****************************************************************************
55 template <typename TAccumulator, size_t Accumulator_Bits, TAccumulator Polynomial, bool Reflect, TAccumulator Entry>
57 {
58 private:
59
60 static ETL_CONSTANT bool Do_Poly = Reflect ? (Entry & TAccumulator(1U)) != 0U
61 : (Entry & (TAccumulator(1U) << (Accumulator_Bits - 1U))) != 0U;
62
63 public:
64
65 static ETL_CONSTANT TAccumulator value = Reflect ? TAccumulator(Do_Poly ? (Entry >> 1U) ^ etl::reverse_bits_const<TAccumulator, Polynomial>::value : (Entry >> 1U))
66 : TAccumulator(Do_Poly ? (Entry << 1U) ^ Polynomial : (Entry << 1U));
67 };
68
69 template <typename TAccumulator, size_t Accumulator_Bits, TAccumulator Polynomial, bool Reflect, TAccumulator Entry>
71
72 //*****************************************************************************
74 //*****************************************************************************
75 template <typename TAccumulator, size_t Accumulator_Bits, TAccumulator Polynomial, bool Reflect, size_t Index, uint8_t Chunk_Bits>
77 {
78 ETL_STATIC_ASSERT((Chunk_Bits == 2U) || (Chunk_Bits == 4U) || (Chunk_Bits == 8U), "Chunk bits must be 2, 4 or 8");
79 };
80
81 //*********************************
82 // Chunk bit size of 2.
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>
85 {
86 public:
87
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);
90
91 static ETL_CONSTANT TAccumulator value = crc_partial_table_entry<TAccumulator, Accumulator_Bits, Polynomial, Reflect,
93 };
94
95 template <typename TAccumulator, size_t Accumulator_Bits, TAccumulator Polynomial, bool Reflect, size_t Index>
97
98 template <typename TAccumulator, size_t Accumulator_Bits, TAccumulator Polynomial, bool Reflect, size_t Index>
100
101 template <typename TAccumulator, size_t Accumulator_Bits, TAccumulator Polynomial, bool Reflect, size_t Index>
103
104 //*********************************
105 // Chunk bit size of 4.
106 template <typename TAccumulator, size_t Accumulator_Bits, TAccumulator Polynomial, bool Reflect, size_t Index>
107 class crc_table_entry<TAccumulator, Accumulator_Bits, Polynomial, Reflect, Index, 4U>
108 {
109 public:
110
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);
113
114 static ETL_CONSTANT TAccumulator value = crc_partial_table_entry<TAccumulator, Accumulator_Bits, Polynomial, Reflect,
115 crc_partial_table_entry<TAccumulator, Accumulator_Bits, Polynomial, Reflect,
116 crc_partial_table_entry<TAccumulator, Accumulator_Bits, Polynomial, Reflect,
118 };
119
120 template <typename TAccumulator, size_t Accumulator_Bits, TAccumulator Polynomial, bool Reflect, size_t Index>
122
123 template <typename TAccumulator, size_t Accumulator_Bits, TAccumulator Polynomial, bool Reflect, size_t Index>
125
126 template <typename TAccumulator, size_t Accumulator_Bits, TAccumulator Polynomial, bool Reflect, size_t Index>
128
129 //*********************************
130 // Chunk bit size of 8.
131 template <typename TAccumulator, size_t Accumulator_Bits, TAccumulator Polynomial, bool Reflect, size_t Index>
132 class crc_table_entry<TAccumulator, Accumulator_Bits, Polynomial, Reflect, Index, 8U>
133 {
134 public:
135
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);
138
139 static ETL_CONSTANT TAccumulator value = crc_partial_table_entry<TAccumulator, Accumulator_Bits, Polynomial, Reflect,
140 crc_partial_table_entry<TAccumulator, Accumulator_Bits, Polynomial, Reflect,
141 crc_partial_table_entry<TAccumulator, Accumulator_Bits, Polynomial, Reflect,
142 crc_partial_table_entry<TAccumulator, Accumulator_Bits, Polynomial, Reflect,
143 crc_partial_table_entry<TAccumulator, Accumulator_Bits, Polynomial, Reflect,
144 crc_partial_table_entry<TAccumulator, Accumulator_Bits, Polynomial, Reflect,
145 crc_partial_table_entry<TAccumulator, Accumulator_Bits, Polynomial, Reflect,
146 crc_partial_table_entry<TAccumulator, Accumulator_Bits, Polynomial, Reflect, Entry>::value>::value>::value>::value>::value>::value>::value>::value;
147 };
148
149 template <typename TAccumulator, size_t Accumulator_Bits, TAccumulator Polynomial, bool Reflect, size_t Index>
151
152 template <typename TAccumulator, size_t Accumulator_Bits, TAccumulator Polynomial, bool Reflect, size_t Index>
154
155 template <typename TAccumulator, size_t Accumulator_Bits, TAccumulator Polynomial, bool Reflect, size_t Index>
157
158 //*****************************************************************************
160 //*****************************************************************************
161
162 //*********************************
163 // Accumulator_Bits > Chunk_Bits
164 // Not Reflected
165 template <typename TAccumulator, size_t Accumulator_Bits, size_t Chunk_Bits, uint8_t Chunk_Mask, bool Reflect>
166 static ETL_CONSTEXPR14
167 typename etl::enable_if<(Accumulator_Bits > Chunk_Bits) && !Reflect, TAccumulator>::type
168 crc_update_chunk(TAccumulator crc, uint8_t value, const TAccumulator table[])
169 {
170 value &= Chunk_Mask;
171
172 uint8_t index = (crc >> (Accumulator_Bits - Chunk_Bits)) ^ value;
173
174 crc <<= Chunk_Bits;
175 crc ^= table[index];
176
177 return crc;
178 }
179
180 //*********************************
181 // Accumulator_Bits > Chunk_Bits
182 // Reflected
183 template <typename TAccumulator, size_t Accumulator_Bits, size_t Chunk_Bits, uint8_t Chunk_Mask, bool Reflect>
184 static ETL_CONSTEXPR14
185 typename etl::enable_if<(Accumulator_Bits > Chunk_Bits) && Reflect, TAccumulator>::type
186 crc_update_chunk(TAccumulator crc, uint8_t value, const TAccumulator table[])
187 {
188 value &= Chunk_Mask;
189
190 uint8_t index = (crc & Chunk_Mask) ^ value;
191
192 crc >>= Chunk_Bits;
193 crc ^= table[index];
194
195 return crc;
196 }
197
198 //*********************************
199 // Accumulator_Bits == Chunk_Bits
200 // Not Reflected
201 template <typename TAccumulator, size_t Accumulator_Bits, size_t Chunk_Bits, uint8_t Chunk_Mask, bool Reflect>
202 static ETL_CONSTEXPR14
203 typename etl::enable_if<(Accumulator_Bits == Chunk_Bits) && !Reflect, TAccumulator>::type
204 crc_update_chunk(TAccumulator crc, uint8_t value, const TAccumulator table[])
205 {
206 value &= Chunk_Mask;
207
208 uint8_t index = (crc >> (Accumulator_Bits - Chunk_Bits)) ^ value;
209
210 crc = table[index];
211
212 return crc;
213 }
214
215 //*********************************
216 // Accumulator_Bits == Chunk_Bits
217 // Reflected
218 template <typename TAccumulator, size_t Accumulator_Bits, size_t Chunk_Bits, uint8_t Chunk_Mask, bool Reflect>
219 static ETL_CONSTEXPR14
220 typename etl::enable_if<(Accumulator_Bits == Chunk_Bits) && Reflect, TAccumulator>::type
221 crc_update_chunk(TAccumulator crc, uint8_t value, const TAccumulator table[])
222 {
223 value &= Chunk_Mask;
224
225 uint8_t index = (crc & Chunk_Mask) ^ value;
226
227 crc = table[index];
228
229 return crc;
230 }
231
232 //*****************************************************************************
233 // CRC Tables.
234 //*****************************************************************************
235 template <typename TAccumulator, size_t Accumulator_Bits, size_t Chunk_Bits, uint8_t Chunk_Mask, TAccumulator Polynomial, bool Reflect, size_t Table_Size>
236 struct crc_table;
237
238 //*********************************
239 // Table size of 4.
240 template <typename TAccumulator, size_t Accumulator_Bits, size_t Chunk_Bits, uint8_t Chunk_Mask, TAccumulator Polynomial, bool Reflect>
241 struct crc_table<TAccumulator, Accumulator_Bits, Chunk_Bits, Chunk_Mask, Polynomial, Reflect, 4U>
242 {
243 //*************************************************************************
244#if !ETL_USING_CPP11
245 TAccumulator add(TAccumulator crc, uint8_t value) const
246 {
247#endif
248 static ETL_CONSTANT TAccumulator table[4U] =
249 {
254 };
255#if ETL_USING_CPP11
256 ETL_CONSTEXPR14 TAccumulator add(TAccumulator crc, uint8_t value) const
257 {
258#endif
259 if ETL_IF_CONSTEXPR(Reflect)
260 {
265 }
266 else
267 {
272 }
273
274 return crc;
275 }
276 };
277#if ETL_USING_CPP11
278 template <typename TAccumulator, size_t Accumulator_Bits, size_t Chunk_Bits, uint8_t Chunk_Mask, TAccumulator Polynomial, bool Reflect>
280#endif
281
282 //*********************************
283 // Table size of 16.
284 template <typename TAccumulator, size_t Accumulator_Bits, size_t Chunk_Bits, uint8_t Chunk_Mask, TAccumulator Polynomial, bool Reflect>
285 struct crc_table<TAccumulator, Accumulator_Bits, Chunk_Bits, Chunk_Mask, Polynomial, Reflect, 16U>
286 {
287 //*************************************************************************
288#if !ETL_USING_CPP11
289 TAccumulator add(TAccumulator crc, uint8_t value) const
290 {
291#endif
292 static ETL_CONSTANT TAccumulator table[16U] =
293 {
310 };
311#if ETL_USING_CPP11
312 ETL_CONSTEXPR14 TAccumulator add(TAccumulator crc, uint8_t value) const
313 {
314#endif
315 if ETL_IF_CONSTEXPR(Reflect)
316 {
319 }
320 else
321 {
324 }
325
326 return crc;
327 }
328 };
329#if ETL_USING_CPP11
330 template <typename TAccumulator, size_t Accumulator_Bits, size_t Chunk_Bits, uint8_t Chunk_Mask, TAccumulator Polynomial, bool Reflect>
332#endif
333
334 //*********************************
335 // Table size of 256.
336 template <typename TAccumulator, size_t Accumulator_Bits, size_t Chunk_Bits, uint8_t Chunk_Mask, TAccumulator Polynomial, bool Reflect>
337 struct crc_table<TAccumulator, Accumulator_Bits, Chunk_Bits, Chunk_Mask, Polynomial, Reflect, 256U>
338 {
339 //*************************************************************************
340#if !ETL_USING_CPP11
341 TAccumulator add(TAccumulator crc, uint8_t value) const
342 {
343#endif
344 static ETL_CONSTANT TAccumulator table[256U]=
345 {
602 };
603#if ETL_USING_CPP11
604 ETL_CONSTEXPR14 TAccumulator add(TAccumulator crc, uint8_t value) const
605 {
606#endif
607
609
610 return crc;
611 }
612 };
613#if ETL_USING_CPP11
614 template <typename TAccumulator, size_t Accumulator_Bits, size_t Chunk_Bits, uint8_t Chunk_Mask, TAccumulator Polynomial, bool Reflect>
616#endif
617 //*****************************************************************************
618 // CRC Policies.
619 //*****************************************************************************
620 template <typename TCrcParameters, size_t Table_Size>
622
623 //*********************************
624 // Policy for 256 entry table.
625 template <typename TCrcParameters>
626 struct crc_policy<TCrcParameters, 256U> : public crc_table<typename TCrcParameters::accumulator_type,
627 TCrcParameters::Accumulator_Bits,
628 8U,
629 0xFFU,
630 TCrcParameters::Polynomial,
631 TCrcParameters::Reflect,
632 256U>
633 {
634 typedef typename TCrcParameters::accumulator_type accumulator_type;
635 typedef accumulator_type value_type;
636
637 //*************************************************************************
638 ETL_CONSTEXPR accumulator_type initial() const
639 {
641 : TCrcParameters::Initial;
642 }
643
644 //*************************************************************************
645 ETL_CONSTEXPR accumulator_type final(accumulator_type crc) const
646 {
647 return crc ^ TCrcParameters::Xor_Out;
648 }
649 };
650
651 //*********************************
652 // Policy for 16 entry table.
653 template <typename TCrcParameters>
654 struct crc_policy<TCrcParameters, 16U> : public crc_table<typename TCrcParameters::accumulator_type,
655 TCrcParameters::Accumulator_Bits,
656 4U,
657 0x0FU,
658 TCrcParameters::Polynomial,
659 TCrcParameters::Reflect,
660 16U>
661 {
662 typedef typename TCrcParameters::accumulator_type accumulator_type;
663 typedef accumulator_type value_type;
664
665 //*************************************************************************
666 ETL_CONSTEXPR accumulator_type initial() const
667 {
669 : TCrcParameters::Initial;
670 }
671
672 //*************************************************************************
673 ETL_CONSTEXPR accumulator_type final(accumulator_type crc) const
674 {
675 return crc ^ TCrcParameters::Xor_Out;
676 }
677 };
678
679 //*********************************
680 // Policy for 4 entry table.
681 template <typename TCrcParameters>
682 struct crc_policy<TCrcParameters, 4U> : public crc_table<typename TCrcParameters::accumulator_type,
683 TCrcParameters::Accumulator_Bits,
684 2U,
685 0x03U,
686 TCrcParameters::Polynomial,
687 TCrcParameters::Reflect,
688 4U>
689 {
690 typedef typename TCrcParameters::accumulator_type accumulator_type;
691 typedef accumulator_type value_type;
692
693 //*************************************************************************
694 ETL_CONSTEXPR accumulator_type initial() const
695 {
697 : TCrcParameters::Initial;
698 }
699
700 //*************************************************************************
701 ETL_CONSTEXPR accumulator_type final(accumulator_type crc) const
702 {
703 return crc ^ TCrcParameters::Xor_Out;
704 }
705 };
706 }
707
708 //*****************************************************************************
710 //*****************************************************************************
711 template <typename TCrcParameters, size_t Table_Size>
712 class crc_type : public etl::frame_check_sequence<private_crc::crc_policy<TCrcParameters, Table_Size> >
713 {
714 public:
715
716 ETL_STATIC_ASSERT((Table_Size == 4U) || (Table_Size == 16U) || (Table_Size == 256U), "Table size must be 4, 16 or 256");
717
718 //*************************************************************************
720 //*************************************************************************
721 ETL_CONSTEXPR14 crc_type()
722 {
723 this->reset();
724 }
725
726 //*************************************************************************
730 //*************************************************************************
731 template<typename TIterator>
732 ETL_CONSTEXPR14 crc_type(TIterator begin, const TIterator end)
733 {
734 this->reset();
735 this->add(begin, end);
736 }
737 };
738}
739
740#endif
Basic parameterised CRC type.
Definition crc_implementation.h:713
ETL_CONSTEXPR14 crc_type(TIterator begin, const TIterator end)
Definition crc_implementation.h:732
ETL_CONSTEXPR14 crc_type()
Default constructor.
Definition crc_implementation.h:721
CRC Partial Table Entry.
Definition crc_implementation.h:57
CRC Table Entry.
Definition crc_implementation.h:77
Definition binary.h:480
Definition frame_check_sequence.h:98
enable_if
Definition type_traits_generator.h:1186
bitset_ext
Definition absolute.h:38
ETL_CONSTEXPR TContainer::iterator begin(TContainer &container)
Definition iterator.h:962
ETL_CONSTEXPR TContainer::iterator end(TContainer &container)
Definition iterator.h:992
pair holds two objects of arbitrary type
Definition utility.h:164
Definition crc_implementation.h:621
Definition crc_implementation.h:236