Phillip Pearson - web + electronics notes

tech notes and web hackery from a new zealander who was vaguely useful on the web back in 2002 (see: python community server, the blogging ecosystem, the new zealand coffee review, the internet topic exchange).


Phil's guide to Burning Man, part 1

This year will be Burning Man #7 for me and #3 for my fiancée, but #1 for many of our friends, who we've finally convinced to come with us :D

We have a ton of advice to share. It probably won't all fit in one blog post, but here goes. I expect to write about each of the following:

  • Basics: when and where
  • Tickets, and obtaining them
  • Transport: getting in and out
  • Camping: friends and family -- your support network
  • Accommodation: your tent and everything inside
  • Your bike: essential for getting around
  • Food
  • Hygiene

Here we go!


If you know nothing about Burning Man, start by reading everything you can on the official Burning Man site, but especially the preparation page and the 10 principles. I'd highly recommend watching Spark: A Burning Man Story too; you can stream it on Netflix.

In a nutshell: Burning Man is a week long party in the Black Rock Desert, to the north of Reno, Nevada. It runs for about a week, ending on Labor Day: in 2016 it's Sunday August 28 - Monday September 5. It's a festival of some sort, except all the entertainment comes from the participants; there aren't any "official" acts, but hundreds of groups of determined campers make amazing art and throw parties large and small, so it feels less like a music festival and more like you've stumbled upon some foreign-but-familiar city filled with hedonistic artists and house party hosts.

Some jargon: "Burning Man" is the event, "Black Rock City" is the place. If you attend Burning Man, you're a "burner", and BM is typically referred to as "the burn". The desert floor is called "the playa", and the ever-present beige dust is "playa dust". When you or your car or your stuff is covered in enough of it, you're "playafied".

I highly recommend trying to catch as much of the event as possible; I've always gone in on Monday or Tuesday, and left on Labor Day. If you can't spare that much time, you can trim a little off each end of the week: you could probably feel pretty satisfied coming in during the day on Wednesday and leaving early Sunday morning. Wednesday night is a big party night, as are Friday and Saturday. I personally love staying for Sunday night; while there's less to do during the day as many camps start packing up early Sunday morning, the Temple Burn that evening is beautiful, and the departure line ("exodus") is much shorter on Monday morning.

Assuming you intend to go, at this point in the year you need to be thinking about a few things:

  • Ticket: you need one to get in. They cost about $400, plus another $80 or so for your car. It's not the end of the world if you don't have one yet, but you will have to hustle.
  • Transport: how are you getting there? Do you have your own car, or are you going to rent one or drive with friends? Are you renting an RV to sleep in, or do you just need something big enough for you and your gear?
  • Friends: who are you camping with? You probably want to join a pre-existing camp. If you don't know any burners, it's time to start making friends!

Those are your priorities right now. Less critical, but still important later on, are the details of how you'll survive the event itself.


The main ticket sale is over now, which means ticket availability will be pretty scarce for the next little while. Ask around in case one of your friends picked up more tickets than they needed, though. Some camps are permitted to pre-purchase tickets (because the Burning Man Organization wants to make sure they can attend), so your camp organizer may be able to point you in the right direction.

Failing that, when tickets start hitting mailboxes around July, they'll also start showing up on Craigslist. Right before the event, there's an "OMG Sale", which releases a few thousand more tickets onto the market.


If you're camping in a tent (which doesn't have to be so bad -- I'll be writing another post with details on how I do it relatively comfortably), you just need a ride for you and your gear. You'll end up with a surprising amount of stuff; I've never ended up with spare room in a car after packing two people, their gear, and their bikes, especially once you include food and ~18 gallons of water per person.

If you're planning on renting an RV, enquire now. I looked into it in December and found that the cheapest RVs available were around the $5000 mark -- it seems that taking an RV is now an expensive luxury. If you don't mind adding 10 hours to the drive, you can save some money by renting in LA or Las Vegas instead of San Francisco or Reno.

