Electronic – Freescale Kinetis KE – writing to flash

flashj-linkkinetisprogrammingtools

I've been using various microcontrollers and microprocessors for many, many years now but I seem to be stymied by the Kinetis KE series (specifically the S9KEAZN64AMLC).

Jan 17, 2015 TL;DR:

Freescale confirms that v2.0.0 of their Kinetis Design Studio software does not work with this device (including their own TRK-KEA64 eval board). They recommend using CodeWarrior MCU V10.6 for the time being.

Segger has released v4.96a (the "a" is important, I was using v4.96) which corrects the issue and allows you to use a Segger J-Link Lite CortexM debugger board with KDS and have full program/debug capability.

Before Segger released v4.96a I managed to be able to flash the chip by reprogramming the OpenSDA debugger on Freescale's inexpensive ($15) FRDM-KL25Z eval board by reflashing the OpenSDA firmware it comes with with USBDM (using v4.10.6.240). I then used USBDM's standalone "ARM Programmer" software. I did not spend much time trying to get debugging working, as I am proficient enough at "oldschool" debugging to not need it. Please make sure that you flash a "benign" program into the on-board target KL25 or it may interfere with programming since the on-board target KL25's reset line is still connected to the OpenSDA debugger even with J11 cut (see Keith Wakeham's blog post, linked below).

A big thank you to Erich Styger for very very graciously helping me determine the issue and confirm my findings over email.

Now back to our regularly scheduled question:

I've built a stupid-simple 3.3V breakout board. It's got some LEDs on PTA, a UART connection on PTC and the SWD lines are on their dedicated lines. There's literally nothing fancy or funny about this board.

I'm using a J-Link Lite for Cortex-M (J-Link LITE CortexM-9, see https://www.segger.com/jlink-lite-cortexm.html) and under both OSX and Windows I get the same result: the J-Link Commander utility can identify the chip, I can read and write to SRAM and play around with the peripherals with manual reads and writes to the correct memory-mapped I/O address. When I try to flash the device, though, it fails.

$ JLinkExe
SEGGER J-Link Commander V4.94c ('?' for help)
Compiled Oct 31 2014 20:08:55
DLL version V4.94c, compiled Oct 31 2014 20:08:48
Firmware: J-Link Lite-Cortex-M V8 compiled Jul 17 2014 11:40:12
Hardware: V8.00
S/N: 518107921
Feature(s): GDB
VTarget = 3.332V
Info: Could not measure total IR len. TDO is constant high.
Info: Could not measure total IR len. TDO is constant high.
No devices found on JTAG chain. Trying to find device on SWD.
Info: Found SWD-DP with ID 0x0BC11477
Info: Found Cortex-M0 r0p0, Little endian.
Info: FPUnit: 2 code (BP) slots and 0 literal slots
Cortex-M0 identified.
Target interface speed: 100 kHz

J-Link>device skeazn64xxx2
Info: Device "SKEAZN64XXX2" selected (64 KB flash, 4 KB RAM).
Reconnecting to target...
Info: Found SWD-DP with ID 0x0BC11477
Info: Found SWD-DP with ID 0x0BC11477
Info: Found Cortex-M0 r0p0, Little endian.
Info: FPUnit: 2 code (BP) slots and 0 literal slots

J-Link>r
Reset delay: 0 ms
Reset type NORMAL: Resets core & peripherals via SYSRESETREQ & VECTRESET bit.

J-Link>erase
Erasing device (SKEAZN64xxx2)...

(...several second pause while it communicates with the MCU...)



****** Error: PC of target system has unexpected value after erasing sector. (PC = 0xFFFFFFFE)!
---------------------------------------------------------------------- Registers -------------------------------------------------------------------------------------
    PC   = FFFFFFFE
Current: R0   = 00F3E3BE, R1   = 00000001, R2   = 4004801C, R3   = 00000001
    R4   = 00000000, R5   = 00000000, R6   = 000000F4, R7   = 1FFFFD61
----------------------------------------------------------------------------------------------------------------------------------------------------------------------------


Info: J-Link: Flash download: Total time needed: 2.174s (Prepare: 0.894s, Compare: 0.000s, Erase: 0.736s, Program: 0.000s, Verify: 0.000s, Restore: 0.542s)
ERROR: Erase returned with error code -5.

The J-Link Lite is perfectly fine (I can read and write to the nRF58122 SoC, another Cortex-M0 processor, with it) and the device seems to otherwise work. I know the Kinetis is unlocked as they're factory fresh stock from DigiKey, but even then the "kinetis unlock" command in JLinkExe times out without any error or useful information.

