Winterbloom is a boutique, delivery-provide synthesizer company and it has precisely one engineer – me. I am to blame for every thing – from the hardware cling, to the firmware, to the documentation, and every thing else! Which potential that is a ton of labor I’ve needed to be very deliberate with the tools and tech that I exploit.
This article is a eye into our most modern tech stack one 300 and sixty five days in and a few tips I appreciate for the future. I could switch from the microcontrollers, the firmware, and your whole manner up to consumer book. I’m hoping this is efficacious, but when it is likely you’ll perchance well deserve to appreciate extra particulars about one thing or if one thing would not get sense, of direction be at liberty to attain out.
General philosophy
A one-lady company requires a a long way varied manner than any invent of company with greater than one engineer. As I whisk thru this tech stack, be conscious that these selections and choices are made with that context in tips- they potentially can also not lengthen as smartly when taken out of that context!
“Lateral thinking with withered technology”
– Gunpei Yokoi
The quote above is one thing that of direction resonates with my philosophy: I am not looking to toddle the utter-of-the-artwork, I am looking to utilize smartly-understood tools and technology to cling my dreams. Whereas I’ve used a comparatively nice place of abode of languages, tools, and frameworks for the length of my career, with Winterbloom I strive to leverage stuff that I of direction feel “fluent” in as worthy as likely.
I am also keenly privy to the affect of increasing physical units. I cling not desire to proper accomplish extra e-damage. I desire to carry out things that would possibly perchance well well of direction be owned, repaired, re-used, and re-purposed for so lengthy as likely. I retain in my tips that there is a proper factual argument that shall be made in opposition to increasing novel hardware at all1, so as I bring treasured offers collectively into novel varieties I of direction strive to weigh the lengthy-term affect of my creations. Right here’s one more cause I assign conclude “withered” technology – it is miles extra with out concerns understood and maintained by others.
Whereas this philsophy can lead to picking solutions that don’t appear to be “ideally suited”, I strive to earn the very best tool for the job that works for me elegant now and offers my creations a elegant shot at longevity.
Microcontrollers
Most of our products require a microcontroller and there are a lot of decisions available. The use of a definite microcontroller for every product is never forever of direction feasible- I would settle on to learn thousands of pages of documentation to learn to utilize the novel controller, its peripherals, its board structure requirements, and the procedure in which put in pressure drivers. Or not it is worthy better for me to earn two or three microcontrollers to focal point on so I will construct ride as I accomplish extra products.
Winterbloom’s major microcontroller is the Microchip SAM D series- particularly, the SAM D21, SAM D51, and SAM D11. These three general-cause microcontrollers cloak a diversity of use conditions and they actually appreciate a general place of abode of peripherals. That’s superior– it lets me re-use records and code all the procedure in which thru projects that use any of these three microcontrollers.
It also helps that these microcontrollers are smartly established and appreciate a truly solid neighborhood. They’re used within the Arduino Zero, Adafruit’s M0 and M4 boards, SparkFun’s Issues, and additional. This methodology there are many present designs and firmware that will also be tailored.
Right here’s some aspects general to all three that are nice significant for me:
- USB diagram: Most of our products can feature as USB MIDI units so having it is miles a need to. USB also makes programming, debugging, configuration, and firmware updates so worthy more uncomplicated.
- Flexible SERCOM peripheral: SERCOMs will also be configured for various serial communication protocols including SPI, I2C, and USART. Right here’s ideally suited for speaking with exterior peripherals.
- Multi-channel 12-bit ADC: All of our products need to learn analog signals from the delivery air world. Having a built-in, multi-channel analog-to-digital converter is supreme handy and simplifies our designs.
- Evolved timer peripherals: These timers will also be used for excessive-resolution timekeeping, PWM technology, and waveform technology.
Right here’s just a tiny comparability desk for these three microcontrollers:
SAM D11 | SAM D21 | SAM D51 | |
---|---|---|---|
CPU | Cortex-M0+ | Cortex-M0+ | Cortex-M4F |
Clock plod | 48 MHz | 48 MHz | 120 MHz |
Max flash | 16 kB | 256 kB | 1024 kB |
Max RAM | 4 kB | 32 kB | 256 kB |
Max pins | 24 | 64 | 128 |
SERCOMs | 3 | 6 | 8 |
ADC channels | 10 | 20 | 32 |
DACs | 1 | 1 | 2 |
I2S | No | Yes | Yes |
This offers me a definite place of abode of criteria for picking which SAM D to utilize – the SAM D11 is big for nice straightforward things, the SAM D21 is a big all-arounder, and the SAM D51 is big for extra stressful applications.
Having a eye towards the future I am brooding about two other microcontrollers – the RP2040 and the STM32H7. The RP2040 shall be big for applications that cling not require a lot of analog I/O, and the STM32H7 is an absolute powerhouse that shall be precious for applications the place sound technology wishes to happen for the length of the firmware itself.
Hardware cling
I cling all of our hardware the use of KiCAD, a free and delivery provide electronics cling automation suite. KiCAD fits smartly with our philosophy: since our hardware is delivery provide, we desire this diagram used to peep and edit the hardware documentation to be delivery provide as smartly.
We’ve got a limited, but precious place of abode of general symbols, footprints, and 3D models for parts that we use. We’ve also revealed a list of our most smartly-preferred parts in case it be precious for others.
Firmware
There is in actual fact several varied bits that approach collectively to invent the firmware for our products- the programming language, the construct machine, the testing framework, etc. The following couple of sections will cloak every half in turn.
The C Programming Language, GCC, and CMSIS
I write our firmware the use of C. Whereas some can also gasp on the use of such an “ragged” language, it looks that the mix of my familiarity with C, the maturity of its sources and tooling, and the low-stage nature of writing firmware methodology that C occurs to be a gratified language for me to write firmware in.
There are several alternatives by manner of toolchains for microcontrollers. You would possibly perchance well well well perchance also pay a lot of cash for industrial compiliers from Keil, IAR, and others, but it absolutely’s of direction major to that our products, that are delivery provide, use free and delivery provide tools. We use the GCC ARM Embedded Toolchain.
We use --std=gnu11
as our C dialect, which comprises of the most modern C fashioned and GCC’s C language extensions. We also assemble with -Wall -Wextra
and a few other precious warnings enabled to relieve spend undefined conduct.
Creating firmware can of direction feel esteem a frightening process. Most microcontroller vendors present a spot of abode of tools, frameworks, and examples – and most severely – a hardware abstraction layer (HAL) library. As an illustration, Microchip offers several alternatives including Atmel START and MPLAB Solidarity. These provider sources can simultaneously be very significant and extremely hard to work with. They in general comprise of a lot of generated code with very tiny within the style of commenting and documentation.
I in my idea fetch the Microchip-supplied HAL to be just a tiny too unwieldy2. Thanks to that, we use the low-stage CMSIS library without lengthen and I write very limited, in general venture-particular, abstractions over that3. Whereas it has a steep initial finding out curve, getting accustomed to working at this stage has allowed me to greater understand and spend the hardware.
Firmware libraries
I cling not write every thing from scratch. There are several excessive quality libraries available that of direction plod up the approach of writing firmware. On the opposite hand, I am extremely cautious about the use of libraries in our firmware. Carelessly the use of a bunch of third-celebration code that I cling not understand can discontinue up hurting greater than serving to.
Right here’s one of the crucial libraries we use:
- TinyUSB: an comely and limited USB library.
- Marco Paland’s printf: a printf implementation optimized for microcontrollers.
- libfixmath: a limited library for fixed-point arthemetic, which is supreme handy on microcontrollers that cling not appreciate a floating-point unit.
- µnit: a truly limited, very precious testing framework.
After we use a third-celebration library, we pull its provide without lengthen into the firmware’s provide tree (such as a monorepo). This has a couple of advantages:
- The total code desired to construct the firmware is in one place.
- We get to assign conclude how updates are utilized to the library.
- We’re going to get changes to the library with out caring about impacting other things.
- We’ve got a definite picture of all the code that we’re constructing and shipping.
- We’ve got a definite belief of which licenses the code and ensuing firmware are below.
There is also somewhat of re-usable code that we portion all the procedure in which thru projects. I’ve mute all of it into libwinter. It involves limited helpers for things esteem random numbers, GPIO, colorspace conversion, MIDI, and timing.
Construct machine
Our construct machine uses Python and Ninja. Python is used to generate the ninja.construct
file and Ninja as a result of this truth performs the construct:
$ python3 configure.py $ ninja
I within the origin started with Makefiles, but it absolutely rapidly turned hard to work with. Makefiles are unparalleled, but at a definite stage of complexity it makes extra sense to switch to an proper turing-whole language. Ninja is deliberately designed to be utilized by a greater-stage construct machine4 and Python used to be an evident preference for me as a result of my familiarity with it. All over again, it helps that Ninja and Python are smartly-established with hundreds sources.
You would possibly perchance well well well perchance also explore an example of our configure.py
script right here. This one is used to construct Castor & Pollux’s firmware for the SAM D21.
You would possibly perchance well well well perchance also wonder why I stopped up kinda rolling my possess rather than the use of some present excessive-stage construct machine esteem CMake, Meson, etc. It mostly comes all the manner down to preference and the flexibility to totally know the manner the construct machine works. Or not it is worthy more uncomplicated for me to cause about 300 traces of Python that are particularly tailor-made to our use case than to pick out a eye at to cause a couple of sprawlingly advanced general-cause construct machine.
All of our tooling uses Python and lives in a single repository, wintertools. Having these general utilities makes striking forward a couple of products worthy extra feasible for a single person.
First, wintertools
has a diversity of tools used for the length of firmware vogue- it helps generate ninja
recordsdata, analyses RAM and flash usage, provides detailed construct files, etc. These forms of are utilized by every product’s configure.py
script (esteem the one mentioned within the final half).
Second, it has tooling for programming and testing our products- it has modules for interacting with our debug probe, our oscilloscope, our bench multimeter, and with the products themselves over serial or MIDI. These are used to carry out program & test scripts for every product (esteem this one).
I chose Python for all of this because I appreciate a lot of ride with the use of Python for developer tooling. Beyond that, Python has lengthy been viewed as an supreme “glue” and tooling language thanks to its readability and nice fashioned library. Or not it is an supreme preference to be used conditions esteem this and there is literally a lot of sources for writing tools esteem this in Python.
Having a eye towards the future, there is a couple of things I will affect to get wintertools
more uncomplicated to utilize for folk that don’t appear to be me- things esteem documentation and assessments. There is a couple of extra aspects/tools I’d pick so that you just can add as smartly, esteem unifying our firmware free up & publishing process.
CircuitPython
A number of of our products cling not use custom firmware; they as a replacement use CircuitPython, an education-centered Python for microcontrollers. There is a lot of the rationalization why I picked CircuitPython:
- It makes it straightforward for our possibilities to customize the product’s conduct. A CircuitPython diagram reveals up as just a tiny flash force with a
code.py
file that they are able to proper edit! - It makes establishing the firmware/diagram for a product worthy more uncomplicated (as lengthy as it fits for the length of the constraints of CircuitPython).
- It has an wonderful neighborhood that is maintained by Adafruit.
For products esteem Colossal Honking Button and Sol, that are supposed to be personalized, CircuitPython is an extremely powerful probability. Or not it is miles so straightforward to utilize and so approachable that it turns what would in general be a nerve-racking and confusing ride sincere into a delicious one. It also helps with the longevity of my creations; CircuitPython supports these products without lengthen and will continue to free up novel variations for them as lengthy as there are of us striking forward CircuitPython5.
Documentation & consumer guides
As hard as that you just would possibly as well strive, it be almost not likely to carry out a product that wishes no directions. Difficult things esteem synthesizers need to present as a minimal some steering or of us will proper be annoyed by looking to realise some inscrutable interface. Documentation is so major and I pick it very severely- pick a eye at Castor & Pollux’s consumer book for a eye at how we manner documentation.
All of our product documentation is written in Markdown, built into static webpages the use of MkDocs, and hosted on GitHub Pages.
First, I chose Markdown because it be very straightforward to write and its also straightforward for other to contribute to. Fixing a couple of documentation disorders is a general manner that folk delivery up contributing to an delivery-provide venture, so I desired to get that as straightforward as likely. Within the previous, I’ve most smartly-preferred reStructuredText for writing technical documentation (especially API documentation), but this invent of documentation lends itself worthy better to Markdown.
Second, MkDocs is a comparatively straightforward static topic generator that works smartly for us. The use of a static topic generator simplifies records superhighway web hosting and locations the provide of truth into the venture’s repository – each and each very precious things for us. MkDocs is the elegant steadiness of limited ample but with proper ample flexibility for us. Or not it would perchance be written in Python which methodology that if I affect need to dig into the internals I will be smartly-equipped to impress so.
Third, we use GitHub Pages as our host. Since MkDocs proper generates a static web notify material, records superhighway web hosting on a provider esteem GitHub Pages is extremely straightforward. I chose GitHub Pages because we’re already records superhighway web hosting our provide code on GitHub and it be a free provider that offers all the aspects we would like (custom domains, HTTPS, etc.) The implausible thing about the use of a static web notify material is that if for some cause GitHub Pages turns into undesirable, it be straightforward to switch.
By technique of MkDocs’ theming engine our documentation sites all appreciate the similar think & of direction feel, winterbloom-mkdocs-theme. This theme is built on the Bulma CSS framework and is optimized for readability and accessibility. We cling not use any CSS compiler tools esteem Sass or LESS since I pick to sustain things straightforward.
JavaScript
Our documentation shall be static pages, but they cling not appear to be tiresome. They cling precious interactive animations, embedded audio samples, WebMIDI-basically basically based settings editors, and additional. For this, we would like JavaScript.
This half is perchance going to be the most controversial. It looks it be licensed to loathe on JavaScript on the 2nd; while there are undoubtedly legit criticisms I cling not earn it be as irascible as of us would appreciate you ever suspect. There would possibly perchance be not any denying how precious JavaScript is and there is no escaping it when you’re doing any invent of web vogue.
In most modern years, changes to the language appreciate made it a lot more uncomplicated to work with. On the opposite hand, the final ecosystem continues to churn so rapid that it be very stressful to sustain up with most modern easiest practices – especially for a single developer with a lot of different tasks.
I’ve chosen to keep a long way from the use of the Node.js ecosystem in desire of proper straightforward JavaScript. Right here’s in general because that whole half of the JavaScript ecosystem is overwhelming to me. Or not it is precious, it be powerful, and I am not right here to rain on someone’s parade, but for me and for Winterbloom it be pointless, refined, and wasteful. Or not it is totally legit to approach reduction to a definite conclusion for your use case.
Thanks to improvements each and each within the core language and Internet APIs, the use of clear-slash JavaScript isn’t very most bright feasible but practically gratified for a limited developer. We use aspects esteem modules, classes, arrow functions, Canvas, WebMIDI, TypedArray, and additional. These contemporary aspects enable me to sustain our JavaScript codebase limited, magnificent, and free of exterior dependencies.
Factual esteem with our general C and Python code, I’ve pulled out our general JavaScript code into just a tiny library named winterjs. There of direction is never forever of direction worthy there- proper some fashioned helpers for aspects,
, and WebMIDI.
Having a eye towards the future, I am in actual fact pretty enraged by Deno. Deno is severely of a parallel-universe Node.js that involves a ragged library and carefully fits Internet APIs wherever likely. Right here’s pretty precious for me since it opens up the likely for with out concerns testing our JavaScript code – one thing I’ve already experimented with.
At final, when you’re a JavaScript developer and also you whisk digging into my JavaScript code that you just would possibly as well fetch some of my style selections offensive- I exploit 4 spaces and snake_case
. I affect this so as that I am in step with our C and Python code which makes context switching worthy more uncomplicated for me. Your style is perchance varied and that’s totally okay!
Wrapping up
I’m hoping this used to be insightful, and perchance even significant. Obviously I am unable to display every single layer of the onion or interpret every resolution, but when you appreciate got gotten questions or solutions I’d pick to listen to it.