This is an automated email from Gerrit.

Tomas Vanek ([email protected]) just uploaded a new patch set to Gerrit, which you 
can find at http://openocd.zylin.com/4059

-- gerrit

commit d7d188a082efaabf2dd6ee8412f1cddfed09f30e
Author: Tomas Vanek <[email protected]>
Date:   Fri Mar 10 21:43:46 2017 +0100

    flash Kinetis: add KL28 device
    
    This device differs a lot from others in KL series.
    
    Unfortunately System Integration Module, where device identification 
resides,
    moved to new address so probe now have to try both addresses of SIM_SDID.
    
    Introduce a new bank creation option: -sim-base to ensure error free probe.
    
    WDOG32 is slightly different from KE1x and on different address.
    System Mode Controler changed layout to word aligned.
    
    Change-Id: I2c9dca0c4ad4228fcc941d6078d15f5e394833ff
    Signed-off-by: Tomas Vanek <[email protected]>

diff --git a/doc/openocd.texi b/doc/openocd.texi
index e869fe8..be96607 100644
--- a/doc/openocd.texi
+++ b/doc/openocd.texi
@@ -5189,6 +5189,11 @@ recognizes flash size and a number of flash banks (1-4) 
using the chip
 identification register, and autoconfigures itself.
 Use kinetis_ke driver for KE0x devices.
 
+The @var{kinetis} driver defines option:
+@itemize
+@item -sim-base @var{addr} ... base of System Integration Module where chip 
identification resides. Driver tries two known locations if option is omitted.
+@end itemize
+
 @example
 flash bank $_FLASHNAME kinetis 0 0 0 0 $_TARGETNAME
 @end example
diff --git a/src/flash/nor/kinetis.c b/src/flash/nor/kinetis.c
index 6af17d6..f73ac9e 100644
--- a/src/flash/nor/kinetis.c
+++ b/src/flash/nor/kinetis.c
@@ -96,19 +96,25 @@
 #define FTFx_FCCOB3    0x40020004
 #define FTFx_FPROT3    0x40020010
 #define FTFx_FDPROT    0x40020017
-#define SIM_SDID       0x40048024
-#define SIM_SOPT1      0x40047000
-#define SIM_FCFG1      0x4004804c
-#define SIM_FCFG2      0x40048050
+#define SIM_BASE       0x40047000
+#define SIM_BASE_KL28  0x40074000
 #define SIM_COPC       0x40048100
+       /* SIM_COPC does not exist on devices with changed SIM_BASE */
 #define WDOG_BASE      0x40052000
 #define WDOG32_KE1X    0x40052000
 #define WDOG32_KL28    0x40076000
 #define SMC_PMCTRL     0x4007E001
 #define SMC_PMSTAT     0x4007E003
+#define SMC32_PMCTRL   0x4007E00C
+#define SMC32_PMSTAT   0x4007E014
 #define MCM_PLACR      0xF000300C
 
 /* Offsets */
+#define SIM_SOPT1_OFFSET    0x0000
+#define SIM_SDID_OFFSET            0x1024
+#define SIM_FCFG1_OFFSET    0x104c
+#define SIM_FCFG2_OFFSET    0x1050
+
 #define WDOG_STCTRLH_OFFSET      0
 #define WDOG32_CS_OFFSET         0
 
