<<

I2S Slave

This module is an I2S slave transmitter and receiver in a single thread. It sends and receives samples over a pair of chanends and transmits audio over I2S. It can send and receive multiple I2S links on separate ports.

As a slave it is driven by the bit clock (BCK) and word clock (WCK) on input ports.

API

Symbolic constants

I2S_SLAVE_NUM_IN

Number of input ports, each carries two channels of audio.

I2S_SLAVE_NUM_OUT

Number of output ports, each carries two channels of audio.

Structures

i2s_slave

Resources for I2S_SLAVE.

Structure Members:

clock cb

Clock block for external BCK.

in port bck

Clock port for BCK.

in port wck

Clock port for WCK.

in buffered port:32 din

Array of I2S_SLAVE_NUM_IN x 1-bit ports for audio input.

out buffered port:32 dout

Array of I2S_SLAVE_NUM_OUT x 1-bit ports for audio output.

Functions

void i2s_slave(struct i2s_slave &r_i2s_slave, streaming chanend c_in, streaming chanend c_out)

I2S Slave function.

Samples are left-aligned signed values. e.g. 24-bit audio will look like 0x12345600 (positive) or 0xFF123400 (negative)

Parameters:
  • r_i2s_slave – Structure to configure the i2s_slave
  • c_in – Input streaming channel for sample data. Samples are returned in the following order: Left (din[0]), .., Left (din[I2S_SLAVE_NUM_IN - 1]), Right (din[0]), .., Right (din[I2S_SLAVE_NUM_IN - 1])
  • c_out – Output streaming channel for sample data Samples should be sent in the following order: Left (dout[0]), .., Left (dout[I2S_SLAVE_NUM_OUT - 1]), Right (dout[0]), .., Right (dout[I2S_SLAVE_NUM_OUT - 1])

Example

This example is designed to run on the XR-USB-AUDIO-2.0-MC board. It takes input on 3 I2S links and outputs the selected one on four I2S links. I2S_SLAVE_NUM_IN and I2S_SLAVE_NUM_OUT are defined in the Makefile.

First of all i2s_slave should be included and the structure i2s_slave defined.

#include "i2s_slave.h"

on stdcore[1] : struct i2s_slave r_i2s_slave =
{
   XS1_CLKBLK_1,
   XS1_PORT_1I,  // BCK
   XS1_PORT_1E,  // WCK
   { XS1_PORT_1G, XS1_PORT_1A, XS1_PORT_1B },  // DIN
   { XS1_PORT_1M, XS1_PORT_1F, XS1_PORT_1H, XS1_PORT_1N },  // DOUT
};

The top level of this example creates the i2s_slave on core 1, along with a 1KHz clock to the PLL and occupies the remaining 6 threads with computation.

Core 0 runs the loopback function which reads the I2S inputs from the i2s_slave thread over a streaming channel and sends them over a streaming channel back to the i2s_slave thread to the I2S outputs.

int main()
{
   streaming chan c_in, c_out;
   par
   {
      on stdcore[1] :
      {
         char name[3][4] = { "1/2", "3/4", "5/6" };
         print_info();
         init_pll(r_i2c);
         reset_codec(rst);
         init_codec(r_i2c);
         printstr("looping back line input ");
         printstr(name[INPUT]);
         printstrln(" to line outputs 1/2 3/4 5/6 7/8");
         par {
            fsgen(1000, fs);
            {
               mswait(3000);
               i2s_slave(r_i2s_slave, c_in, c_out);
            }
            par (int i = 0; i < 6; i++) {
               traffic();
            }
         }
      }
      on stdcore[0] : loopback(c_in, c_out);
      //on stdcore[0] : input_test(c_in, c_out);
   }
   return 0;
}