yotta, cmake, ninja build tools for the Micro:bit explained

Understanding the offline build tools for the BBC Micro:bit

I use the offline build tools from Lancaster University for compiling and building C-code for the BBC Micro:bit board. I used the toolset without really understanding what was going on under the hood. Understanding our tools gives us a better chance of fixing things when they fail. So I spent a happy afternoon learning about these tools and how they differ from the system I was using for building C-code into executables. These executables are often called binaries.


yotta is a tool created at mbed to build C code aimed at a range of ARM processors into executable files. The processor on the BBC Micro:bit is an ARM processor. yotta is written in python so python needs to be installed on your system for yotta to run.

yotta uses a file called module.json containing information about the target platform. This information is used by yotta to download files that are required for your target hardware platform to enable your C code to work on that platform. These files are downloaded to a directory named yotta_modules. These files are used during the build process.

An example module.json file for the BBC Micro:bit is:

[code language="shell" light="true"]
"name": "microbit-c",
"version": "2.0.0-rc8",
"description": "The micro:bit runtime common abstraction with examples.",
"license": "MIT",
"dependencies": {
"microbit": "lancaster-university/microbit"
"targetDependencies": {},
"bin": "./source"

In the file yotta_targets/bbc-microbit-classic-gcc/target.json is a line:
[code language="shell" light="true"]
"toolchain": "CMake/toolchain.cmake",

This tells us that the CMake build system is used by yotta. So, what is CMake?


CMake is a command line tool that uses a file called CMakeLists.txt to create a list of shell commands that are run in a later stage to create the final executable for a C  project. This list of commands ends up in a file called Makefile. The CMakeLists.txt file contains things such as the flags passed to the compiler used to build the executable and the source files to be used in the build process.

Here I digress into the build system I am used to seeing, which uses ‘make’ to create the final binary executable. make is replaced by ninja in the Micro:bit build system. I cover this in the next section.

Github projects often use CMake to enable you to build the project’s source code on your system. To build these projects you often run the command ‘cmake’, which takes the CMakeLists.txt file in the github project and uses this to create the file Makefile. Then, running the command ‘make’ causes each of the commands in Makefile to execute.

As Makefile was created using cmake, the shell commands in Makefile will be the compiler commands to:

  • create .o files for all of our .c files

  • link these .o files together

  • create a /build/src directory

  • place the linked executable into this directory.

Often we run ‘make install’ to complete the installation of the binaries created from C code. The final output from running the commands in Makefile is often an executable binary file. The ‘install’ command copies this to wherever it needs to be in your system for it to run from the command line.

Digression ends.

But, but, but – the Micro:bit build system does not use ‘make’ to build the binary executable. Instead, it uses ninja.


If you can see the ninja, you are already dead.

ninja replaces make. make has been around for decades. Which is no bad thing. But somebody, somewhere, decided to make a better make.

One of the design goals for ninja is:

very fast (i.e., instant) incremental builds, even for very large projects

A quick search found somebody has compared the speed of make and ninja:

jpopsil – reports an increase in speed using ninja.

ninja creates a file called rules.ninja and build.ninja. ninja looks for build.ninja and uses this file to create the executable. If we look in rules.ninja, we see, well, some rules for how to build the executable. Looking in build.ninja…. there’s a lot of things. From reading the documentation, one of the ideas behind ninja is that all the decisions about how to create the executable are taken prior to the build. It looks like build.ninja has all of these build decisions in it. This allows ninja to do its job and create the binary without having to think too much along the way about what to do.

Edit April 2019

I found an excellent explanation of the micropython stack by Steve Stagg, who clearly understands the tool chain far better than I, about 3/4 of the way down this link:


This post refers to the micropython stack for the BBC Micro:bit, which  is built on top of the C stack.

The author has a picture, which shows the tool chain to be like this:





gcc g++ ld

According to the post ‘Micropython has some extra build stages, so has a Makefile wrapper around yotta,….’. So the make module at the top refers to the micropython implementation.  The post goes on to explain that  Yotta creates the CMake config file. I think I got that in this post as well. Ninja then builds this configuration. So far so good. Looks to be in agreement with what I wrote above. Steve has more details about what the ninja does when it runs. His post is worth a read.




Using the DRV8662 chip to create 105V DC from battery voltage.

This is how I generated a little over 100V of DC using a 3.95 V power supply with about $10 of parts.


Using a DRV8662 chip we can create a battery powered board that will generate a 105V DC power rail using around $10 worth of parts. Some surface mount soldering is needed though. If you have an input signal below about 500Hz, you can use the chip to amplify this to have a peak to peak output of up to around 200V.

DRV8662 test board, 3.95V DC input from the middle power supply, 104.7V DC output. What could go wrong?

All right. I said battery voltage but am using a beefy bench power supply. What’s with that? The beefy bench power supply has all kinds of current limiting and safety stuff built in that a battery pack does not have built in. Let’s not start fires until we want to.


I need a 100+ V DC rail as an input to a circuit to drive some piezoelectric crystals. The crystals I’ve been tasked to use resonate at 40KHz.  How should I go about this? First off, the crystals need a signal with an amplitude of around 100+V. How hard could that be. Errrr….


There are a couple of standard methods to create a boost converter:


For instance flyback transformers as used in ‘old school’ television sets. The type with tubes. Remember those? No? I’m old…

Inductor switching circuit

Switching a voltage into an inductor ‘bounces’ the output voltage up. One interesting design based on this idea can be found here. The switching frequency needs to be controlled to maintain a steady output voltage, ideally using some kind of a controller. It is a beautiful piece of electronic design which I think I would enjoy, but it’s all about time.

Have somebody else make it

Of course. The simplest and fastest way. Stand on the shoulders of giants. Now, how many battery powered 100V DC-DC converters can I find on eBay. None. However, after some searching, I did find an integrated chip that does most of the work for me made by Texas Instruments.

Enter the DRV8662

Texas Instrument’s DRV8662 chip is designed to drive a haptic feedback piezoelectric transducer at up to about 500HZ. If we look at the functional block diagram in the data sheet, which I copied below, we can see that an external inductor (L1) is used by the IC to generate a voltage rail at up to about 105 V. This voltage rail is called VBST. This is used to power an internal operational amplifier. This op-amp can be used to amplify an input signal from IN+ and IN-. The output can be applied to a piezoelectric transducer, shown acroos OUT- and OUT+. 

So we have an inductor switching circuit to generate the DC voltage rails and a high voltage op-amp with a gain-width bandwidth somewhere around 500V which can be used to drive a piezo actuator. The chip is designed to be used inside of e.g. mobile phones, to make a piezoelectric crystal vibrate so that your phone shakes. Now you know where that comes from.

The simplified schematic below the functional block diagram is basically the same, but the outline of the chip is dotted in. The components outside of the dotted line are the ones that we need to add to make the circuit work. What values to use? I copied the ones from the demo board that Texas Instruments make.Then started playing.

I used R1=768K and R2=16K gives me a 105V DC output. According to my calcs, R2 = 10K should give me a 105V output. I think the extra inductance from using flying leads on the inductor affected this. On my first board with the inductor soldered close to the IC, using R2=20K gave me about a 52V VBST. On board two, with the inductor on flying leads, I got VBST as 84V.

On a PCB I would place 10K to get the 105V output. Or maybe start with 12K and resolder it if the rail was too low. I used L1 = 3.3uH and Rext = 7.5K, using a recommended inductor from the data sheet. GAIN0, GAIN1 and EN are tied high using 1K resistors. Don’t forget that EN needs to be high. Or the chip no worky.

DRV8662 functional block diagram, from Texas Instrument’s data sheet.
DRV8662 simplified schematic, from Texas Instrument’s data sheet.

If the resonance frequency of the crystals I want to drive was below about 500Hz I could use the DRV8662 on its own to generate the necessary driving signal. Feed a square wave at the crystal’s resonance frequency to the input pins and slap the crystal across the output pins. But I can’t. The resonance frequency of my targets is too high. Once I put a signal over 500Hz into IN+ and IN-, the output amplitude rapidly decreases.

However, the chip does allow me to tap the boost voltage that it creates from the VBST or PVDD pins. I can use this high voltage with some extra circuitry to generate a high voltage oscillating signal at 40 KHz to make my crystals shake. Watch this space.

‘But, but but, you’re using a fraction of the IC’s capability to just generate the 100 V rail, wouldn’t it be cheaper to make your own voltage boost circuit?’. The DRV8662 costs $3 in low quantities. Even Farnell in the UK only charges £3 each. Plus VAT. Plus postage. Even so, no, it wouldn’t be cheaper to spin my own circuit using transformers or a switched inductor, especially when you factor in my valuable time at $1 an hour. I know, I earn the Big Bucks.

So I bought a few DRV8662s from Farnell and soldered one down onto a QFN20 to DIL converter board. Which in plain speak is a little circuit board that converts a stupid small chip with no legs into something that I can plug into some breadboard to play with. The soldering is not too tricky if you use a decent small bit in your soldering iron, plenty of liquid solder flux and have a fan to blow the toxic fumes away. I use a USB powered fan designed to go inside computer cases with a power brick for this. eBay.

The first board I made is on the picture below on the left. Note that I soldered the inductor directly to this board. It worked. Lovely. Then I shorted the VBST pin to ground with a crocodile clip. Careless. Not that I’m bitter. Still, a bit of care would have avoided this. I learned my lesson.

Why is there a bit of brown tape on the second board? I put a corresponding bit of brown tape on one edge of my breadboard to remind me which way around to stick the module into my breadboard as it looks pretty much the say both ways around, but only works one way around and may never work again after being put in the wrong way around. I don’t want to find out if the last statement is true or not.

With the second board, I soldered the inductor onto some leads and stuck this into the breadboard. I found that the output voltage was higher than when the inductor was stuck directly to the surface mount to DIL converter board. Why? I suspect that the extra leads and path to and from the inductor increases the overall inductance.

Why did I use that particular inductor? Because the data sheet said that make and model would work. That’s why.

DRV8662s on surface mount to DIP converter boards. Why two? Because I wrecked the one on the left.

Looking at the picture below, which shows the DRV8662 on the converter board on the test breadboard, you can see that for instance, the two power leads I use are of different lengths. This makes it hard for the crocodile clips to ever come into contact. If you look closely at the flying leads connected to the yellow multimeter in the picture at the top of this article, these are placed so that they cannot easily come into contact. I live and learn. Slowly. I ordered some decent grabber probes.

DRV8662 on breadboard. It works.

Why are there two capacitors daisy chained on the VBST pin?

VBST -||–||- GND

Because the output on VBST is 105V and each of the two capacitors is only rated to 63V. So I daisy-chained two of them. There is probably not much risk of a 63V rated capacitor cooking off at 105V, but if it were to short, then the DRV8662 could die. As I found out when I shorted VBST to ground with a crocodile clip. Not that I’m bitter about this. Not at all.

How smooth is the 105V voltage rail? No way to tell using breadboard. If you want a smooth rail, don’t use breadboard.

I tested using an input from a signal generator. Each output pin generates a signal in anti-phase to the other, so the peak to peak difference is about twice the VBST voltage.

Please find a couple of photos showing this testing below. For these tests I only had a 52V VBST. Then I learned that adjusting R1 in the simplified schematic above changed the output voltage. Reading the data sheet always helps. I started out using an old-school ‘scope as I like them. Then switched to a new-school ‘scope because I could and nobody stopped me.

DRV8662 testing using an old-school ‘scope.
DRV8622 circuit output with 52V VBST rail using a new-school scope..

Useful extra stuff

How do we know if we have soldered down the chip correctly? Please find some impedances that I measured between various pins for a working board below.

Pins   Impedance (Ohms)

1-6  9.61M

5-6   short

4-5   open (despite both being labelled GND)

10-11   short

1-3   5.12M

12-5   26.32M

13-5   23.8M

14-5   23.8M

15-5   16.25M

16-5   16.25M

17-5   16.25M

18-5   16.25M

19-5   16.25M

20-5   8.15M