From 97cb75145d08c8f93113af1e576563672b312ff2 Mon Sep 17 00:00:00 2001 From: Nicolas Schodet Date: Mon, 17 Aug 2015 14:35:11 +0200 Subject: [PATCH] Add support for STM32F2xx family The F405 rev A uses a wrong CPUID, this patch use the core identifier to make the distinction. Tested with: - F205 - F405 rev Z - F429 Unfortunately, I do not have any F405 rev A. --- src/stm32f4.c | 28 +++++++++++++++++++++++----- 1 file changed, 23 insertions(+), 5 deletions(-) diff --git a/src/stm32f4.c b/src/stm32f4.c index 6446a153..b8a5d58b 100644 --- a/src/stm32f4.c +++ b/src/stm32f4.c @@ -52,6 +52,7 @@ static int stm32f4_flash_write(struct target_flash *f, uint32_t dest, const void *src, size_t len); static const char stm32f4_driver_str[] = "STM32F4xx"; +static const char stm32f2_driver_str[] = "STM32F2xx"; /* Flash Program ad Erase Controller Register Map */ #define FPEC_BASE 0x40023C00 @@ -91,6 +92,7 @@ static const char stm32f4_driver_str[] = "STM32F4xx"; #define SR_EOP 0x01 #define DBGMCU_IDCODE 0xE0042000 +#define ARM_CPUID 0xE000ED00 /* This routine is uses word access. Only usable on target voltage >2.7V */ static const uint16_t stm32f4_flash_write_stub[] = { @@ -124,9 +126,23 @@ static void stm32f4_add_flash(target *t, bool stm32f4_probe(target *t) { + bool f2 = false; uint32_t idcode; idcode = target_mem_read32(t, DBGMCU_IDCODE); + + if ((idcode & 0xFFF) == 0x411) + { + /* F405 revision A have a wrong IDCODE, use ARM_CPUID to make the + * distinction with F205. Revision is also wrong (0x2000 instead + * of 0x1000). See F40x/F41x errata. */ + uint32_t cpuid = target_mem_read32(t, ARM_CPUID); + if ((cpuid & 0xFFF0) == 0xC240) + idcode = 0x10000413; + else + f2 = true; + } + switch(idcode & 0xFFF) { case 0x419: /* 427/437 */ /* Second bank for 2M parts. */ @@ -134,19 +150,21 @@ bool stm32f4_probe(target *t) stm32f4_add_flash(t, 0x8110000, 0x10000, 0x10000, 16); stm32f4_add_flash(t, 0x8120000, 0xE0000, 0x20000, 17); /* Fall through for stuff common to F40x/F41x */ - case 0x411: /* Documented to be 0x413! This is what I read... */ - case 0x413: /* F407VGT6 */ + case 0x411: /* F205 */ + case 0x413: /* F405 */ case 0x421: /* F446 */ case 0x423: /* F401 B/C RM0368 Rev.3 */ case 0x431: /* F411 RM0383 Rev.4 */ case 0x433: /* F401 D/E RM0368 Rev.3 */ - t->driver = stm32f4_driver_str; - target_add_ram(t, 0x10000000, 0x10000); + t->driver = f2 ? stm32f2_driver_str : stm32f4_driver_str; + if (!f2) + target_add_ram(t, 0x10000000, 0x10000); target_add_ram(t, 0x20000000, 0x30000); stm32f4_add_flash(t, 0x8000000, 0x10000, 0x4000, 0); stm32f4_add_flash(t, 0x8010000, 0x10000, 0x10000, 4); stm32f4_add_flash(t, 0x8020000, 0xE0000, 0x20000, 5); - target_add_commands(t, stm32f4_cmd_list, "STM32F4"); + target_add_commands(t, stm32f4_cmd_list, f2 ? "STM32F2" : + "STM32F4"); return true; } return false;