@@ -271,6 +277,7 @@ struct kinetis_chip {
        uint32_t dflash_size;           /* accessible rest of FlexNVM if EEPROM 
backup uses part of FlexNVM */
 
        uint32_t progr_accel_ram;
+       uint32_t sim_base;
 
        enum {
                FS_PROGRAM_SECTOR = 1,
@@ -296,6 +303,11 @@ struct kinetis_chip {
                KINETIS_WDOG32_KL28,
        } watchdog_type;
 
+       enum {
+               KINETIS_SMC,
+               KINETIS_SMC32,
+       } sysmodectrlr_type;
+
        char name[40];
 
        unsigned num_banks;
@@ -843,11 +855,25 @@ static struct kinetis_chip *kinetis_get_chip(struct 
target *target)
        return NULL;
 }
 
+static int kinetis_chip_options(struct kinetis_chip *k_chip, int argc, const 
char *argv[])
+{
+       int i;
+       for (i = 0; i < argc; i++) {
+               if (strcmp(argv[i], "-sim-base") == 0) {
+                       if (i + 1 < argc)
+                               k_chip->sim_base = strtoul(argv[++i], NULL, 0);
+               } else
+                       LOG_ERROR("Unsupported flash bank option %s", argv[i]);
+       }
+       return ERROR_OK;
+}
+
 FLASH_BANK_COMMAND_HANDLER(kinetis_flash_bank_command)
 {
        struct target *target = bank->target;
        struct kinetis_chip *k_chip;
        struct kinetis_flash_bank *k_bank;
+       int retval;
 
        if (CMD_ARGC < 6)
                return ERROR_COMMAND_SYNTAX_ERROR;
@@ -864,6 +890,11 @@ FLASH_BANK_COMMAND_HANDLER(kinetis_flash_bank_command)
                }
 
                k_chip->target = target;
+
+               /* only the first defined bank can define chip options */
+               retval = kinetis_chip_options(k_chip, CMD_ARGC - 6, CMD_ARGV + 
6);
+               if (retval != ERROR_OK)
+                       return retval;
        }
 
        if (k_chip->num_banks >= KINETIS_MAX_BANKS) {
@@ -1465,17 +1496,44 @@ static int kinetis_ftfx_command(struct target *target, 
uint8_t fcmd, uint32_t fa
 }
 
 
-static int kinetis_check_run_mode(struct target *target)
+static int kinetis_read_pmstat(struct kinetis_chip *k_chip, uint8_t *pmstat)
+{
+       int result;
+       uint32_t stat32;
+       struct target *target = k_chip->target;
+
+       switch (k_chip->sysmodectrlr_type) {
+       case KINETIS_SMC:
+               result = target_read_u8(target, SMC_PMSTAT, pmstat);
+               return result;
+
+       case KINETIS_SMC32:
+               result = target_read_u32(target, SMC32_PMSTAT, &stat32);
+               if (result == ERROR_OK)
+                       *pmstat = stat32 & 0xff;
+               return result;
+       }
+       return ERROR_FAIL;
+}
+
+static int kinetis_check_run_mode(struct kinetis_chip *k_chip)
 {
        int result, i;
-       uint8_t pmctrl, pmstat;
+       uint8_t pmstat;
+       struct target *target;
+
+       if (k_chip == NULL) {
+               LOG_ERROR("Chip not probed.");
+               return ERROR_FAIL;
+       }
+       target = k_chip->target;
 
        if (target->state != TARGET_HALTED) {
                LOG_ERROR("Target not halted");
                return ERROR_TARGET_NOT_HALTED;
        }
 
-       result = target_read_u8(target, SMC_PMSTAT, &pmstat);
+       result = kinetis_read_pmstat(k_chip, &pmstat);
        if (result != ERROR_OK)
                return result;
 
@@ -1485,13 +1543,21 @@ static int kinetis_check_run_mode(struct target *target)
        if (pmstat == PM_STAT_VLPR) {
                /* It is safe to switch from VLPR to RUN mode without changing 
clock */
                LOG_INFO("Switching from VLPR to RUN mode.");
-               pmctrl = PM_CTRL_RUNM_RUN;
-               result = target_write_u8(target, SMC_PMCTRL, pmctrl);
+
+               switch (k_chip->sysmodectrlr_type) {
+               case KINETIS_SMC:
+                       result = target_write_u8(target, SMC_PMCTRL, 
PM_CTRL_RUNM_RUN);
+                       break;
+
+               case KINETIS_SMC32:
+                       result = target_write_u32(target, SMC32_PMCTRL, 
PM_CTRL_RUNM_RUN);
+                       break;
+               }
                if (result != ERROR_OK)
                        return result;
 
                for (i = 100; i; i--) {
-                       result = target_read_u8(target, SMC_PMSTAT, &pmstat);
+                       result = kinetis_read_pmstat(k_chip, &pmstat);
                        if (result != ERROR_OK)
                                return result;
 
@@ -1537,8 +1603,9 @@ static int kinetis_erase(struct flash_bank *bank, int 
first, int last)
 {
        int result, i;
        struct kinetis_flash_bank *k_bank = bank->driver_priv;
+       struct kinetis_chip *k_chip = k_bank->k_chip;
 
-       result = kinetis_check_run_mode(bank->target);
+       result = kinetis_check_run_mode(k_chip);
        if (result != ERROR_OK)
                return result;
 
@@ -1814,8 +1881,9 @@ static int kinetis_write(struct flash_bank *bank, const 
uint8_t *buffer,
        bool set_fcf = false;
        int sect = 0;
        struct kinetis_flash_bank *k_bank = bank->driver_priv;
+       struct kinetis_chip *k_chip = k_bank->k_chip;
 
-       result = kinetis_check_run_mode(bank->target);
+       result = kinetis_check_run_mode(k_chip);
        if (result != ERROR_OK)
                return result;
 
@@ -1900,7 +1968,18 @@ static int kinetis_probe_chip(struct kinetis_chip 
*k_chip)
 
        name[0] = '\0';
 
-       result = target_read_u32(target, SIM_SDID, &k_chip->sim_sdid);
+       if (k_chip->sim_base)
+               result = target_read_u32(target, k_chip->sim_base + 
SIM_SDID_OFFSET, &k_chip->sim_sdid);
+       else {
+               result = target_read_u32(target, SIM_BASE + SIM_SDID_OFFSET, 
&k_chip->sim_sdid);
+               if (result == ERROR_OK)
+                       k_chip->sim_base = SIM_BASE;
+               else {
+                       result = target_read_u32(target, SIM_BASE_KL28 + 
SIM_SDID_OFFSET, &k_chip->sim_sdid);
+                       if (result == ERROR_OK)
+                               k_chip->sim_base = SIM_BASE_KL28;
+               }
+       }
        if (result != ERROR_OK)
                return result;
 
@@ -2002,7 +2081,7 @@ static int kinetis_probe_chip(struct kinetis_chip *k_chip)
                        case KINETIS_SDID_FAMILYID_K2X | 
KINETIS_SDID_SUBFAMID_KX2: {
                                /* MK24FN1M reports as K22, this should detect 
it (according to errata note 1N83J) */
                                uint32_t sopt1;
-                               result = target_read_u32(target, SIM_SOPT1, 
&sopt1);
+                               result = target_read_u32(target, 
k_chip->sim_base + SIM_SOPT1_OFFSET, &sopt1);
                                if (result != ERROR_OK)
                                        return result;
 
@@ -2110,8 +2189,21 @@ static int kinetis_probe_chip(struct kinetis_chip 
*k_chip)
                        k_chip->watchdog_type = KINETIS_WDOG_COP;
 
                        cpu_mhz = 48;
-                       if (subfamid == 3 && (familyid == 1 || familyid == 2))
+                       switch (k_chip->sim_sdid & (KINETIS_SDID_FAMILYID_MASK 
| KINETIS_SDID_SUBFAMID_MASK)) {
+                       case KINETIS_SDID_FAMILYID_K1X | 
KINETIS_SDID_SUBFAMID_KX3:
+                       case KINETIS_SDID_FAMILYID_K2X | 
KINETIS_SDID_SUBFAMID_KX3:
                                subfamid = 7;
+                               break;
+
+                       case KINETIS_SDID_FAMILYID_K2X | 
KINETIS_SDID_SUBFAMID_KX8:
+                               cpu_mhz = 72;
+                               k_chip->pflash_sector_size = 2<<10;
+                               num_blocks = 2;
+                               k_chip->watchdog_type = KINETIS_WDOG32_KL28;
+                               k_chip->sysmodectrlr_type = KINETIS_SMC32;
+                               break;
+                       }
+
                        snprintf(name, sizeof(name), "MKL%u%uZ%%s%u",
                                 familyid, subfamid, cpu_mhz / 10);
                        break;
@@ -2232,11 +2324,11 @@ static int kinetis_probe_chip(struct kinetis_chip 
*k_chip)
                return ERROR_FLASH_OPER_UNSUPPORTED;
        }
 
-       result = target_read_u32(target, SIM_FCFG1, &k_chip->sim_fcfg1);
+       result = target_read_u32(target, k_chip->sim_base + SIM_FCFG1_OFFSET, 
&k_chip->sim_fcfg1);
        if (result != ERROR_OK)
                return result;
 
-       result = target_read_u32(target, SIM_FCFG2, &k_chip->sim_fcfg2);
+       result = target_read_u32(target, k_chip->sim_base + SIM_FCFG2_OFFSET, 
&k_chip->sim_fcfg2);
        if (result != ERROR_OK)
                return result;
 
@@ -2571,7 +2663,7 @@ static int kinetis_blank_check(struct flash_bank *bank)
        int result;
 
        /* suprisingly blank check does not work in VLPR and HSRUN modes */
-       result = kinetis_check_run_mode(bank->target);
+       result = kinetis_check_run_mode(k_chip);
        if (result != ERROR_OK)
                return result;
 
@@ -2651,6 +2743,8 @@ COMMAND_HANDLER(kinetis_nvm_partition)
        struct kinetis_chip *k_chip;
        uint32_t sim_fcfg1;
 
+       k_chip = kinetis_get_chip(target);
+
        if (CMD_ARGC >= 2) {
                if (strcmp(CMD_ARGV[0], "dataflash") == 0)
                        sz_type = DF_SIZE;
@@ -2663,7 +2757,11 @@ COMMAND_HANDLER(kinetis_nvm_partition)
        }
        switch (sz_type) {
        case SHOW_INFO:
-               result = target_read_u32(target, SIM_FCFG1, &sim_fcfg1);
+               if (k_chip == NULL) {
+                       LOG_ERROR("Chip not probed.");
+                       return ERROR_FAIL;
+               }
+               result = target_read_u32(target, k_chip->sim_base + 
SIM_FCFG1_OFFSET, &sim_fcfg1);
                if (result != ERROR_OK)
                        return result;
 
@@ -2746,7 +2844,7 @@ COMMAND_HANDLER(kinetis_nvm_partition)
        LOG_INFO("DEPART 0x%" PRIx8 ", EEPROM size code 0x%" PRIx8,
                 flex_nvm_partition_code, ee_size_code);
 
-       result = kinetis_check_run_mode(target);
+       result = kinetis_check_run_mode(k_chip);
        if (result != ERROR_OK)
                return result;
 
@@ -2763,7 +2861,6 @@ COMMAND_HANDLER(kinetis_nvm_partition)
 
        command_print(CMD_CTX, "FlexNVM partition set. Please reset MCU.");
 
-       k_chip = kinetis_get_chip(target);
        if (k_chip) {
                first_nvm_bank = k_chip->num_pflash_blocks;
                num_blocks = k_chip->num_pflash_blocks + k_chip->num_nvm_blocks;

-- 

------------------------------------------------------------------------------
Announcing the Oxford Dictionaries API! The API offers world-renowned
dictionary content that is easy and intuitive to access. Sign up for an
account today to start using our lexical data to power your apps and
projects. Get started today and enter our developer competition.
http://sdm.link/oxford
_______________________________________________
OpenOCD-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/openocd-devel

Reply via email to