Hide navigation sidebar
Hide table of contents sidebar
Skip to content
Back to top
Toggle table of contents sidebar

# ADAT transmit

`lib_xua` supports the development of devices with ADAT transmit functionality through the use of lib_adat. The XMOS ADAT transmitter runs on a single thread and supports transmitting 8 channels of digital audio at 44.1 or 48 kHz. Higher rates are supported with a reduced number of samples via S/MUX (‘sample multiplexing’). Using S/MUX, the ADAT transmitter can transmit four channels at 88.2 or 96 kHz (SMUX II) or two channels at 176.4 or 192 kHz (SMUX IV).

ADAT transmitter requires a thread to run on. Blocks of audio samples are transmitted from the `XUA_AudioHub()` to the ADAT transmitter over either a dedicated channel or a combination of a channel and shared memory.

Each block of audio samples is made of 8 samples. At sampling rates 44.1/48 kHz (SMUX I), this consists of a single sample of each of the eight ADAT channels:

- Channel 0 sample

- Channel 1 sample

- Channel 2 sample

- Channel 3 sample

- Channel 4 sample

- Channel 5 sample

- Channel 6 sample

- Channel 7 sample

At 88.2/96 kHz (SMUX II), the audio sample block consists of two samples per four ADAT channels:

- Channel 0 sample 0

- Channel 0 sample 1

- Channel 1 sample 0

- Channel 1 sample 1

- Channel 2 sample 0

- Channel 2 sample 1

- Channel 3 sample 0

- Channel 3 sample 1

At 176.4/192 kHz (SMUX IV), the audio sample block consists of four samples per two ADAT channels:

- Channel 0 sample 0

- Channel 0 sample 1

- Channel 0 sample 2

- Channel 0 sample 3

- Channel 1 sample 0

- Channel 1 sample 1

- Channel 1 sample 2

- Channel 1 sample 3

The configuration option `ADAT_TX_USE_SHARED_BUFF` determines whether the audio samples block is transmitted using only a channel (`ADAT_TX_USE_SHARED_BUFF` is not defined) or a channel + shared memory (`ADAT_TX_USE_SHARED_BUFF` is defined). When using a channel + shared memory for samples transfer, it is required that the ADAT transmitter and the `XUA_AudioHub()` tasks run on the same tile.

The USB Audio reference applications with ADAT interface enabled in `sw_usb_audio` are only tested with `ADAT_TX_USE_SHARED_BUFF` defined. The sample transfer sequence described in Sample communication assumes that `ADAT_TX_USE_SHARED_BUFF` is defined.

## Declarations

The channel used for communicating between `XUA_AudioHub` and ADAT transmitter should be declared:

    chan c_adat_out

In order to use the ADAT transmitter with `lib_xua` a 1-bit port must be declared e.g:

    on tile[XUA_AUDIO_IO_TILE_NUM] : buffered out port:32 p_adat_tx  = PORT_ADAT_OUT;

This port should be clocked from the master-clock:

    configure_out_port_no_ready(p_adat_tx, clk_audio_mclk, 0);
    set_clock_fall_delay(clk_audio_mclk, 7);

Finally the ADAT transmitter task is run - passing in the port and channel for communication with `XUA_AudioHub`:

    adat_tx_port(c_adat_out, p_adat_tx);

## Sample communication

Samples are communicated between `XUA_AudioHub()` and the `adat_tx_port()` task.

The interface to the ADAT transmitter task is via a normal channel with streaming builtins (`outuint`, `inuint`).

To begin with, `XUA_AudioHub` sends two values on the channel - the master clock multiplier and the S/MUX setting.

The master clock multiplier is the ratio between the mclk freqency and the sampling frequency. The S/MUX setting is 1, 2 or 4, depending on the sampling frequency:

                /* Calculate what master clock we should be using */
                if (((MCLK_441) % curSamFreq) == 0)
                {
                    mClk = MCLK_441;
    #if (XUA_ADAT_TX_EN)
                    /* Calculate ADAT SMUX mode (1, 2, 4) */
                    adatSmuxMode = curSamFreq / 44100;
                    adatMultiple = mClk / 44100;
    #endif
                }
                else if (((MCLK_48) % curSamFreq) == 0)
                {
                    mClk = MCLK_48;
    #if (XUA_ADAT_TX_EN)
                    /* Calculate ADAT SMUX mode (1, 2, 4) */
                    adatSmuxMode = curSamFreq / 48000;
                    adatMultiple = mClk / 48000;
    #endif
                }

This is followed by communicating the address of a block of memory holding the audio samples block. The `XUA_AudioHub` “runs ahead” of the ADAT transmitter task, assembling the next sample block while the ADAT transmitter converts the current block into an ADAT stream to transmit over the optical interface.

The ADAT transmitter, once done processing the current block, acknowledges this by sending a data token over the channel to `XUA_AudioHub` as a handshake mechanism. On receiving this handshake, `XUA_AudioHub` sends the address of the next block of samples over the channel.

Note that a `XS1_CT_END` control token is not sent between blocks of data, leading to the channel remaining open and getting used as a streaming channel.

`XUA_AudioHub` only terminates the connection by sending a `XS1_CT_END` token when there’s a sampling frequency change that requires the `XUA_AudioHub` task to re-communicate the master clock multiplier and the S/MUX setting.

In case of a sampling frequency change, the `XUA_AudioHub()` task receives the pending handshake from the ADAT transmitter, followed by sending the `XS1_CT_END` token indicating the end of data streaming to the ADAT task. A fresh transmission is then started by sending the new master clock multiplier and the S/MUX setting to the ADAT transmitter, followed by audio blocks transfer as described above.

Fig. 2 describes the communication between `XUA_AudioHub` and the ADAT transmitter:

Fig. 2 Communication between XUA_AudioHub and ADAT transmit

For further details please see the documentation and examples provided with lib_adat.

## Channel count changes

When ADAT transmit is enabled, the number of USB playback channels vary depending on the sampling freq (S/MUX mode). This is exposed to the USB host as alternative interfaces, each supporting different channel counts, for the streaming output interface. The number of alternative interfaces exposed depends on the `MIN_FREQ` and `MAX_FREQ` supported over the USB interface. In the most generic case, where the device supports all sampling rates from 44.1 to 192 kHz, 3 alternative interfaces on the streaming output interface are exposed, each supporting a different channel count.