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 <fercerpav@gmail.com>
This commit is contained in:
Paul Fertser 2013-04-14 21:55:32 +04:00 committed by Gareth McMullin
parent 7db6e3e00c
commit 91b481731d
5 changed files with 24 additions and 11 deletions

View File

@ -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 generic_crc32(struct target_s *target, uint32_t base, int len)
{ {
uint32_t data; 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) { while (len > 3) {
if (target_mem_read_words(target, &data, base, 1) != 0) if (target_mem_read_words(target, &data, base, 4) != 0)
return -1; return -1;
CRC_DR = data; CRC_DR = __builtin_bswap32(data);
base+=4; base += 4;
len -= 4; len -= 4;
} }
crc = CRC_DR;
while (len--) { 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; return -1;
CRC_DR = byte; crc ^= data << 24;
base++; for (i = 0; i < 8; i++) {
if (crc & 0x80000000)
crc = (crc << 1) ^ 0x4C11DB7;
else
crc <<= 1;
}
} }
return CRC_DR; return crc;
} }
#endif #endif

View File

@ -53,6 +53,7 @@ int platform_init(void)
rcc_peripheral_enable_clock(&RCC_AHB1ENR, RCC_AHB1ENR_IOPAEN); rcc_peripheral_enable_clock(&RCC_AHB1ENR, RCC_AHB1ENR_IOPAEN);
rcc_peripheral_enable_clock(&RCC_AHB1ENR, RCC_AHB1ENR_IOPBEN); rcc_peripheral_enable_clock(&RCC_AHB1ENR, RCC_AHB1ENR_IOPBEN);
rcc_peripheral_enable_clock(&RCC_AHB1ENR, RCC_AHB1ENR_IOPDEN); rcc_peripheral_enable_clock(&RCC_AHB1ENR, RCC_AHB1ENR_IOPDEN);
rcc_peripheral_enable_clock(&RCC_AHB1ENR, RCC_AHB1ENR_CRCEN);
/* Set up USB Pins and alternate function*/ /* Set up USB Pins and alternate function*/

View File

@ -72,6 +72,7 @@ int platform_init(void)
rcc_peripheral_enable_clock(&RCC_APB2ENR, RCC_APB2ENR_IOPAEN); rcc_peripheral_enable_clock(&RCC_APB2ENR, RCC_APB2ENR_IOPAEN);
rcc_peripheral_enable_clock(&RCC_APB2ENR, RCC_APB2ENR_IOPBEN); rcc_peripheral_enable_clock(&RCC_APB2ENR, RCC_APB2ENR_IOPBEN);
rcc_peripheral_enable_clock(&RCC_APB2ENR, RCC_APB2ENR_AFIOEN); rcc_peripheral_enable_clock(&RCC_APB2ENR, RCC_APB2ENR_AFIOEN);
rcc_peripheral_enable_clock(&RCC_AHBENR, RCC_AHBENR_CRCEN);
/* Setup GPIO ports */ /* Setup GPIO ports */
gpio_clear(USB_PU_PORT, USB_PU_PIN); gpio_clear(USB_PU_PORT, USB_PU_PIN);

View File

@ -79,6 +79,7 @@ int platform_init(void)
rcc_peripheral_enable_clock(&RCC_APB2ENR, RCC_APB2ENR_IOPBEN); rcc_peripheral_enable_clock(&RCC_APB2ENR, RCC_APB2ENR_IOPBEN);
rcc_peripheral_enable_clock(&RCC_APB2ENR, RCC_APB2ENR_IOPCEN); rcc_peripheral_enable_clock(&RCC_APB2ENR, RCC_APB2ENR_IOPCEN);
rcc_peripheral_enable_clock(&RCC_APB2ENR, RCC_APB2ENR_AFIOEN); rcc_peripheral_enable_clock(&RCC_APB2ENR, RCC_APB2ENR_AFIOEN);
rcc_peripheral_enable_clock(&RCC_AHBENR, RCC_AHBENR_CRCEN);
/* On Rev 1 unconditionally activate MCO on PORTA8 with HSE /* On Rev 1 unconditionally activate MCO on PORTA8 with HSE
* platform_hwversion() also needed to initialize led_idle_run! * platform_hwversion() also needed to initialize led_idle_run!

View File

@ -51,6 +51,7 @@ int platform_init(void)
rcc_peripheral_enable_clock(&RCC_APB2ENR, RCC_APB2ENR_IOPAEN); rcc_peripheral_enable_clock(&RCC_APB2ENR, RCC_APB2ENR_IOPAEN);
rcc_peripheral_enable_clock(&RCC_APB2ENR, RCC_APB2ENR_IOPBEN); rcc_peripheral_enable_clock(&RCC_APB2ENR, RCC_APB2ENR_IOPBEN);
rcc_peripheral_enable_clock(&RCC_APB2ENR, RCC_APB2ENR_AFIOEN); rcc_peripheral_enable_clock(&RCC_APB2ENR, RCC_APB2ENR_AFIOEN);
rcc_peripheral_enable_clock(&RCC_AHBENR, RCC_AHBENR_CRCEN);
/* Unmap JTAG Pins so we can reuse as GPIO */ /* Unmap JTAG Pins so we can reuse as GPIO */
data = AFIO_MAPR; data = AFIO_MAPR;