STM32F1xx, some advice

I have worked with the ST Micro ARM Cortex-M3 micro-controllers. I think I like them but here is some advice to help you along.

  • Yes, you really need all those capacitors. These things run at 75MHz or better. Put the caps close to the pins.
  • These things are more easily damaged by ESD than one might think. Yes, I know they’re supposedly marketed for automotive applications. Yes, I know the data-sheet says class blah blah blah. You need to do more, I had a product whose only vulnerability was the battery compartment and I still had to do more. I found this helpful
  • Build your own cross compiler from scratch! You will learn things about C/C++ that you need to know to be a good embedded systems engineer. I have some stuff like crt0 and linker scripts on this site. Yes I cut and pasted them but I was about 3/4ths of the way through writing them from scratch before I found prettier ones on-line and no, I did not waste my clients time, I was able to solve deep problems with other people’s projects at the same client because I understood this stuff. I stood on the shoulders of giants and here’s a link to one of those giants 🙂 The Olimex site also has some info for building a cross compiler.
  • I like and recommend the Olimex boards but they have the same ESD problems I had so don’t be lulled into a false sense of security, add mitigation to your design. I used a TVP diode between VDD and VSS on the line coming from the battery clip.
  • I have the FlySwatterII and the Olimex ARM-USB-OCD-H, I prefer the latter mostly because it can provide power.
  • Use the ST micro provided libraries sparingly, sometimes it’s easier to understand the peripheral and write your own code than to try to sort out their library madness or HAL.
  • OpenOCD and gdb are awesome. Yes gdb has a steep learning curve, no it’s not pretty, but it is the most powerful debugger known to man… The only thing I’ve ever seen that was close ran on a VAX when I was a kid. I find cgdb helpful. I sometimes use the layout stuff but it’s a bit young (read buggy) but helpful. Seriously, learn to cope with gdb it can do things no other debugger can.
  • Read the errata these things have a surprising number of hardware bugs!

PIC Microchip, some advice

I like 8bit PICs but here’s some advice:

  • You want to use assembly. Really, don’t mess with whatever crazy (non-ANSI) c compiler these clowns are pushing. Assembly (particularly on these chips) is not hard.
  • MPLAB X is horrible, it takes all the things I love about PICs and makes it complicated.*
  • Don’t mess with the PICkit3 it only works with MPLAB X. You want the PICkit2, it works with pk2cmd. If you really need those debugging features then it’s time to move on to something with an ARM core (Serial Wire Debug gdb and all that)
  • If you need to do math use a lookup table (array). If your math is complicated then do it in C and use something with an 32 bit ARM core (read: not a PIC); these things don’t have FPUs. Really, most of them multiply by adding in a loop, an FPU is like a pocket calculator for your CPU.
  • Use the simplest chip you need to do the job, start out with something with with a modest number of peripherals lest you be overwhelmed.
  • Really, learn assembler your going to get stuck anyway and have to write some assembly anyway… and it’ll make you feel smart!

* What they’re really up to here is to immerse you in their marketing madness. Hey Microchip, if ya want me to use your high end chips than you need to contribute to gcc or clang or both, if it’s not an open source ANSI compiler I won’t use it, I am not going to learn your crazy dialect of C or pay you for the privilege of writing code that will create demand for your chip!

Beacons using a PIC10F200

Before there were standards like iBeacon and Eddystone we had to “roll our own.” This is a primitive beacon using a PIC10F200 (8pin DIP) along with a simple 315MHz OOK transmitter. Later versions, not shown here, use SDR.


This is written in PIC assembly. It simply transmits my FCC Call sign with a number tacked on the end. Production versions would substitute a UUID and checksum in place of my Call sign. The signal is intentionally weak, we only want to know if the watch (wearable device) is within a few meters. Battery life is important too, this thing should be good for about 57 years on a couple AAA batteries.

The gist of what this code does is to set a timer and go to sleep. When the timer expires the chip wakes up and increments some counter (the timer durations are rather short) and we need some randomization to minimize the possibility of interference betwixt proximal beacons*. If it’s time to send a burst, my Call sign, then it does so, resets the counter and timer and goes back to sleep. The idea is to spend as much time asleep as possible to conserve batteries.



* This is a bit tough to explain so bare with me. The oscillators on these things are not precise. So imagine we were to send a burst every 30 wake-ups (e.g. no randomization). Okay so lets say you have two of these close together and we put batteries in them at the same time. Now every 30 wake-ups they both wake up and clobber each other (the wearable can’t hear either because they “talk” over each other). Now eventually, because the oscillators are imprecise, they drift apart but that may take hours; therefore, we introduce some randomization to keep them asynchronous. I’m skipping some nuance here but I hope you get the idea.