Alternative controller experiments


11 Sep 2014, 14:06

So, I'd like to start experimenting with completely custom controllers, primarily because stock on Atmega32u4s is quite low, and also because there's some nice possibilities with simple inter-chip communication on some of the other chips that might make for some interesting ergodox or modular keyboard implementations. Also, I'd like to think I have my head around AVRs well enough that branching out should be educational. At the moment, I'm going about this the hyper-minimal way, ie no spending money on standalone programmers or whatnot, until I have some idea of which chip I'd like to go with for a keyboard design I have been kicking around.

This will be a (somewhat slowly updated, I'm afraid) build log of sorts that documents my attempts to get up and running with Microchip's PIC and Freescale's Kinetis lines.
So far, I've successfully requested some samples from both companies, namely:
from Freescale (All Kinetis 32-bit ARM MCUs, 50-120Mhz)
from Microchip (40Mhz 32-bit)

Given that these are all SMT parts I've started to fit them to breakouts that can be hooked up with jumpers. This was my first two attempts at drag soldering and I have to say, it was pretty damn easy.

MK22FN1M0VLH12 (QFP-64)
PIC32MX220F032D (QFP-44)

I was originally under the impression that the K22FN1 pictured above actually had a one-time-use bootloader pre-programmed into it, so I put together the following little adapter board to use it over a serial transport which the documentation indicated was possible. Unfortunately it doesn't seem to respond when connected in this fashion, leading me to think that I probably misread the docs, especially seeing as when I went back into them I couldn't find anything claiming they were pre-loaded with a bootloader.

Fortunately Kinetis devices also support EzPort which is a subset of SPI that can be used to flash chips. I'm currently looking for some documentation showing a minimal circuit for this initial flashing, especially given that I can't be 100% sure I wasn't missing something from the minimal configuration on the test board above.

I've managed to locate a few minimal breadboard setups for the PIC and an app to use an AVR as a PIC programmer, (apparently I could probably also use my Raspberry Pi) so will give that a try and update when I have more to show for it.
Anybody else tried anything like this? I'd be curious to hear what people have done.

User avatar

11 Sep 2014, 15:39

what's the size of the controller in mm?

I'm asking because I'd love an oddly shaped PCB to make it more keyboard compatible.

something like this with the USB on top
pcb.png (1.03 KiB) Viewed 6158 times

User avatar
Master Kiibohd Hunter

11 Sep 2014, 19:02

I've been using the Freescale mk20 line for my microcontrollers. Specifically mk20dx128vlf5 (similar chip to the teensy 3.0, but in a LQFP-48 package.
I'm looking at the mk20dx256vlh7 (same as the teensy 3.1), it has dual ADC 16bit ADCs which is nice for things like cap sense (and 64 k of RAM, which is nice for my macro layout state-machine code).

Might do some code on the MK22DX256VLF5, doesn't have as much RAM as the mk20dx256vlh7 and fewer pins.

mk22fn512vlh12 and mk22fn1m0vlh12 look interesting. 128 k of RAM and 512 k / 1 M flash respectively. Also have dual ADCs.

I've been using an SWD flasher for bootloaders (my code-base is sorta a hybrid between the PJRC and MCHCK with a lot of my own code).
The code is working, though I haven't linked in layout compiler to the build system yet.

I'm biased against the microchip stuff because their developer tools and documentation...are awful. I also need the dev environment to work Windows, Linux, Mac which microchip hasn't supported until recently (and the last time I used it, wasn't scripting friendly).

Anyways, I'm interested in your results for the mk22fn1m0vlh12 :mrgreen:
I might also start working with it in the near future.

User avatar

11 Sep 2014, 21:23

this looks awesome, will follow with interest!


11 Sep 2014, 21:50

Matt3o: These micros are all either 7x7mm or 10x10mm. I'm having a little trouble visualizing the shape you drew for me though :P

HaaTa: You wouldn't happen to have a really minimal schematic like the following that you'd care to share would you? The differences between MK20 and MK22 should be only superficial, and the documentation is really quite lacking in showing a bare-bones setup that can be flashed/tested just to make sure the chip works (I would also like some confirmation of the soldering on that chip).

I know Freescale have some really nice FRDM dev boards that are cheap, but I'd rather jump straight into a custom PCB/breadboard setup because I'm going to have to do that at some point anyways.

I'm also considering the PIC because they do the 18F4550 which is one of the few USB-capable chips I've seen that come in a DIP40 package, which I don't seem to really need any more personally, given my success with drag soldering, but having a design that could work with through-hole parts might make the controller more accessible to others.

User avatar
Master Kiibohd Hunter

11 Sep 2014, 22:10

I do have a very minimalist schematic for the Massdrop keyboard I'm working on. I don't really want to leak it before the keyboard is released in October. Though I'm sure I can get you a schematic of just the microcontroller part.

I'm using 6 caps, 3 resistors and an led for the mk20dx128vlf5.
For my next design I want to add a crystal for inter-chip communication. Basically the internal clock has a lot of noise which is bad for synchronization (and according to Freescale the USB won't run a spec without an external oscillator; even though it is "functional"). The Freescale stuff is nice because you just need to add the oscillator (no extra caps needed).

The mchck schematics are basically the same, just don't include any of the optional stuff (in the dotted blue lines). ... and-layout

I moved the LED to a GPIO that is less useful for other things.


11 Sep 2014, 22:47

Thanks for that, I'll see how adapting that goes, but yeah, would love to see just the MCU section of your schematic if that is possible too.


12 Sep 2014, 14:34

Looks like I'll have to hold off on the MK22 for now - I tried implementing the above schematic and got nothing from the chip over SPI or Ezport. Next up is SWD, but I'll have to hold off on that due to a lack of dedicated hardware for a little while. Bit hard to justify forking out for something like that when I've no idea if the chip even functions any more :P
Will see about prodding the PIC soon.

User avatar

15 Sep 2014, 00:45

I'm sure a lot of people would be happy with PIC18F4550, it's much easier to work with through hole components.


15 Sep 2014, 01:27

Good news:

Code: Select all

Initializing EzPort
SPI/EZPort enabled
Sending rsdr command...
EzPort status flags = 0
enabling write
Sending rsdr command...
EzPort status flags = 10
disabling write
Sending rsdr command...
EzPort status flags = 0
Success with the K22F (the above snippet is me successfully enabling, then disabling, writing to the on-chip flash, i.e. enabling the chip's in-circuit programming functionality).

I built a little adapter board to break out the SPI/EzPort header and create a socket I could plug the breakout onto for the programming:

It's being driven by a Arduino Leonardo clone via a bit-banged connection.

The cause for the trouble I was having: SPI is a synchronous protocol, i.e. data is sent and received at the same time.
However, I was trying to read the response to my status register query within the same send/receive cycle.
If you think about it, what I was trying to do was expect the chip to know what I was asking it and start responding before I finished asking. Herp derp. Adding a second tx/rx cycle (send dummy data, keep the received data) after the first command worked.

Bonus shot of the custom switch tester I'll be using with the MCU when it's flashed:

Re: the 4550; We'll have to see. I had a look at the sample documentation from Microchip, and I now know where Haata was coming from. Shedloads of contradictory and often out-of-date information and a sample project so complicated it doesn't know if it is coming or going.. Perhaps I will try it once I've learned the ropes a little better with this chip.

User avatar
Master Kiibohd Hunter

15 Sep 2014, 01:33


twiddle, if you don't have a logic analyzer I'd suggest you get one :D
I have one of the early Saleae Logic 8s. Warranty is awesome, fried one, replaced it no questions asked (even paid for shipping).
(I was doing very iffy things with high voltages, don't worry about frying it :P)

If you're looking for some base bootloader code for the Freescale stuff, I have a working dfu bootloader for the mk20dx128 without a crystal. You'll need to adjust some things to tailor it to the chip, but shouldn't be too bad. ... Bootloader


15 Sep 2014, 01:41

Yeah for now I'm trying to do this on a budget (gotta keep saving for GDC 2015) so I was going to grab
but I've heard good things about the Saleae units from elsewhere so if there's a chance I'll get enough use/profit out of this somehow I'll see about grabbing one at some stage.
Thanks for the bootloader link - I'll take a proper look later but just in main.c I spot something to do with flexRAM which I think this chip doesn't have, so it might be useful as reference only.
Have you looked at using Kinetis Design studio at all? I figured that there might be something I could do with that to easily set up some sort of DFU-esque thing, it looks like it will make it fairly easy to get things up and running.

User avatar
Master Kiibohd Hunter

15 Sep 2014, 01:48

Bootloader took me a while. Not just to load it and have something run, but be able to boot to the main image.

Most of my problems were USB related. So I'd suggest setting up a UART or SPI as a debug terminal. Though an LED/GPIO is probably the first step.

The bootloader code is based on the McHCK stuff. It seems they used the FlexRAM only at the flashing stage so you can likely still use the code (just comment that part out and re-implement it a different way).


15 Sep 2014, 01:58

Will probably roll with UART for that because I have a standalone adapter for it.
Out of curiosity, why didn't you run with one of the 3+ bootloaders Kinetis make available?

User avatar
Master Kiibohd Hunter

15 Sep 2014, 02:13

I wanted something standard and something I could modify. This way I don't have to maintain the utility (dfu-util works on all OSs and I don't have to maintain it).
Another bonus is that I can just add adjustments for each additional microcontroller I add support for.
Probably the biggest reason was that I was using the same hardware as the McHCK (as a base) so it made it easier to start with. From there I was able to setup the interrupt vectors the same was PJRC stuff does (which was the original base for my code).

I added a couple of features to the bootloader (like turning the LED on when in flash mode).


16 Sep 2014, 08:25

So, you started from their code and extended it? What toolchain did you end up using?
The Processor Expert tools look promising in that they can take care of hardware initialization and all you do is just implement event handlers, but finding decent information on using it for a scratch-built circuit instead of a FRDM board is somewhat difficult, so I figure I'd take the time to pick your brain a little more - I looked over some of your Kiibohd slides but didn't see much details on your development process.

User avatar
Master Kiibohd Hunter

16 Sep 2014, 18:43

As for toolchains, I just use the standard Linux ones for the most part. More portable between OSs I find.

arm-none-eabi-gcc on Arch Linux would be my toolchain more or less. McHCK has some similar stuff to do hardware initialization but I found I prefer the PJRC approach where hardware is explicitly initialized for the most control. It's pretty straightforward once you figure out the datasheet.
For stuff like the interrupt vector tables, this stuff needs to be defined at compile so usually something like this: ... b/mk20dx.c

Development you mean how to build the code? Or how I write new stuff?

There is a README in the git repo that describes how to build the code (currently updating it, but it's mostly complete for Linux and Windows). I've been having difficulties compiling the bootloader on Mac (old compiler, doesn't work with needed optimization) and Windows (Windows paths and Make issues).

I'm always in the #geekhack and #deskthority irc channels on if you want some quicker answers.


25 Sep 2014, 04:06

Just a small update - I grabbed one of the FRDM Development boards and started to wrap my head around the development tools.


Successfully got the keypad wired up to the board and ran some tests with it - I've got it working but need to figure out how best to handle repeat delay and so on.
The abstraction that I was using in Kinetis Design Studio is naive and doesn't really have support for keys being held down, so I'm going under that to use the raw USB HID API calls (which is good because I was eventually going to want to do that anyway).


03 Mar 2015, 00:01

Just a short update:
I finally have a custom circuit working:
This is a 50MHz ARM micro (LPC11U35) with onboard USB including USB-drag-and-drop programming.
First board had a few problems, but still works ok. Gonna redo a fixed prototype then send off to Dirtypcbs for a two-layer more compact revision.
Finally making some more substantial progress!

Looks like my bargain price on this controller (< 2.60 AUD) probably won't stay that way for long, seems to be around $4 per chip elsewhere, but it's still better than the Atmega32u family and should support some additional interfaces (i2C etc ) for modular applications.

User avatar

03 Mar 2015, 00:13

Very nicely done. We only use ATMEGA for software compatibility and convenience, it's an antiquated architecture compared to ARM. Tight memory limits go away on ARM, as I understand, and all the extra performance doesn't even cost extra energy.

I'd like to see this drag and drop programmability in action!

And if you ever get interested in Bluetooth… we could really use a community oriented controller with customisability and power saving built into it at the foundation. Right now we're having to do things awkwardly with gear that wasn't intended for the purpose.


03 Mar 2015, 00:33

The drag and drop functionality is what allows the mbed platform to operate in the way that it does:

Basically, use a button to set a certain pin to logic low, plug your device into USB, and it shows up as a virtual flash drive you can copy your new firmware onto. release the button or flick the switch back, so that the pin is pulled high, and power cycle your device - the new firmware now runs :)
Memory limits are far less of a concern, given that some parts include up to 1MB of flash on a hand-solderable QFP64 part.
Bluetooth is definitely something that I am going to look into once I have the basic controller firmware down.. I don't think it should be too tricky to get running.

Freescale and NXP have announced a merger in the last day or so so I am hoping that NXP's USB bootloader will be more prevalent and perhaps even usable on Freescale's silicon eventually.

User avatar

03 Mar 2015, 00:56

Very nifty. And you're right about memory: the Teensy that I'm running just now has mere bytes available, which is pretty retro this day and age.

The thing with Bluetooth is synchronising the sleep and wake events across the wireless and matrix parts of the combined controller. Polling a keyboard draws power, so you do it way less frequently when the board reckons its idle. Then again, bitbanging a separate controller takes way more power still, and that's the stage we're still at! So much better to have one controller handle everything, right down to battery charging ideally.


03 Mar 2015, 01:00

Thankfully ARM chips have some good power management functionality built in. I haven't done any work with it before, but from what I've seen it looks like I can set up different power profiles and customise the functionality for each (idle, normal, charging?)
Even if I separate out the Bluetooth from the main controller, I reckon either SPI or i2C would work out for a communication protocol which isn't *that* power consumptive. (totally uninformed statement there, though, haha)

EDIT: On closer inspection I suspect getting the correct development environment (bluetooth stack, license, whatever else from the bluetooth SIG) looks like it would probably be harder than the hardware /not be feasible for hobbyists.. It bears more investigation anyway.

User avatar

09 Mar 2015, 21:36

Hi there!

I come to mechanical keyboard community over from the AVR world (actually I was curious about how atmega32u4 is used, discovered MK and found out that there's something about having a proper keyboard) ;)

I think that if teensy's flash size is a problem, then one can look at ATMEL's newer chips (atxmega* or at90usb*). The great thing about those is that the LUFA library (the USB stack used in tmk_keyboard) works on those pretty much without any changes, so it would only require very minimal code porting. I've recently played with atxmega128a4u (128kB flash, runs 32MHz) and I really like it. I've even designed a small USB stick for it (with an entirely different goal in mind, namely to have it as an encrypted USB storage on microSD). It comes also in hand-solderable and relatively small TQFP-44 package. I thought about designing a board with the same footprint as Teensy 2.0 (to have it as a drop-in replacement), but Teensy is too narrow (TQFP-44 doesn't fit and I can't solder QFN packages). The only disadvantage is that it requires 3.3V, so a voltage regulator is a must - but on the other hand it doesn't need a crystal.

By the way, all the newer/faster chips (ARM, etc..) run on 3.3V, so they mostly need a regulator as well. So far I've only seen one exception, which is the chip that the infinity keyboard uses, which has an internal regulator.

ABout drag-and-drop programming: for the standard AVRs (e.g. Teensy 2.0 or 2.0++) there's Mass Storage bootloader in the LUFA library, which does precisely that (bootloader mode enumerates as a Mass Storage and to "flash", one just copies the firmware over). The only thing is that it takes 6kB, so only 26kB for left firmware on atmega32u4. There's one also for atxmega128a3u (more pins than a4u), and the guy who wrote it said he'd also port it to a4u.

I don't know anything about bluetooth, but for instance [this]( gadget from Adafruit looks quite interesting, but not directly usable for making a full-blown keyboard. But it seems that it's closed source - so I would wager that you're right about licensing and all that, so making an open source bluetooth keyboard might be quite difficult.

User avatar
Master Kiibohd Hunter

09 Mar 2015, 21:52

While I much prefer AVRs to Microchip offerings (*shudders*), ARM is just so much easier to write clean code to access flash memory (again, totally doable, but you have to remember to do extra things).

All my code (I did the Infinity Keyboard), supports both ARM and AVR so it's really just a personal preference at this point :P

hasu also ported his tmk firmware to the Infinity keyboard. His stuff is much more polished than mine and doesn't require as much hardware, but there's a feature ceiling. Though, there's nothing preventing him from taking the kll module of my code and porting it also to the tmk (or even a piece of it).

As for bootloaders, I thought about doing a mass-storage bootloader (I may do that in the future). Another interesting option might be to do a usb-ethernet mini dhcp web server to load files in. This could be paired with a web configuration UI pretty easily.

I'm starting to take a serious look at bluetooth now. The only bluetooth chips of any note currently are from Nordic Semiconductor. At minimum a free gcc compiler has to be available (excludes all of the TI offerings) for me to even consider using it.
I've settled on trying out the RF Digital offerings ( ... o-ble-smt/) because they are easy to source in the US. But Stollman has basically the same thing ( ... mod-s.html).
Using pre-certified bluetooth modules simplifies a lot of things, especially when it comes to manufacturing.
I want NKRO USB bluetooth to be a thing, but I'm not sure if we'll need custom code on these modules to achieve that.


09 Mar 2015, 23:24

The nRF51422 from Nordic ( was something I looked at recently. It combines their BLE solution with an integrated Cortex M0 based on NXP silicon, so any firmware I wrote for the LPC units would theoretically be simpler to port if I get lazy and don't bother with a HAL. My main concern with it was that from what I've been able to read, BT4/BLE/Bluetooth Smart isn't supported by Win7 and under. The RFduino looks like it has potential as an all-in-one unit, but still has the BLE restrictions. I'll take a look at Stollman's BT2 offerings - I'd considered the Microchip RN42, but perhaps Stollman's libraries etc might be a bit better than I've heard Microchip's are.


25 May 2015, 13:23

Right, so bit of an update after going dark a couple months.. First bit of news is I have my first fully custom hardware prototype ready for firmware development:


So this one is based on the STM32F373 mcu, for no real reason than it happened to be the first PCB I finished laying out and sending off to the fab (Smart Prototyping).


As it stands now it supports DFU for updating the firmware, meaning that I can use DFU-util 's code to make an update utility that is cross-platform, but I will probably implement some sort of HID-based system for reprogramming the keys if I can. I also realised that my custom SWD header was laid out wrong, so I'll probably do a v2 with that fixed so I can use my J-link to debug the firmware, as I expect that the in-app flash writing functionality will require some fiddling, and that is assuming I get the USB stuff working without any problems.

I'm in the process of writing the initial USB implementation, and putting the touches on some LPC and Freescale dev boards as well - eventually I'd like to be able to get the same USB codebase running across all three families of chip, so I can start to exploit the competition between the different manufacturers, and potentially also take advantage of things like the drag-and-drop functionality from LPC, the integrated USB vbus voltage regulator on Kinetis, etc.. Really hope to drive the cost of our keyboard controllers down even below things like the Teensy (without the JTAG/SWD header and the reset/bootloader buttons, estimated cost of parts for one of these is ~S10 AUD when buying parts individually, so a group buy would drop it below that).

More photos:
(I tried to show off the soldering job a bit, given that its all done by hand and I hope to convince more people hand soldering SMT parts isn't nearly as difficult as they might think - the smaller capacitors there are 0603 - 1.6 mm × 0.8 mm, and with tweezers they aren't too bad.)

User avatar

25 May 2015, 14:17

This is pretty cool!

I would be really happy if there was a good USB library for STM32 and Freescale's K20 or KL20. I've also started playing with ARM chips lately. So far I like STM32F0x2 the best - they're small in hand-solderable packages (5x5mm LQFP-48 or TSSOP-20), have DFU and/or serial bootloader built-in, and don't need a crystal for USB, so I was thinking of cooking up a small board with them (would probably cost about $5-$7 depending on which chip) which would be more-less a Teensy 2.0 drop-in replacement.

However programming these things is a bit more unpleasant (than AVR) for me so far - that's why I would really welcome a clean USB library for them. Keep up the nice work!


15 Jun 2015, 01:34

This is awesome! I might be spending some time trying to get my teensy 3.1 to work for a small keypad project.


15 Jun 2015, 01:52

Got a few other prototypes on the boil as we speak. Currently working on the LPC chip as its USB library was way better documented than the STM32 libs.
My main problem with the teensy is the proprietary loader /extra chip required to actually program the Kinetis part on the board. Code space isn't at *that* much of a premium so I dont really think its a big deal to have a bootloader stored internally - and some Kinetis parts have an integrated USB bootloader in ROM anyways so you dont lose out on flash storage.

Post Reply

Return to “Workshop”