The current sd_crc16() function does not pass the Spec test, change it by a working one.
Code generated with pycrc v0.9.1 (https://pycrc.org) using the configuration: - Width = 16 - Poly = 0x1021 - XorIn = 0x0000 - ReflectIn = False - XorOut = 0x0000 - ReflectOut = False - Algorithm = bit-by-bit-fast Copyright of the generated source code ====================================== The code generated by pycrc is not considered a substantial portion of the software, therefore the licence does not cover the generated code, and the author of pycrc will not claim any copyright on the generated code. Signed-off-by: Philippe Mathieu-Daudé <f4...@amsat.org> --- hw/sd/sdmmc-internal.c | 32 ++++++++++++++++++++------------ 1 file changed, 20 insertions(+), 12 deletions(-) diff --git a/hw/sd/sdmmc-internal.c b/hw/sd/sdmmc-internal.c index 0e82e69d99..d6f9b3b51c 100644 --- a/hw/sd/sdmmc-internal.c +++ b/hw/sd/sdmmc-internal.c @@ -90,23 +90,31 @@ uint8_t sd_crc7(const void *message, size_t width) return shift_reg; } -uint16_t sd_crc16(const void *message, size_t width) +/* 16 bit XMODEM CRC (polynomial 0x1021) */ +uint16_t sd_crc16(const void *data, size_t data_len) { - int i, bit; - uint16_t shift_reg = 0x0000; - const uint16_t *msg = (const uint16_t *)message; - width <<= 1; - - for (i = 0; i < width; i++, msg++) { - for (bit = 15; bit >= 0; bit--) { - shift_reg <<= 1; - if ((shift_reg >> 15) ^ ((*msg >> bit) & 1)) { - shift_reg ^= 0x1011; + const unsigned char *d = (const unsigned char *)data; + uint16_t crc = 0x0000; + unsigned char c; + unsigned int i; + bool bit; + + while (data_len--) { + c = *d++; + for (i = 0x80; i > 0; i >>= 1) { + bit = crc & 0x8000; + if (c & i) { + bit = !bit; + } + crc <<= 1; + if (bit) { + crc ^= 0x1021; } } + crc &= 0xffff; } - return shift_reg; + return crc; } static uint8_t sd_calc_frame48_crc7(uint8_t cmd, uint32_t arg, bool is_response) -- 2.17.0