Raspberry Pi -A New DIY'ers Digital Hub?

Status
This old topic is closed. If you want to reopen this topic, contact a moderator using the "Report Post" button.
how I power-wired mine.
 

Attachments

  • 8367353581_e005b98265_b.jpg
    8367353581_e005b98265_b.jpg
    205.3 KB · Views: 607
Hi all,

Over on the raspberry pi forums, I've knocked up a rudimentary ALSA I2S driver for Raspberry Pi.
It works, and is stable, but is hardwired for 16 bits per sample, 44.1kHz stereo, I2S output (no odd variants). It is in a github repository (link below).
If it doesn't meet your needs, feel free to alter it to suit, but I don't intend to modify it for every man and his dog :)
It's a kernel space driver, so I'm afraid you'll have to build a kernel, start using it, and then build this driver using the source code as a reference. If that doesn't make sense, then google something like "Raspberry Pi Kernel build", or similar, and spend some time researching.
As you can read in the thread, I had some issues with a USB keyboard that was causing interrupt problems, so be aware that some peripherals might be upsetting your scenario. (on the pi, USB has access to the high priority IRQ, so can hog things if things go wrong, as they did for me).

For me, I have GMPC running, playing FLAC, WAV, M4A (not tried MP3 yet, don't have any to hand) with an old DIY TDA1541A DAC. I haven't configured my hardware yet to feed a clock into the pi yet, so it's just running in NOS at the moment (gulp!) but it works.

I want to try dividing down my Kwak clock variant to feed BCLK into the Pi. I hope that will work, and I can feed MCLK into my oversampler. That's for another day though.

https://github.com/philpoole/snd_pi_i2s
Raspberry Pi • View topic - I2S: Anyone got it running?

Might consider a photo if I can be bothered. It's not very pretty, and you can probably imagine what it looks like.
Might do some hardware for a change next :)

Phil
 
That's excellent news, well done! :D:D:D Did you get your driver to work with DMA? Are you cross-compiling, or doing it on the Pi?

From the point of view of figuring out what on earth the Pi's problem actually is... It's interesting to hear that you get the same keyboard-related glitches in your I2S driver as us USB soundcard users have been suffering.

To cut a long story short, I think it is all connected to the USB controller's mishandling of split transactions, which are used for carrying USB1.x data over a 2.0 link, as required when you plug a 1.x device into a 2.0 hub. The problem seems to go away when you use the latest Raspbian kernel, and only USB2.0 devices.
 
Last edited:
Hi all,
Over on the raspberry pi forums, I've knocked up a rudimentary ALSA I2S driver for Raspberry Pi. It works, and is stable
Phil
That's pretty impressive to get it all working. Some earlier I2S explorers had some documentation troubles and others lost resistors along the way. We'll be watching your work with great anticipation, especially external clock bit.
 
As requested I'm posting some details of my Raspberry Pi music project. It's working at up to 24 bit/192kHz with no obviously unpleasant glitches.

I'm using the Pi Model B, connected to the QNKTC USB DAC (also described on the forum) in UAC2.0 mode, plus a 320GB HDD in a USB2.0 enclosure, and an "Edimax N150" wi-fi dongle.

I chose the QNKTC DAC because it was advertised as USB2.0 asynchronous, and the Pi's problems were with USB1.x.

A brain dump of what I did to get the USB audio working: I downloaded the recommended "Raspbian Wheezy" image in December, and upgraded it after installation.

My kernel version shows as follows:
Linux pitunes 3.2.27+ #250 PREEMPT Thu Oct 18 19:03:02 BST 2012 armv6l

Then I made the following changes to the config files:

/boot/cmdline.txt: added option: dwc_otg.lpm_enable=0
(this activates an experimental fix to the USB driver. I don't know if it is enabled by default in later kernels)

/boot/config.txt: added following options:
arm_freq_min=700
gpu_freq_min=250
(This prevents the power management from slowing down the clocks. Hopefully it can service interrupts quicker if it's always running full speed. I stopped short of overclocking it.)

/etc/mpd.conf: Changed the audio_output section as follows:

audio_output {
type "alsa"
name "QNKTC USB DAC"
device "hw:1,0"
auto_resample "no"
samplerate_converter "0"
}

After all this, I still got glitches when typing on the USB keyboard, and even when not touching it, I seemed to get one small glitch per 5 minutes.

As a last resort, I removed the keyboard, leaving only USB2.0 devices on the system, and it seems to be performing solidly.
 
Parisnight, scopeboy,
Yes, USB does seem to be an issue. I think it's too many interrupts.
Replacing the keyboard (a comedy £2 Argos keyboard that read 'USB Keykoard' upon registering!) seemed to help.
However, I developed it using a couple of FLAC files on the SDHC card, and it seemed okay. Now I'm having fun with a USB HDD (I've tried a couple of USB-SATAs and one USB to IDE), and it plays okay, no glitches, but it's occasionally swapping channels, which suggests buffer underruns. I hope performing some error handling may help.
I haven't implemented DMA. I think it may be overkill, although I wonder if it will overcome this current issue I have.
I think I'm using a fairly up to date kernel. I had to rebuild it in November I suppose in order to put some debug in it. I guess there's no harm in a pull from github.
(I cross compiled the kernel, but built the module on the pi.)
I do plan to do external clocking too. It's simple from a software point of view. I might include it untested for now (I am planning to knock up a divide by 4 for my clock though).
Thankfully, I didn't need to lose any resisitors as I waited for the v2 pi :)
 
I removed the keyboard, leaving only USB2.0 devices on the system, and it seems to be performing solidly.

Thanks for all the details of your setup. The results are very encouraging to me. I found it interesting that you achieved all this with your files on a locally connected USB2 drive.

Yesterday I was thinking that philpoole's beautiful ALSA I2S driver would circumvent a lot of the USB troubles and make one of the lowest cost asynchronous DACs possible. Sorry, I'm so slow to realize these things. If indeed there are occasional underruns, I'd have to agree that DMA would be a premature optimization. There must be some other botttleneck, especially in view of scopeboy's success with USB2 data and USB2 soundcard. Maybe try his /boot/* adjustments?
 
I haven't implemented DMA. I think it may be overkill, although I wonder if it will overcome this current issue I have.

If used correctly, DMA is a big win. It takes a lot of load off the processor and relaxes the interrupt latency requirements.

Here is an example of how I believe it's normally done. You set up two buffers in memory, and set the DMA controller up for linked transfers. The DMA controller dishes out one sample at a time to the SPI controller, and it does this with a hardware "interrupt" that has higher priority than any code on the system. When it has finished reading one buffer, it raises an interrupt to the OS (calling your audio driver) and immediately starts on the second one.

So, your driver code gets called "once per buffer full", and it has almost "one buffer's worth" of time to respond to the IRQ and fill the buffer up.

Without DMA, your driver code will get called once per sample, and you have one sample's worth of time to respond. (Maybe a little more, as some SPI controllers include a small FIFO.)

The clincher is that the response time includes the "interrupt latency": the time between the hardware asking for another sample, and the Linux kernel getting its act together to execute your driver code. I don't know much about the details of the Linux kernel, but I doubt it can reliably service an interrupt in one sample's worth of time.

So, to cut a long story short, DMA allows you to cope with worse interrupt latency (such as Linux has) without getting underruns, by just using bigger buffers.

You may think that if you just spin in a tight loop, polling the SPI controller, you won't miss any samples. But this is doomed to failure. The OS will swap your task out sooner or later, as it needs to get other stuff done. (maybe mpd needs to decode some more audio.)

The last project I worked on was an industrial ultrasound system handling 6 channels of data at 1MHz sampling rate. Without DMA and double buffering, it would simply never have worked.
 
Last edited:
I'm aware of how DMAs work. I wrote a SB16 device driver for my degree, using DMAs.
My reluctance to start work on DMA, might be to do with needing a break, but also to understand what I currently have - and how it can be optimised. I'm not fully aware of how to implement an ALSA driver correctly. The ALSA documentation is a bit vague in places, so I'm not fully confident my implementation is the most efficient regarding the API.
Your description is a bit more loading than in the raspberry pi. For the pi, you receive an interrupt every 64 samples, not every individual sample. So although a little excessive, it's not as bad as you think.
With my current ALSA setup, the DMA could be interrupting every 2048 samples. An order of magnitude better than 64 samples, but not as good as DMA could be (e.g. 64k buffer's worth per interrupt, or more).
Having said all that. DMA will be free from interrupts, unlike the ARM, so hopefully will show some resilience (as long as there is always a spare DMA for this purpose, which may well be being used for USB HDD transfers).

I've been more interested recently in why my USB HDD (well, usb to sata hdd) is upsetting things - and why it's much better reading music files from SDHC.
Based on my keyboard incident I wondered if a better quality usb -> sata adaptor might improve things, or perhaps a very solid PSU, but it sounds like that may not be the case.
 
There are several ways one connected usb device can upset another usb device.

1. the two devices may share the same host controller and interrupts

2. a low or full speed device will render ALL devices connected to the same hub to enumerate at the lowest speed. (keyboards are low speed devices usually).

3. some usb device may reserve and hog a large nandwidth although it is not needed.

Alex
 
Point 2 is wrong. You can plug any combination of devices into a USB 2.0 hub, and the high-speed ones will still get high speed.

What really happens is that the hub packages the low-speed transactions into its high-speed upstream connection. High-speed frames go by much faster than low-speed ones, so one low-speed transaction sometimes needs to be split across several high-speed frames. It's at this point that the Pi's USB controller drops the ball.

Philpoole: Do you know where this 64 sample figure comes from? Does the SPI controller have a 64 sample FIFO, or is there some DMA going on already?

I'm using a USB-SATA enclosure with a Jmicron chipset.
 
Last edited:
I do not know about the specifics of the RPi. I was just listing various possible problems when you mix different speed USB devices.

For example, below is a comment from a user regarding a particular USB hub:


This review is from: D-Link DUB-H4 High Speed USB 2.0 4-Port Hub (Personal Computers)
I think the other reviews largely get it right. Two things I haven't seen in them, however: first, the plug on the power cord is in the shape of a wide black monolith, so, like bulky a/c adaptors... Second, the included documentation says that the hub will revert to a USB 1.1 hub FOR ALL DEVICES if you have any USB 1 device connected. It says that to get USB 2.0 throughput, you must disconnect all USB 1.0 or 1.1 devices from the hub first. That's worth knowing.

Finally, if you buy the hub, I suggest going to Windows Update and downloading the optional USB 2.0 fix for WinXP SP 1.
 
Status
This old topic is closed. If you want to reopen this topic, contact a moderator using the "Report Post" button.