At this point in time I'm sure I'm doing something stupid, but I'm at a loss for what it could be.

Has anyone worked with these devices before? How are you programming them?

edit to add walkthrough:

Some more information:

I read that the NMI# pin is enabled out of reset (and verified this by reading SIM_SOPT) but also that it has an internal pull-up when enabled. On this particular part PTB4 is on pin 10 which is a no-connect in my design. Disabling the NMI pin makes no difference. RST# is similar; It's connected to a pushbutton that grounds the pin and also goes to the J-Link Lite but there is no external pullup. This shouldn't matter because like NMI#, the RST# pin has an internal pullup that is enabled when PTA5 is configured to be a reset.

Looking at clocking now… Out of reset, ICS is the clock source to the FLL and BDIV in ICS_C2 is set to 001 (the reset default). If I understand correctly, this means that the 32kHz internal oscillator is multiplied by 1024 by the FLL and then divided by 2, making ICSOUTCLK 32kHz * 1024 / 2 or 16.8MHz. I can verify through the J-Link CLI that the FLL is locked by reading ICS_S:

J-Link>mem8 40064004 1
40064004 = 50

(LOCK and IREFST are set, this is correct.)

I then move on to verify that the SIM has the clock enabled for the flash controller by reading SIM_SCGC. I can also quickly check to make sure that BUSDIV in SIM_BUSDIV is set to zero which means that the BUSCLK is the same frequency as ICSOUTCLK (i.e. it's not being divided down):

J-Link>mem32 4004800c 1
4004800C = 00003000
J-Link>mem32 40048018 1
40048018 = 00000000

So far, everything looks fine. BUSCLK is 16.8MHz and the flash controller clock isn't gated.

Now let's move on to the flash controller. Out of reset FCLKDIV is zero, and we need a 1MHz clock. Table 18-2 in KEA64RM shows that FDIV should be set to 0x10.

Out of reset:

J-Link>mem8 40020000 1
40020000 = 00

Setting up the divider and verifying things are good:

J-Link>w1 40020000 10
Writing 10 -> 40020000
J-Link>mem8 40020000 1
40020000 = 90

FDIVLD is set and the correct value in FDIV is shown.

Before going too far ahead, let's make sure that the flash isn't protected:

J-Link>mem8 40020001 1
40020001 = FE

KEYEN = 11 (disabled) and SEC=10 (unsecured). Ok. Let's try to verify the device is blank:

J-Link>mem8 40020006 1
40020006 = 80
J-Link>w1 40020002 0
Writing 00 -> 40020002
J-Link>w1 4002000a 1
Writing 01 -> 4002000A
J-Link>mem8 40020006
J-Link>w1 40020006 80
Writing 80 -> 40020006
J-Link>mem8 40020006 1
40020006 = 83

Here we see that the MGSTAT bits in FSTAT indicate that blank check has failed and also that non-correctable errors were found. Odd. Let's try erasing it ourselves:

J-Link>w1 40020002 0
Writing 00 -> 40020002
J-Link>w1 4002000a 8
Writing 08 -> 4002000A
J-Link>w1 40020006 80
Writing 80 -> 40020006
J-Link>mem8 40020006 1
40020006 = 80

The erase all command succeeded. Now let's try a blank check:

J-Link>w1 40020002 0
Writing 00 -> 40020002
J-Link>w1 4002000a 1
Writing 01 -> 4002000A
J-Link>w1 40020006 80
Writing 80 -> 40020006
J-Link>mem8 40020006 1
40020006 = 80

Now the blank check is fine?

At this point I'm about ready to give up, eat the loss on these prototypes and go with a processor from ST where I've never had these kinds of issues before. The Kinetis documentation is thorough enough but it is very dense and I'm finding it very difficult to get started. I can wiggle I/O through memory reads and access other peripherals but I can't for the life of me figure out what's wrong with the flash controller. I've been working with micros for over 20 years and this kind of difficulty is something I have never encountered before.

20150102 edit:

So still no go here. I have actually bought a FRDM-KL25Z eval board ($15 from DigiKey) and modified it by putting the generic CMSIS-DAP software on the OpenSDA debugger and cutting J11 as per Keith Wakeham's blog. I've got the on-board target (the KL25Z) running a simple program so it doesn't interfere with the reset line and I can see my SKEAZN64 with OpenOCD and play with it, but unfortunately it can't program it either. The Kinetis Design Studio (KDS) software won't flash my Kinetis because it says it's protected and I need to do a mass erase, but OpenOCD (as part of KDS) doesn't seem to know how to do this. The git master version of OpenOCD I built on my Mac understands Kinetis, but not the specific KEA series, so I'm back to square one.

Going back to the J-Link…

@AdamHaun had a really good clue, and if I set the J-Link reset type (rsettype command) to type '6' (Kinetis) J-Link is supposed to disable the watchdog after resetting the core. Looking at the WDOG_CS1 register (0x40052000) it does appear that that is the case, but still no dice. An erase operation seems to go off the rails with PC at 0xfffffffe and error code -5, and an "unlock kinetis" command only works if I disable the reset pin using SIM_SOPT (by writing the 32-bit value 0x00000008 to 0x40048004). Unfortunately if I do that the CPU cannot ever be halted again, presumably because the SWD interface can't use the reset line to force the SWD DAP into a known state.

20150103 edit:

I HAVE BLINKING LED

REPEAT

I HAVE BLINKING LED

TL;DR version: put the USBDM image on the FRDM-KL25Z board (a story all on its own), use the ARM Programmer standalone app to send the test .elf over to the board. Power cycle and voilĂ .

Long version will come later. I now have less than 48h to write and debug software for this KEAZN64 board, finish modifying/testing other software that goes with it, and work on some documentation for another client. I promise I will update this question with a detailed answer. I just wanted to share my success. Thank you EVERYONE for your assistance. I might have to speak with the mods because I would really like to give the bounty to a couple of you in particular.

Best Answer

I cannot actually find any logical errors in your procedure, but here are some suggestions:

  • there's also a FTMRH_FERSTAT register (at 4002_0007h). It's supposed to tell you what went wrong... but only in the case of parity (or double parity errors). I'm not convinced this will record anything in case or erase errors, but probably worth checking out.

  • the KEA documentation also mentions that an interrupt may be triggered by flash errors (section "18.3.5 Flash and EEPROM interrupts"). I don't know if that's what happens when the SEGGER erases it, but it is a plausible explanation as to why the PC changes too since you did see errors flagged in the FSTAT register. Unfortunately the KEA documentation section for the interrupt controller ("3.3.2 Nested Vectored Interrupt Controller (NVIC) configuration") is rather vaguely pointing in the direction of ARM's website for full documentation. I wasn't able to figure out if there is a default interrupt handler set up (at boot) for flash errors.

  • You've only done erases at sector level manually, so try to manually (as in by writing the appropriate register yourself) issue a full flash erase command; the only way to do this in a single command seems to be the "Unsecure flash command" documented in section 18.3.9.10 (p. 246) of the manual. This will both "unsecure" the device and do a full flash and EEPROM erase. You can poll a FSTAT bit (CCIF) to see when it's supposedly completed and check the error flags again afterwards. EDIT: there's also a "18.3.9.7 Erase All Blocks command" section in the manual, duh.

  • try a lower bus clock frequency. Anything above 0.8 Mhz works according to the documentation. I'm suggesting this because there was one thread on the Freescale forum where an external flash worked fine, but not above a certain frequency that still was in the ok-documented range. So it's possible that the flash controller in the chip is flakey and cannot operate on the full range of stated frequencies.

  • likewise, thy a different chip. It's not inconceivable that given how much these cost (around $3) you've got a bad one. I do remember having an embedded x86 chip that worked fine in most ways but had weird errors on certain protected mode instructions; my problem went away with a different device of the same make. It's not clear to me if Freescale has (publicly stated) steppings and errata for these devices or not.

This is all I can think of in terms of debugging suggestions that wasn't said by others on this page.

20150103 edit(s):

(Moved material here from my comments & expanded)

It seems that not all Kinetis Series are (officially, at least) tested with all flashers. The fairly new EA series that you're actually using appears to be officially supported only by Freescale's own/OEM Cyclone MAX flasher; it's the only one listed on Freescale's page for the EA serires. Now granted, for older Kinetis like KL0 the list is much longer, including a SEGGER. I don't know if that's simply because of a lack of testing of other flashers for the EA series or if there's actually some programming quirk involved that only their Cyclone MAX currently knows about. I was hoping that maybe this is just Freescale being slow on listing other flashers, but upon checking the J-link manual (hopefully the right one), there's no Kinetis E or EA series listed there (p. 249) as tested either, but only Kinetis K10 to K60 devices (and some older MAC7's).

Worth noting is that the PExDrv software/firmware for the Cyclone MAX has a service pack (v10.3) dated 3/20/2014, which "Adds support for MKE04Z64, MKE04Z128, MKE06Z64, MKE06Z128, SKEAZ64 and SKEAZ128 derivatives." Another clue is that Freescale's own open-source bootloader/flashloader software for the Kinetis, despite being updated even more recently in 12/2014, does not list any E or EA [sub]series devices as supported. So I think there's something sufficiently different regarding flashing between the E/EA-series and other Kinetis like the K10, although I have no idea what exactly is that difference. Therefore I think that expecting EA flashing to work automatically with anything but the Cyclone MAX is probably unrealistic at this point. You might be able to eventually figure out how to do it at "bare metal" level (direct register commands) from the EA-series documentation, but I agree that the documentation is pretty obtuse; it certainly lacks any step-by-step instructions being just a reference manual. Had Freescale's open-source bootloader/flashloader supported the E/EA series, you'd have been able to peek at its source code and reproduce its steps... but that's alas not an option.

Your experiment with the FRDM-KL25Z (which comes with a Kinetis L series) points in the same direction, i.e. you can't swap an L-series with an EA-series and use the same flasher (OpenSDA in this case).

And if you're like Keith (the blogger) who "think[s] $100 dollars for a programmer is ridiculous", you probably won't be pleased with the perspective of dropping $900+ on that Cyclone. I don't know if Freescale does this on purpose to fleece their automotive customers or what... It surely looks odd that the tooling for most of the Kinetis series doesn't work with the E/EA.

Also beware that OpenSDA's flashing function only works under MS Windows, apparently.

If you're willing to try (hacking) more boards, one with an E-series Kinetis might a better idea, e.g. FRDM-KE02Z ($13 at Digi-Key); also uses OpenSDA so it might be hackable. They don't make/sell boards with the EA-series, as far as I can tell. However, it seems you cannot use one OpenSDA processor/board to program a different Kinetis type than the one on its own board, even if both processors are in the same (e.g. L) series, but different numbers. Unfortunately "Open" in OpenSDA only means the SDA spec is open, not that they give out the source code as open-source; so I can't even find source code to program an E-series flash. Apparently, I'm only half-right about that. OpenSDA v1 is not open-source, but v2 is.

So here's the lowdown on OpenSDAv2. It's basically just a CMSIS-DAP/mbed bootloader & flasher. So it may not have the same features or support the same chips as v1... and that actually turns out to be the case because flash_features.h does not list any MKE (Kinetis E-series) let alone SKE (EA-series) devices. In summary, Freescale's proposition for the EA series seem to be: buy our $900 Cyclone flasher or good luck writing your own from whatever incomplete bits of open source we have released.

It turns out however that there is an open source project that can program at least the E-series Kinetis, namely USBDM. The relevant bit from its changelog is:

V4.1.6.140 (April 2014)

Additional Kinetis devices (MKE04, MKE06, MK64F)

  • Fixes for MKE devices (failed to program except after Mass Erase)

And based on that log entry, it surely appears the E-series are quirky. There's no direct support for EA-series (SKE), but that code base is probably your best bet if you want to hack your own flasher; or perhaps you can convince USBDM's author to add EA-series (SKE) support. As hardware for USBDM it turns out you can use the FRDM-KL25Z you've alreadly acquired; but you still have to hack the USBDM software to support the SKE chips.

The master config file for USBDM looks rather daunting. In USDBM different flashers (code bases) are used for different MKE series devices: something called "FTMRE" is used for MKE04 & MKE06, but "FTMRH" is used for MKE02. After looking myself briefly at the two code bases, you almost surely want the FTRMH code base not the FTRME one. The latter has a different FTMRH structure than your SKEA64 device, for example, the clock divider is not the first but the 4th field. FTRME also sets the bus FIDV to 0x17 = 24Mhz, which seems out of range for your chip (p. 224 in the KEA64 manual suggests max 20Mhz). FTMRH sets it to 0x0F = 16Mhz (like you do), which seems okay.

At this point, (unless you wanna buy the Cyclone MAX) your best bet is to contact Podonoghue to get your chip working with his code base. He seems active and quite willing to help with new devices (on the freescale forum).

Also from that USDBM source code I can prophesy that there's no way your SEGGER can correctly flash your SKEA by itself unless it gets its own firmware update first. Why do I say that? Because USDBM's FTMRH code base is used by exactly one device there, the MKE02, which your SEGGER seems to know nothing about either (based on its manual). Other, more common devices like the Kinetis L and K series use a different USDBM flasher based on a "FTFA" code base. If you look at FTFA's code, the flash controller register structure (also starting at 0x40020000) is different for these; the first field isn't even a clock divider, but the stat register, etc. "Great" way for Freescale to make incompatible devices... but a boon for flasher-makers, no doubt.