CategoryTutorials

Tup: Make Alternative for Embedded Systems

T

I hate Make.  With a fiery burning passion, I hate Make.  From day one, I found it difficult to understand, difficult to write Makefiles, difficult to modify Makefiles, and difficult to use Makefiles.  Over the years, I have built a collection of boilerplate Makefiles that only sort-of worked for a given project, and any time I wanted to do something creative with the build system, it was a challenge to figure out how to force Make to do what I knew damn well how to do via the command line.

There has to be a better way!
There has to be a better way!

Wasting time on HackerNews, I saw a post about a build system called Tup.  It was designed as a pet project for a pet project, but I was able to understand the syntax in just a couple hours of reading and experimenting.  Seriously, in just a couple hours, I was writing Tupfiles from scratch, something I would never think of doing with Make.

Tup has some seriously huge benefits if you’re building projects with thousands of files, and lots of nested directories.  Tup uses inotify and some other tricks to automatically figure out what needs to be rebuilt, and when it needs to be rebuilt.  I’ve been told that you can do a lot of this using Make, but I have never been able to write a Makefile that didn’t try to rebuild everything all the time, so even though I shouldn’t be saving build time using Tup on small embedded projects, I am, by a huge margin.

In fact, “tup monitor -a” is probably the most magical command I’ve encountered in any build system ever.  Because tup uses inotify, the monitor daemon can receive notifications that files in the build chain have changed, and automatically determine what parts of the project need to be rebuilt.  As a result of this, my project is often rebuilt by the time I’ve alt-tabbed to the terminal to check the results of the build and upload to the board.  Serious, magic.

Most of my projects lately have been built on AVR8 processors, so I’ve created two Tup skeletons on github, if you’d like to try it out:

https://github.com/Zuph/TupArduinoSkeleton

https://github.com/Zuph/TupLufaSkeleton

The first is an Arduino skeleton project that allows you to easily write Arduino code using whatever text editor and programmer you damn well please.  Simply #include “Arduino.h” at the top of every file, and you’re in Arduino-land.  Works out-of-the-box with any AVR processor used on an Arduino, including the AtMega328, and AtMega2560.  Other processors will require a pin definition file in order to work with Arduino functions.  To use, clone it, run “tup init” then “tup upd”.

The second is a skeleton project for LUFA, the AVR USB library.  I’ve been using LUFA with the Teensy++ 2.0, but there are plenty of other boards and processors that can make use of the library.

If you want to improve the skeletons, or submit your own, I welcome all pull requests.  I’m also happy to help folks get started with tup.  The more folks using it, the more well-supported it will be in the future!

LPC1114FN28 with Open Source Tools

L

I’ve been excited about the LPC1114FN28 for a while now (at least, as excited as one could be about a microcontroller).  The LPC1114FN28 is a microcontroller from NXP with an ARM Cortex-M0 core in a 28 pin DIP package. With 32k of flash and 4k of RAM, this chip isn’t the biggest or baddest on the block, but at $1.50 in small quantities, it has just about every other uC beat in the performance-per-dollar arena.  It’s got the basic peripherals, SPI, Serial, ADC, and I2C.  It’s programmable via SWD or serial bootloader. Though I don’t use a breadboard too often any more, it’s great to have an easy-to-prototype ARM chip in my box.  Unfortunately, these chips are notoriously difficult to work with, especially with open source tools.

A few posts ago, I talked about getting an open-source ARM toolchain up and running.  With the correct linker scripts, this toolchain will work very well for this chip.  NXP has also seen fit to include an internal RC oscillator on-board, so the breadboard setup for this chip is surprisingly simple.  Here’s what I used:

I’ve got an LED for power, an LED hooked up to PIO1_8 (pin 17), a reset switch, and a pin header configured to work with an FTDI cable or an FTDI friend hooked up to the serial lines.  Most important is the resistor between ground and PIO0_1 (pin 24).  The value of this pin is sampled at reset, and if it is tied to ground, the chip enters the serial bootloader. Otherwise, it executes the loaded program.  This process can’t be done in software, so you have to connect this resistor when you want to load code, and disconnect the resistor when you want to run your program.  You could also use a pin on the FTDI friend for this, but you’d have to modify the ISP software.

As I said, I’m using the toolchain I configured earlier.  I found some blinky test code for another chip in the LPC1114 family, and modified it to work with the LPC1114FN28.  The modified code can be found here: https://github.com/Zuph/lpc1114-blink

In order to get the code to work, I altered the linker script to reflect the amount of RAM on this particular chip, and changed the pin configuration for the LED pin.  I also had to change the clock source: this was the most difficult piece to chase down.  Unlike AVR chips, where the clock configuration is set by fuses, this ARM chip (and many others) force the user to configure clock sources manually. Originally, line 154 of main.c read:

LPC_SYSCON->SYSPLLCLKSEL = SYSPLLCLKSEL_SEL_SYSOSC;

