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.

adiblol
  • 61
  • 1
  • 1
  • 3

3 Answers3

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.

  • There is a list of DMA channels used by the GPU. I'm fairly sure that channel 0 is used for the screen. – joan May 01 '15 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. – Philip Ashmore May 03 '15 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 May 03 '15 at 16:06
  • The kernel is where this arbitration happens. – Philip Ashmore May 04 '15 at 16:57
1

Just see this.

Raspberry-Pi-DMA-Example

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

Hender
  • 111
  • 1
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.

Nielsvh
  • 203
  • 1
  • 11
  • How did you test that? Have you tried using mmap-based interface? – adiblol Nov 05 '13 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 Nov 05 '13 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 May 01 '15 at 15:45
  • Well the discussion here is about DMA. Well which is well beyond 1kHz. – n1nj4 Oct 26 '19 at 18:15