Skip to content

Commit

Permalink
kocherga_serial: update header format
Browse files Browse the repository at this point in the history
  • Loading branch information
coderkalyan committed Apr 1, 2024
1 parent 69e2131 commit 08546d7
Show file tree
Hide file tree
Showing 8 changed files with 268 additions and 229 deletions.
106 changes: 104 additions & 2 deletions kocherga/kocherga.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -238,6 +238,110 @@ auto getRandomByte() -> std::uint8_t;

// --------------------------------------------------------------------------------------------------------------------

namespace detail
{

static constexpr uint8_t BitsPerByte = 8U;

/// Size-optimized implementation of CRC16-CCITT
class CRC16CCITT
{
public:
static constexpr std::size_t Size = 2;

void update(const std::uint8_t b) noexcept
{
value_ ^= static_cast<std::uint16_t>(b << BitsPerByte);
// Manually unrolled because the difference in performance is drastic. Can't use table because size limitations.
value_ =
static_cast<std::uint16_t>(static_cast<std::uint16_t>(value_ << 1U) ^ (((value_ & Top) != 0U) ? Poly : 0U));
value_ =
static_cast<std::uint16_t>(static_cast<std::uint16_t>(value_ << 1U) ^ (((value_ & Top) != 0U) ? Poly : 0U));
value_ =
static_cast<std::uint16_t>(static_cast<std::uint16_t>(value_ << 1U) ^ (((value_ & Top) != 0U) ? Poly : 0U));
value_ =
static_cast<std::uint16_t>(static_cast<std::uint16_t>(value_ << 1U) ^ (((value_ & Top) != 0U) ? Poly : 0U));
value_ =
static_cast<std::uint16_t>(static_cast<std::uint16_t>(value_ << 1U) ^ (((value_ & Top) != 0U) ? Poly : 0U));
value_ =
static_cast<std::uint16_t>(static_cast<std::uint16_t>(value_ << 1U) ^ (((value_ & Top) != 0U) ? Poly : 0U));
value_ =
static_cast<std::uint16_t>(static_cast<std::uint16_t>(value_ << 1U) ^ (((value_ & Top) != 0U) ? Poly : 0U));
value_ =
static_cast<std::uint16_t>(static_cast<std::uint16_t>(value_ << 1U) ^ (((value_ & Top) != 0U) ? Poly : 0U));
}

[[nodiscard]] auto get() const noexcept { return value_; }

[[nodiscard]] auto getBytes() const noexcept -> std::array<std::uint8_t, Size>
{
const auto x = get();
return {
static_cast<std::uint8_t>(x >> (BitsPerByte * 1U)),
static_cast<std::uint8_t>(x >> (BitsPerByte * 0U)),
};
}

void update(const std::size_t size, const std::uint8_t* const ptr) noexcept
{
const auto* p = ptr;
for (std::size_t s = 0; s < size; s++)
{
update(*p);
p++;
}
}

[[nodiscard]] auto isResidueCorrect() const noexcept { return value_ == Residue; }

private:
static constexpr std::uint16_t Initial = 0xFFFFU;
static constexpr std::uint16_t Poly = 0x1021U;
static constexpr std::uint16_t Top = 0x8000U;
static constexpr std::uint16_t Residue = 0x0000U;

std::uint16_t value_ = Initial;
};

/// Size-optimized implementation of CRC32-C (Castagnoli).
class CRC32C
{
public:
static constexpr std::size_t Size = 4;

void update(const std::uint8_t b) noexcept
{
value_ ^= static_cast<std::uint32_t>(b);
for (auto i = 0U; i < BitsPerByte; i++)
{
value_ = ((value_ & 1U) != 0) ? ((value_ >> 1U) ^ ReflectedPoly) : (value_ >> 1U); // NOLINT
}
}

[[nodiscard]] auto get() const noexcept { return value_ ^ Xor; }

[[nodiscard]] auto getBytes() const noexcept -> std::array<std::uint8_t, Size>
{
const auto x = get();
return {
static_cast<std::uint8_t>(x >> (BitsPerByte * 0U)),
static_cast<std::uint8_t>(x >> (BitsPerByte * 1U)),
static_cast<std::uint8_t>(x >> (BitsPerByte * 2U)),
static_cast<std::uint8_t>(x >> (BitsPerByte * 3U)),
};
}

[[nodiscard]] auto isResidueCorrect() const noexcept { return value_ == Residue; }

private:
static constexpr std::uint32_t Xor = 0xFFFF'FFFFUL;
static constexpr std::uint32_t ReflectedPoly = 0x82F6'3B78UL;
static constexpr std::uint32_t Residue = 0xB798'B438UL;

std::uint32_t value_ = Xor;
};
} // namespace detail

