From facd715c126d80e2120a1ef69e27b29f4697f5bc Mon Sep 17 00:00:00 2001 From: iabdalkader Date: Sun, 24 Aug 2025 19:04:44 +0200 Subject: [PATCH 1/3] common: Add CRC HAL. CRC-16 support. Signed-off-by: iabdalkader --- common/common.mk | 1 + common/omv_crc.c | 86 ++++++++++++++++++++++++++++++++++++++++++++++++ common/omv_crc.h | 63 +++++++++++++++++++++++++++++++++++ 3 files changed, 150 insertions(+) create mode 100644 common/omv_crc.c create mode 100644 common/omv_crc.h diff --git a/common/common.mk b/common/common.mk index 93b7562bd..090db25f1 100644 --- a/common/common.mk +++ b/common/common.mk @@ -31,6 +31,7 @@ COMMON_SRC_C += \ mutex.c \ nosys_stubs.c \ omv_csi.c \ + omv_crc.c \ pendsv.c \ tinyusb_debug.c \ trace.c \ diff --git a/common/omv_crc.c b/common/omv_crc.c new file mode 100644 index 000000000..d4dfcf48f --- /dev/null +++ b/common/omv_crc.c @@ -0,0 +1,86 @@ +/* + * SPDX-License-Identifier: MIT + * + * Copyright (C) 2025 OpenMV, LLC. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +#include "omv_crc.h" + +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 +}; + +__attribute__((weak)) void omv_crc_init(void) { + +} + +__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++) { + 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++) { + uint8_t index = (crc >> 8) ^ data[i]; + crc = (crc << 8) ^ crc16_table[index]; + } + + return crc; +} diff --git a/common/omv_crc.h b/common/omv_crc.h new file mode 100644 index 000000000..6c56fa991 --- /dev/null +++ b/common/omv_crc.h @@ -0,0 +1,63 @@ +/* + * SPDX-License-Identifier: MIT + * + * Copyright (C) 2025 OpenMV, LLC. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +#ifndef __OMV_CRC_H__ +#define __OMV_CRC_H__ +#include +#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; + +// Initialize CRC hardware (if available) +void omv_crc_init(void); + +// Start CRC calculation for buffer data +omv_crc_t omv_crc_start(const void *buf, size_t size); + +// Update CRC with additional buffer data +omv_crc_t omv_crc_update(omv_crc_t crc, const void *buf, size_t size); + +// 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); +} + +// 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; +} + +// 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); +} +#endif // __OMV_CRC_H__ From 1dd9b33acca03cecef50595f5c422dd62e8d08e6 Mon Sep 17 00:00:00 2001 From: iabdalkader Date: Sun, 24 Aug 2025 19:05:13 +0200 Subject: [PATCH 2/3] ports/alif: Implement hardware accelerated CRC. Signed-off-by: iabdalkader --- lib/alif/alif.mk | 1 + ports/alif/omv_crc.c | 70 ++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 71 insertions(+) create mode 100644 ports/alif/omv_crc.c diff --git a/lib/alif/alif.mk b/lib/alif/alif.mk index 12d73cb2e..83aad5e53 100644 --- a/lib/alif/alif.mk +++ b/lib/alif/alif.mk @@ -9,6 +9,7 @@ HAL_SRC_C += \ drivers/source/adc.c \ + drivers/source/crc.c \ drivers/source/dma_ctrl.c \ drivers/source/dma_op.c \ drivers/source/i2c.c \ diff --git a/ports/alif/omv_crc.c b/ports/alif/omv_crc.c new file mode 100644 index 000000000..e769ca69c --- /dev/null +++ b/ports/alif/omv_crc.c @@ -0,0 +1,70 @@ +/* + * SPDX-License-Identifier: MIT + * + * Copyright (C) 2023-2024 OpenMV, LLC. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +#include "crc.h" +#include "global_map.h" +#include "omv_crc.h" + +#define CRC0 ((CRC_Type *)CRC0_BASE) + +static bool crc_initialized = false; + +void omv_crc_init(void) { + crc_clear_config(CRC0); + crc_enable_16bit(CRC0); + crc_enable_custom_poly(CRC0); + crc_set_custom_poly(CRC0, OMV_CRC_POLY); + crc_set_seed(CRC0, OMV_CRC_INIT); + crc_enable(CRC0); + crc_initialized = true; +} + +omv_crc_t omv_crc_start(const void *buf, size_t size) { + if (!crc_initialized) { + omv_crc_init(); + } + + if (size == 0) { + return OMV_CRC_INIT; + } + + uint32_t result = 0; + crc_calculate_16bit(CRC0, buf, size, &result); + return (omv_crc_t)result; +} + +omv_crc_t omv_crc_update(omv_crc_t crc, const void *buf, size_t size) { + if (!crc_initialized) { + omv_crc_init(); + } + + if (size == 0) { + return crc; + } + + // Set current CRC value and calculate incrementally + crc_set_seed(CRC0, crc); + uint32_t result = 0; + crc_calculate_16bit(CRC0, buf, size, &result); + return (omv_crc_t)result; +} From 616ce71b96c8520d6a80b20c7e0e4231fea04772 Mon Sep 17 00:00:00 2001 From: iabdalkader Date: Sun, 24 Aug 2025 19:05:39 +0200 Subject: [PATCH 3/3] ports/stm32: Implement hardware accelerated CRC. Signed-off-by: iabdalkader --- ports/stm32/omv_crc.c | 73 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 73 insertions(+) create mode 100644 ports/stm32/omv_crc.c diff --git a/ports/stm32/omv_crc.c b/ports/stm32/omv_crc.c new file mode 100644 index 000000000..8d6e12751 --- /dev/null +++ b/ports/stm32/omv_crc.c @@ -0,0 +1,73 @@ +/* + * SPDX-License-Identifier: MIT + * + * Copyright (C) 2025 OpenMV, LLC. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +// Only compile for STM32 families with configurable CRC hardware +#include STM32_HAL_H +#include "omv_crc.h" +#include + +#if defined(STM32F7) || defined(STM32H7) || defined(STM32N6) +static CRC_HandleTypeDef hcrc = {0}; +static bool crc_initialized = false; + +void omv_crc_init(void) { + hcrc.Instance = CRC; + hcrc.Init.DefaultPolynomialUse = DEFAULT_POLYNOMIAL_DISABLE; + hcrc.Init.GeneratingPolynomial = OMV_CRC_POLY; + hcrc.Init.DefaultInitValueUse = DEFAULT_INIT_VALUE_DISABLE; + hcrc.Init.InitValue = OMV_CRC_INIT; + hcrc.Init.CRCLength = CRC_POLYLENGTH_16B; + hcrc.Init.InputDataInversionMode = CRC_INPUTDATA_INVERSION_NONE; + hcrc.Init.OutputDataInversionMode = CRC_OUTPUTDATA_INVERSION_DISABLE; + hcrc.InputDataFormat = CRC_INPUTDATA_FORMAT_BYTES; + + HAL_CRC_Init(&hcrc); + crc_initialized = true; +} + +omv_crc_t omv_crc_start(const void *buf, size_t size) { + if (!crc_initialized) { + omv_crc_init(); + } + + if (size == 0) { + return OMV_CRC_INIT; + } + + return (omv_crc_t) HAL_CRC_Calculate(&hcrc, (uint32_t *)buf, size); +} + +omv_crc_t omv_crc_update(omv_crc_t crc, const void *buf, size_t size) { + if (!crc_initialized) { + omv_crc_init(); + } + + if (size == 0) { + return crc; + } + + return (omv_crc_t) HAL_CRC_Accumulate(&hcrc, (uint32_t *)buf, size); +} + +#endif // STM32F7 || STM32H7 || STM32N6