This configured the chip to use an external oscillator.  Changing this to:

LPC_SYSCON->SYSPLLCLKSEL = SYSPLLCLKSEL_SEL_IRC;

resolved the problems.  Output code is now being generated properly, but getting it on the chip is a different problem entirely!  Reading the manual for the series makes the bootloader look like a fairly simple piece of work!  Auto-baud synchronization makes interfacing simple, and the commands are reasonably easy to understand.  There are a few programs which purport compatibility with the the LPC111x family, including VSProg (from the Versaloon folks), and a likely-abandoned projected called lpc21isp.  Neither of these programs, however, support the LPC1114FN28/102 variant.  VSProg looked to be the most promising (given its general purpose nature), but modifying the config files proved fruitless in adding support for the FN28 (if you can get it working, please let me know!).  lps21isp, however, worked well once the parameters for the chip were programmed in.  I’ve uploaded the code for my variant here: https://github.com/Zuph/lpc21isp

I had to change lpcprog.c, adding the following on line 116:

{ 0x1A40902B, "1114FN.../102", 32, 4, 8, 1024, SectorTable_17xx, CHIP_VARIANT_LPC11XX },

This adds the FN28 chip-id, along with the amount of RAM, flash, number of flash pages, and the maximum amount of data to transfer at once (the bootloader uses a two step process, writing code to RAM, then moving it to flash in order to reprogram the ship).  Once this is added, I was able to easily flash code to the chip, although I wasn’t able to do so at 9600 baud.  115200 baud works well.

In summary, wire up a breadboard as seen in the picture above, compile the blink code, flash it on to the chip using the lpc21isp program, remove the resistor on pin 24, reset the chip, and watch it blink!

Here are the exact commands I used:

Possible caveats: The chip will only attempt to enter the bootloader once.  If autobaud has been attempted and failed, you’ll need to reset your chip to attempt it again.  Also, in the programming command, we give it the speed (in kHz) of the RC oscillator, since that’s the oscillator that the bootloader will be using.

Let me know if you have any questions.

ARM Cortex-Mx Quickstart

A

By now, almost everyone’s managed to acquire a bajillion cheap ARM dev boards, and there are always more coming.  As these chips get cheaper, and available in more hacker-friendly packages, they’re going to overtake chips and boards like the AVR and the Arduino, it’s just a matter of time.  Unfortunately, the ARM ecosystem isn’t as simple to work with as the AVR or PIC ecosystem.  With both of these 8-bitters, you’re working in the manufacturer’s walled garden.  ARM manufacturers, on the other hand, are free to glue whatever crazy stuff they want onto the ARM core.  As a result, peripheral sets and their use vary widely, even within the same manufacturer.  Efforts like the CMSIS ameliorate this effect to some degree, but this isn’t a cake-walk.  Add on to that the difficulties in simply getting a toolchain up and running, and anyone with mere Arduino experience is lost (even more experienced 8-bit devs are going to have some tough going).

So, here’s a short guide to getting a toolchain for the STM32 series up and running quickly.  These instructions will be specific to Linux, but should translate to OSX or Windows fairly easily.