Renting a car will cost you ~$600 with all the insurance, and you'll need a bike rack also. If you have a brand new car that you can't stand to get dirty, you probably don't want to take it (because it'll smell like playa dust for up to a year afterwards), but the playa-inflicted damage isn't that bad; it's probably equivalent to a couple of years of ski trips.

I rented an ordinary compact from various rental agencies in 2010, 2011, and 2012, and it was a little cramped, but worked just fine -- although you'll save on time and stress during the packing process if you rent a bigger car.

There are various other options available to you if you have someone to haul all your gear, and possibly all your food: buses, trains, and planes!

Burning Man runs the official Burner Express bus all the way from San Francisco to BRC, and also for the short hop from Reno to BRC. It has its own entry line, so you get in much faster than driving, except your luggage is limited to one or two suitcases. This is probably an excellent way to get in solo, as long as you have transport for your bike (or you rent one from Playa Bike Repair).

Consider also mixing it up: Last year one campmate packed his bike and cooler in our camp trailer, took Amtrak from SF to Reno last year (and loved it!), then joined other campmates in their RV from there.

Finally, the luxury option is to catch a small plane from Reno airport directly in to BRC; this will set you back about $1000, but is by far the quickest way to get in and out, and the view is amazing.

Your camp

Unless you really like roughing it, it's essential to join a pre-existing camp that has done this before and is fairly good at it. A really organized camp will have a generator, trash disposal, greywater disposal, a shower or two, perhaps their own porta-pottie, a kitchen with a grill or two, a chill space, and a public space. IMHO the absolute minimum for comfort is: a shower, good greywater disposal (so individuals don't have to haul their dirty shower water home), and a chill space.

Some camps will require you to work planned shifts as well as pay camp dues and bring gifts for the bar, etc. Others won't be very demanding at all. If you're camping on Esplanade, 2:00, or 10:00 (the highest visibility streets), or in one of the plazas, you'll probably have to spend time helping out with whatever entertainment your camp is contributing. If you're camping further inside the city, your camp might be purely residential, or you might be putting on smaller parties. Shop around to find something that works for you :)

For friends who are camping with us: the camp I'm part of has a shower, workable greywater disposal, some solar panels and car batteries for lighting, a kitchen dome, and a really nice chill area out front. Some campmates put together a giant trampoline type hammock every year, and we also have a dome full of chairs to hang out in during the day. We also have no camp dues, and nobody will yell at you if you don't do any work (but folks who do help out will be remembered when it comes to allocating pre-sale tickets the following year).

That's all for now... the next blog post will be about tents and bikes, I imagine!

... more like this: []


Cheap Chinese STM32F103 boards

I recently ordered a bunch of STM32F103 boards from China. They have a rectangular footprint like the Teensy or Arduino Micro, and a 48-pin STM32F103C8T6 MCU on board -- a 72MHz Cortex-M3 with 64kB of flash and 20kB of RAM. It's just the single MCU chip on board, with a bootloader, and the SWD pins brought out to a header, which should make it quite flexible; I'll be able to program/debug them with Eclipse and OpenOCD if I want full control, or I can use the STM32duino Arduino port if I just want to push code to them. The best part is that they only cost $2.25 each on Aliexpress, or about $3.50 on eBay, which is about half the cost of the chip alone when bought in the US.

The boards I've ordered are 2.1" long by 0.9" wide, with a rows of 20 pins along each side, and 0.6" from the center of one row to the other. I've made a KiCad part and footprint for them:

Part/library → myelin-kicad-libraries/stm32f103c8t6-module-china.lib

Footprint/module → myelin-kicad.pretty/stm32f103c8t6-module-china.kicad_module

These should be good for controlling LEDs over USB, or for soldering into projects where I feel that a Teensy would be too expensive.


CMSIS-DAP work: implemented raw JTAG support, and ported the HID firmware to Pro Micro and Teensy 3.2

