Thursday, January 30, 2014

Testing the step sequencer architecture

So I got the basic step sequencer architecture up and running. I made it as flexible and upgradeable as I possibly could, without making it too complex.
Currently I'm using 20.44 fixed points to iteratively calculate the absolute position in the pattern and then doing rest of the math and triggering based on that data. This approach streamlines the overall step sequencer architecture nicely and makes it a bit easier to integrate all kinds of fancy extras. Some of them are the upcoming swing function, MIDI sync and the note offset & note length which scale with the swing properly.

Here is a video showing the step sequencer running and updating the LEDs accordingly. The lit up LEDs have note data in them. The oscilloscope screen shows debug control data the microcontroller's DAC sends out.

The oscilloscope also shows that the long notes are properly cut off by the new ones. That would be the second longer "bump" which has a hump at the end.

Visualising the system performance

Now that my groovebox's operating system was able to calculate the amount of CPU used, I wanted to get a realtime view of it. Easiest way to do it on my system was to use the note step LED's to indicate the amount of free CPU left. The lit up LEDs represented the amount of unused CPU left and the dim LEDs represented the amount of used CPU.

For the record, the picture was taken of the system running 60 000 rounds per second. Each round doing 2 thread switches, lots of 64bit integer and 32bit integer and floating point calculations, memory accesses and function calls. In other words, the system ran the whole step sequencer and audio/sample generation routines, unoptimised, 60 000 times per second. And this was a debug build. The release build runs around 3-4 times faster. That's a lot of power the 72 MHz microcontroller packs inside itself!

How much CPU am I using?

A little bit earlier I had decided to start keeping a keen eye on the amount of processing power my RTOS was using. It's way too easy to get all kinds of performance issues if one isn't really careful throughout the whole design process.

ARM Cortex based microcontrollers - like the one I'm using - all have something called a "SysTick timer". This is a timer specifically designed and dedicated for operating system usage. It runs on every cycle the microcontroller is running, counting down cycles. It can even create exceptions if the system designer needs them. This was the logical place to look into when figuring out how to profile the system performance.

It turned out that SysTick timer was designed to be super simple to use. Even better, it is identical on every ARM Cortex microcontroller out there! This includes even the memory address where its control registers are located. Superb!

I wrote a short example code snippet which demonstrates the basic usage of SysTick timer. The example is HERE.

Wednesday, January 29, 2014

Starting to build my own operating system

I was missing something obvious. If my groovebox was going to be built around a microcontroller, I would need to design and program my own RTOS for it (Real-Time Operating System).

It's responsibilities would include things like reading button presses on the user interface of the groovebox, controlling which LEDs are on and which are off, handling the MIDI communication, running the sequencer and synthesis routines, etc.

A quick browsing through the Amazon bookstore revealed quite a few books covering the basics of ARM microcontroller programming. I ended up buying couple of books covering the hardware side of the microcontroller and one book covering the assembly language used for the low level programming. Now I was ready to dive into the wonderful world of figuring out how to make my very own RTOS.

The first thing on my feature wish list was multitasking. A little bit of head scratching was needed to get it up and running. Fortunately ARM based micro controllers have been designed with multitasking in mind. They automatically take care of some of the time consuming things, such as pushing the most used registers on stack, when interrupt/exception happens.

I've uploaded my first small and simple multithread test on GitHub. You can check it out HERE if you're interested in doing some multitasking on ARM based microcontrollers. The test program uses SysTick timer to switch back and forth between two threads.

Once I was confident that I understood what was needed to get multitasking working, I modified and expanded the code. This time I used STM32F373 microcontroller specific timer to trigger the thread switching in the RTOS. This same timer also triggered the DAC and starts a "critical thread" simultaneously. This thread would be used to calculate the next sample for the DAC and what ever parameters would be needed to control the analog audio generation circuitry later in the development.

I also added support for multiple threads and Yield() command to switch to the next thread whenever needed. This was the base code for my RTOS which I would be expanding, modifying and refactoring throughout the rest of the project.


How to get 72 MHz out of this thing?

The microcontroller I used for this board (STM32F373CBT6) was capable of running at 72 MHz speed. But out of the box the thing ran at mere 8 MHz using it's internal clock. Need more speed!

It was time to take advantage of the external crystal I had soldered on the board. It would be used to generate accurate 8 MHz signal which would then be multiplied into 72 MHz using the microcontroller's internal PLL (Phase Locked Loop).

