DSP

Stream Data Into ADSP-2156

Published 3 Nov 2026, modified 5 Nov 2026. By Jakob Kastelic.

The ADSP-21569, as demonstrated on the EV-21569-SOM and EV-SOMCRR-EZLITE boards, appears to be optimized for streaming lots of audio channels. What if we instead need to stream fewer channels at faster sample rates? In this article, we will try out several possible pathways.

UART

The first step after “blink” works is to have a debug input/output and UART is always the easiest. Of course we already had to set it out previously to enable automated agentic code development and testing.

QSPI: From USB into DSP using FT4222

We can test mass data ingestion without any additional wiring via the QSPI interface, since the EZLITE board includes a USB-to-SPI adapter FT4222HQ-D-T. (Make sure to follow the QSPI setup instructions in the previous article to make sure that FT4222-as-master works.)

With DSP in slave mode, we can write a little test program that ingests the data using DMA into two buffers, “ping-ponging” between them: DMA writes into one buffer while we read from the other, and when the first one is full, DMA starts to write into the second one. If we process the data fast enough, this guarantees there’ll be no contention between the CPU and DMA without requiring any other synchronization.

In this case, all we are interested in is whether the data is received correctly. As a simple test, we can write a couple bytes and then read them out via UART, but then we cannot test the data transfer speed. Instead, we can tell the CPU to consume the data when DMA buffer fills up and calculate a running checksum (e.g., XOR all words into a single accumulator).

The data rates from USB into FT4222 and thence into the DSP are as shown in the table:

LanesSCKMbps actualMbps theoretical% peak
110 MHz4.41044 %
120 MHz5.82029 %
140 MHz6.84017 %
210 MHz16.12081 %
220 MHz27.14068 %
240 MHz40.78051 %
410 MHz27.14068 %
420 MHz41.18051 %
440 MHz53.916034 %

“Up to 53.8Mbps data transfer rate in SPI master with quad mode transfer” says the bullet point on FT4222 datasheet front page. Later on, in Table 4.1 on page 11, the “Max Throughput” is stated as 52.8Mbps. “It also depends on the USB bus transfer condition.”

The quad-lane theoretical maximum takes into account that at most 64K bytes can be transmitted at once, the clock rate is 40 MHz, and there’s an extra 6.65 ms (or is it 6.47 ms?) of library/USB overhead.

FT4222 Silicon bug: need 0x00 first byte

Using SPI2 in the 1-lane mode (regular four-wire SPI), the transfer works as expected. In Python, simply import ft4222 and then make use of the spiMaster_SingleWrite() function to write the data.

The dual and quad SPI modes, however, are more tricky. First of all, the spiMaster_SingleWrite() refuses to send data outside the single-lane mode. The library provides spiMaster_MultiReadWrite() which does transmit data but sometimes all but the first byte is transmitted incorrectly: the bit corresponding to D1 stays stuck at 0.

There’s a hint in the “User Guide for LibFT4222” (FTDI App Note AN_329), in a section on using the FT4222 in slave mode:

For some reasons, support lib will append a dummy byte (0x00) at the first byte automatically.

We’re using the FT4222 in master mode, but it seems that the library author knew something that the app note writer did not: the chip has a quirk, or perhaps an undocumented in-band command depending on the contents of the first byte transmitted.

For example, if the first word transmitted is 0x0d4416c4, then all subsequent data will be corrupted. However, many other first words do not trigger the bug (e.g. 0x00000000, 0xFFFFFFFF, 0xc8ad14e5).

The workaround is as indicated in the above quote: always send 0x00 as the first byte. Annoying, but irrelevant in this instance since all we care about is to measure what is the maximum reliable data rate.

I have not been able to find this bug documented either in the datasheet or in the Technical Note TN_161, “FT4222H Errata”.

QSPI out of DSP

Getting the data output of the DSP is just a little bit more tricky. We do not want to switch the FT4222 into slave mode, because then we need to physically move the S5 jumper on the EZLITE board, which would be annoying to automate. Moreover, the FT4222 only supports the single-bit data transfer in slave mode, while the master supports all three bit widths, both data directions.

GPIO loopback

Some of the tests in the future will require wiring SPI and SPORT ports between each other as “external loopback”. To verify wiring continuity, it is helpful to set up a GPIO example code that verifies which pins are connected to which pins.

On the EZLITE board, connector P13 breaks out the DAI pins that are used for the SPORT interface. Note that the pins’ presence on the board does not mean they are connected to anything! (They may be used with other SOM boards.)

P13 pinP13 signalNotes
7DAI0_PIN13absent both packages
9DAI0_PIN14absent both packages
19DAI0_PIN15absent both packages
21DAI0_PIN16absent both packages
31DAI0_PIN17absent both packages
33DAI0_PIN18absent both packages
2DAI1_PIN01
4DAI1_PIN02
6DAI1_PIN03
8DAI1_PIN04
10DAI1_PIN05
12DAI1_PIN06
14DAI1_PIN07
16DAI1_PIN08
18DAI1_PIN09
20DAI1_PIN10
22DAI1_PIN11absent 120-lead LQFP
24DAI1_PIN12absent 120-lead LQFP
26DAI1_PIN13absent both packages
28DAI1_PIN14absent both packages
30DAI1_PIN15absent both packages
32DAI1_PIN16absent both packages
34DAI1_PIN17absent both packages
36DAI1_PIN18absent both packages
38DAI1_PIN19
40DAI1_PIN20

On the P14 header, we get access to the I2C and two SPI ports. These are highly multiplexed. For example, the PA_06 and PA_07 are UART0_TX and UART0_RX, respectively.

P14 pinP14 signalP14 functionMultiplexed
25PA_14TWI2_SCLFn 0
27PA_15TWI2_SDAFn 0
2PA_06SPI0_CLKFn 0
4PA_07SPI0_MISOFn 0
6PA_08SPI0_MOSIFn 0
8PA_09SPI0_SSBInput Tap
10PB_05SPI0_SEL2*Fn 2
12PA_10SPI1_CLKFn 1
14PA_11SPI1_MISOFn 1
16PA_12SPI1_MOSIFn 1
18PA_13SPI1_SEL1*Fn 1
20PB_10SPI1_SEL2*Fn 1