While I am so happy to have my J-Link back, the couple of weeks without it have been very productive in terms of open source contributions. After finding out that OpenOCD didn't support raw JTAG mode on CMSIS-DAP adapters, I bit that off as a potential project, and eventually got it working, then did some performance tuning, and I'm pretty pleased with it now. With my LPC-Link2, it can program the flash in an ATMEGA32U4 over JTAG at about 1/4-1/3 of the speed of the J-Link (which is kind of a speed demon). I'm going to let it soak on GitHub for a while, then clean it up and submit it to OpenOCD once it's had a bit of scrutiny.

Clone myelin/openocd and check out the cmsis-dap-jtag branch to try it out.

Implementing this required getting pretty familiar with the CMSIS-DAP source code and protocol, and at some point I realized that it wouldn't be super hard to port the SWD/JTAG debugger part of the CMSIS-DAP firmware over to any USB capable microcontroller. Full CMSIS-DAP support requires the debugger part, plus a serial port and a mass storage device emulator that's also capable of flashing a .bin file to a chip, but I'm not doing this to provide a USB interface to a custom board (like the ones on the mbed site), so I've skipped those two. I'll probably add in the serial port sometime, because I wrote serial bridge code for teensy-openocd-remote-bitbang already.

This was mainly a matter of getting rid of Keil-specific code, plus a small amount of debugging:

  • The _OUT functions (e.g. PIN_SWDIO_OUT) take a uint32_t with a boolean value in the LSB, but often junk in the higher bits.
  • A 32-bit processor is expected, so there was one point where I needed to add (uint32_t) casts to avoid losing the high bytes of a word.

So here's CMSIS-DAP firmware for your Pro Micro (ATMEGA32U4) or Teensy 3.2 (MK20DX256) board.



Trying out the CNC mill at Noisebridge

I've been doing quite a bit of fabrication work at Noisebridge over the last year or so -- mostly electronics, plus a bit of 3D printing. One bit of equipment I've been interested in for a while is the MaxNC 10 CNC mill, which has been covered by a sheet for a while and appeared out of order, but has recently been unearthed and looks a bit happier. I gave it a try tonight, and it looks like it should be usable!

It's controlled by a computer under the desk running an ancient version of Ubuntu, with a realtime kernel for the control software. Booting it up and double-clicking the maxnc10ol link on the desktop brought up LinuxCNC. Flipping the red switch on the mill brought it to life, and the machine started up properly after hitting F1 then F2.

The axes are set up so that the origin is the bottom left front corner of the thing being milled, and the positive direction is right/back/up in the x/y/z axes:

  • X axis: + moves the platform left, - moves the platform right
  • Y axis: + moves the platform towards the user, - moves the platform towards the machine
  • Z: + moves the bit up, - moves the mill down

When homing axes, you can only move an inch in the 'negative' direction before the software will stop you -- need to rehome the axis (redefine your negative position as 0) then hit F1 twice and F2 again, then you can move it another inch. So it took a few tries to get the machine to move far enough to the left (moving the platform over to the right), and a couple to get the Y axis homed.

Once the spindle looks like it's in a safe place, you can run your program with Machine | Run Program. This will start the spindle and move through the program, then stop wherever it finished. It happily ran through its demo program.

