6

I want to connect multiple I2S ADCs to RaspberryPi and record multi-channel audio. I calculated that it requires copying GPIO input port to RAM at 3072kHz (or every 0.33µs). I want to do it using DMA.

I know that PiBlaster (PWM) and PiFM (radio transmitter) use DMA but the lowest sampling period was about 4µs.

So, is reading GPIO at 3072kHz possible, using DMA?

The detailed calculations why I need 3072kHz are on RaspberryPi forum: http://www.raspberrypi.org/phpBB3/viewtopic.php?f=44&t=55799 . Here I'm asking only about GPIO and DMA throughput.

2
  • I would suggest asking this question on electronics stack exchange. THere are some experienced guys there that might be able to help you.
    – Piotr Kula
    Commented Sep 18, 2013 at 11:41
  • 4
    Belongs on Electronics Exchange
    – Piotr Kula
    Commented Sep 18, 2013 at 11:41

3 Answers 3

3

I wrote a C++ library called v3c-raspi. You can download it from SourceForge.

I wrote an example program that tries to do just what you want, called "i2s".

Unfortunately it experiences a "program anomaly" anywhere from straight away to a couple of seconds after it starts - it looks like something else uses dma channel 0 and leaves rubbish in the block address register.

I could get the Raspberry Pi to process about 16 million DMA control blocks per second (in another test).

The i2s microphones I'm planning to use are the Analog Devices ADMP441 which output 24 bit audio.

At 48kHz that's a bit clock frequency of 48000 x 32 = 1.536 MHz. The code toggles the clock using dma as well, so we double the frequency to 3.072MHz.

Add in PWM pauses and you double the number of control blocks again to 6.144 million, still well within the 16 million I could get out of the rpi.

I reported a bug about this very issue to Raspbian but no responses yet.

I solved most of the problems - see linux-rpi-kernel mailing list 2013-November, message 000734 for more.

It's limited to about 2M samples/sec so you could capture 22.1 kHz samples from 8 stereo pairs with it.

4
  • There is a list of DMA channels used by the GPU. I'm fairly sure that channel 0 is used for the screen.
    – joan
    Commented May 1, 2015 at 15:47
  • In cmdline.txt you specify which DMA channels the kernel (and its modules) may use. Just Google "dma.dmachans=0x7f35" for more. In v3c-raspi/v3c/examples/i2s.cpp I made a note of the dma channels I tested - search for "let user mode programs use DMA 0, 4, 5". I do remember trying DMA channel 0 with success, but I'm in the dark as to how this is handled by the video-kernel-module/GPU/binary-blob. Commented May 3, 2015 at 15:52
  • We can specify what we want. However if we use DMA channels 0, 1, 2, 3, 6, or 7 we will have conflicts with the kernel and/or GPU.
    – joan
    Commented May 3, 2015 at 16:06
  • The kernel is where this arbitration happens. Commented May 4, 2015 at 16:57
1

Just see this.

Raspberry-Pi-DMA-Example

https://github.com/Wallacoloo/Raspberry-Pi-DMA-Example

2
  • The link explains how to use DMA for GPIO output, the OP is asking about input.
    – Malvineous
    Commented Dec 28, 2017 at 13:38
  • You are absolutely right, my fault. But a lot of information about DMA.
    – Hender
    Commented Dec 31, 2017 at 13:48
0

The GPIO pins cannot handle such speeds. I've found that the max read speed of the GPIO header is about 1kHz. The max the UART can handle is about 1Mbaud for stable communication and 4Mbaud is the max the kernel can handle. Anything higher than 1Mbaud requires USB or Ethernet. According to documentation, you can access DMA, whose speed is substantially faster than that of the UART. It also bypasses the CPU, making the operation cheaper in the long run.

4
  • How did you test that? Have you tried using mmap-based interface?
    – adiblol
    Commented Nov 5, 2013 at 10:01
  • I had a signal generator send 'a' at 1MBaud and used the mmap code found here and read in the information in a while loop with gcc's O3 flag, every code optimization I could think of, and running without the user interface. The fastest it could handle is 4Mbaud (the kernel's support stops at 4Mbaud) messages. Sustained message streaming was really patchy and broken past 1Mbaud.
    – Nielsvh
    Commented Nov 5, 2013 at 16:35
  • 2
    SPI can handle 32Mbps if you are careful with your signal conditioning. The max speed of the GPIO header is of the order of 10Mbps. I do not understand what typo could have resulted in the 1kHz of your post.
    – joan
    Commented May 1, 2015 at 15:45
  • Well the discussion here is about DMA. Well which is well beyond 1kHz.
    – n1nj4
    Commented Oct 26, 2019 at 18:15

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.