diff --git a/src/flash/nor/kinetis.c b/src/flash/nor/kinetis.c index 6adc4ef73..12e3f5fb9 100644 --- a/src/flash/nor/kinetis.c +++ b/src/flash/nor/kinetis.c @@ -97,6 +97,8 @@ #define SMC_PMSTAT 0x4007E003 #define SMC32_PMCTRL 0x4007E00C #define SMC32_PMSTAT 0x4007E014 +#define PMC_REGSC 0x4007D002 +#define MC_PMCTRL 0x4007E003 #define MCM_PLACR 0xF000300C /* Offsets */ @@ -188,6 +190,9 @@ #define KINETIS_K_SDID_K60_M150 0x000001C0 #define KINETIS_K_SDID_K70_M150 0x000001D0 +#define KINETIS_K_REVID_MASK 0x0000F000 +#define KINETIS_K_REVID_SHIFT 12 + #define KINETIS_SDID_SERIESID_MASK 0x00F00000 #define KINETIS_SDID_SERIESID_K 0x00000000 #define KINETIS_SDID_SERIESID_KL 0x00100000 @@ -298,6 +303,7 @@ struct kinetis_chip { enum { KINETIS_SMC, KINETIS_SMC32, + KINETIS_MC, } sysmodectrlr_type; char name[40]; @@ -1537,6 +1543,17 @@ static int kinetis_read_pmstat(struct kinetis_chip *k_chip, uint8_t *pmstat) if (result == ERROR_OK) *pmstat = stat32 & 0xff; return result; + + case KINETIS_MC: + /* emulate SMC by reading PMC_REGSC bit 3 (VLPRS) */ + result = target_read_u8(target, PMC_REGSC, pmstat); + if (result == ERROR_OK) { + if (*pmstat & 0x08) + *pmstat = PM_STAT_VLPR; + else + *pmstat = PM_STAT_RUN; + } + return result; } return ERROR_FAIL; } @@ -1577,6 +1594,10 @@ static int kinetis_check_run_mode(struct kinetis_chip *k_chip) case KINETIS_SMC32: result = target_write_u32(target, SMC32_PMCTRL, PM_CTRL_RUNM_RUN); break; + + case KINETIS_MC: + result = target_write_u32(target, MC_PMCTRL, PM_CTRL_RUNM_RUN); + break; } if (result != ERROR_OK) return result; @@ -2143,6 +2164,24 @@ static int kinetis_probe_chip(struct kinetis_chip *k_chip) } } + /* first revision of some devices has no SMC */ + switch (mcu_type) { + case KINETIS_K_SDID_K10_M100: + case KINETIS_K_SDID_K20_M100: + case KINETIS_K_SDID_K30_M100: + case KINETIS_K_SDID_K40_M100: + case KINETIS_K_SDID_K60_M100: + { + uint32_t revid = (k_chip->sim_sdid & KINETIS_K_REVID_MASK) >> KINETIS_K_REVID_SHIFT; + /* highest bit set corresponds to rev 2.x */ + if (revid <= 7) { + k_chip->sysmodectrlr_type = KINETIS_MC; + strcat(name, " Rev 1.x"); + } + } + break; + } + } else { /* Newer K-series or KL series MCU */ familyid = (k_chip->sim_sdid & KINETIS_SDID_FAMILYID_MASK) >> KINETIS_SDID_FAMILYID_SHIFT;