First, I downloaded the Linaro Bare-Metal ARM toolchain (http://www.linaro.org/downloads/).  It’s important to get the Bare-Metal toolchain.  Other toolchains generate binaries that aren’t capable of running sans operating system. The bare-metal toolchain is at the bottom of the page.  This package contains the compiler, linker, debugger, and other tools used to turn source code into machine code.  I used the precompiled package from Linaro because it’s a simple off-the-shelf method to get up and running quickly.  Unlike Codesourcery/Sourcery Tools, the Linaro toolchain supports the Cortex M4 with FPU right out of the box.

In the past, I have attempted to compile their own toolchain (https://github.com/esden/summon-arm-toolchain/), but this is not a simple process.

In Linux, I just extracted the tar.gz file to the folder I wanted it to live, and added that folder to my PATH.

Next comes OpenOCD.  OpenOCD is an open source debugger/flash utility for lots and lots of different chips.  I had to get the latest dev version from the git repo, (http://openocd.sourceforge.net/repos/), as the latest stable release does not include STLink code.  If a version beyond 0.5.0 is released by the time you’re reading this, download that instead.

Installation was pretty easy.  I installed the dependencies using “sudo apt-get build-dep openocd”, then ran “./bootstrap”, followed by “./configure –enable-maintainer-mode –enable-stlink”, followed by “make” and “make install”.

Once I had the toolchain and debugger up and running, I downloaded some software to compile.  This github repository (https://github.com/nabilt/STM32F4-Discovery-Firmware) includes the test firmware provided by ST, with a Makefile capable of building it using GCC. Chibios (http://chibios.org/dokuwiki/doku.php) also includes demo files for all the discovery boards.

The first time I attempted to build the STM32F4 firmware, it didn’t quite work out.  Due to the varied nature of the ecosystem, a separate linker script is needed for each chip.  Furthermore, different compilers need different sections to their linker scripts, so it might not be possible to simply yank one from somewhere else.  The linker script tells the linker where different memory sections map into real, physical memory on the chip.

Here’s the linker script I eventually got working for my STM32F4-Discovery:

Makefiles themselves are beyond the scope of this post (and beyond the scope of my brain, in a lot of ways), but taking a peek at the Makefile used in the STM32F4 Demonstration firmware from above, there are  a boatload of dependencies from outside the project.  These are all CMSIS drivers, or required startup code.  This is a big part of why ARM chips are more difficult to use than ARM or PIC chips.  Fortunately, most manufacturers release some boilerplate startup code for their chips.  As long as it’s included in the makefile, everything will work as it should.

And those are the basics of going from nothing, to compiling demonstration code.  Right now, I’m looking heavily at the ChibiOS platform to develop some projects.  This abstracts a lot of the hardware stuff, although it isn’t nearly as simple as Arduino for getting up and running.  Hopefully with the upcoming release of the Arduino Due, there will be some development in making a really easy-to-use ARM platform.

Creating SVG files for solder paste stencil stencils from KiCad

C

Eventually, hand soldering surface mount components becomes a pain, especially if you’re doing small manufacturing runs. It’s much easier to work with solder paste and a hotplate.  Joints are higher quality, and you can manufacture more boards at once.  If it was good enough to get Sparkfun started, it’s certainly good enough for us! Working with solder paste does require a stencil, though.  The stencil contains precisely sized holes which allow solder paste to be precision applied to the metal pads on your PCB.  There are many companies which will provide cheap and high quality stencils, but if you have access to a laser cutter, there’s no reason you can’t do this yourself.

There are a lot of guides out there for creating SVG stencils from Eagle, so I’ll be covering KiCad in this tutorial.  Additionally, the laser cutter I have access to at the LVL1 Hackerspace is a Full Spectrum laser which can cut directly from Inkscape, so I’ll be basing this tutorial on Inkscape.

Step 1

Generate gerbers from your completely routed KiCad PCB project.  There are a lot of good guides out there for getting to this point in KiCad.

http://reprap.org/wiki/KiCad

http://code.google.com/p/opendous/wiki/KiCADTutorialCreatingGerberFiles

and a collection of resources here: https://meatandnetworking.com/w/Kicad_Resources

Step 2

Open your PCB in a program like Gerbv.  Any gerber viewer capable of outputting to SVG is alright for this, but I like gerbv the best.  You’ll want to open the solder paste layer, which KiCad names by default to something like “pcbFileName-SoldP_Front.gtp”.

Export to SVG, put the file anywhere you like. In Linux, you have to manually add the SVG file extension.

Step 3

Open the file in Inkscape.

Ungroup the objects by right-clicking on a pad or line and selecting “Ungroup.”

Open the “Fill and Stroke” menu.

Clear the “Fill”.

Turn on “Stroke” and set it to a color that your laser cutter likes.

Our full spectrum laser will try to cut the inside and the outside of the stroke if it’s too thick.  .1mm is thin enough that our laser cutter software will only cut the outside of the stroke.

Step 4

Before proceeding, you can delete the board outline, since it’s unnecessary.

Select all the objects, and open the “Transform” menu under “Object.”  Under the “Scale” tab, MAKE SURE that “Apply to each object seperately” is CHECKED.  This maintains the centroids of all your pads.  You’ll have to play around a little bit to get this value just right. Decreasing the size of the features is necessary due to the thickness of the stencil material.  The thicker the material, the more you’ll need to reduce the size of each feature.  For overhead transparency plastic, 90% is just about right.

Now you’ve got a finished stencil SVG, suitable for lasering.  In a future post, I’ll show off how to soldering using paste and a hotplate.

Toner Transfer and Muriatic Acid Etchant: Making PCBs at LVL1

T

LVL1 is great.  A place for creative and motivated people to get together and goad each-other into doing more creative things.  It’s also a great gathering place for tools, as well as knowledge.  A few months ago, the spoiled electrical engineer that I am, I never would have considered making my own PCBs.  Any project worth taking off the breadboard was worth sending to China to get made “right.”

Of course, there isn’t always time and money to send something to China.  Today’s installment is the Sumo-bot board I’m trying to put together for the Hive13 sumobot competition.  Unfortunately, it doesn’t look like poor Snoopy bot will make it to the ring, but the board making process itself is worth talking about.

Laying out a PCB using software like Eagle is beyond the scope of this post.  If you can follow the appropriate Sparkfun Tutorial, it’s pretty easy to pick up.  Something to note:  for single sided home-made PCBs, put all traces and surface mount components on the BOTTOM layer.  Put any necessary jumpers on the top layer.  When you’re ready to print, just turn off all the layers you don’t want turned into copper.

(more…)