Turtle Bitch: an USB audio system for gaming

The amount of hobby projects I start, or let alone finish, has decreased quite a bit since I started my professional career. Nowadays my projects are usually things that do not exist in a market, or that only exist in an unsatisfactory form. This project falls into the first category; given the vast increase in the amount of gear marketed towards the gamer community I am still perplexed why I had to build this USB DAC / amplifier for my weekly fixes of online gaming with friends.

Front panel
One knob is for voice chat and another one for main volume; one button for muting the microphone and another one for playback mute.

 

There are some headphones on the market which allows the user to adjust the volume separately for voice chat and game audio. It narrows down the list of headphones to purchase to just a few products. Moreover, the functionality is also often implemented with software, which is way too unreliable for me. The same functionality could be achieved by using a software mixer without any special hardware, but given how often Windows seems to update itself and break features that is a path that I was not willing to travel.

The key design choice was that I wanted to use two separate USB audio chips, one which is dedicated to voice chat and one that handles everything else. Both chips need to have separate volume controls. I also threw in an optical audio input (with TI DIR9001) for a network media player, and decided that I could do the mixing with an FPGA. I ended up using two separate chips just so that it would be easy to distinguish the chips from each other in Windows; I was already familiar with TI PCM2707, and chose to accompany it with a C-Media CM108AH that also had a microphone input. Both chips can be configured to use I2S for inputs and outputs.

Turtle Bitch PCB

One of the most difficult things to get right was to make sure that the USB bus would work reliably if both chips were active. Through trial and error I found out that the USB 2.0 hub inside Microchip USB5742 seems to work well, and ended up integrating a Muxtronics Nanohub on the board.

After leaving the USB audio chips the I2S buses go through Si86xx isolators as I wanted to ensure that none of the USB power supply noise gets into the sensitive analog parts. After isolations I am using TI SRC4190 sample rate converters as I didn’t really want to spend the time to do the sample rate conversions on the FPGA.

Around the time of designing this I spotted an advertisement in a magazine, promoting the compact MAX1000 FPGA board and was immediately interested. After waiting for a couple of months I finally got my hands on one, and as a result this amplifier is also sporting an Intel MAX10 FPGA. The FPGA does the mixing, and its Nios II softcore processor also controls all the buttons, knobs and switches of the user interface.

For the DAC I am using a Cirrus Logic WM8731 which was yet another chip I was already familiar with. It acts as the I2S master, and has both headphone and line level outputs. Initially I was going to use passive speakers so I hooked it up to an TPA3116 class D amplifier circuit with the option of having a preamplifier output as well.

 

Back panel
From left to right: USB, Toslink in, DC in, preamp out, speaker terminals.

I have been using this system for over a year now and it has worked well. If I were to do a re-spin, I would change a couple of things; first of all, having the DC input next to the Toslink input was a bad idea as it is possible to jam the barrel plug to the Toslink connector and damage it. Moreover, sometimes Windows does not find the USB devices after boot unless I reconnect the USB lead – probably it would have been wiser just to have two USB connectors on the back.

I have built two of these boards, one for myself and one for a friend, and have no interest in building more as bringing the cost down would require quite significant effort. Therefore I challenge manufacturers to stop fiddling with RGB leds and offer something as good as this amplifier to the rest of the world. That is, unless you are still busy trying to make an usable solid state relay

For those who are curious to find out more, check the schematic. The schematic and the information in this blog post has been licensed under CC BY 4.0.

Embedded Linux datalogger

I have been building an FPGA FM receiver for quite a while now – I have had too many hobby projects running at the same time. Just for the sport I have decided to do the downconversion in digital domain – as a downside the ADC sample rate is then quite high even when undersampling. I plan to keep a GNU Radio design as the golden reference to aid debugging. However, this created another problem; how to sample a few seconds of the high sample rate data so that I can process it with a computer?

I decided that this would be a perfect excuse to learn some embedded Linux so I ordered a Terasic DE10-Nano board from Mouser. My plan was to store the data to the SDRAM memory and then use the on-chip hard processor (HPS) to transfer it to my PC.

The best place to get started is the Golden Reference Hardware Design (GHRD) for the DE10-Nano board. It worked fine. After that I tried to compile all the GHRD stuff myself using a tutorial from Bitlog, which is basically a practical and compressed version of a Rocketboards.org guide.

However, the GHRD just blinks a few LEDs by sending commands from HPS, and I want to send information the opposite way. I was able to figure the rest out with the help of a wiki page from Critical Link. Basically I use the modular SGDMA dispatcher and write master components to adapt the streaming output of my block to the F2H-SDRAM interface. The H2F is used to configure the DMA blocks. My advice is that you should just use these blocks instead of trying to write your own. You don’t need any fancy drivers if you are happy using devmem. You can then copy all the memory mapping stuff from the devmem source code.

Platform designer view of my datalogger