/// This is used to verify integrity of the application and other data.
/// Note that the firmware CRC verification is a computationally expensive process that needs to be completed
/// in a limited time interval, which should be minimized. This class has been carefully manually optimized to
Expand Down Expand Up @@ -307,8 +411,6 @@ class CRC64
/// Internal use only.
namespace detail
{
static constexpr auto BitsPerByte = 8U;

static constexpr std::chrono::microseconds DefaultTransferIDTimeout{2'000'000}; ///< Default taken from Specification.

/// Detects the application in the ROM, verifies its integrity, and retrieves the information about it.
Expand Down
47 changes: 1 addition & 46 deletions kocherga/kocherga_can.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -234,59 +234,14 @@ class TxQueue final
namespace detail
{
using kocherga::detail::BitsPerByte; // NOSONAR
using kocherga::detail::CRC16CCITT; // NOSONAR

static constexpr std::uint8_t TailByteStartOfTransfer = 0b1000'0000;
static constexpr std::uint8_t TailByteEndOfTransfer = 0b0100'0000;
static constexpr std::uint8_t TailByteToggleBit = 0b0010'0000;

static constexpr std::uint8_t MaxTransferID = 31;

class CRC16CCITT
{
public:
static constexpr std::size_t Size = 2;

void update(const std::uint8_t b) noexcept
{
value_ ^= static_cast<std::uint16_t>(static_cast<std::uint16_t>(b) << 8U);
// Manually unrolled because the difference in performance is drastic. Can't use table because size limitations.
value_ = static_cast<uint16_t>(static_cast<uint16_t>(value_ << 1U) ^ (((value_ & Top) != 0U) ? Poly : 0U));
value_ = static_cast<uint16_t>(static_cast<uint16_t>(value_ << 1U) ^ (((value_ & Top) != 0U) ? Poly : 0U));
value_ = static_cast<uint16_t>(static_cast<uint16_t>(value_ << 1U) ^ (((value_ & Top) != 0U) ? Poly : 0U));
value_ = static_cast<uint16_t>(static_cast<uint16_t>(value_ << 1U) ^ (((value_ & Top) != 0U) ? Poly : 0U));
value_ = static_cast<uint16_t>(static_cast<uint16_t>(value_ << 1U) ^ (((value_ & Top) != 0U) ? Poly : 0U));
value_ = static_cast<uint16_t>(static_cast<uint16_t>(value_ << 1U) ^ (((value_ & Top) != 0U) ? Poly : 0U));
value_ = static_cast<uint16_t>(static_cast<uint16_t>(value_ << 1U) ^ (((value_ & Top) != 0U) ? Poly : 0U));
value_ = static_cast<uint16_t>(static_cast<uint16_t>(value_ << 1U) ^ (((value_ & Top) != 0U) ? Poly : 0U));
}

void update(const std::size_t size, const std::uint8_t* const ptr) noexcept
{
const auto* p = ptr;
for (std::size_t s = 0; s < size; s++)
{
update(*p);
p++;
}
}

[[nodiscard]] auto get() const noexcept { return value_; }

[[nodiscard]] auto getBytes() const noexcept -> std::array<std::uint8_t, Size>
{
const auto x = get();
return {static_cast<std::uint8_t>(x >> BitsPerByte), static_cast<std::uint8_t>(x)};
}

[[nodiscard]] auto isResidueCorrect() const noexcept { return value_ == 0; }

private:
static constexpr std::uint16_t Top = 0x8000U;
static constexpr std::uint16_t Poly = 0x1021U;

std::uint16_t value_ = std::numeric_limits<std::uint16_t>::max();
};

inline auto makePseudoUniqueID(const SystemInfo::UniqueID& uid) -> std::uint64_t
{
CRC64 crc;
Expand Down
Loading

0 comments on commit 08546d7

Please sign in to comment.