Again it took the standard couple of evenings in the kingdom of RTFM and debugging before the PLL did exactly what I wanted it to do. One of the harder to find bugs in the PLL configuration was that once I went over 48 MHz or so, the system crashed. Eventually this was due to the flash ROM wait states: I hadn't configured the flash memory usage speed so that the microcontroller would wait long enough for the data to read correctly. No wonder the system crashed when the microcontroller was in too much of a hurry and as a result read only garbage from the flash memory.

Here's the source file I wrote to clock the microcontroller up to 72 MHz.

First proto PCB

I designed the first prototype brain PCB for my groovebox using a software called Eagle. The PCB wasn't pretty, but it was good enough to fill its short term job before it would be replaced with the next iteration. You can check the PCB design in the picture on the right.

Once the PCB design looked functional enough, I sent the design to Seeed Studio Bazaar so they would make me a small batch of these circuit boards. It didn't cost many tens of euros to get a batch of 10 two sided PCBs done and shipped back to me. Awesome!

The second picture on the right shows the PCB. The two larger white squares at the upper left corner are the MIDI input and output. The white square in the middle is the place where the microcontroller would go. The white line at the bottom is a row of 16 LEDs, which will be used to test and design the groovebox's step LEDs.

The lowest picture shows the same board with the components attached.

So I soldered most of the needed components on the board and powered it up. No magic smoke, so everything was likely to be fine. Then I ran the same software I had written for the previous board. Everything seemed to work just fine. Then I started turning on more of the LEDs and noticed that after around 8 or 9 of them lighting up, they all went crazy. Some already lit up ones turned off and some which were off turned on etc. Seriously WTF?!?

I spent two evening cursing and debugging my software. Eventually I decided that the bug wasn't in the software, but in the hardware.

So what was the problem then? I used a 5V regulator to feed both the LEDs and the MIDI circuitry and 3.3V to feed the microcontroller. Everything would have been just fine, but the 595 chips (serial to parallel data converter) controlling the LEDs assumed that the digital data sent to it would be of much higher voltage. This is because the assumed input voltage of the incoming data is relative to the operating voltage I use to actually power up the chip. So the 595 chip assumed incoming data of around 3.0-4.0 volts, but the incoming signal barely touched the 3.0 volts. This meant that the more LEDs I turned on, the lower the voltage became (since this thing ate up current). After turning on around 8 or 9 LEDs some of the incoming bits didn't get through to the 595 and the lights went wild on the board.

This sucked, so it was time to figure out how to fix this issue without having to reorder a new batch of PCBs all the way from China. If I changed the 5V regulator to a 3.3V one, then the signal sent from the microcontroller into the 595s would be in the right operating level and the LEDs would work just fine. This also meant that the MIDI circuit wouldn't get high enough voltage. So I had to choose which was more important: the LEDs or the MIDI I/O. I decided to go with the LEDs so I can get the UI design work started. Also if I really needed the MIDI right now, I could always connect the previous MIDI proto board to the pins on top of this new board.

After 10 minutes of solder work I had replaced the 5V regulator with a 3.3V one. Quick power up and hey presto! The LEDs worked exactly as they should!

Sometimes you have to sacrifice one thing to gain another.

Tuesday, January 28, 2014

Moving towards PCBs and SMDs

Next I took a proto board and built a row of 16 LEDs which I would control with the Discovery board. Soon I noticed that the loosely hanging wires from the Discovery board were a compete mess. They were highly irritating to work with. I had to integrate the microcontroller onto the proto board to get rid of some of the mess.

Since the Discovery board used ARM Cortex M4 microcontroller, made by ST, I decided to stick with those for now and browsed through their catalogue. I wanted to have a microcontroller with fewer pins and lower price point, so I wouldn't feel so much mental pain whenever I managed to destroy one of those chips. After several nights of research my choice ended up being STM32F373CBT6. It is maximum of 72 MHz and has 48 pins and all the peripherals and features I might need. This includes additional touch sensor support, if I ever wanted to experiment with it (which I did want to but didn't have the time to do it). This microcontroller has only 24KB of SRAM and 128KB of flash, but that should be enough for what I'm doing with it.

I soldered the chip onto one of those small green adapter boards which enabled me to use it with a standard proto board.