In addition I have routed a few of the FPGA IOs to the I2C core on the HPS side. It is used to control the sampling clock generator. The FPGA design is basically just a FIFO for clock domain crossing.

Even though Altera forums are full of threads where people are struggling with the FPGA-HPS interconnect I found out that it more or less works just like you would assume as long as you do not try to take any shortcuts. For example, make sure to regenerate the preloader every time you change some of the HPS properties.

I am able to access the HPS shell with the USB serial port connection to initiate a data logging event. I then redirect the output to a text file which I can download to my computer over an SFTP connection. I can also use the SFTP connection to send programs the cross-compiled programs onto the board.

Arduino core memory shield is ready and for sale

Hi all,

I was selling this core memory shield it as a kit on Tindie between 2016 – 2022 but it is now discontinued. See Andy Geppert’s Core64 project if you’re interested in getting into core memories, or build your own based on the information on this page.

coremem-v3

Here is all the material related to the kit:

coremem-shield-app

Thanks to Ben North and Oliver Nash at corememoryshield.com for the inspiration and encouragement!

Building a ferrite core memory, part 2

My ferrite core memory is progressing nicely. I have received the PCB and assembled it for the most parts.

Core memory shield without sense circuit

This evening I tried out how the H bridges worked – after a few tweaks in the Arduino code I was able to get this sequence out:

ferritecore-2
Bit read values from an array of cores.

The only remaining things are to assemble the sense line circuit and to do the final testing and tweaking, which will most likely take a long time.

Playing music using floppy drives, revisited

Playing music on floppy drives is nothing new. The Moppy project has been popular for a few years now, and it was the project that initially caught my attention as well. However, I though that it lacked a certain sense of elegance; FPGA would be much better in generating the waveforms for a bunch of floppy drives at the same time. That project also combines Arduino and Java, both of which are not my favourite things in the world. It also requires a PC.

So I decided to roll an implementation of my own. Last summer I programmed the midi parser on an ARM microcontroller, which sent the data to the FPGA via SPI. The basic VHDL block consists of nothing more than a counter and a lookup table. Eight of these blocks were instantiated in a higher level block and connected to a SPI block which was trivial to program.  The MIDI file was hard-coded in the program memory of the microcontroller as a C array. It worked, but it was certainly not satisfied. There’s no need to have anything besides a single FPGA, and the project must have an user interface. Changing the song was too hard in the old version.

In late 2013 I dug up my Terasic DE2 board, which is on loan from my university (thanks TUT!). It’s been a while since my VHDL and SoC classes but I was able to create a QSys system in a short time. Of course, I also had to wrap my HD44780 and waveform generation blocks to use Altera’s Avalon bus. I was really amazed how smoothly everything went.

IPs connected in QSys
IPs connected in QSys

Besides the aforementioned blocks I also used Altera’s SD card IP. It didn’t work with my SDHC card, but an old 128 MB SD card worked fine. I can just save mid files on the SD card and choose the song to play from the HD44780 LCD screen. User input is given using pushbuttons (parallel IO).

HD44780 LCD showing the MIDI files on SD card.
HD44780 LCD showing the MIDI files on SD card.

 

The “music” waveforms are output from the GPIO header and fed to a 74LVC245 buffer. Besides buffering, it also converts the 3.3V signals to 5V. The buffer outputs are directly connected to the floppy drives using 10-pin IDC cables and a simple adapter PCB. The PCB also has an LED indicating power – it also turned out that the current draw of the motors made them flicker in a nice way.

My PCB which brings out all the signals in a single 10-pin connector.
My PCB which brings out all the signals in a single 10-pin connector.
Buffer PCB
Buffer PCB

That’s all there was to it really. I think this is as far as I’ll go with this as I think my solution is now elegant enough and I’m sick of hoarding floppy drives. Possible improvements would be combining the channels and floppy drives more intelligently (not all floppy drives are the same and play at the same volume  – some sound much more ugly than the others). Sometimes beautiful melodies are hidden beneath the grunting sounds from the other drives.

Here’s a few songs I recorded.


Playing music using floppy drives

The Moppy project, which enables an Arduino to use floppy drives to play music, is something a lot of people have tried, but I was not comfortable with installing Netbeans to run the Java app. Instead, I built my own system from scratch.

I used my NXP LPC1768 dev board “LandTiger” for all the complex stuff. It had the MID file in its memory as an array, parsed it and sent the notes over SPI.

A Micronova Mercury FPGA board received the notes and generated the waveforms to play the notes. I used an FPGA so that I could utilize its parallelism for the waveforms and to prevent my VHDL skills from rusting. A neater way would have been to replace the microcontroller with a softcore one inside the FPGA, but I didn’t feel the need as I was just dicking around.

Regrettably, this video is the only piece of evidence I have left. Well, the system consisted of a lot of software and a few wires, so there was nothing much to see.