From b997cc2b69e4003c46eaec2210c8042e3361c506 Mon Sep 17 00:00:00 2001 From: iabdalkader Date: Sat, 1 Nov 2025 09:40:23 +0100 Subject: [PATCH 1/3] boards/MPS: Enable CRC module. Signed-off-by: iabdalkader --- boards/MPS2_AN500/omv_boardconfig.mk | 1 + boards/MPS3_AN547/omv_boardconfig.mk | 1 + 2 files changed, 2 insertions(+) diff --git a/boards/MPS2_AN500/omv_boardconfig.mk b/boards/MPS2_AN500/omv_boardconfig.mk index e0161f300..58b419534 100755 --- a/boards/MPS2_AN500/omv_boardconfig.mk +++ b/boards/MPS2_AN500/omv_boardconfig.mk @@ -8,6 +8,7 @@ OMV_BOARD_CFLAGS= -DQEMU_SOC_MPS2 \ -DCPU_FREQ_HZ=25000000 MICROPY_PY_CSI = 1 MICROPY_PY_CSI_NG = 1 +MICROPY_PY_CRC = 1 MICROPY_PY_FIR = 0 MICROPY_PY_ULAB = 1 MICROPY_PY_WINC1500 = 0 diff --git a/boards/MPS3_AN547/omv_boardconfig.mk b/boards/MPS3_AN547/omv_boardconfig.mk index a09f70528..8204287b6 100644 --- a/boards/MPS3_AN547/omv_boardconfig.mk +++ b/boards/MPS3_AN547/omv_boardconfig.mk @@ -9,6 +9,7 @@ OMV_BOARD_CFLAGS= -mcmse \ -DCPU_FREQ_HZ=32000000 MICROPY_PY_CSI = 1 MICROPY_PY_CSI_NG = 1 +MICROPY_PY_CRC = 1 MICROPY_PY_FIR = 0 MICROPY_PY_ULAB = 1 MICROPY_PY_WINC1500 = 0 From c3b0676470c3eb9e26754f01940a5b379d712d9f Mon Sep 17 00:00:00 2001 From: iabdalkader Date: Sat, 1 Nov 2025 09:40:43 +0100 Subject: [PATCH 2/3] scripts/unittest: Add total test execution time to summary. Signed-off-by: iabdalkader igned-off-by: iabdalkader --- scripts/unittest/run.py | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/scripts/unittest/run.py b/scripts/unittest/run.py index 4029d7cc1..42daaabbe 100644 --- a/scripts/unittest/run.py +++ b/scripts/unittest/run.py @@ -44,6 +44,8 @@ def main(): if not "temp" in os.listdir(): os.mkdir("temp") # Make a temp directory + total_start_time = time.ticks_ms() + for test in tests: result = "PASSED" path = "/".join((TEST_PATH, test)) @@ -72,14 +74,21 @@ def main(): print_result(test, result, time_ms) gc.collect() + total_time_ms = time.ticks_diff(time.ticks_ms(), total_start_time) + # Print summary total_tests = passed_count + failed_count + skipped_count - print("\n" + "=" * 60) + stats_line = ("Total: %d | Passed: %d | Failed: %d | Skipped: %d | Time: %dms" % + (total_tests, passed_count, failed_count, skipped_count, total_time_ms)) + separator = "=" * len(stats_line) + + print("\n" + separator) print("Total: %d | " % total_tests + COLOR_GREEN + "Passed: %d" % passed_count + COLOR_RESET + " | " + COLOR_RED + "Failed: %d" % failed_count + COLOR_RESET + " | " + - COLOR_YELLOW + "Skipped: %d" % skipped_count + COLOR_RESET) - print("=" * 60) + COLOR_YELLOW + "Skipped: %d" % skipped_count + COLOR_RESET + " | " + + "Time: %dms" % total_time_ms) + print(separator) if failed_count > 0: print(COLOR_RED + "Some tests FAILED." + COLOR_RESET) From 627dc0b1f606c131268e4acea3efc072b7f0524c Mon Sep 17 00:00:00 2001 From: iabdalkader Date: Sat, 1 Nov 2025 09:43:36 +0100 Subject: [PATCH 3/3] scripts/unittest: Add CRC module unit test. Signed-off-by: iabdalkader --- scripts/unittest/tests/crc.py | 109 ++++++++++++++++++++++++++++++++++ 1 file changed, 109 insertions(+) create mode 100644 scripts/unittest/tests/crc.py diff --git a/scripts/unittest/tests/crc.py b/scripts/unittest/tests/crc.py new file mode 100644 index 000000000..22d9a7c4e --- /dev/null +++ b/scripts/unittest/tests/crc.py @@ -0,0 +1,109 @@ +def unittest(data_path, temp_path): + try: + import crc + except ImportError: + raise Exception("crc module unavailable") + + # Test data + test_data1 = b"Hello, World!" + test_data2 = b"OpenMV" + test_data3 = b"1234567890" + + # Test 1: Basic CRC16 calculation + crc16_result1 = crc.crc16(test_data1) + if not isinstance(crc16_result1, int): + return False + + # CRC16 should be 16-bit value (0-65535) + if crc16_result1 < 0 or crc16_result1 > 0xFFFF: + return False + + # Test 2: Basic CRC32 calculation + crc32_result1 = crc.crc32(test_data1) + if not isinstance(crc32_result1, int): + return False + + # CRC32 should be 32-bit value + if crc32_result1 < 0 or crc32_result1 > 0xFFFFFFFF: + return False + + # Test 3: Consistency - same input should give same output + crc16_result1_repeat = crc.crc16(test_data1) + if crc16_result1 != crc16_result1_repeat: + return False + + crc32_result1_repeat = crc.crc32(test_data1) + if crc32_result1 != crc32_result1_repeat: + return False + + # Test 4: Different inputs should give different outputs + crc16_result2 = crc.crc16(test_data2) + if crc16_result1 == crc16_result2: + return False + + crc32_result2 = crc.crc32(test_data2) + if crc32_result1 == crc32_result2: + return False + + # Test 5: Incremental CRC16 calculation + # Calculate CRC of concatenated data in one go + combined_data = test_data1 + test_data2 + crc16_combined = crc.crc16(combined_data) + + # Calculate CRC incrementally + crc16_part1 = crc.crc16(test_data1) + crc16_incremental = crc.crc16(test_data2, value=crc16_part1) + + # Both methods should give same result + if crc16_combined != crc16_incremental: + return False + + # Test 6: Incremental CRC32 calculation + crc32_combined = crc.crc32(combined_data) + + crc32_part1 = crc.crc32(test_data1) + crc32_incremental = crc.crc32(test_data2, value=crc32_part1) + + if crc32_combined != crc32_incremental: + return False + + # Test 7: Multi-step incremental CRC16 + crc16_step1 = crc.crc16(test_data1) + crc16_step2 = crc.crc16(test_data2, value=crc16_step1) + crc16_step3 = crc.crc16(test_data3, value=crc16_step2) + + # Should match single calculation + all_data = test_data1 + test_data2 + test_data3 + crc16_all = crc.crc16(all_data) + + if crc16_step3 != crc16_all: + return False + + # Test 8: Multi-step incremental CRC32 + crc32_step1 = crc.crc32(test_data1) + crc32_step2 = crc.crc32(test_data2, value=crc32_step1) + crc32_step3 = crc.crc32(test_data3, value=crc32_step2) + + crc32_all = crc.crc32(all_data) + + if crc32_step3 != crc32_all: + return False + + # Test 9: Empty data handling + empty_data = b"" + crc16_empty = crc.crc16(empty_data) + crc32_empty = crc.crc32(empty_data) + + # Empty data should return valid CRC values + if not isinstance(crc16_empty, int) or not isinstance(crc32_empty, int): + return False + + # Test 10: Single byte data + single_byte = b"A" + crc16_single = crc.crc16(single_byte) + crc32_single = crc.crc32(single_byte) + + if not isinstance(crc16_single, int) or not isinstance(crc32_single, int): + return False + + return True