CRC internal type more suitable for ARM.

This commit is contained in:
Jared Boone 2016-02-18 21:31:51 -08:00
parent 00fb25f143
commit 1e0d34c98b
4 changed files with 35 additions and 25 deletions

View File

@ -105,8 +105,8 @@ size_t Packet::crc_valid_length() const {
}
uint32_t checksum = 0;
CRC<uint8_t> crc_72 { 0x01, 0x00 };
CRC<uint8_t> crc_80 { 0x01, 0x00 };
CRC<8> crc_72 { 0x01, 0x00 };
CRC<8> crc_80 { 0x01, 0x00 };
for(size_t i=0; i<bytes.size(); i++) {
const uint32_t byte_mask = 1 << i;

View File

@ -185,7 +185,7 @@ Longitude Packet::longitude(const size_t start_bit) const {
bool Packet::crc_ok() const {
CRCReader field_crc { packet_ };
CRC<uint16_t> ais_fcs { 0x1021, 0xffff, 0xffff };
CRC<16> ais_fcs { 0x1021, 0xffff, 0xffff };
for(size_t i=0; i<data_length(); i+=8) {
ais_fcs.process_byte(field_crc.read(i, 8));

View File

@ -24,6 +24,7 @@
#include <cstddef>
#include <cstdint>
#include <limits>
#include <array>
/* Inspired by
@ -39,13 +40,15 @@
*
*/
template<typename T, bool RevIn = false, bool RevOut = false>
template<size_t Width, bool RevIn = false, bool RevOut = false>
class CRC {
public:
using value_type = uint32_t;
constexpr CRC(
const T truncated_polynomial,
const T initial_remainder = 0,
const T final_xor_value = 0
const value_type truncated_polynomial,
const value_type initial_remainder = 0,
const value_type final_xor_value = 0
) : truncated_polynomial { truncated_polynomial },
initial_remainder { initial_remainder },
final_xor_value { final_xor_value },
@ -53,11 +56,11 @@ public:
{
}
T get_initial_remainder() const {
value_type get_initial_remainder() const {
return initial_remainder;
}
void reset(T new_initial_remainder) {
void reset(value_type new_initial_remainder) {
remainder = new_initial_remainder;
}
@ -74,14 +77,17 @@ public:
}
}
void process_bits(uint8_t bits, size_t bit_count) {
bits <<= (8 - bit_count);
void process_bits(value_type bits, size_t bit_count) {
constexpr auto digits = std::numeric_limits<value_type>::digits;
constexpr auto mask = static_cast<value_type>(1) << (digits - 1);
bits <<= (std::numeric_limits<value_type>::digits - bit_count);
for(size_t i=bit_count; i>0; --i, bits <<= 1) {
process_bit(static_cast<bool>(bits & 0x80));
process_bit(static_cast<bool>(bits & mask));
}
}
void process_bits_lsb_first(uint8_t bits, size_t bit_count) {
void process_bits_lsb_first(value_type bits, size_t bit_count) {
for(size_t i=bit_count; i>0; --i, bits >>= 1) {
process_bit(static_cast<bool>(bits & 0x01));
}
@ -106,26 +112,30 @@ public:
process_bytes(data.data(), data.size());
}
T checksum() const {
return (RevOut ? reflect(remainder) : remainder) ^ final_xor_value;
value_type checksum() const {
return ((RevOut ? reflect(remainder) : remainder) ^ final_xor_value) & mask();
}
private:
const T truncated_polynomial;
const T initial_remainder;
const T final_xor_value;
T remainder;
const value_type truncated_polynomial;
const value_type initial_remainder;
const value_type final_xor_value;
value_type remainder;
static constexpr size_t width() {
return 8 * sizeof(T);
return Width;
}
static constexpr T top_bit() {
static constexpr value_type top_bit() {
return 1U << (width() - 1);
}
static T reflect(T x) {
T reflection = 0;
static constexpr value_type mask() {
return (~(~(0UL) << width()));
}
static value_type reflect(value_type x) {
value_type reflection = 0;
for(size_t i=0; i<width(); ++i) {
reflection <<= 1;
reflection |= (x & 1);

View File

@ -76,7 +76,7 @@ bool Packet::crc_ok() const {
}
bool Packet::crc_ok_scm() const {
CRC<uint16_t> ert_bch { 0x6f63 };
CRC<16> ert_bch { 0x6f63 };
size_t start_bit = 5;
ert_bch.process_byte(reader_.read(0, start_bit));
for(size_t i=start_bit; i<length(); i+=8) {
@ -86,7 +86,7 @@ bool Packet::crc_ok_scm() const {
}
bool Packet::crc_ok_idm() const {
CRC<uint16_t> ert_crc_ccitt { 0x1021, 0xffff, 0x1d0f };
CRC<16> ert_crc_ccitt { 0x1021, 0xffff, 0x1d0f };
for(size_t i=0; i<length(); i+=8) {
ert_crc_ccitt.process_byte(reader_.read(i, 8));
}