The xcore.ai Multi-Channel Audio Board#

An application of the USB audio framework is provided specifically for the XK_AUDIO_316_MC hardware described in USB Audio hardware platforms and is implemented on an xcore.ai series dual tile device. The related code can be found in app_usb_aud_xk_316_mc.

The design supports upto 8 channels of analogue audio input/output at sample-rates up to 192 kHz (assuming the use of I²S). This can be further increased by utilising TDM. It also supports S/PDIF, ADAT and MIDI input and output as well as the mixing functionalty of lib_xua.

The design uses the following tasks:

  • XMOS USB Device Driver (XUD)

  • Endpoint 0

  • Endpoint Buffer

  • Decoupler

  • AudioHub Driver

  • Mixer

  • S/PDIF Transmitter

  • S/PDIF Receiver

  • ADAT Transmitter

  • ADAT Receiver

  • Clockgen

  • MIDI

The software layout of the USB Audio 2.0 Reference Design running on the xcore.ai device is shown in Fig. 1.

Each circle depicts a task running in a single core concurrently with the other tasks. The lines show the communication between each task.

../../_images/xk_316_system.png

Fig. 1 xcore.ai multichannel audio system/task diagram#

Audio hardware#

Clocking and clock selection#

As well as the secondary (application) PLL of the xcore.ai device the board includes two options for master clock generation:

  • A Cirrus Logic CS2100 fractional-N clock multiplier allowing the master clock to be generated from a xcore derived reference clock.

  • A Skyworks Si5351A-B-GT CMOS clock generator.

The master clock source is chosen by driving two control signals as shown below:

Control Signal

Master Clock Source

EXT_PLL_SEL

MCLK_DIR

0

0

Cirrus CS2100

1

0

Skyworks SI5351A-B-GT

X

1

xcore.ai secondary (application) PLL

Each of the sources have potential benefits, some of which are discussed below:

  • The Cirrus CS2100 simplifies generating a master clock locked to an external clock (such as S/PDIF in or word clock in).

    • It multiplies up the PLL_SYNC signal which is generated by the xcore.ai device based on the desired external source (so S/PDIF in frame signal or word clock in).

  • The Si5351A-B-GT offers very low jitter performance at a relatively lower cost than the CS2100. Locking to an external source is more difficult.

  • The xcore.ai secondary PLL is obviously the lowest cost and significantly lowest power solution, however its jitter performance can not match the Si5351A which may be important in demanding applications. Locking to an external clock is possible but involves more complicated firmware and more MIPS.

The master clock source is controlled by a mux which, in turn, is controlled by bit 5 of PORT 8C:

Table 4 Master Clock Source Selection#

Value

Source

0

Master clock is sourced from PhaseLink PLL

1

Master clock is source from Cirrus Clock Multiplier

The clock-select from the phaselink part is controlled via bit 7 of PORT 8C:

Table 5 Master Clock Frequency Select#

Value

Frequency

0

24.576MHz

1

22.579MHz

DAC and ADC#

The board is equipped with four PCM5122 stereo DACs from Texas instruments and two quad-channel PCM1865 ADCs from Texas Instruments, giving 8 channels of analogue output and 8 channels of analogue input. Configuration of both the DAC and the ADC takes place over I²C.

Configuring audio hardware#

All of the external audio hardware is configured using lib_board_support.

Note

lib_board_support has the I²C library (lib_i2c) in its dependency list.

The hardware targeted is the XMOS XU316 Multichannel Audio board (XK-AUDIO-316-MC). The lib_board_support functions xk_audio_316_mc_ab_board_setup(), xk_audio_316_mc_ab_i2c_master(), xk_audio_316_mc_ab_AudioHwInit() and xk_audio_316_mc_ab_AudioHwConfig() are called at various points during initialisation and runtime to start the I²C master, initialise and configure the audio hardware.

The audio hardware configuration is set in the config structure of type xk_audio_316_mc_ab_config_t which is passed to the xk_audio_316_mc_ab_board_setup(), xk_audio_316_mc_ab_AudioHwInit() and xk_audio_316_mc_ab_AudioHwConfig() functions.

static xk_audio_316_mc_ab_config_t config =
{
    // clk_mode
    (XUA_SYNCMODE == XUA_SYNCMODE_SYNC || XUA_SPDIF_RX_EN || XUA_ADAT_RX_EN)
    ? ( XUA_USE_SW_PLL
        ? CLK_PLL : CLK_CS2100 )
    : CLK_FIXED,

    // dac_is_clk_master
    CODEC_MASTER,

    // default_mclk
    (DEFAULT_FREQ % 22050 == 0) ? MCLK_441 : MCLK_48,

    // pll_sync_freq
    PLL_SYNC_FREQ,

    // pcm_format
    XUA_PCM_FORMAT,

    // i2s_n_bits
    XUA_I2S_N_BITS,

    // i2s_chans_per_frame
    I2S_CHANS_PER_FRAME
};

xk_audio_316_mc_ab_board_setup() function is called from the wrapper function board_setup() as part of the application’s initialisation process. It performs the required port operations to enable the audio hardware on the platform.

xk_audio_316_mc_ab_i2c_master() function is called after board_setup() during initialisation and it starts the I²C master task. This is required to allow the audio hardware to be configured over I²C, remotely from the other tile, due to the IO arrangement of the XK-AUDIO-316-MC board.

#define USER_MAIN_CORES on tile[0]: {\
                                        board_setup();\
                                        xk_audio_316_mc_ab_i2c_master(i2c);\

The AudioHwInit() function is implemented to make a call to the lib_board_support function xk_audio_316_mc_ab_AudioHwInit() to power up and initialise the audio hardware ready for a configuration.

The AudioHwConfig() function configures the audio hardware post initialisation. It is typically called each time a sample rate or stream format change occurs. It is implmented to make a call to the lib_board_support function xk_audio_316_mc_ab_AudioHwConfig().

For further details on the hardware platform and the functions available for configuring it refer to lib_board_support documentation.

Validated build options#

The reference design can be built in several ways by changing the build options. These are described in Configuration defines.

The design has only been fully validated against the build options as set in the application as distributed in the CMakeLists.txt. See Build configurations for details and general information on build configuration naming scheme.

These fully validated build configurations are enumerated in the supplied CMakeLists.txt.

The build configuration naming scheme employed in the CMakeLists.txt is shown in Table 6.

Table 6 Build config naming scheme#

Feature

Option 1

Option 2

Audio Class

1

2

USB Sync Mode

async: A

sync: S

I²S Role

slave: S

master: M

Input

enabled: i (channel count)

disabled: x

Output

enabled: i (channel count)

disabled: x

MIDI

enabled: m

disabled: x

S/PDIF input

enabled: s

disabled: x

S/PDIF input

enabled: s

disabled: x

ADAT input

enabled: a

disabled: x

ADAT output

enabled: a

disabled: x

DSD output

enabled: d

disabled: x

e.g. A build configuration named 2AMi10o10xsxxxx would signify: Audio Class 2.0 running in asynchronous mode. The xcore is I²S master. Input and output enabled (10 channels each), no MIDI, S/PDIF input, no S/PDIF output, no ADAT or DSD.

In addition to this some terms may be appended onto a build configuration name to signify additional options. For example, tdm may be appended to the build configuration name to indicate the I²S mode employed.