I saw the Organelle, and I really wanted one. They released their software as open source, but not their hardware. I decided I would just figure out what they were doing and recreate it on a quad-core Allwinner H3 instead of their single core implementation.
I decided there needed to be an open source hardware project along the pocket operator-organelle-OP1 spectrum. Single board computers are powerful enough to manage. This is the beginning of creating a series of open source hardware projects with a musical embedded linux focus.
This can run any basic organelle synth patch (puredata patch or 'virtual instrument') ,doesn't have fancy drawing on the tft yet, uses the same basic IO (1 rotary encoder, 5 knobs, some buttons), and boots in about 3 seconds. It enumerates as an RNDIS networking, mass storage, and MIDI device via the usb composite library.
It uses the python curses library to draw to the screen, and an OSC implementation for threaded handling of messages. A few bash scripts run on boot to set IRQ affinity on the USB soundcard and the running Puredata process. Two of the four cores are reserved using isolcpus=2,3 in uboot settings.
The prototype functions well enough as a playground to test out my code, but I'm making a PCB to hold it all together. The PCB will have an STM32F103C microcontroller, a CM6206 soundcard, an FE1.1s usb hub IC, and a kindle 3 battery attached. In an ideal world, it'll also have a USB WIFI board soldered on, an SI4720 for FM receive/transmit capabilities, and a button layout more along the lines of Teenage Engineering's OP-1.
My goal here isn't to end the project once I get this set of designs figured out. I want to make it small enough to go into a pocket, and last a few hours on battery. This might not be possible with the H3, but the V3s is an option. Currently my system boots into puredata and python using only about 11 Mb of ram, leaving about 53Mb in an ideal world. The power draw would be less, and it'd have a mic in/line out. The H3 and V3s are both supported in mainline linux, so the software port should be painless.
I only made 2 mistakes on this one, both involve the 5v rail. One mistake involves drilling a via out, the other is cutting a trace and soldering a jumper.
The firmware for the STM32 works on the first try, which is rare. Now the display is handled by the micro instead of sbc.
Big ups to @Sunshine_Jones for the boot screen quote from embedded.fm.
Currently working on bringing the linux version up from 4.13 to 4.18. Playing with -mtune gcc options in buildroot.
Learned about `ldd -v` and `patchelf`, so I'm creating a small script to help non-developers bring their favorite binaries over to this. I have this feature working with orca, which you can find here: https://github.com/hundredrabbits/Orca-c . It basically finds all shared library dependencies, copies them over, tweaks the search path for that binary, tars it, and it generates a shell script for the LD_LIBRARY_PATH update when you try to run the binary.
This week will be dedicated to getting the linux groundwork complete so I can work on full feature compatibility within puredata. I also ditched python and the curses module for the screen. Its all OSC messages over the serial port now.
I haven't died, I just took a break. After adding some features like FM transmit and receive, I realized I really do need a 4 layer board. I added the transmitter and receiver on the I2C bus and I have bash scripts to control em. I upgraded the STM32F103C to an R series, which is a 64 tqfp instead of 48. To save room, I switched from 16 to 1 muxes to the good ol' 8-1 CD4051. Added a few more buttons so I can add features I want to add without ruining the organelle patches. Added some USB A ports to the bottom so you can plug in any other gear you want without having to solder to pads.
On the software side, I've implemented the SPI screen drawing on the STM32 now, and send all messages over the UART with puredata instead of python. I'm trying to make everything run in puredata, which I understand is a fool's gambit, but I want to see if its possible. Using lists in pd 49.1 it does seem to be possible, as long as you're willing to put in the time to understand it. I've added a waveform drawing mechanism, which seems to work really well for showing samples. In the mother.pd main patch, I have logic for launching child pd processes, so mother.pd should never close. I'm adding a 4 track looper and some other features from OP-1 in the mother patch, so building full songs shouldn't require any external gear.
Still very much a work in progress. Turns out C-media chips are only being sold by Symmetry Semiconductors, and they have MOQ of 1k sometimes. I can't get my hands on any of the USB 2.0 spec'd codecs, so I'm stuck with 48KHz 16 bit. Not a problem for now, but I do want lower latency audio. I've been on a wild goose chase reading about XMOS series USB to I2S microcontrollers, and they've really got something going there. Their XC code is readable and very deterministic, with threading and interrupts practically built-in. I do intend to follow along and create an XUF208 TQFP module with some TQFP codecs, which should all be USB 2.0. I dont intend to do any DSP on the XMOS series, but it could be a nice starting place for others.
Anyway, here is what the new design looks like:
The large empty space on the bottom of the board is for a fan.
It works! After some bodge wires and double checking everything, it successfully boots into a working clone of the organelle! Its smaller and costs about $80 to make, and its all open source! It is only a first-pass at this, I do intend to make it better.
Hopefully this post will detail how the device works in a way that makes sense.
The power supply circuit is lifted pretty much wholesale from adafruit's powerboost 1000. The li-on charger and power mux IC looked really great, and the DC-DC boost converter they used seemed extremely efficient. It also has rave reviews on people's portable emulator project, so I'd seen it around. I've never soldered qfn, so I got chipquik on my digikey order. I then realized that a power supply done in chipquik is an awful idea, but I had no other options. I slowly soldered the circuit, first doing the battery management IC, and testing along with a battery and a 5v in from a USB cable. It did what it said on the box, so I moved to the DC-DC converter. This one also seemed to do what they said it would do. Shortly after this, things fell apart.
I had spec'd out a DC boost to around 6.5, for a 5v clean output for the audio card. The nanopi's 5v line gets so polluted by all the fast switching from various sources. I used the same circuit all those cheap MT3608 boost converters from china use. They work, in my experience, and you can get 40 of them, shipped to USA, for about $6. The 5v reg is an MIC2920, just because I had them in stock. Their LDO characteristics aren't bad, either. There is another 3.3v line for the STM32, mainly so it's ADCs are a little bit cleaner. I used a MAX604, since I had it around.
I should probably explain that I got extremely lucky on craigslist a few years ago and ended up with the entire stock of a local 90's telecom that went under. I've got loads of parts, mostly jellybean stuff, but all of it is labeled and inventoried. I didn't get it that way, the labeling took months. This will help to explain the footprint size of the capacitors and resistors. I wish I could just used 0603 parts for everything, but its better for me to do what I have on hand.
Right away the 3.3v line had a short. After hunting around, I found something I'd overlooked in eagle. I felt very stupid. Clearly a short from some previous trace before I'd added the ground plane.
Had to use my scalpels to slice it. Swapped out the MAX604 and we were off to the races. Except the STM32 now would not flash. It turned out I'd misinterpreted the reference schematic I was looking at, and misplaced some pullups/capacitors. Bodge wires fixed that up well.
I also had to tweak the software on the nanopi, as the reset and boot0 pins have to always be initialized. I use stm32flash to do the business. Since the nanopi doesn't have a compiler, I rsync the bin from my desktop the board, then have a bash script which handles the flashing. It works reliably now!
I also misinterpreted about the same thing on the button debouncing for the rotary encoder's switch. A similar bodge occurred there.
I was getting pretty scared that the 2.2 inch TFTs I ordered at the end of august wouldn't show up before the deadline, so I bought two for about double the cost, shipped locally. I still hadn't tested my footprint from the first revision, so its all pretty up in the air whether its going to work. To fit in space for a hypothetical fan that may or may not be needed, I moved the nanopi a bit, and flipped the screen layout to give me about 42mm. I knew I could flip the screen in software, I just didn't expect it to be that easy. Oh, and I messed up by one GPIO on the pinout from my prototype, so I had to tweak it in software. Then it worked like a charm!
My phone's camera is a piece of shit. It looks quite clear to human eyes, even with the screen protector.
I know I'm cutting it extremely close to the deadline, but I think it'll be fine. Had some time this weekend to get through the laundry list of PCB mistakes, and sent off another board to JLC pcb. Needed to tweak the enable pin on the initial DC-DC boost converter so I can toggle it on and off, added the inrush current limiter, and jumpers to the 3v3 and 5v 'clean' LDO lines. This way when I do board bringup I can test each power supply separately. I had a hell of a time troubleshooting my circuit when the DC-DC shorted 5V to ground. This will make any mistakes like that less time costly. Also added more vias to the power supply components. Using chipquick as solder is probably a ~really bad~ idea for these components.
The knobs were wired in backwards, ground and 3v3 had to get switch around. Their footprint was also awful, with the output being a good 2mm off. The LQFP 48 packages had absolutely no pad footprints extending beyond the actual pins of the package, which makes hand soldering/drag soldering/troubleshooting very very frustrating. I changed the pad length from .9mm to 1.7mm, and adjusted their origins. The STM32 and audio codec should be a breeze now.
The "aux" button and the first C of the keyboard were switched around. I fixed that. Oddly, the 11 and 13th pins of the mux both register as 11. I think this is an issue with my muxing code.
Due to flipping the nanopi the right way, I had my SPI lane running across the board in an ugly way, so I made it slightly less ugly by flipping the display as well. I purposefully left all that room under the rotary encoder for some tiny blower fans, which aren't exactly necessary, but I'll feel a lot better about constant performance with one installed. It'll blow across the CPU first, power supplies second. The listing said they're about .7cm tall, 4cm square, so hopefully its true. Not much room to play with.
I hesitated on switching out the entire CM6206 codec with a PCM2906, but the PCM doesn't have any headphone driver. Since this is an extremely late revision I'd rather just stick with what I know will work.
Threw together the github repo for the linux side of things. Really creative name. I pumped the Puredata version up to 0.49.3, since it just came out and looks really promising, feature-wise. Nothing DSP related, but with ease-of-use like infinite undo/redo, intelligent autopatching, and some other niceties.
I updated the files part of this project with the last board revision, and Things are Looking Good.
I got the boards in about a week and a half ago. Nice job JLC pcb. I noticed a few things right off the bat:
The TQFP-48 footprints are precisely the same size as the pins, which makes soldering and alignment really hard. I haven't been able to successfully do solder one yet, so I'll redo that part design for the next board.
Using surface mount pads to mount the SBC is a bad idea. Its not easy to solder the further back rows. It should be through hole.
Didn't measure inrush current before I designed the board, and this killed my DC-DC boost converter, and battery management ICs.
Footprint for SI4720 RF transceiver is wrong. Its just wrong. I'm thinking of switching to discrete TX and RX ICs.
Through hole design for the potentiometers is just wrong.
Mounting screws for nanopi neo are off by about .1mm. Can't fully tighten the screws.
I completely inverted the pinout of the neo, and now it is installed upside-down. As in, the CPU and RAM are facing downwards towards the main pcb. This is the opposite of what I wanted, and I need to completely redo it.
The kindle battery mounts are slightly off, but they still work. Fit an M2.5 screw.
On top of that, the supplier of the CM6206 is moving their entire warehouse from CA to TX. It took over a month to get my 5 chips. In a huge 200 tray.
In the interim, I built the PCM2906 audio card and the FE1.1s USB hub projects for the square inch competition, and they both work! I've been thinking that the PCM290x would be better suited for this project, as it takes up a lot less space than the CM6206 design. I'll have to verify that on my next board revision.
To solve the whole "blowing up my DC-DC conv and battery IC" problem, I had to get back to basics. Using the relevant application notes from ON Semiconductor, I was able to experimentally get a design that worked for me. I have a lot of parts on hand, so I used an IRF7404 P channel mosfet and an AO3400 N channel mosfet.
I tested it on a 5 ohm, 100uF load. I used a simple button to enable Q1, with a 10k pulldown so its default state was off. After a few tries of swapping out parts, I got a pleasant curve that wouldn't break the electronic bank. Sorry for the photo quality, I have an Android. The final values: R1 is 100K, R2 is 50K, and C1 is 4.7uF. I could have divided all of these down, but these values were just on my desk. I was worried about the load mosfet heating up as its in the linear region too long, but as long as you don't toggle it on and off 15 times in a row, its nothing to worry about. I then tested this design on a 2.5 ohm, 1 farad load at 5 volts. It performed well.
I finally installed the circuit on some spare room on the PCB, and everything worked!
Had to use an eye loop to get this. You can see the unfortunate capacitor choice. I'll have to find SMD electrolytic variants. The ceramic and tantalum ones I tried didn't give the desired results.
During all of this, I also learned that the nanopi neo can run at 3.3 volts. As in, the 5v rail is only supplied 3.3 volts. I logged in and ran stress -c 4 for a while, and it never crashed. In this light, I've decided to forgo the main 5.1 volt DC-DC converter altogether, and use a smaller, accessory only 5v boost circuit based on the MT3806. I bought 40 of them for about 4 dollars shipped on Aliexpress.
This only complicates matters, though. I need 5 volts for USB accessories, but I also need a clean 5v line, using an LDO and ~6.5 volts from an MT3806 circuit. I also need a clean 3v3 line for the STM32, and a 3v3 line for any other accessories, such as the USB WLAN card. I measured it drawing upwards of 250ma in bursts during brief testing.
Anyway, I have the kindle battery working, the battery mgmt IC doing its business, a soft-start switch, and thats good enough for board 1. I'm going to make another board and get it here a week or two before the competition ends and prove the concept. ...
Spent a few days creating a schematic to contain my current protoboard project, with some other additions I'd like to try when the parts come in.
Right now the board is at 96x156mm, which is a bit big. Its constrained by the kindle battery I've chosen, so we'll see if its a good fit for the hands.
Right now it has the bare minimum for user input. I last minute added an SI4720 for some radio stuff, a mic input, and alternative (and most likely better) designs for battery management/boost converter. They're taken from adafruit's powerboost 1000c, which is a proven design. I tweaked some of the regulators based on what I have in stock. Added a USB wifi card (MT7601U) I found on aliexpress, which is supported in the mainline kernel. Makes ad-hoc UDP-OSC multicast stuff seem more plausible, too.
Unfortunately Friendlyarm raised the price of their nanopi neo core boards from about $9.99 to $18. Not too big a deal for one, but I'm making a few for my friends. Bummer.
After I sent this off to jlcpcb, I decided to try my hand at a "what if" situation, and designed some of this synth in the style of the 1 square inch contest. I figure I could take a modular approach, so if you wanted, say, a 4 in/ 4 out soundcard, you could plop a tiny PCB on to your main PCB and be off to the races. Right now I've got a decent audio mux, the RF transceiver, a PCM2906 2in/2out soundcard, and an FE1.1s usb hub each on their own < 1 inch PCBs.
I'm envisioning a sort of main bus backbone, eurorack style, on the main or carrier PCB, with room for all these little 'expansion cards' so the end user could build the synth they want. This'd make adding more buttons/knobs on the top easier, too, as you could create a PCB to mount to the front and hook into, say, a USB or UART interface.