The mill is a little small for the sorts of things I have in mind (large wooden boards cut in interesting shapes, like a lot of art at Burning Man these days) but could work nicely for PCB milling -- someone at Noisebridge has had some luck with this -- if I get some cheap PCB blanks from Aliexpress, and a couple of carbide mill bits. I suspect that the sweet spot here would be for very simple single-sided boards which are SMD-only... for example, one-off custom LED fixtures with a string of addressable LEDs and no onboard controller (or a very simple one that doesn't need any complicated traces or small pads -- so my favourite tiny MCU, the MKE04Z8VTG4, would be out, but the SOIC version would be OK, or maybe the 0.8mm TQFP44 MKE*VLD* chips).


Still trying to get JTAG working with the ESP8266

Good news -- my replacement J-Link is in the mail! Reliable hardware on the way.

In the meantime, I'm still working on my CMSIS-DAP adapter and my ESP8266 board. I'd mis-soldered a 10uF capacitor between TCK and ground (instead of 3V3 and ground), which was stopping anything from working, but after hooking my Saleae box up to the board, I debugged that fairly quickly. I fixed some bugs in the code, but OpenOCD still failed to do the initial chain scan, so something's still broken.

To debug this, I changed tack: OpenOCD also has a "remote_bitbang" driver, where it sends a series of ASCII characters to a TCP socket, to drive a very very simple JTAG adapter. This sounds like a recipe for the worst JTAG performance ever, except that the Teensy 3.2's serial-over-USB performance is very very good, and I saw some pulses as short as 2us in the logic capture, so this should be able to get me ~250 kbit/s, which is certainly good enough for now.

Here's the teensy-openocd-remote-bitbang code, on GitHub

It took a bit of messing around with socat on OS X to get it to bridge between a TCP socket and a serial port, but I found the magic set of arguments eventually:

socat -d -d -d file:/dev/tty.usbmodem1485121,clocal=1,cs8,nonblock=1,ixoff=0,ixon=0,ispeed=9600,ospeed=9600,raw,echo=0,crtscts=0 tcp-listen:3335,reuseaddr

The corresponding OpenOCD incantation is:

openocd -d -c "reset_config srst_only; interface remote_bitbang; remote_bitbang_port 3335; remote_bitbang_host localhost" -f target/esp8266.cfg

Unfortunately OpenOCD *still* couldn't scan the JTAG chain, and it did get bits out TDO this time, so that hardware is not completely broken, but I still have some debugging to do.

Update: I suspect TDO is in high-impedance mode -- it looks like it's floating around 1.5V. Perhaps the ESP8266 doesn't enable its JTAG pins while in reset? Either that or maybe I need to program the chip with code that enables the JTAG pins.

Update 2: Got it working! It turns out that my understanding of remote_bitbang's reset signals was the wrong way around -- RESET is active-low electrically, but the remote_bitbang protocol spec assumes active high. So "reset=0" means 3v3 on the reset pin, and vice versa. The ESP8266 JTAG pins are high-impedance in reset, which is why I saw TDO floating. This doesn't explain why my CMSIS-DAP code didn't work, but at least now I have a known-good state to compare with.


Kinetis E and OpenOCD update, and some Kinetis FTMRH flasher code and JTAG rambling

Following up on my last post, I managed to get OpenOCD flashing a Kinetis MKE02Z64VLD2 chip, to the point that I could hook it up to Kinetis Design Studio and program/debug almost as easily as with my J-Link, albeit without unlimited flash breakpoints, and it would often get confused about where it was on startup, although after hitting F8 everything would come back to normal.

I posted to the OpenOCD-devel mailing list and got a bunch of responses from others who had been working on the same problem, including Ivan Meleca, who had written a flash driver for the KE02/4/6 series but hadn't had time to upload it. I tested this out tonight on my MKE02Z64VLD2 and MKE04Z8VTG4 boards and it works well, so look forward to seeing that in mainline OpenOCD soon.

Ivan's code works, so I don't want to mess with it, but I'm proud of a couple of little tricks I figured out for my own implementation. I wrote a Python script to process the output of arm-none-eabi-gcc -g -O0 -mcpu=cortex-m0plus -mthumb -c -Wa,-adhln, extract out the opcodes, and comment everything up nicely, which lets you build self-contained routines that are easy to download and run on target devices. I'm not sure how everybody else wrote their flasher code, but they all seem to have ended up with slightly differently formatted hex bytes embedded in C files, so maybe by hand? Anyway, my flash algorithms and C-to-assembly-to-C code are up on GitHub as myelin-mcu-flash.

Next, my esp8266-jtag boards came back from OSHPark, and I soldered one up and connected it to my LPC-Link2, only to find that OpenOCD doesn't support JTAG operations on CMSIS-DAP adapters, only SWD. So I started writing some code to get that working. The next day, someone wrote on OpenOCD-devel that they were trying to do the same thing. So hopefully we can combine efforts and sort it out. I've learned a lot about JTAG in the last few days -- in a nutshell it's a very complicated way to reset a chip and read and write two registers, but it turns out that you can do a *lot* with those building blocks :)

Here are some notes from my attempts to get OpenOCD to support the raw JTAG operations in the CMSIS-DAP API, to talk to my ESP8266 board.

To get JTAG to work, you need to be able to clock in arbitrary sequences on the TMS pin, and you need to be able to clock in arbitrary sequences on the TDI pin with TMS low, while capturing output on the TDO pin, and setting TMS high as you clock in the final bit. This makes more sense if you look at the JTAG state diagram. TEST LOGIC RESET resets the test logic. Entering CAPTURE-DR copies data from the device into the DR register, and entering UPDATE-DR copies data from the register to the device. Every entry into SHIFT-DR clocks a bit from TDI into DR (on the rising edge of TCK), and a bit from DR out TDO (on the falling TCK edge). CAPTURE-IR, SHIFT-IR, and UPDATE-IR work similarly. All other states are just intermediaries that make it convenient to navigate around the state machine without needing too long of a sequence on TMS.

The relevant CMSIS-DAP operations, using the defines in the mbed CMSIS-DAP code:

  • ID_DAP_SWJ_Sequence, which clocks out a sequence on TMS
  • ID_DAP_JTAG_Sequence, which clocks out sequences on TDI, and optionally sets TMS and captures TDO.

DAP_SWJ_Sequence is already supported, because it's necessary to switch between JTAG and SWD mode. ID_DAP_JTAG_Sequence isn't used for SWD, but we need it for raw JTAG. The packet format seems to be:

  • byte 0: the number of TDI bit sequences in the packet
  • byte 1: sequence info for the first sequence
  • byte 2..length(sequence 1): sequence data for the first sequence
  • ... other sequences follow ...

The max sequence length is 8 bytes (64 bits), and the sequence info byte is: (0x80 if capturing TDO, else 0) | (0x40 if TMS is set, else 0) | (sequence length in bits, with 64 encoded as 0).

This suggests that a 'scan' operation (writing something into the IR or DR register) will require one DAP_SWJ_Sequence command to move the TAP to Shift_IR or Shift_DR and one DAP_JTAG_Sequence command to write the command. We can probably just leave the TAP in the shift state once the command is done, but we could use another DAP_SWJ_Sequence to get back to the idle state if that's not okay.

Looking at the bitbang driver, it looks like the desired end state is given in cmd->cmd.scan->end_state, the input and type (input or output) can be obtained via jtag_build_buffer and jtag_scan_type, and it's an IR scan if cmd->cmd.scan->ir_scan is set. The actual scan function moves to the TAP_DRSHIFT or TAP_IRSHIFT state as required, then clocks the data in/out on TDI/TDO, then executes another state_move to get to the desired end state. So I guess we'll actually require three DAP operations to do this, because of the final requirements for TMS (unless we want to try to pack those into the JTAG_Sequence packet).

11pm update: Implemented! It compiles, but I haven't tested it at all yet, so expect many bugs..


Working toward being able to flash Kinetis E chips with OpenOCD, using USBDM flash routines

My J-Link broke yesterday, so I'm back to using either my FRDM-KE04Z board with USBDM firmware or my LPC-Link2 with CMSIS-DAP firmware to program my Kinetis E devices. USBDM seems to only support Windows and Linux, so I'm trying out the LPC-Link2 with OpenOCD today.

My chip is a Kinetis MKE02Z64VLD2 (64 kB flash, 4 kB RAM, 20 MHz max), which OpenOCD doesn't have a flash algorithm for. With any luck it should be able to debug my chip out of the box, but I'm going to have to steal code from USBDM to get it to download my code.

First things first... Homebrew seems to install OpenOCD 0.8.0 when you run 'brew install open-ocd', so I built and installed 0.10.0-dev from git. Copying /usr/local/share/openocd/script/kl25.cfg as ke02.cfg and running openocd with the following in openocd.cfg seems to get it started:

interface cmsis-dap
adapter_khz 500
transport select swd

source ke02.cfg

Once OpenOCD is running, it listens on ports 3333 (GDB remote protocol) and 4444 (command shell). telnet localhost 4444 gives you something like the J-Link Commander console. 'reset' and 'halt' do the expected things, so it looks like it's handling the SWD protocol just fine.

Now to figure out how to extract the KE02Z64 flashing code from USBDM... here's what I've figured out:

So it looks like we have all the pieces of the puzzle... the trick will be to get FlashProgrammer_ARM.cpp wired up to OpenOCD's interface code, so it can write and execute code on the target.

(to be continued)


Using a Teensy as a USB-Serial bridge to program an ESP8266

Hopefully in future I'll be able to program my ESP8266 modules using JTAG, but I have a project from last year which used the ESP8266, didn't bring out the JTAG pins, and tied GPIO15 (TDO) to ground, which means it would require desoldering the ESP-03 module to fix. I programmed it using the ESP8266 Arduino extension and a Sparkfun FTDI Basic Breakout board, which unfortunately doesn't bring out RTS, which meant for a lot of power cycling. To make matters worse, the FT232 seems to crash sometimes when subjected to this sort of thing, losing control of its DTR output and needing power cycling *itself*.

I happen to have a couple of Teensy 3.2 boards here, however, and they're super easy to program up to act as a more flexible serial adapter. Here's the sketch I ended up with, which happily programs my ESP-03 at the max upload speed selectable in the ESP8266 Arduino IDE, 921600 baud, and with any luck will work with the ESP GDB stub:

// Simple USB-Serial bridge for programming ESP8266 modules

// new connector:
// GND (black) RXD (grey)  GPIO0 (brown)
// 5V (n/c)    TXD (white) RTS (purple)

// RX2 = pin 9, white wire, connects to ESP8266 TX [saleae ch0]
// TX2 = pin 10, grey wire, connects to ESP8266 RX [saleae ch1]
#define HWSerial Serial2
// DTR = pin 11, brown wire, connects to GPIO0 on the ESP8266 [saleae ch2]
#define DTR_PIN 11
// RTS = pin 12, purple wire, connects to CH_PD on the ESP8266 [saleae ch3]
#define RTS_PIN 12

uint32_t current_baud = 9600;
uint8_t current_dtr = -1, current_rts = -1;

void setup() {
  Serial.begin(9600); // fake value -- USB always 12Mbit
  pinMode(RTS_PIN, OUTPUT);
  digitalWrite(RTS_PIN, LOW);
  pinMode(DTR_PIN, OUTPUT);
  digitalWrite(DTR_PIN, HIGH);

void loop() {
  if (Serial.available() > 0) {
    uint8_t c =;
  while (HWSerial.available() > 0) {
  // update params
  uint32_t baud = Serial.baud();
  if (baud != current_baud) {
    current_baud = baud;
  uint8_t rts = Serial.rts();
  if (rts != current_rts) {
    current_rts = rts;
    digitalWrite(RTS_PIN, current_rts ? LOW : HIGH);
  uint8_t dtr = Serial.dtr();
  if (dtr != current_dtr) {
    current_dtr = dtr;
    digitalWrite(DTR_PIN, current_dtr ? LOW : HIGH);
... more like this: [, ]


Debugging the ESP8266 with JTAG -- breakout board with an SWD-style JTAG connector

I found out a few days ago that it's possible to debug the ESP8266 using JTAG (and the Xtensa-specific xt-ocd, or the open source OpenOCD). It looks like work to make this possible has been going on for about a year now, as well as related work to develop UART-based GDB stubs (there's now an official one!).

This doesn't seem to have attracted nearly as much attention as I would have thought. Maybe because hobbyists nowadays are used to the Arduino platform, which doesn't include any on-chip debugging support? (Unless you cut some traces and plug in an Atmel ICE unit.) The ubiquitous availability of on-chip debugging is probably my favourite thing about working with ARM Cortex-M chips; it's kinda painful to go back to an environment where I don't have access to that. I'm currently working on some DMX512 hardware, and recently had a yak-shaving-like need to implement my own non-blocking software UART; this wouldn't have been possible without being able to breakpoint and single-step using KDS, SWD, my J-Link, and my Saleae Logic 8.

Anyway, I'm super excited to give this a try on an ESP8266. Unfortunately all my ESP-03 modules are soldered into boards that tie GPIO15/MTDO to ground, and otherwise I only have a couple of ESP-01 units, which don't bring out the JTAG pins.

So... time to get an ESP-12 or two, and whip up a board with all the bits and pieces JTAG requires!

JTAG is an old interface/protocol, and is designed to daisy chain through a bunch of chips, so it has much more in the way of pullup/pulldown requirements than SWD. Here's what I ended up putting on my board:

- Pulldown on TDO. This should really be a pullup, except that TDO/GPIO15 is part of the boot_sel combo (GPIO15:GPIO0:GPIO2), which has to be 011 to boot from flash, so GPIO15 must be pulled low if you ever want to boot without an attached debugger.

- Pulldown on TCK. This is also nonstandard; most JTAG diagrams show no pull resistors on TCK, but have it terminated with 68R and 100pF in series to ground. ARM recommends a pulldown, though -- to avoid spurious clock edges during hot-plugging -- so I'm going with that.

- Pullups on TDI and TMS. This is standard JTAG.

- Pullups on CHIP_EN and /RESET -- always required on the ESP8266.

I chose to use an SWD-style 2x5 1.27mm connector, which will hopefully let me connect this to my J-Link using the same cable that I use for ARM debugging. Here's how the board looks:

Sending this off to OSHPark shortly! Design files and most recent gerbers are on GitHub.


Serial Wire Debug - properly wiring up a Cortex-M debug connector, and debug adapter/software thoughts

One of the things that confused me the most when moving between the AVR and ARM Cortex-M worlds was what debug/flash interfaces to support. The LPC11U1x series has a UART based flash download method (shared with the LPC810, according to this Adafruit tutorial), and the LPC11U2x/3x chips add in various USB options. STM32F chips have their own method, and I've seen an I2C downloader for WLCSP (very small) versions of Freescale Kinetis chips.

All of these are red herrings! The only interface you need is SWD, an ARM standard that gives you a connection right into the processor bus -- i.e., pretty much full control of the chip. It's active all the time unless you've disabled the SWDIO and SWCLK pins or assigned them to other duties, and has very good open and closed source support across the board.

This PDF from ARM explains the connector you need. It's a 2x5 header with 1.27mm (0.05") pitch. One row of pins for power/ground, another for data. There are some gotchas in there, and here is what I've figured out through trial and error. First, the power row:

1 - VCC - connect this to your MCU power net to get convenient power right from the debug adapter. You might want to put a jumper in series if you'll sometimes want to self-power the board, or leave this disconnected entirely if you'll *always* have the board self-powered.

3 and 5 - GND - connect to your ground net.

7 - KEY - leave this unconnected

9 - GNDDetect - this is for target boards to detect the presence of a debugger. I always leave it unconnected, but if knowing a debugger is connected is useful to you, put a pullup to VDD and feed this into a GPIO.

Now, the data row:

2 - SWDIO - connect this to your MCU's SWDIO pin. Pull-up/down resistors are usually unnecessary here, although check your datasheet to be sure.

4 - SWCLK - connect this to your MCU's SWCLK pin. Add a pull-down resistor to ground, between 10-100k.

6 - SWO/TDO - connect this to SWO (Serial Wire Output) on your MCU if you're using a Cortex-M3/M4. Cortex-M0/M0+ chips don't implement SWO, so I like to connect it to TXD on a spare UART in that case, which gives me a convenient serial console over the debug connector (I have a board that breaks out the UART pins separately so they don't go to the debugger).

8 - NC/TDI - either leave this unconnected, or connect it to RXD on a spare UART if you like my UART multiplexing trick.

10 - nRESET - connect to your MCU's /RESET pin. This usually needs a 10-100k pullup to VDD.

That's the electrical side of things sorted. Now, the physical. You'll find that SMD and thru-hole 0.05" pitch connectors are surprisingly expensive compared to 0.1" headers. After buying a bunch of $0.70 SMD 2x5 connectors and $0.30 thru-hole ones, I found a vendor on Aliexpress who was selling 10-packs of 2x50 connectors (of either type) for about $8, which can easily be chopped up into whatever length you like. This brings the cost of a 2x5 connector down to about $0.10, which seems much more reasonable.

Finally, debug connectors and software. Each chip family, and sometimes each chip, has a different flash controller, so you'll find that you need software for your particular device before you can erase, flash, or debug it. Here's what I've gathered so far:

- The SEGGER J-Link is a very very flexible debug adapter, that supports pretty much any Cortex-M chip, and is supported by pretty much every IDE. It will save you a ton of time to buy one of these, but you'll be paying $400 for a commercial-licensed version if you're doing anything other than educational/hobbyist work (in which case the $60 "EDU" version will do).

- CMSIS-DAP is ARM's standard for SWD over USB. Any CMSIS-DAP compliant adapter should work with any CMSIS-DAP compliant tool. As of now, there aren't a ton of these, but if you buy a development board, there's a good chance you'll be able to reflash the debug connector side of it with CMSIS-DAP firmware, and use it as a CMSIS-DAP dongle for any chip you can find software for (i.e., you're not limited by processor family any more). The firmware is open-source, available on GitHub.

- Free IDEs exist for most chip families. For Atmel ATSAM chips, there's the Visual Studio based Atmel Studio (which requires a J-Link, or the $50 ATMEL ICE adapter, to program chips). For Freescale Kinetis chips, you want the Kinetis Design Studio (which supports J-Link out of the box, or you can hack up a Freescale Freedom dev board and program it with the USBDM firmware). For NXP LPC chips, there's LPCXPresso (which supports CMSIS-DAP, J-Link, and NXP's $20 LPC-Link2, or you can hack up an LPCXPresso dev board).

- I'm a little confused about the STMF32 chips from STMicroelectronics. They have super cheap ~$10 "Discovery" dev boards, which come with an on-board ST-LINK/V2 debug adapter (available separately for ~$20), but as far as I can tell, don't have a vendor-supported free toolchain. However, there's a ton of open-source support, and you can put together a free toolchain without too much trouble. For flashing/debugging your chips, you'll want OpenOCD, which supports pretty much any debug adapter under the sun.

While we're talking about OpenOCD... it is an awesome open source project that I would love to use/contribute to if I find time. It seems like the Right Thing to do, allowing you to debug many kinds of chips with many kinds of adapter. I see it has support for some members of the Freescale Kinetis family, and it was able to connect to a MKE04Z8VTG4 using my LPC-Link2 with CMSIS-DAP firmware, but doesn't have support for the FTMRE flash controller there. Porting the flash code from USBDM into OpenOCD would be an excellent project, and would enable OS X support for more Kinetis devices. Both projects are licensed under the GPLv2.

That said, I'm probably going to buy myself a J-Link soon, because I really like the look of the Atmel ATSAM4S16B -- $5 in single quantities, 120 MHz Cortex-M4 with 1MB flash and 128k sram -- and I want to use Atmel Studio. So far I've been using a Freescale FRDM-KE04Z board with USBDM to debug my MKE04Z8VTG4 and MKE02Z64VLD2 based boards, and an LPC-Link2 to debug my LPC11U14 and LPC11U12 based boards.

... more like this: []