diff --git a/ion/Makefile b/ion/Makefile index f3ab41ebb..49131c7b7 100644 --- a/ion/Makefile +++ b/ion/Makefile @@ -22,6 +22,7 @@ initializer_list = $(shell echo $(1) | sed "s/\(.\)/'\1',/g")0 $(call object_for,ion/src/shared/platform_info.cpp): SFLAGS += -DPATCH_LEVEL="$(call initializer_list,$(PATCH_LEVEL))" -DEPSILON_VERSION="$(call initializer_list,$(EPSILON_VERSION))" src += $(addprefix ion/src/shared/, \ + crc32_eat_byte.cpp \ decompress.cpp \ events.cpp \ led.cpp \ diff --git a/ion/include/ion.h b/ion/include/ion.h index aa3de318e..f9ae2f129 100644 --- a/ion/include/ion.h +++ b/ion/include/ion.h @@ -35,6 +35,8 @@ const char * fccId(); // CRC32 : non xor-ed, non reversed, direct, polynomial 4C11DB7 uint32_t crc32Word(const uint32_t * data, size_t length); // Only accepts whole 32bit values uint32_t crc32Byte(const uint8_t * data, size_t length); +uint32_t crc32EatByte(uint32_t previousCRC, uint8_t data); + // Provides a true random number uint32_t random(); diff --git a/ion/src/device/n0100/regs/config/crc.h b/ion/src/device/n0100/regs/config/crc.h new file mode 100644 index 000000000..3735b0808 --- /dev/null +++ b/ion/src/device/n0100/regs/config/crc.h @@ -0,0 +1,6 @@ +#ifndef ION_DEVICE_N0100_REGS_CONFIG_CRC_H +#define ION_DEVICE_N0100_REGS_CONFIG_CRC_H + +#define REGS_CRC_CONFIG_BYTE_ACCESS 0 + +#endif diff --git a/ion/src/device/n0110/regs/config/crc.h b/ion/src/device/n0110/regs/config/crc.h new file mode 100644 index 000000000..faa0a263b --- /dev/null +++ b/ion/src/device/n0110/regs/config/crc.h @@ -0,0 +1,6 @@ +#ifndef ION_DEVICE_N0110_REGS_CONFIG_CRC_H +#define ION_DEVICE_N0110_REGS_CONFIG_CRC_H + +#define REGS_CRC_CONFIG_BYTE_ACCESS 1 + +#endif diff --git a/ion/src/device/shared/drivers/crc32.cpp b/ion/src/device/shared/drivers/crc32.cpp index cb97c4962..6d392e226 100644 --- a/ion/src/device/shared/drivers/crc32.cpp +++ b/ion/src/device/shared/drivers/crc32.cpp @@ -6,6 +6,7 @@ namespace Ion { using namespace Device::Regs; uint32_t crc32Byte(const uint8_t * data, size_t length) { + uint32_t result = 0; bool initialCRCEngineState = RCC.AHB1ENR()->getCRCEN(); RCC.AHB1ENR()->setCRCEN(true); CRC.CR()->setRESET(true); @@ -18,12 +19,20 @@ uint32_t crc32Byte(const uint8_t * data, size_t length) { CRC.DR_WordAccess()->set(*((uint32_t *)data)); data += 4; } - // Scanning the remaining data with byte accesses + +#if REGS_CRC_CONFIG_BYTE_ACCESS + // Scan the remaining data with byte accesses while (data < end) { CRC.DR_ByteAccess()->set(*data++); } + result = CRC.DR_WordAccess()->get(); +#else + result = CRC.DR_WordAccess()->get(); + while (data < end) { + result = Ion::crc32EatByte(result, *data++); + } +#endif - uint32_t result = CRC.DR_WordAccess()->get(); RCC.AHB1ENR()->setCRCEN(initialCRCEngineState); return result; } diff --git a/ion/src/device/shared/regs/crc.h b/ion/src/device/shared/regs/crc.h index e3b468179..4c4c95903 100644 --- a/ion/src/device/shared/regs/crc.h +++ b/ion/src/device/shared/regs/crc.h @@ -9,8 +9,10 @@ namespace Regs { class CRC { public: +#if REGS_CRC_CONFIG_BYTE_ACCESS class DR_ByteAccess : public Register8 { }; +#endif class DR_WordAccess : public Register32 { }; @@ -20,7 +22,9 @@ public: }; constexpr CRC() {}; +#if REGS_CRC_CONFIG_BYTE_ACCESS REGS_REGISTER_AT(DR_ByteAccess, 0x00); +#endif REGS_REGISTER_AT(DR_WordAccess, 0x00); REGS_REGISTER_AT(CR, 0x08); private: diff --git a/ion/src/shared/crc32.cpp b/ion/src/shared/crc32.cpp index 8b95ed102..0fdfd3f6a 100644 --- a/ion/src/shared/crc32.cpp +++ b/ion/src/shared/crc32.cpp @@ -1,15 +1,5 @@ #include -constexpr uint32_t polynomial = 0x04C11DB7; - -static uint32_t crc32(uint32_t crc, uint8_t data) { - crc ^= data << 24; - for (int i=8; i--;) { - crc = crc & 0x80000000 ? ((crc<<1)^polynomial) : (crc << 1); - } - return crc; -} - uint32_t crc32Helper(const uint8_t * data, size_t length, bool wordAccess) { size_t uint32ByteLength = sizeof(uint32_t)/sizeof(uint8_t); uint32_t crc = 0xFFFFFFFF; @@ -20,11 +10,11 @@ uint32_t crc32Helper(const uint8_t * data, size_t length, bool wordAccess) { // FIXME: Assumes little-endian byte order! for (int j = uint32ByteLength-1; j >= 0; j--) { // scan byte by byte to avoid alignment issue when building for emscripten platform - crc = crc32(crc, data[i*uint32ByteLength+j]); + crc = Ion::crc32EatByte(crc, data[i*uint32ByteLength+j]); } } for (int i = (int) wordLength * uint32ByteLength; i < byteLength; i++) { - crc = crc32(crc, data[i]); + crc = Ion::crc32EatByte(crc, data[i]); } return crc; } diff --git a/ion/src/shared/crc32_eat_byte.cpp b/ion/src/shared/crc32_eat_byte.cpp new file mode 100644 index 000000000..a4bb6c66d --- /dev/null +++ b/ion/src/shared/crc32_eat_byte.cpp @@ -0,0 +1,11 @@ +#include + +constexpr uint32_t polynomial = 0x04C11DB7; + +uint32_t Ion::crc32EatByte(uint32_t crc, uint8_t data) { + crc ^= data << 24; + for (int i=8; i--;) { + crc = crc & 0x80000000 ? ((crc<<1)^polynomial) : (crc << 1); + } + return crc; +}