The picture to the right shows two brown proto boards. The one on the left has the MIDI input and output circuitry as well as the 3.3V regulator feeding the microcontroller with proper voltage. The board on the right is the one containing the row of LEDs as well as the microcontroller. I even added an 8 MHz crystal next to the green adapter board, but I was a bit too optimistic thinking it would actually work so far away from the microcontroller. The four digit LED screen was something I also was going to get up and running, but before I managed to do that, I already had the next revision of the board in the works. I ended up running this iteration of the board in 8 MHz, which was driven by the microcontroller's internal clock. I used the STM32F4Discovery board's SWD output connector to program this board.


The middle picture on the right shows a close up view of the adapter board with the STM32 soldered on it. The last picture shows a closeup shot of the MIDI I/O circuit.

At this point I cursed the dark gods of electronics because of how quickly those proto boards fill up. Also the issue with excessive amount of wires was still there, even though not as prominent. It was time to move into using surface mount devices and printed circuit boards…

Evaluating the STM32F4Discovery

I started the project by pondering on which micro controller might suit my needs. One of the friendly and helpful Helsinki Hacklab actives (greetings!) mentioned that the ARM based micro controllers are quite powerful and have plenty of I/O and output options. STM32F4Discovery board was mentioned during the conversation, so I decided to take a look at the board and evaluate what it's capable of doing.

After browsing the Mouser's catalogue I was pleasantly surprised how cheap the evaluation board was. For only about 12 euros it was a no brainer for a 168 MHz chip with 1MB of flash and 192KB of SRAM. The chip also has a floating point unit, SIMD instructions and a DMA. Nice! That's like 2-3 pints of beer here in Finland (depending on which bar you end up into). Sold!

I chose the CrossWorks for ARM as my development environment and browsed the internet for simple examples on how to get the basics on this microcontroller working. The basic I/O was fairly straightforward, but the PWM timers took several evenings of RTFM'ing the chip manufacturer's massive documents. Eventually I had one of the pins make a LED blink in the frequency of my choice.

The next thing I wanted to get working was the MIDI I/O. After several evenings of RTFM'ing I got the UART ports working properly. The damn system had been sending inverted signal (flipped polarity) which caused me more headaches than was humane considering the situation! Anyway, now the evaluation board was finally sending proper MIDI notes into my trusty MOTU Midi Express 128, which was connected to my computer running Logic Pro. The DAW recognised the incoming notes beautifully. The Discovery board could also receive MIDI data the Logic Pro was sending.

I experimented by programming a few simple procedural note patterns in C++ and listened to the Logic Pro playing the notes with Sylenth1. I felt the excitement I had last experienced as a kid.

The next stop was the 12bit ADC. After some more RTFM the ADC turned out to be one of the easiest peripherals to use on this micro controller. After awhile I got it to respond to the potentiometer I had attached to the input pin. Out of the 12bits there was a noise floor which ate up around 2-3 bits of precision. Oh well, software filtering would hopefully fix that. A quick browsing through the data sheets also revealed that this micro controller could scan different pins (or "channels") using the same ADC and convert the input signals one after the other and put them into a buffer using DMA. Well, this had to be my next stop then.

About the design philosophy

My goal is to design and build my own groove box. My top priorities with this project are:

1. Make the UI and workflow quick, intuitive, easy and fun to use.
2. Make the groovebox sound good.

Basically my intention is to create a piece of music making gear which does one thing and it does it really well. I want to use this machine actively in my own music productions, so the workflow is super important for me.

I don't care about music gear doing everything imaginable. If the machine ends up doing a lot more than intended without cluttering the UI/usability, then so be it. It's left to be seen how all this works out. I'm still in the middle of the design process.

The initial specs for the machine are:
- A monophonic groovebox.
- Analog/digital hybrid dual layer oscillators.
- At least 16 steps per pattern.
- The results should sound "pro" without additional processing or layering.
- Workflow has to be quick, intuitive, easy and fun.
- The UI should suit both studio and live work.
- Users shouldn't need instructions to get the hang of the machine.

I'm working on this project during nights after work days at my day job. This usually causes unforeseen delays in my personal work rhythm.

Starting the documentation work...

A few of my friends have been following my personal project of designing and building my own groovebox synthesizer. They persuaded me to document my work on a blog as things happen. After lots of convincing, I decided to give in. Here we go...