From e075aefca4c4e6d64aadfd3864f8774aa295af3f Mon Sep 17 00:00:00 2001 From: iabdalkader Date: Wed, 24 Sep 2025 13:36:35 +0200 Subject: [PATCH] common/omv_crc: Update CRC support. - Add support for CRC32 with software fallback. - Update polynomials and lookup tables. Signed-off-by: iabdalkader --- common/omv_crc.c | 146 ++++++++++++++++++++++++++++++++--------------- common/omv_crc.h | 83 +++++++++++++++++++-------- 2 files changed, 161 insertions(+), 68 deletions(-) diff --git a/common/omv_crc.c b/common/omv_crc.c index d4dfcf48f..02b3ef312 100644 --- a/common/omv_crc.c +++ b/common/omv_crc.c @@ -23,64 +23,120 @@ */ #include "omv_crc.h" +// CRC16 lookup table for polynomial 0xF94F (HD=6, len=135) static const uint16_t crc16_table[256] = { - 0x0000, 0xBAAD, 0xCFF7, 0x755A, 0x2543, 0x9FEE, 0xEAB4, 0x5019, - 0x4A86, 0xF02B, 0x8571, 0x3FDC, 0x6FC5, 0xD568, 0xA032, 0x1A9F, - 0x950C, 0x2FA1, 0x5AFB, 0xE056, 0xB04F, 0x0AE2, 0x7FB8, 0xC515, - 0xDF8A, 0x6527, 0x107D, 0xAAD0, 0xFAC9, 0x4064, 0x353E, 0x8F93, - 0x90B5, 0x2A18, 0x5F42, 0xE5EF, 0xB5F6, 0x0F5B, 0x7A01, 0xC0AC, - 0xDA33, 0x609E, 0x15C4, 0xAF69, 0xFF70, 0x45DD, 0x3087, 0x8A2A, - 0x05B9, 0xBF14, 0xCA4E, 0x70E3, 0x20FA, 0x9A57, 0xEF0D, 0x55A0, - 0x4F3F, 0xF592, 0x80C8, 0x3A65, 0x6A7C, 0xD0D1, 0xA58B, 0x1F26, - 0x9BC7, 0x216A, 0x5430, 0xEE9D, 0xBE84, 0x0429, 0x7173, 0xCBDE, - 0xD141, 0x6BEC, 0x1EB6, 0xA41B, 0xF402, 0x4EAF, 0x3BF5, 0x8158, - 0x0ECB, 0xB466, 0xC13C, 0x7B91, 0x2B88, 0x9125, 0xE47F, 0x5ED2, - 0x444D, 0xFEE0, 0x8BBA, 0x3117, 0x610E, 0xDBA3, 0xAEF9, 0x1454, - 0x0B72, 0xB1DF, 0xC485, 0x7E28, 0x2E31, 0x949C, 0xE1C6, 0x5B6B, - 0x41F4, 0xFB59, 0x8E03, 0x34AE, 0x64B7, 0xDE1A, 0xAB40, 0x11ED, - 0x9E7E, 0x24D3, 0x5189, 0xEB24, 0xBB3D, 0x0190, 0x74CA, 0xCE67, - 0xD4F8, 0x6E55, 0x1B0F, 0xA1A2, 0xF1BB, 0x4B16, 0x3E4C, 0x84E1, - 0x8D23, 0x378E, 0x42D4, 0xF879, 0xA860, 0x12CD, 0x6797, 0xDD3A, - 0xC7A5, 0x7D08, 0x0852, 0xB2FF, 0xE2E6, 0x584B, 0x2D11, 0x97BC, - 0x182F, 0xA282, 0xD7D8, 0x6D75, 0x3D6C, 0x87C1, 0xF29B, 0x4836, - 0x52A9, 0xE804, 0x9D5E, 0x27F3, 0x77EA, 0xCD47, 0xB81D, 0x02B0, - 0x1D96, 0xA73B, 0xD261, 0x68CC, 0x38D5, 0x8278, 0xF722, 0x4D8F, - 0x5710, 0xEDBD, 0x98E7, 0x224A, 0x7253, 0xC8FE, 0xBDA4, 0x0709, - 0x889A, 0x3237, 0x476D, 0xFDC0, 0xADD9, 0x1774, 0x622E, 0xD883, - 0xC21C, 0x78B1, 0x0DEB, 0xB746, 0xE75F, 0x5DF2, 0x28A8, 0x9205, - 0x16E4, 0xAC49, 0xD913, 0x63BE, 0x33A7, 0x890A, 0xFC50, 0x46FD, - 0x5C62, 0xE6CF, 0x9395, 0x2938, 0x7921, 0xC38C, 0xB6D6, 0x0C7B, - 0x83E8, 0x3945, 0x4C1F, 0xF6B2, 0xA6AB, 0x1C06, 0x695C, 0xD3F1, - 0xC96E, 0x73C3, 0x0699, 0xBC34, 0xEC2D, 0x5680, 0x23DA, 0x9977, - 0x8651, 0x3CFC, 0x49A6, 0xF30B, 0xA312, 0x19BF, 0x6CE5, 0xD648, - 0xCCD7, 0x767A, 0x0320, 0xB98D, 0xE994, 0x5339, 0x2663, 0x9CCE, - 0x135D, 0xA9F0, 0xDCAA, 0x6607, 0x361E, 0x8CB3, 0xF9E9, 0x4344, - 0x59DB, 0xE376, 0x962C, 0x2C81, 0x7C98, 0xC635, 0xB36F, 0x09C2 + 0x0000, 0xF94F, 0x0BD1, 0xF29E, 0x17A2, 0xEEED, 0x1C73, 0xE53C, + 0x2F44, 0xD60B, 0x2495, 0xDDDA, 0x38E6, 0xC1A9, 0x3337, 0xCA78, + 0x5E88, 0xA7C7, 0x5559, 0xAC16, 0x492A, 0xB065, 0x42FB, 0xBBB4, + 0x71CC, 0x8883, 0x7A1D, 0x8352, 0x666E, 0x9F21, 0x6DBF, 0x94F0, + 0xBD10, 0x445F, 0xB6C1, 0x4F8E, 0xAAB2, 0x53FD, 0xA163, 0x582C, + 0x9254, 0x6B1B, 0x9985, 0x60CA, 0x85F6, 0x7CB9, 0x8E27, 0x7768, + 0xE398, 0x1AD7, 0xE849, 0x1106, 0xF43A, 0x0D75, 0xFFEB, 0x06A4, + 0xCCDC, 0x3593, 0xC70D, 0x3E42, 0xDB7E, 0x2231, 0xD0AF, 0x29E0, + 0x836F, 0x7A20, 0x88BE, 0x71F1, 0x94CD, 0x6D82, 0x9F1C, 0x6653, + 0xAC2B, 0x5564, 0xA7FA, 0x5EB5, 0xBB89, 0x42C6, 0xB058, 0x4917, + 0xDDE7, 0x24A8, 0xD636, 0x2F79, 0xCA45, 0x330A, 0xC194, 0x38DB, + 0xF2A3, 0x0BEC, 0xF972, 0x003D, 0xE501, 0x1C4E, 0xEED0, 0x179F, + 0x3E7F, 0xC730, 0x35AE, 0xCCE1, 0x29DD, 0xD092, 0x220C, 0xDB43, + 0x113B, 0xE874, 0x1AEA, 0xE3A5, 0x0699, 0xFFD6, 0x0D48, 0xF407, + 0x60F7, 0x99B8, 0x6B26, 0x9269, 0x7755, 0x8E1A, 0x7C84, 0x85CB, + 0x4FB3, 0xB6FC, 0x4462, 0xBD2D, 0x5811, 0xA15E, 0x53C0, 0xAA8F, + 0xFF91, 0x06DE, 0xF440, 0x0D0F, 0xE833, 0x117C, 0xE3E2, 0x1AAD, + 0xD0D5, 0x299A, 0xDB04, 0x224B, 0xC777, 0x3E38, 0xCCA6, 0x35E9, + 0xA119, 0x5856, 0xAAC8, 0x5387, 0xB6BB, 0x4FF4, 0xBD6A, 0x4425, + 0x8E5D, 0x7712, 0x858C, 0x7CC3, 0x99FF, 0x60B0, 0x922E, 0x6B61, + 0x4281, 0xBBCE, 0x4950, 0xB01F, 0x5523, 0xAC6C, 0x5EF2, 0xA7BD, + 0x6DC5, 0x948A, 0x6614, 0x9F5B, 0x7A67, 0x8328, 0x71B6, 0x88F9, + 0x1C09, 0xE546, 0x17D8, 0xEE97, 0x0BAB, 0xF2E4, 0x007A, 0xF935, + 0x334D, 0xCA02, 0x389C, 0xC1D3, 0x24EF, 0xDDA0, 0x2F3E, 0xD671, + 0x7CFE, 0x85B1, 0x772F, 0x8E60, 0x6B5C, 0x9213, 0x608D, 0x99C2, + 0x53BA, 0xAAF5, 0x586B, 0xA124, 0x4418, 0xBD57, 0x4FC9, 0xB686, + 0x2276, 0xDB39, 0x29A7, 0xD0E8, 0x35D4, 0xCC9B, 0x3E05, 0xC74A, + 0x0D32, 0xF47D, 0x06E3, 0xFFAC, 0x1A90, 0xE3DF, 0x1141, 0xE80E, + 0xC1EE, 0x38A1, 0xCA3F, 0x3370, 0xD64C, 0x2F03, 0xDD9D, 0x24D2, + 0xEEAA, 0x17E5, 0xE57B, 0x1C34, 0xF908, 0x0047, 0xF2D9, 0x0B96, + 0x9F66, 0x6629, 0x94B7, 0x6DF8, 0x88C4, 0x718B, 0x8315, 0x7A5A, + 0xB022, 0x496D, 0xBBF3, 0x42BC, 0xA780, 0x5ECF, 0xAC51, 0x551E, }; -__attribute__((weak)) void omv_crc_init(void) { +// CRC32 lookup table for polynomial 0xFA567D89 +const uint32_t crc32_table[256] = { + 0x00000000, 0xFA567D89, 0x0EFA869B, 0xF4ACFB12, 0x1DF50D36, 0xE7A370BF, 0x130F8BAD, 0xE959F624, + 0x3BEA1A6C, 0xC1BC67E5, 0x35109CF7, 0xCF46E17E, 0x261F175A, 0xDC496AD3, 0x28E591C1, 0xD2B3EC48, + 0x77D434D8, 0x8D824951, 0x792EB243, 0x8378CFCA, 0x6A2139EE, 0x90774467, 0x64DBBF75, 0x9E8DC2FC, + 0x4C3E2EB4, 0xB668533D, 0x42C4A82F, 0xB892D5A6, 0x51CB2382, 0xAB9D5E0B, 0x5F31A519, 0xA567D890, + 0xEFA869B0, 0x15FE1439, 0xE152EF2B, 0x1B0492A2, 0xF25D6486, 0x080B190F, 0xFCA7E21D, 0x06F19F94, + 0xD44273DC, 0x2E140E55, 0xDAB8F547, 0x20EE88CE, 0xC9B77EEA, 0x33E10363, 0xC74DF871, 0x3D1B85F8, + 0x987C5D68, 0x622A20E1, 0x9686DBF3, 0x6CD0A67A, 0x8589505E, 0x7FDF2DD7, 0x8B73D6C5, 0x7125AB4C, + 0xA3964704, 0x59C03A8D, 0xAD6CC19F, 0x573ABC16, 0xBE634A32, 0x443537BB, 0xB099CCA9, 0x4ACFB120, + 0x2506AEE9, 0xDF50D360, 0x2BFC2872, 0xD1AA55FB, 0x38F3A3DF, 0xC2A5DE56, 0x36092544, 0xCC5F58CD, + 0x1EECB485, 0xE4BAC90C, 0x1016321E, 0xEA404F97, 0x0319B9B3, 0xF94FC43A, 0x0DE33F28, 0xF7B542A1, + 0x52D29A31, 0xA884E7B8, 0x5C281CAA, 0xA67E6123, 0x4F279707, 0xB571EA8E, 0x41DD119C, 0xBB8B6C15, + 0x6938805D, 0x936EFDD4, 0x67C206C6, 0x9D947B4F, 0x74CD8D6B, 0x8E9BF0E2, 0x7A370BF0, 0x80617679, + 0xCAAEC759, 0x30F8BAD0, 0xC45441C2, 0x3E023C4B, 0xD75BCA6F, 0x2D0DB7E6, 0xD9A14CF4, 0x23F7317D, + 0xF144DD35, 0x0B12A0BC, 0xFFBE5BAE, 0x05E82627, 0xECB1D003, 0x16E7AD8A, 0xE24B5698, 0x181D2B11, + 0xBD7AF381, 0x472C8E08, 0xB380751A, 0x49D60893, 0xA08FFEB7, 0x5AD9833E, 0xAE75782C, 0x542305A5, + 0x8690E9ED, 0x7CC69464, 0x886A6F76, 0x723C12FF, 0x9B65E4DB, 0x61339952, 0x959F6240, 0x6FC91FC9, + 0x4A0D5DD2, 0xB05B205B, 0x44F7DB49, 0xBEA1A6C0, 0x57F850E4, 0xADAE2D6D, 0x5902D67F, 0xA354ABF6, + 0x71E747BE, 0x8BB13A37, 0x7F1DC125, 0x854BBCAC, 0x6C124A88, 0x96443701, 0x62E8CC13, 0x98BEB19A, + 0x3DD9690A, 0xC78F1483, 0x3323EF91, 0xC9759218, 0x202C643C, 0xDA7A19B5, 0x2ED6E2A7, 0xD4809F2E, + 0x06337366, 0xFC650EEF, 0x08C9F5FD, 0xF29F8874, 0x1BC67E50, 0xE19003D9, 0x153CF8CB, 0xEF6A8542, + 0xA5A53462, 0x5FF349EB, 0xAB5FB2F9, 0x5109CF70, 0xB8503954, 0x420644DD, 0xB6AABFCF, 0x4CFCC246, + 0x9E4F2E0E, 0x64195387, 0x90B5A895, 0x6AE3D51C, 0x83BA2338, 0x79EC5EB1, 0x8D40A5A3, 0x7716D82A, + 0xD27100BA, 0x28277D33, 0xDC8B8621, 0x26DDFBA8, 0xCF840D8C, 0x35D27005, 0xC17E8B17, 0x3B28F69E, + 0xE99B1AD6, 0x13CD675F, 0xE7619C4D, 0x1D37E1C4, 0xF46E17E0, 0x0E386A69, 0xFA94917B, 0x00C2ECF2, + 0x6F0BF33B, 0x955D8EB2, 0x61F175A0, 0x9BA70829, 0x72FEFE0D, 0x88A88384, 0x7C047896, 0x8652051F, + 0x54E1E957, 0xAEB794DE, 0x5A1B6FCC, 0xA04D1245, 0x4914E461, 0xB34299E8, 0x47EE62FA, 0xBDB81F73, + 0x18DFC7E3, 0xE289BA6A, 0x16254178, 0xEC733CF1, 0x052ACAD5, 0xFF7CB75C, 0x0BD04C4E, 0xF18631C7, + 0x2335DD8F, 0xD963A006, 0x2DCF5B14, 0xD799269D, 0x3EC0D0B9, 0xC496AD30, 0x303A5622, 0xCA6C2BAB, + 0x80A39A8B, 0x7AF5E702, 0x8E591C10, 0x740F6199, 0x9D5697BD, 0x6700EA34, 0x93AC1126, 0x69FA6CAF, + 0xBB4980E7, 0x411FFD6E, 0xB5B3067C, 0x4FE57BF5, 0xA6BC8DD1, 0x5CEAF058, 0xA8460B4A, 0x521076C3, + 0xF777AE53, 0x0D21D3DA, 0xF98D28C8, 0x03DB5541, 0xEA82A365, 0x10D4DEEC, 0xE47825FE, 0x1E2E5877, + 0xCC9DB43F, 0x36CBC9B6, 0xC26732A4, 0x38314F2D, 0xD168B909, 0x2B3EC480, 0xDF923F92, 0x25C4421B, +}; -} +__attribute__((weak)) uint16_t omv_crc16_start(const void *buf, size_t len) { + const uint8_t *data = (const uint8_t *) buf; + uint16_t crc = OMV_CRC16_INIT; -__attribute__((weak)) omv_crc_t omv_crc_start(const void *buf, size_t size) { - const uint8_t *data = (const uint8_t *)buf; - omv_crc_t crc = OMV_CRC_INIT; - - for (size_t i = 0; i < size; i++) { + for (size_t i = 0; i < len; i++) { uint8_t index = (crc >> 8) ^ data[i]; crc = (crc << 8) ^ crc16_table[index]; } - + return crc; } -__attribute__((weak)) omv_crc_t omv_crc_update(omv_crc_t crc, const void *buf, size_t size) { - const uint8_t *data = (const uint8_t *)buf; - - for (size_t i = 0; i < size; i++) { +__attribute__((weak)) uint16_t omv_crc16_update(uint16_t crc, const void *buf, size_t len) { + const uint8_t *data = (const uint8_t *) buf; + + for (size_t i = 0; i < len; i++) { uint8_t index = (crc >> 8) ^ data[i]; crc = (crc << 8) ^ crc16_table[index]; } - + + return crc; +} + +__attribute__((weak)) uint32_t omv_crc32_start(const void *buf, size_t len) { + const uint8_t *data = (const uint8_t *) buf; + uint32_t crc = OMV_CRC32_INIT; + + for (size_t i = 0; i < len; i++) { + uint8_t index = (crc >> 24) ^ data[i]; + crc = (crc << 8) ^ crc32_table[index]; + } + + return crc; +} + +__attribute__((weak)) uint32_t omv_crc32_update(uint32_t crc, const void *buf, size_t len) { + const uint8_t *data = (const uint8_t *) buf; + + for (size_t i = 0; i < len; i++) { + uint8_t index = (crc >> 24) ^ data[i]; + crc = (crc << 8) ^ crc32_table[index]; + } + return crc; } diff --git a/common/omv_crc.h b/common/omv_crc.h index 6c56fa991..3febe730c 100644 --- a/common/omv_crc.h +++ b/common/omv_crc.h @@ -27,37 +27,74 @@ #include #include -// 0xBAAD is ironically good - HD=5 up to 108 bits, HD=4 up to 7985 bits -#define OMV_CRC_POLY (0xBAAD) -#define OMV_CRC_INIT (0xFFFF) -#define OMV_CRC_SIZE (16) -typedef uint16_t omv_crc_t; +// CRC size enumeration +typedef enum { + OMV_CRC16 = 16, + OMV_CRC32 = 32 +} omv_crc_size_t; -// Initialize CRC hardware (if available) -void omv_crc_init(void); +// HD=6 up to 114 bits +#define OMV_CRC16_POLY (0xF94F) +#define OMV_CRC16_INIT (0xFFFF) -// Start CRC calculation for buffer data -omv_crc_t omv_crc_start(const void *buf, size_t size); +// HD=6 up to 32738 bits (~4K) +#define OMV_CRC32_POLY (0xFA567D89) +#define OMV_CRC32_INIT (0xFFFFFFFF) -// Update CRC with additional buffer data -omv_crc_t omv_crc_update(omv_crc_t crc, const void *buf, size_t size); +// Default software implementations +uint16_t omv_crc16_start(const void *buf, size_t len); +uint16_t omv_crc16_update(uint16_t crc, const void *buf, size_t len); -// Read CRC value from the last 2 bytes of buffer -static inline omv_crc_t omv_crc_read(const void *buf, size_t size) { - const uint8_t *crc_buf = (const uint8_t *)buf + size - 2; - return *((omv_crc_t*) crc_buf); +uint32_t omv_crc32_start(const void *buf, size_t len); +uint32_t omv_crc32_update(uint32_t crc, const void *buf, size_t len); + +// Public API functions +static inline uint32_t omv_crc_start(omv_crc_size_t size, const void *buf, size_t len) { + if (size == OMV_CRC16) { + return omv_crc16_start(buf, len); + } else if (size == OMV_CRC32) { + return omv_crc32_start(buf, len); + } + return 0; } -// Calculate CRC and write it to the last 2 bytes of buffer -static inline void omv_crc_write(void *buf, size_t size) { - omv_crc_t crc = omv_crc_start(buf, size - 2); - uint8_t *crc_buf = (uint8_t *)buf + size - 2; - crc_buf[0] = crc & 0xFF; - crc_buf[1] = (crc >> 8) & 0xFF; +static inline uint32_t omv_crc_update(omv_crc_size_t size, uint32_t crc, const void *buf, size_t len) { + if (size == OMV_CRC16) { + return omv_crc16_update((uint16_t) crc, buf, len); + } else if (size == OMV_CRC32) { + return omv_crc32_update(crc, buf, len); + } + return crc; +} + +// Read CRC value from the last bytes of buffer +static inline uint32_t omv_crc_read(omv_crc_size_t crc_size, const void *buf, size_t size) { + const uint8_t *crc_buf = (const uint8_t *) buf + size - (crc_size == OMV_CRC16 ? 2 : 4); + if (crc_size == OMV_CRC16) { + return *((uint16_t *) crc_buf); + } else { + return *((uint32_t *) crc_buf); + } +} + +// Calculate CRC and write it to the last bytes of buffer +static inline void omv_crc_write(omv_crc_size_t crc_size, void *buf, size_t size) { + uint32_t crc = omv_crc_start(crc_size, buf, size - (crc_size == OMV_CRC16 ? 2 : 4)); + uint8_t *crc_buf = (uint8_t *) buf + size - (crc_size == OMV_CRC16 ? 2 : 4); + + if (crc_size == OMV_CRC16) { + crc_buf[0] = crc & 0xFF; + crc_buf[1] = (crc >> 8) & 0xFF; + } else { + crc_buf[0] = crc & 0xFF; + crc_buf[1] = (crc >> 8) & 0xFF; + crc_buf[2] = (crc >> 16) & 0xFF; + crc_buf[3] = (crc >> 24) & 0xFF; + } } // Calculate and check if CRC matches the one stored in buffer -static inline bool omv_crc_check(const void *buf, size_t size) { - return omv_crc_read(buf, size) == omv_crc_start(buf, size - 2); +static inline bool omv_crc_check(omv_crc_size_t crc_size, const void *buf, size_t size) { + return omv_crc_read(crc_size, buf, size) == omv_crc_start(crc_size, buf, size - (crc_size == OMV_CRC16 ? 2 : 4)); } #endif // __OMV_CRC_H__