Open source firmware for the Novation Launchpad Pro grid controller! By customising this code, you can:
You'll definitely need some C programming experience, but we've deliberately kept much of the firmwarey nastiness tucked away, to make the process a little friendlier.
We could have released the full source for the factory shipping firmware, but we decided not to for a variety of reasons. Instead, we created a simplified framework for developing "apps" on Launchpad Pro, which comprises a build environment, application entry points / API, and a library of low level source code. Our reasoning is as follows:
I'm sure you'll have feedback for us, so please do get in touch! I'm blogging the process too if you'd like to read my musings.
If your system is running docker you can easily setup the environment with:
docker build -t novation-launchpad-pro-dev .
docker run -it -v $(pwd):/launchpad-pro novation-launchpad-pro-dev
make
To use Vagrant to manage the build environment you need to:
git clone --recursive
).vagrant up
, hit enter and grab a beverage of your choice. Maybe two - it is building a lovely fresh development machine just for you!If you have a poor internet connection, ummm, find a better one :)
Once your new "box" is up and running, you can build the app in one of two ways. In the spirit of experimentation, we've created a full Eclipse development environment for you to use. However, you might prefer to do things on the command line.
vagrant ssh
make
Make sure you wait until the vagrant up
command has fully completed before logging in to your VM. The GUI appears long before the provisioning script finishes. If you don't, you'll have to log out and log back in again before Eclipse can see the correct path.
/vagrant
. The toolchain isn't important, the compiler is part of the Makefile.Either of the above methods will generate the firmware image, launchpad_pro.syx
, in the project build
directory. You can then upload this to your Launchpad Pro from the host!
On macOS you can easily install the GCC ARM toolchain using the homebrew package manager. The EABI tools are maintained in an external repository which you need to put on tap first. You can then run make
to directly compile the code:
brew tap PX4/homebrew-px4
brew install gcc-arm-none-eabi
make
Now you've got some nice new code to run! To upload it to your Launchpad Pro, you'll need a sysex tool for your host platform (I'd love to get it working from the virtual machine, but that's for later). I recommend Sysex Librarian on macOS, and MIDI OX on Windows. On Linux, I'll bet you already have a tool in mind.
I won't describe how to use these tools, I'm sure you already know - and if you don't, their documentation is superior to mine! Here's what you need to do:
Tip - set the delay between sysex messages to as low a value as possible, so you're not waiting about for ages while the firmware uploads!
Don't worry - even if you upload toxic nonsense to the device, you cannot brick it - the bootloader is stored in a protected area of flash. If your new firmware doesn't boot, you'll get stuck at step (3) above, or with a crashed unit. Simply repeat the above process with the shipping firmware image (resources/Launchpad Pro-1.0.154.syx
) to restore your unit to the factory defaults. Better yet, fix the bugs :)
The API works in two directions - from the HAL (hardware abstraction layer) to the app, and from the app to the HAL. The HAL calls into your app to:
By calling into the HAL, your app can:
The best way to learn about these is to read the documentation in app.h
, and to study the (very basic) example code!
We decided not to support or encourage using a hardware debugger, as opening a Launchpad Pro to fit a debugging header can easily damage the FSR (force sensitive resistor) sheet.
Instead, you're going to have to do things the old fashioned way - by blinking LEDs or sending MIDI messages (though hopefully no need for a 'scope!). For what it's worth, that's the way I've developed this version of the firmware - dogfooding all the way ;)
If do you want to debug interactively (and of course you do), you can use the interactive desktop simulator on macOS:
/tools/osx
Currently it only supports button presses and LED messages - there's no setup button, flash storage or aftertouch (yet). It has a really awful busywaiting timer for the 1kHz tick. However, it does allow you to debug your application logic using Xcode!
You can also use the simple command-line simulator located in the /tools
directory. It is compiled and ran as part of the build process, so it serves as a very basic test of your app before it is baked into a sysex dump - more of a test harness.
To debug the simulator interactively in Eclipse:
/vagrant/build/simulator
The Launchpad Pro is based around an ARM Cortex M3 from STMicroelectronics. Specifically, an STM32F103RBT6. It's clocked at 72MHz, and has 20k RAM (I'm not sure how much of this we're using in the open build yet - should be a fair amount left but I haven't measured it). The low level LED multiplexing and pad/switch scanning consume a fair bit of CPU time in interrupt mode, but have changed a little in the open firmware library (so again, I don't have measurements for how many cycles they're using).
It has 128k of flash memory, but we won't be exposing all of it as part of this API (dangerously easy to corrupt things!).
When you're done developing, simply type vagrant suspend
to halt your VM without destroying it - this will make vagrant up
a lot quicker next time. If you're really finished, vagrant destroy
will completely remove the VM from your system (but not any of your code).
If you only want to build using the command line, you might want to run your Vagrant box headless, which you can do by modifying the Vagrantfile: vb.gui = false
. You can also add more CPUs, RAM etc. if you want.
If prefer, you can install the gcc-arm toolchain on your local machine, or you might already have it. You can find all you need here.
If your connection drops out while updating the Vagrant box, you can get stuck, unable to vagrant up
. To resolve, you need to delete the temp file - ~/vagrant.d/tmp
.
OK - we're not going to need to use the MISRA rules, but there are a few things to avoid. Dynamic memory allocation is a no (well it will work, but it's best avoided). Floating point will work, but it's implemented in software and will be slooooow. C++ ought to work, but you'll definitely want to avoid exceptions and RTTI!