Firmware First or Hardware First (or Something Else)

I’ve been trying to hack together some simple prototypes in an attempt to learn DSP programming. At the moment I throw something together on a breadboard or use an existing module that I can reflash, do a quick proof of concept and then get a PCB built by one of the super cheap Chinese PCB sites. After that I wait a few weeks, build the PCB, realise I made a stupid mistake and order another one…

Only once I’ve got a finished board can I really start to work on the firmware.

I did build a big development board which I can test stuff on, but in the end I find I need to use some different components somewhere (for example a different DAC) or I want to try a different microcontroller (because STM32 chips disappeared off the face of the earth!) so I’m not sure how useful this approach is.

So I guess the question I’m asking is: how do you overcome the interdependence between the hardware and the firmware?

Is it better to prototype the software part first using VCV rack or a VST plugin? Or do you over-spec the MCU on your development board and then figure out which final MCU is good enough later? Or is what I’m currently doing the best approach and I just have to accept that sometimes I might get quite far in a project and then realise the MCU is not fast enough or the circuit design is not quite right and have to redesign the hardware?

Learning C/C++, all of the weird processes for flashing different chips, circuit design and a whole new type of programming for DSP code is pretty overwhelming! I’m basically trying to work out if there is a “best practice” or if I just have to muddle along and figure out my own way of doing things!

I’d refer you to a couple of relevant lines from Emilie’s discussion of " What do I need to learn to do your job?" from this part of the MI website: Mutable Instruments | Contact

What do I need to learn to do your job?

  1. Back to basics: write simple command line python programs doing stuff on .wav files, or programs generating .wav files (don’t get distracted with real-time processing, user interface, etc). Write signal generators, filters, etc using what you learnt from the signal processing book.

  2. Your new-found understanding of signal processing theory will allow you to dig into Udo Zolzer’s “DAFX” book and learn about synthesis techniques, FX, etc. Try implementing some effects in the book as Python programs, or with pd. This is something you’ll end up doing a lot anyway to sketch ideas.

  3. Understand that python or pd are towers of abstractions and that writing code for an embedded processor is done at a much lower level. A good online course for understanding towers of abstraction, and what’s going on inside processors is Nand 2 Tetris.

  4. At this stage, you can learn a low-level programming language like C. Write C equivalents of the oscillators, filters, etc. you wrote in Python. “The Audio Programming Book” by Boulanger is great at this stage!

  5. If you ever decide to make your own hardware, start with a development board (like the STM32F4 discovery). And study the code/schematics of Mutable Instruments’ products. If you want, you can spend a couple of weeks playing with Arduino boards, but don’t spend too much time learning it: to make it simple for beginners they often do things the “wrong” way (especially on questions related to timing, multi-tasking that are of prime importance in musical instruments), so remember that whatever arduinese you learn will have to be unlearned later.

1 Like

There are a few ways in which I overcame this:

  • Over the years, get a good sense of what can be done for how many MHz. I know this is not the answer you were expecting, but I truly believe that after a year or two, you start to get better at the kind of back of the envelope calculations involved in this.
  • Develop a “platform” and reuse it to develop different modules. For example, all the STM32F4 modules ran, at one point or another, on a generic board probably similar to the “big development board” you described. It’s okay if all the features of the module are not implemented yet at the stage it only runs of the “big development board” – feed it fake data with code, adjust some settings in code without having the UI for it, it’s just a matter of validating the overall concept and making sure you have enough CPU for everything.
  • Reuse previously released modules as development platforms.

To give you an idea, for my modules, 70-80% of the code is already written (and validated on some hardware) before I actually design a board specifically for this module.

3 Likes

Command-line program dumping multi-channel .wav files is still my favorite method :rofl:

1 Like

Thanks for your reply. It looks like I’m approaching things from roughly the right angle!

The big development board is an STM32 MCU with a DAC, 4 cv inputs, 4 trigger inputs, 4 CV outputs and 4 gate outputs. When I made it I didn’t really understand much about the DAC chip and it uses SPI and is too slow for audio rate stuff which limits how useful the whole thing is!

To give you an idea, for my modules, 70-80% of the code is already written (and validated on some hardware) before I actually design a board specifically for this module.

This is very useful information. I think the problem I’m having has been a bit of a chicken and egg thing though - until I’ve created hardware I don’t have anything to run the code on! I couldn’t get hold of STM32s for ages so I switched to an Atmel (Microchip) MCU for my next project but then I had to start again from scratch!

Command-line program dumping multi-channel .wav files is still my favorite method :rofl:

I’m totally going to try this! Thanks for your advice!

1 Like

Also, to start, I would not try and do everything all at once. It’s easy to get overwhelmed trying to understand hardware, software, and DSP all simultaneously. Take things piecemeal and try to become a master of small things before moving onto bigger things.

Here are a couple other thoughts I had:

So I guess the question I’m asking is: how do you overcome the interdependence between the hardware and the firmware?

  • Try prototyping your design or parts of your design using a visual programming language like Max or Pure data (or with a high-level programming language like Python) before implementing it on an embedded processor.

Is it better to prototype the software part first using VCV rack or a VST plugin?

  • Maybe! I think what’s important is to find a prototyping/development environment that you are comfortable working in. This might be a visual programming language or maybe a higher level language. Something that lets you move quickly and gives you somewhat immediate feedback is what you want.

Or do you over-spec the MCU on your development board and then figure out which final MCU is good enough later?

  • That’s one approach. The main things to consider are: memory, speed, and peripherals. If you need a floating point processor, I would consider using the STM32F3, F4, G4, or H7 series. Those are listed in ascending order of speed (in Mhz). If you need more memory, check the datasheet or the ST site for a pn that has more memory. Regarding peripherals: investigate or test the MCU before hand and make sure it has all the peripherals you want to use.

Or is what I’m currently doing the best approach and I just have to accept that sometimes I might get quite far in a project and then realise the MCU is not fast enough or the circuit design is not quite right and have to redesign the hardware?

  • Alas… this does happen… Luckily, STM32 mcus (if you’re using STM32…) are fairly compatible from one line to the next. I had this happen to me on a project in January… I bread boarded a design using an F4 but then decided to use an F7 at the last moment in-case I needed the extra speed. When the prototype arrived and I soldered everything up, I struggled to get the F7 to work with full-duplex I2S and DMA (the implementation of I2S on the F7 is different from the other STM32 lines). The solution ended up being jumping to the H7, which was wayyyyy faster than I needed but it was more or less drop-in compatible and all I had to add was one jumper wire.

This is basically what I’m doing already.

I’ve tried some Nucleo boards and Arduinio, then made my own development board with STM32F4 and had a go at some gate sequencing and clock types stuff. I understand how to write the low level code I’m just not hugely practised at it. When I was younger I did a bit of low level game development code and it’s kind of similar in some ways.

DSP stuff is next on my list but none of the hardware I’ve developed so far is suitable to make that jump so I think some command line stuff in C is next on the list! Or maybe just reflash Clouds and play with that!

1 Like

Check the source code of Marbles, Tides2 and Stages. They all use the I2S peripheral of the MCU to send SPI-compatible signals to the DAC. The massive advantage is that a large block of several samples, across several channels, can be transferred in the background using DMA.

2 Likes

That is actually very interesting!

I’m not sure if the DAC can even run fast enough to do audio but I will experiment and see what happens!

Marbles and Tides were my reference for a lot of stuff on my development board! I learnt a lot about clipping and conditioning CV inputs from their schematics! Time to dive into the code!

1 Like

I’ll just throw this out there in-case you’re interested. Here is some python code I’ve written for some basic DSP stuff. Maybe it would be useful to you. Some programs are for reading .wavs and processing audio, some are for graphing frequency responses of filters: GitHub - jaakjensen/PythonDSP: Collection of Python DSP Scripts

Which DAC is it? When you mentioned speed, I thought you mentioned the cycles lost to waiting for SPI writes…

MAX5715

https://www.maximintegrated.com/en/products/analog/data-converters/digital-to-analog-converters/MAX5715.html#product-details

I “chose” this one because it had a development build that would plug into the nucleo board I had. Really I was being impatient and just ordered the thing I could get right then. It might sound like a stupid thing to do but I was very motivated in that moment and wanted to start before the motivation disappeared!

Although, now I’m not so sure it is slow. To be honest the datasheet is a little bit difficult to understand.

EDIT: actually I think it might be ok. On page 6 it says SCLK frequency is 50MHz. I think I need to write a test program to run it as fast as it can possibly go and see what happens!

Here’s the important number - how fast it reaches the right voltage.

Screen Shot 2021-06-22 at 18.01.21

Fast enough for audio :slight_smile:

1 Like

Woohoo! That’s great!

Every time I talk to you you somehow manage to solve a problem for me, even if I didn’t know I had the problem in the first place!

So to summarise what I’ve learnt today:

  • My approach seems generally fine with regards to hardware development and is kind of similar to what you do
  • You write most of the code before you make the hardware
  • My terrible DAC chip that I hastily chose is actually not terrible and seems like it should do the job
  • I can do a cool hack to get SPI chips to work as an I2C device
  • I need to practice writing some C (or even python) command line tools to process WAV files
  • I’m not very good at reading datasheets!

Thanks a lot for your help - this was time very well spent!

You could also give it a go with a dev board geared towards audio, like the electro-smith Daisy: Daisy™ Seed — Electro-Smith

It’s open hardware and software, code is in C++, here’s a deeplink to what the example programs look like: DaisyExamples/seed at master · electro-smith/DaisyExamples · GitHub

3 Likes

Maybe it’s a typo, maybe not, just a reminder that I2C and I2S are different things!

Yes I2S! Too many similar acronyms have fried my brain!

Not sure typo is the right word though - I think I just got confused :smiley: