Unbricking an EFM8UB3 Thunderboard

13 Jan 2021embeddedelectronics

I’ve been doing some work recently with a little Silicon Labs EFM8UB3 microcontroller. This is a nice 8051 clone with a bunch of peripherals all in a QFN24 package. I’ve been using a minimal development board Silicon Labs calls the Thunderboard. It’s mostly fine, but it has one failure mode that’s pretty annoying. This article is about how to back out of that failure mode if you encounter it.

The Thunderboard has a built-in JLink debugger, and it’s unfortunately possible to put the MCU into a state where the debugger can’t talk to it. That means that you can’t program the board any more, so you might think you’re stuck. You’re not!

This is an intermediate form of “bricking” a device. It’s worse than accidentally deleting a bootloader (just reflash the bootloader: you do have access to the programming interface for your device on your development board, don’t you?). It’s not as bad as letting the magic smoke out of your MCU (if you do that, your best debugging tool is a credit card...). Your MCU is still alive, it’s just unresponsive to the debugger.

The problem, as I understand it so far

I’ve not quite yet worked out what’s going on here, but here’s my understanding so far:

So you’re left with an MCU that is really perfectly fine, but you can’t do anything with it using the JLink debugger on the Thunderboard. Annoying, eh?

Never fear! There is a way out. Table 4.3 on page 19 of the EFM8UB3 datasheet has the following information:

Time between reset and code execution

So after reset, we have a gap of around 50 µs before the processor starts executing code, and if it’s a power-on reset, at least 3 ms, and more likely about 10 ms. Can we get in and halt the processor during that time window?

We’re obviously out of luck with the JLink, but we can use the C2 programming interface on the EFM8UB3 directly.

Unbricking with an Arduino

Instead of using the on-board JLink debugger, we can twiddle the C2 clock and data lines ourselves. The easiest way to do this is to hook the Thunderboard up to an Arduino or similar. I used an Arduino MKR WiFi 1010 board, just because that’s what I had lying around, but more or less any Arduino-compatible board should work with the unbricking software described below. I plugged both the Arduino and the Thunderboard into a breadboard and made the following connections:

Arduino Thunderboard
Digital pin 0 P2.0 C2D data connection
Digital pin 1 RST C2CK clock connection

The Thunderboard is a little bit wide for a standard breadboard, so you may end up doing what I did and routing the ground wire out from underneath the board. My setup looks like this:

Connections 1

Connections 2

Unbricking software

We need some software to twiddle the C2 clock and data lines. The C2 algorithm is partially documented in Chapter 23 of the EFM8UB3 reference manual and in more detail in application note AN127: Flash Programming via the C2 Interface, but fortunately, Conor Patrick has already done most of the work for us, by writing a flash programmer for EFM8 devices (conorpp/efm8-arduino-programmer) that uses an Arduino to communicate over the C2 interface.

I took Conor’s code and chopped out the parts that I needed and built an “unbricker”. You can find the source here. Here’s what it does:

So the procedure is:

  1. Connect up your Arduino and Thunderboard as described above.

  2. Make sure the “Power Source” selection switch on your Thunderboard is set to "DBG USB”.

  3. Flash the unbricker.ino sketch to the Arduino.

  4. Start the Arduino’s serial monitor and send an "unbrick" command.

  5. Disconnect the Thunderboard from the Arduino and connect to the debug USB port as usual. You should now be able to reprogram the Thunderboard using JLink Commander or whatever other programming software you use.

Testing it

To test an unbricker, you obviously need a reliable way of bricking the thing. The first time I got a Thunderboard into this state, it took me a while to figure out what had happened. Long enough that I’d completely forgotten what I’d done to mess things up in the first place...

I ended up writing a little "brick-it" program that does some slapdash clock configuration on the EFM8UB3 that seems to reliably put the thing in a state where the JLink debugger can’t talk to it. (I still don’t understand 100% what’s going on here, but I’ve seen this problem mostly when trying to enable the 48 MHz HFOSC1 oscillator on the EFM8UB3. I’m doing something wrong there, for sure, but it’s allowed me to build a reliable means of bricking a Thunderboard, so I don’t feel too bad about it!)

I’ve included the source for the brick-it program in the unbricker repository, but you probably don’t want to run it on purpose. It’s useful for testing the unbricker, but that’s about it.

Actually, one other thing it might be useful for is to learn what kinds of messages your programming tools display when you connect them to a board that’s bricked this way. I use JLink Commander for programming my Thunderboard, and when I try to connect to a bricked board, I get messages that look like this (mostly including these here for the benefit of people who might Google for them):

Connecting to target via C2
DevID, DerivID: 0x36, 0x00
Core: CIP-51 (8051 compatible)
Device series: <Unknown> series device
CPU supports 4 code breakpoints
Flash infos: 512 byte sectors, 80 sectors, all sectors unlocked
DevID, DerivID: 0x36, 0x00
Core: CIP-51 (8051 compatible)
Device series: <Unknown> series device
CPU supports 4 code breakpoints
Flash infos: 512 byte sectors, 80 sectors, all sectors unlocked

****** Error: EFM8 (C2): Unsecure failed.

DevID, DerivID: 0x36, 0x00
Core: CIP-51 (8051 compatible)
Device series: <Unknown> series device
CPU supports 4 code breakpoints
Flash infos: 512 byte sectors, 80 sectors, all sectors unlocked

****** Error: EFM8 (C2): Connect failed and connected J-Link (S/N 440110519) does not support fallback method (firmware too old). Please get in touch with SEGGER
EFM8 (C2): Unsecure failed.
Cannot connect to target.
Target connection not established yet but required for command.
Device "EFM8UB31F40G" selected.

If you ever see something like that, your board might be in this state, and you might be able to recover it using the method described here.

I have so far found the Arduino unbricker sketch to be 100% successful in recovering a Thunderboard that’s in this state. I believe that it should also work for other early start-up misconfiguration issues (putting the MCU to sleep in a low power mode right after reset, for example). It may also work for other EFM8 parts, but I have only tested it with the EFM8UB3 Thunderboard, so YMMV.

OK, board unbricked! Back to work! Now I need to figure out how to set these clocks the way I want them without breaking things...