This module is an I2S master 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 master it drives the bit clock (BCK) and word clock (WCK) on output ports. It is clocked by an external master clock (MCK) on an input port.
Number of input ports, each carries two channels of audio.
Number of output ports, each carries two channels of audio.
BCK is soft divided off MCK.
MCK frequency is MCK_BCK_RATIO times BCK frequency.
Resources for I2S_MASTER.
Structure Members:
Clock block for MCK.
Clock block for BCK.
Clock port for MCK.
Clock port for BCK.
Clock port for WCK.
Array of I2S_MASTER_NUM_IN x 1-bit ports for audio input.
Array of I2S_MASTER_NUM_OUT x 1-bit ports for audio output.
I2S Master function.
Samples are left-aligned signed values. e.g. 24-bit audio will look like 0x12345600 (positive) or 0xFF123400 (negative)
Parameters: |
|
---|
This example is designed to run on the XR-USB-AUDIO-2.0-MC board. It takes 3 stereo I2S inputs and sends them out over 4 stereo I2S outputs. I2S_MASTER_NUM_IN and I2S_MASTER_NUM_OUT are defined in the Makefile.
First of all i2s_master should be included and the structure i2s_master defined.
#include "i2s_master.h"
on stdcore[1] : struct i2s_master r_i2s =
{
XS1_CLKBLK_1,
XS1_CLKBLK_2,
XS1_PORT_1L, // MCK
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_master 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_master thread over a streaming channel and sends them over a streaming channel back to the i2s_master 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" };
#ifndef SIM
init_pll(r_i2c);
reset_codec(rst);
init_codec(r_i2c);
#endif
printstr("looping back line input ");
printstr(name[INPUT]);
printstrln(" to line outputs 1/2 3/4 5/6 7/8");
par {
fsgen_busy(1000, fs);
{
mswait(300);
i2s_master(r_i2s, 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);
#ifdef SIM
on stdcore[0] : {
// generate 25MHz MCK
set_clock_div(b_mck_sim, 2);
set_port_clock(p_mck_sim, b_mck_sim);
set_port_mode_clock(p_mck_sim);
start_clock(b_mck_sim);
}
#endif
}
return 0;
}