mirror of
https://github.com/portapack-mayhem/mayhem-firmware.git
synced 2025-05-02 13:10:46 +00:00
Clean up CRC class/interface, make more like boost::crc_basic.
This commit is contained in:
parent
c38beb70e5
commit
7cded79b59
@ -132,23 +132,18 @@ struct PacketTooLong {
|
|||||||
|
|
||||||
struct CRCCheck {
|
struct CRCCheck {
|
||||||
bool operator()(const ::Packet& packet) {
|
bool operator()(const ::Packet& packet) {
|
||||||
|
const size_t fcs_length = 16;
|
||||||
const size_t data_and_fcs_length = packet.size() - 7;
|
const size_t data_and_fcs_length = packet.size() - 7;
|
||||||
const size_t data_length = data_and_fcs_length - 16;
|
const size_t data_length = data_and_fcs_length - fcs_length;
|
||||||
|
|
||||||
CRCFieldReader field_crc { packet };
|
CRCFieldReader field_crc { packet };
|
||||||
CRC<uint16_t> ais_fcs { 0x1021 };
|
CRC<uint16_t> ais_fcs { 0x1021, 0xffff, 0xffff };
|
||||||
|
|
||||||
uint16_t crc_calculated = 0xffff;
|
for(size_t i=0; i<data_length; i+=8) {
|
||||||
|
ais_fcs.process_byte(field_crc.read(i, 8));
|
||||||
for(size_t i=0; i<data_length + 16; i+=8) {
|
|
||||||
if( i == data_length ) {
|
|
||||||
crc_calculated ^= 0xffff;
|
|
||||||
}
|
|
||||||
const uint8_t byte = field_crc.read(i, 8);
|
|
||||||
crc_calculated = ais_fcs.calculate_byte(crc_calculated, byte);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return crc_calculated == 0x0000;
|
return ais_fcs.checksum() == field_crc.read(data_length, fcs_length);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -87,22 +87,19 @@ bool Packet::crc_ok() const {
|
|||||||
bool Packet::crc_ok_scm() const {
|
bool Packet::crc_ok_scm() const {
|
||||||
CRC<uint16_t> ert_bch { 0x6f63 };
|
CRC<uint16_t> ert_bch { 0x6f63 };
|
||||||
size_t start_bit = 5;
|
size_t start_bit = 5;
|
||||||
auto crc_calculated = ert_bch.calculate_byte(0x0000, reader_.read(0, start_bit));
|
ert_bch.process_byte(reader_.read(0, start_bit));
|
||||||
for(size_t i=start_bit; i<length(); i+=8) {
|
for(size_t i=start_bit; i<length(); i+=8) {
|
||||||
const uint8_t byte = reader_.read(i, 8);
|
ert_bch.process_byte(reader_.read(i, 8));
|
||||||
crc_calculated = ert_bch.calculate_byte(crc_calculated, byte);
|
|
||||||
}
|
}
|
||||||
return crc_calculated == 0x0000;
|
return ert_bch.checksum() == 0x0000;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Packet::crc_ok_idm() const {
|
bool Packet::crc_ok_idm() const {
|
||||||
CRC<uint16_t> ert_crc_ccitt { 0x1021 };
|
CRC<uint16_t> ert_crc_ccitt { 0x1021, 0xffff, 0x1d0f };
|
||||||
uint16_t crc_calculated = 0xffff;
|
|
||||||
for(size_t i=0; i<length(); i+=8) {
|
for(size_t i=0; i<length(); i+=8) {
|
||||||
const uint8_t byte = reader_.read(i, 8);
|
ert_crc_ccitt.process_byte(reader_.read(i, 8));
|
||||||
crc_calculated = ert_crc_ccitt.calculate_byte(crc_calculated, byte);
|
|
||||||
}
|
}
|
||||||
return crc_calculated == 0x1d0f;
|
return ert_crc_ccitt.checksum() == 0x0000;
|
||||||
}
|
}
|
||||||
|
|
||||||
} /* namespace ert */
|
} /* namespace ert */
|
||||||
|
@ -25,61 +25,74 @@
|
|||||||
#include <cstddef>
|
#include <cstddef>
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
|
|
||||||
|
/* Inspired by
|
||||||
|
* http://www.barrgroup.com/Embedded-Systems/How-To/CRC-Calculation-C-Code
|
||||||
|
*
|
||||||
|
* ...then munged into a shape resembling boost::crc_basic.
|
||||||
|
* http://www.boost.org/doc/libs/release/libs/crc/
|
||||||
|
*/
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
class CRC {
|
class CRC {
|
||||||
public:
|
public:
|
||||||
constexpr CRC(
|
constexpr CRC(
|
||||||
const T polynomial/*,
|
const T truncated_polynomial,
|
||||||
const T initial*/
|
const T initial_remainder = 0,
|
||||||
) : polynomial { polynomial }/*,
|
const T final_xor_value = 0
|
||||||
initial { initial }*/
|
) : truncated_polynomial { truncated_polynomial },
|
||||||
|
initial_remainder { initial_remainder },
|
||||||
|
final_xor_value { final_xor_value },
|
||||||
|
remainder { initial_remainder }
|
||||||
{
|
{
|
||||||
// CRC LSB must always be 1
|
|
||||||
}
|
}
|
||||||
/*
|
|
||||||
template<typename U>
|
|
||||||
T calculate(const U& bits, const size_t length) {
|
|
||||||
if( length > bits.size() ) {
|
|
||||||
// Exception.
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
T crc = 0;
|
T get_initial_remainder() const {
|
||||||
|
return initial_remainder;
|
||||||
for(size_t i=0; i<length; i++) {
|
|
||||||
crc = feed_bit(crc, bits[i]);
|
|
||||||
}
|
|
||||||
|
|
||||||
return crc;
|
|
||||||
}
|
}
|
||||||
*/
|
|
||||||
T calculate_byte(const T crc_in, const uint8_t data) {
|
void reset(T new_initial_remainder) {
|
||||||
/* Inspired by
|
remainder = new_initial_remainder;
|
||||||
* http://www.barrgroup.com/Embedded-Systems/How-To/CRC-Calculation-C-Code
|
}
|
||||||
*/
|
|
||||||
T remainder = crc_in;
|
void reset() {
|
||||||
|
remainder = initial_remainder;
|
||||||
|
}
|
||||||
|
|
||||||
|
void process_bit(bool bit) {
|
||||||
|
remainder ^= bit << (width() - 1);
|
||||||
|
if( remainder & top_bit() ) {
|
||||||
|
remainder = (remainder << 1) ^ truncated_polynomial;
|
||||||
|
} else {
|
||||||
|
remainder = (remainder << 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void process_byte(const uint8_t data) {
|
||||||
remainder ^= data << (width() - 8);
|
remainder ^= data << (width() - 8);
|
||||||
for(size_t bit=0; bit<8; bit++) {
|
for(size_t bit=0; bit<8; bit++) {
|
||||||
if( remainder & top_bit() ) {
|
if( remainder & top_bit() ) {
|
||||||
remainder = (remainder << 1) ^ polynomial;
|
remainder = (remainder << 1) ^ truncated_polynomial;
|
||||||
} else {
|
} else {
|
||||||
remainder = (remainder << 1);
|
remainder = (remainder << 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return remainder;
|
|
||||||
}
|
}
|
||||||
/*
|
|
||||||
T calculate(const uint8_t* const data, const size_t length) {
|
void process_bytes(const uint8_t* const data, const size_t length) {
|
||||||
T remainder = initial;
|
for(size_t i=0; i<length; i++) {
|
||||||
for(size_t byte=0; byte<length; ++byte) {
|
process_byte(data[i]);
|
||||||
remainder = calculate_byte(remainder, data[byte]);
|
|
||||||
}
|
}
|
||||||
return remainder;
|
|
||||||
}
|
}
|
||||||
*/
|
|
||||||
|
T checksum() const {
|
||||||
|
return remainder ^ final_xor_value;
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
const T polynomial;
|
const T truncated_polynomial;
|
||||||
// const T initial;
|
const T initial_remainder;
|
||||||
|
const T final_xor_value;
|
||||||
|
T remainder;
|
||||||
|
|
||||||
static constexpr size_t width() {
|
static constexpr size_t width() {
|
||||||
return 8 * sizeof(T);
|
return 8 * sizeof(T);
|
||||||
@ -88,16 +101,6 @@ private:
|
|||||||
static constexpr T top_bit() {
|
static constexpr T top_bit() {
|
||||||
return 1U << (width() - 1);
|
return 1U << (width() - 1);
|
||||||
}
|
}
|
||||||
/*
|
|
||||||
T feed_bit(const T crc_in, const uint_fast8_t bit) {
|
|
||||||
T crc_out = crc_in ^ (bit & 1);
|
|
||||||
if( crc_in & top_bit() ) {
|
|
||||||
return ((crc_in << 1) | (bit & 1)) ^ polynomial;
|
|
||||||
} else {
|
|
||||||
return (crc_in << 1) | (bit & 1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user