Skip to content

Commit

Permalink
Merge branch 'pull-request/#1016-Allow-compile-time-CRC-calculation' …
Browse files Browse the repository at this point in the history
…into development
  • Loading branch information
jwellbelove committed Jan 24, 2025
2 parents a0668ff + b3f7d82 commit 42dae97
Show file tree
Hide file tree
Showing 52 changed files with 1,627 additions and 26 deletions.
10 changes: 5 additions & 5 deletions include/etl/crc1.h
Original file line number Diff line number Diff line change
Expand Up @@ -52,19 +52,19 @@ namespace etl
};

//*********************************
value_type initial() const
ETL_CONSTEXPR14 value_type initial() const
{
return even_parity;
}

//*********************************
uint8_t add(int parity, uint8_t value) const
ETL_CONSTEXPR14 uint8_t add(int parity, uint8_t value) const
{
return parity ^ etl::parity(value);
}

//*********************************
uint8_t final(uint8_t parity) const
ETL_CONSTEXPR14 uint8_t final(uint8_t parity) const
{
return parity;
}
Expand All @@ -83,7 +83,7 @@ namespace etl
//*************************************************************************
/// Default constructor.
//*************************************************************************
crc1()
ETL_CONSTEXPR14 crc1()
{
this->reset();
}
Expand All @@ -94,7 +94,7 @@ namespace etl
/// \param end End of the range.
//*************************************************************************
template<typename TIterator>
crc1(TIterator begin, const TIterator end)
ETL_CONSTEXPR14 crc1(TIterator begin, const TIterator end)
{
this->reset();
this->add(begin, end);
Expand Down
17 changes: 9 additions & 8 deletions include/etl/frame_check_sequence.h
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,8 @@ namespace etl
//*************************************************************************
/// Default constructor.
//*************************************************************************
frame_check_sequence()
ETL_CONSTEXPR14 frame_check_sequence()
: frame_check()
{
reset();
}
Expand All @@ -118,7 +119,7 @@ namespace etl
/// \param end End of the range.
//*************************************************************************
template<typename TIterator>
frame_check_sequence(TIterator begin, const TIterator end)
ETL_CONSTEXPR14 frame_check_sequence(TIterator begin, const TIterator end) : frame_check()
{
ETL_STATIC_ASSERT(sizeof(typename etl::iterator_traits<TIterator>::value_type) == 1, "Type not supported");

Expand All @@ -129,7 +130,7 @@ namespace etl
//*************************************************************************
/// Resets the FCS to the initial state.
//*************************************************************************
void reset()
ETL_CONSTEXPR14 void reset()
{
frame_check = policy.initial();
}
Expand All @@ -140,7 +141,7 @@ namespace etl
/// \param end
//*************************************************************************
template<typename TIterator>
void add(TIterator begin, const TIterator end)
ETL_CONSTEXPR14 void add(TIterator begin, const TIterator end)
{
ETL_STATIC_ASSERT(sizeof(typename etl::iterator_traits<TIterator>::value_type) == 1, "Type not supported");

Expand All @@ -154,31 +155,31 @@ namespace etl
//*************************************************************************
/// \param value The uint8_t to add to the FCS.
//*************************************************************************
void add(uint8_t value_)
ETL_CONSTEXPR14 void add(uint8_t value_)
{
frame_check = policy.add(frame_check, value_);
}

//*************************************************************************
/// Gets the FCS value.
//*************************************************************************
value_type value() const
ETL_CONSTEXPR14 value_type value() const
{
return policy.final(frame_check);
}

//*************************************************************************
/// Conversion operator to value_type.
//*************************************************************************
operator value_type () const
ETL_CONSTEXPR14 operator value_type () const
{
return policy.final(frame_check);
}

//*************************************************************************
/// Gets an add_insert_iterator for input.
//*************************************************************************
add_insert_iterator input()
ETL_CONSTEXPR14 add_insert_iterator input()
{
return add_insert_iterator(*this);
}
Expand Down
53 changes: 40 additions & 13 deletions include/etl/private/crc_implementation.h
Original file line number Diff line number Diff line change
Expand Up @@ -163,7 +163,7 @@ namespace etl
// Accumulator_Bits > Chunk_Bits
// Not Reflected
template <typename TAccumulator, size_t Accumulator_Bits, size_t Chunk_Bits, uint8_t Chunk_Mask, bool Reflect>
static
static ETL_CONSTEXPR14
typename etl::enable_if<(Accumulator_Bits > Chunk_Bits) && !Reflect, TAccumulator>::type
crc_update_chunk(TAccumulator crc, uint8_t value, const TAccumulator table[])
{
Expand All @@ -181,7 +181,7 @@ namespace etl
// Accumulator_Bits > Chunk_Bits
// Reflected
template <typename TAccumulator, size_t Accumulator_Bits, size_t Chunk_Bits, uint8_t Chunk_Mask, bool Reflect>
static
static ETL_CONSTEXPR14
typename etl::enable_if<(Accumulator_Bits > Chunk_Bits) && Reflect, TAccumulator>::type
crc_update_chunk(TAccumulator crc, uint8_t value, const TAccumulator table[])
{
Expand All @@ -199,7 +199,7 @@ namespace etl
// Accumulator_Bits == Chunk_Bits
// Not Reflected
template <typename TAccumulator, size_t Accumulator_Bits, size_t Chunk_Bits, uint8_t Chunk_Mask, bool Reflect>
static
static ETL_CONSTEXPR14
typename etl::enable_if<(Accumulator_Bits == Chunk_Bits) && !Reflect, TAccumulator>::type
crc_update_chunk(TAccumulator crc, uint8_t value, const TAccumulator table[])
{
Expand All @@ -216,7 +216,7 @@ namespace etl
// Accumulator_Bits == Chunk_Bits
// Reflected
template <typename TAccumulator, size_t Accumulator_Bits, size_t Chunk_Bits, uint8_t Chunk_Mask, bool Reflect>
static
static ETL_CONSTEXPR14
typename etl::enable_if<(Accumulator_Bits == Chunk_Bits) && Reflect, TAccumulator>::type
crc_update_chunk(TAccumulator crc, uint8_t value, const TAccumulator table[])
{
Expand All @@ -241,16 +241,21 @@ namespace etl
struct crc_table<TAccumulator, Accumulator_Bits, Chunk_Bits, Chunk_Mask, Polynomial, Reflect, 4U>
{
//*************************************************************************
#if !ETL_USING_CPP11
TAccumulator add(TAccumulator crc, uint8_t value) const
{
#endif
static ETL_CONSTANT TAccumulator table[4U] =
{
crc_table_entry<TAccumulator, Accumulator_Bits, Polynomial, Reflect, 0U, Chunk_Bits>::value,
crc_table_entry<TAccumulator, Accumulator_Bits, Polynomial, Reflect, 1U, Chunk_Bits>::value,
crc_table_entry<TAccumulator, Accumulator_Bits, Polynomial, Reflect, 2U, Chunk_Bits>::value,
crc_table_entry<TAccumulator, Accumulator_Bits, Polynomial, Reflect, 3U, Chunk_Bits>::value
};

#if ETL_USING_CPP11
ETL_CONSTEXPR14 TAccumulator add(TAccumulator crc, uint8_t value) const
{
#endif
if ETL_IF_CONSTEXPR(Reflect)
{
crc = crc_update_chunk<TAccumulator, Accumulator_Bits, Chunk_Bits, Chunk_Mask, Reflect>(crc, value, table);
Expand All @@ -269,15 +274,21 @@ namespace etl
return crc;
}
};
#if ETL_USING_CPP11
template <typename TAccumulator, size_t Accumulator_Bits, size_t Chunk_Bits, uint8_t Chunk_Mask, TAccumulator Polynomial, bool Reflect>
ETL_CONSTANT TAccumulator crc_table<TAccumulator, Accumulator_Bits, Chunk_Bits, Chunk_Mask, Polynomial, Reflect, 4U>::table[4U];
#endif

//*********************************
// Table size of 16.
template <typename TAccumulator, size_t Accumulator_Bits, size_t Chunk_Bits, uint8_t Chunk_Mask, TAccumulator Polynomial, bool Reflect>
struct crc_table<TAccumulator, Accumulator_Bits, Chunk_Bits, Chunk_Mask, Polynomial, Reflect, 16U>
{
//*************************************************************************
#if !ETL_USING_CPP11
TAccumulator add(TAccumulator crc, uint8_t value) const
{
#endif
static ETL_CONSTANT TAccumulator table[16U] =
{
crc_table_entry<TAccumulator, Accumulator_Bits, Polynomial, Reflect, 0U, Chunk_Bits>::value,
Expand All @@ -297,7 +308,10 @@ namespace etl
crc_table_entry<TAccumulator, Accumulator_Bits, Polynomial, Reflect, 14U, Chunk_Bits>::value,
crc_table_entry<TAccumulator, Accumulator_Bits, Polynomial, Reflect, 15U, Chunk_Bits>::value
};

#if ETL_USING_CPP11
ETL_CONSTEXPR14 TAccumulator add(TAccumulator crc, uint8_t value) const
{
#endif
if ETL_IF_CONSTEXPR(Reflect)
{
crc = crc_update_chunk<TAccumulator, Accumulator_Bits, Chunk_Bits, Chunk_Mask, Reflect>(crc, value, table);
Expand All @@ -312,16 +326,22 @@ namespace etl
return crc;
}
};
#if ETL_USING_CPP11
template <typename TAccumulator, size_t Accumulator_Bits, size_t Chunk_Bits, uint8_t Chunk_Mask, TAccumulator Polynomial, bool Reflect>
ETL_CONSTANT TAccumulator crc_table<TAccumulator, Accumulator_Bits, Chunk_Bits, Chunk_Mask, Polynomial, Reflect, 16U>::table[16U];
#endif

//*********************************
// Table size of 256.
template <typename TAccumulator, size_t Accumulator_Bits, size_t Chunk_Bits, uint8_t Chunk_Mask, TAccumulator Polynomial, bool Reflect>
struct crc_table<TAccumulator, Accumulator_Bits, Chunk_Bits, Chunk_Mask, Polynomial, Reflect, 256U>
{
//*************************************************************************
#if !ETL_USING_CPP11
TAccumulator add(TAccumulator crc, uint8_t value) const
{
static ETL_CONSTANT TAccumulator table[256U] =
#endif
static ETL_CONSTANT TAccumulator table[256U]=
{
crc_table_entry<TAccumulator, Accumulator_Bits, Polynomial, Reflect, 0U, Chunk_Bits>::value,
crc_table_entry<TAccumulator, Accumulator_Bits, Polynomial, Reflect, 1U, Chunk_Bits>::value,
Expand Down Expand Up @@ -580,13 +600,20 @@ namespace etl
crc_table_entry<TAccumulator, Accumulator_Bits, Polynomial, Reflect, 254U, Chunk_Bits>::value,
crc_table_entry<TAccumulator, Accumulator_Bits, Polynomial, Reflect, 255U, Chunk_Bits>::value
};
#if ETL_USING_CPP11
ETL_CONSTEXPR14 TAccumulator add(TAccumulator crc, uint8_t value) const
{
#endif

crc = crc_update_chunk<TAccumulator, Accumulator_Bits, Chunk_Bits, Chunk_Mask, Reflect>(crc, value, table);

return crc;
}
};

#if ETL_USING_CPP11
template <typename TAccumulator, size_t Accumulator_Bits, size_t Chunk_Bits, uint8_t Chunk_Mask, TAccumulator Polynomial, bool Reflect>
ETL_CONSTANT TAccumulator crc_table<TAccumulator, Accumulator_Bits, Chunk_Bits, Chunk_Mask, Polynomial, Reflect, 256U>::table[256U];
#endif
//*****************************************************************************
// CRC Policies.
//*****************************************************************************
Expand Down Expand Up @@ -615,7 +642,7 @@ namespace etl
}

//*************************************************************************
accumulator_type final(accumulator_type crc) const
ETL_CONSTEXPR accumulator_type final(accumulator_type crc) const
{
return crc ^ TCrcParameters::Xor_Out;
}
Expand Down Expand Up @@ -643,7 +670,7 @@ namespace etl
}

//*************************************************************************
accumulator_type final(accumulator_type crc) const
ETL_CONSTEXPR accumulator_type final(accumulator_type crc) const
{
return crc ^ TCrcParameters::Xor_Out;
}
Expand Down Expand Up @@ -671,7 +698,7 @@ namespace etl
}

//*************************************************************************
accumulator_type final(accumulator_type crc) const
ETL_CONSTEXPR accumulator_type final(accumulator_type crc) const
{
return crc ^ TCrcParameters::Xor_Out;
}
Expand All @@ -691,7 +718,7 @@ namespace etl
//*************************************************************************
/// Default constructor.
//*************************************************************************
crc_type()
ETL_CONSTEXPR14 crc_type()
{
this->reset();
}
Expand All @@ -702,7 +729,7 @@ namespace etl
/// \param end End of the range.
//*************************************************************************
template<typename TIterator>
crc_type(TIterator begin, const TIterator end)
ETL_CONSTEXPR14 crc_type(TIterator begin, const TIterator end)
{
this->reset();
this->add(begin, end);
Expand Down
11 changes: 11 additions & 0 deletions test/test_crc1.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,17 @@ namespace
CHECK_EQUAL(calculate_parity(data.begin(), data.end()), int(crc));
}

#if ETL_USING_CPP14
//*************************************************************************
TEST(test_crc1_constructor_constexpr)
{
constexpr char data[] = "123456789";
constexpr uint8_t crc = etl::crc1(data, data + 9);

CHECK_EQUAL(calculate_parity(data, data + 9), int(crc));
}
#endif

//*************************************************************************
TEST(test_crc1_add_values)
{
Expand Down
22 changes: 22 additions & 0 deletions test/test_crc16.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,17 @@ namespace
CHECK_EQUAL(0xBB3DU, crc);
}

#if ETL_USING_CPP14
//*************************************************************************
TEST(test_crc16_16_constexpr)
{
constexpr char data[] = "123456789";
constexpr uint16_t crc = etl::crc16_t16(data, data + 9);

CHECK_EQUAL(0xBB3DU, crc);
}
#endif

//*************************************************************************
TEST(test_crc16_16_add_values)
{
Expand Down Expand Up @@ -199,6 +210,17 @@ namespace
CHECK_EQUAL(0xBB3DU, crc);
}

#if ETL_USING_CPP14
//*************************************************************************
TEST(test_crc16_4_constexpr)
{
constexpr char data[] = "123456789";
constexpr uint16_t crc = etl::crc16_t4(data, data + 9);

CHECK_EQUAL(0xBB3DU, crc);
}
#endif

//*************************************************************************
TEST(test_crc16_4_add_values)
{
Expand Down
Loading

0 comments on commit 42dae97

Please sign in to comment.