After piecemeal work on it over the last few months, I’ve been intensively working for the past week or so on Cortex-M support in muforth.
In order to try to understand the CMSIS-DAP code – in particular, how one writes an OpenSDA application – I ended up adding almost all the “everyday” ARMv7-M instructions to the disassembler – ALU ops, memory loads and stores, but none of the floating point or exotic SIMD instructions.
I finally finished the Cortex-M0 (ie, ARMv6-M) assembler, and just two days ago added basic debug support for the Stellaris Launchpad, a bright red ten-dollar board with an 80MHz ARM Cortex-M4F processor on it.
I’m working on a native Forth compiler that initially will target the Cortex-M0, but that means it will run fine (just slower than ideal) on Cortex-M3 and -M4 parts. (I can always tweak and improve it later to support the M3 and M4.)
The CMSIS-DAP support – for the Freescale Freedom board – is working fine, but seems a bit slow. I think doing debug over HID packets is a mistake; using bulk endpoints, or even doing control transfers (like I do for the S08JS16) seems much faster. Since I have access to the CMSIS-DAP source code, I know that they have up to 32 packets in a ring. In an effort to get things to go faster, I changed my code to have up to 16 packets “in the air” at a time; sadly, a large transfer (reading 128KiB of flash) went only two times faster.
Fundamentally I don’t care about the performance of CMSIS-DAP – or any of these built-in debug protocols. I plan to use them only to explore the board and chip, and to get my debug stub code onto the chip. Once I’ve done that I can ignore their firmware entirely. Of course this means mastering the curiousities of (currently) three ways to program the flash and talk to the USB. One reason I’m working on getting my Forth meta-compiler working is that I’d ideally like to write my USB debug stub in Forth. The stub – and all other little USB “apps” – I’ve written for the S08JS16 is assembler (all 512 bytes of it. ;-)
All in all, I’m pretty happy with my progress. Once the Forth (meta)compiler is done, I can start thinking about adding ARMv7-M instructions to the assembler.
Two days ago, after modifying the OSX USB support in muforth (to support USB HIDs), I was able to turn the “connect” LED on the board on and off. This meant that the connection between muforth and the HID firmware was working.
Then, yesterday afternoon I successfully read the IDCODE from the on-chip SW-DP. This required getting the connection sequence right – sending a binary string to the SW-DP. ARM’s documentation – the ARM Debug Interface v5 spec and the ADI v5.1 supplement – disagreed on what this sequence should be. I settled on sending 56 ones followed by 8 zeros, and this seemed to work.
My next hurdle was to try to read the chip’s memory. But any access to AP (access port) registers failed, returning a FAULT. It turns out that it is necessary to first turn on the CSYSPWRUPREQ and CSYSDBGREQ bits in the DP.CTRLSTAT register... Once I did this, the chip was mine!
Read the 2010 journal.