From 91b481731d14789a87b9e5db29e7b715bcbc618b Mon Sep 17 00:00:00 2001 From: Paul Fertser Date: Sun, 14 Apr 2013 21:55:32 +0400 Subject: stm32f1/stm32f4: fix hardware CRC calculation This was real-life tested on stm32f1 hardware including computation for odd-sized ranges. Signed-off-by: Paul Fertser --- src/crc32.c | 31 ++++++++++++++++++++----------- 1 file changed, 20 insertions(+), 11 deletions(-) (limited to 'src/crc32.c') diff --git a/src/crc32.c b/src/crc32.c index d5c8732..810a9dd 100644 --- a/src/crc32.c +++ b/src/crc32.c @@ -113,26 +113,35 @@ uint32_t generic_crc32(struct target_s *target, uint32_t base, int len) uint32_t generic_crc32(struct target_s *target, uint32_t base, int len) { uint32_t data; - uint8_t byte; + uint32_t crc; + size_t i; - CRC_CR |= CRC_CR_RESET; + CRC_CR |= CRC_CR_RESET; - while (len >3) { - if (target_mem_read_words(target, &data, base, 1) != 0) + while (len > 3) { + if (target_mem_read_words(target, &data, base, 4) != 0) return -1; - CRC_DR = data; - base+=4; - len -= 4; + CRC_DR = __builtin_bswap32(data); + base += 4; + len -= 4; } + + crc = CRC_DR; + while (len--) { - if (target_mem_read_bytes(target, &byte, base, 1) != 0) + if (target_mem_read_bytes(target, (uint8_t *)&data, base++, 1) != 0) return -1; - CRC_DR = byte; - base++; + crc ^= data << 24; + for (i = 0; i < 8; i++) { + if (crc & 0x80000000) + crc = (crc << 1) ^ 0x4C11DB7; + else + crc <<= 1; + } } - return CRC_DR; + return crc; } #endif -- cgit v1.2.3