From 30fb9dd438b8253547258d6fb02d2a4201becaf9 Mon Sep 17 00:00:00 2001 From: Per Ekman Date: Thu, 24 Oct 2013 14:06:16 +0200 Subject: [PATCH] kinetis : Add flash sector size detection for K21 MCU. The current way of detecting the sector size of the internal flash does not work for all Kinetis MCUs. Add support for the K21 flash by detecting the specific model from the SDID register and picking the correct sector size based on that. Change-Id: I41f678353e45a44561af8a3398bdd4479dfeea4f Signed-off-by: Per Ekman Reviewed-on: http://openocd.zylin.com/1764 Tested-by: jenkins Reviewed-by: Spencer Oliver --- src/flash/nor/kinetis.c | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/src/flash/nor/kinetis.c b/src/flash/nor/kinetis.c index 84cf83133..6512ce760 100644 --- a/src/flash/nor/kinetis.c +++ b/src/flash/nor/kinetis.c @@ -88,6 +88,10 @@ * 8:7 of the read-only SIM_SDID register reflect the granularity * settings 0..3, so sector sizes and block counts are applicable * according to the following table. + * NB. These undocumented bits does not work for all MCUs. + * A more reliable way is to detect the particular MCU model from the + * SDID field and pick the correct granularity based on that. See + * the handling of K21 in kinetis_read_part_info() for an example. */ const struct { @@ -120,6 +124,21 @@ const struct { #define FTFx_CMD_SETFLEXRAM 0x81 #define FTFx_CMD_MASSERASE 0x44 +#define KINETIS_SDID_FAMID_MASK 0x00000070 +#define KINETIS_SDID_FAMID_K10 0x00000000 +#define KINETIS_SDID_FAMID_K12 0x00000000 +#define KINETIS_SDID_FAMID_K20 0x00000010 +#define KINETIS_SDID_FAMID_K22 0x00000010 +#define KINETIS_SDID_FAMID_K30 0x00000020 +#define KINETIS_SDID_FAMID_K11 0x00000020 +#define KINETIS_SDID_FAMID_K61 0x00000020 +#define KINETIS_SDID_FAMID_K40 0x00000030 +#define KINETIS_SDID_FAMID_K21 0x00000030 +#define KINETIS_SDID_FAMID_K60 0x00000040 +#define KINETIS_SDID_FAMID_K62 0x00000040 +#define KINETIS_SDID_FAMID_K70 0x00000050 +#define KINETIS_SDID_FAMID_KW24 0x00000060 + struct kinetis_flash_bank { unsigned granularity; unsigned bank_ordinal; @@ -741,6 +760,9 @@ static int kinetis_read_part_info(struct flash_bank *bank) if (i == 1) { kinfo->klxx = 1; granularity = 0; + } else if ((kinfo->sim_sdid & KINETIS_SDID_FAMID_MASK) + == KINETIS_SDID_FAMID_K21) { + granularity = 2; } else granularity = (kinfo->sim_sdid >> 7) & 0x03;