aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorPaul Fertser2013-04-14 21:55:32 +0400
committerGareth McMullin2013-04-14 11:35:23 -0700
commit91b481731d14789a87b9e5db29e7b715bcbc618b (patch)
tree0971c94a2c8bab1770bb4e0cb7f0098c3dd2a302 /src
parent7db6e3e00c1419fd9c470dc743bdfaf20b197f91 (diff)
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>
Diffstat (limited to 'src')
-rw-r--r--src/crc32.c31
-rw-r--r--src/platforms/f4discovery/platform.c1
-rw-r--r--src/platforms/native/platform.c1
-rw-r--r--src/platforms/stlink/platform.c1
-rw-r--r--src/platforms/swlink/platform.c1
5 files changed, 24 insertions, 11 deletions
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
diff --git a/src/platforms/f4discovery/platform.c b/src/platforms/f4discovery/platform.c
index 4aa14a6..de39ab7 100644
--- a/src/platforms/f4discovery/platform.c
+++ b/src/platforms/f4discovery/platform.c
@@ -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_IOPBEN);
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*/
diff --git a/src/platforms/native/platform.c b/src/platforms/native/platform.c
index 8ded81a..0c13047 100644
--- a/src/platforms/native/platform.c
+++ b/src/platforms/native/platform.c
@@ -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_IOPBEN);
rcc_peripheral_enable_clock(&RCC_APB2ENR, RCC_APB2ENR_AFIOEN);
+ rcc_peripheral_enable_clock(&RCC_AHBENR, RCC_AHBENR_CRCEN);
/* Setup GPIO ports */
gpio_clear(USB_PU_PORT, USB_PU_PIN);
diff --git a/src/platforms/stlink/platform.c b/src/platforms/stlink/platform.c
index 5eaf5fc..e8435b9 100644
--- a/src/platforms/stlink/platform.c
+++ b/src/platforms/stlink/platform.c
@@ -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_IOPCEN);
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
* platform_hwversion() also needed to initialize led_idle_run!
diff --git a/src/platforms/swlink/platform.c b/src/platforms/swlink/platform.c
index 33d4f12..1aa45b1 100644
--- a/src/platforms/swlink/platform.c
+++ b/src/platforms/swlink/platform.c
@@ -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_IOPBEN);
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 */
data = AFIO_MAPR;