Moved legacy tests into tests

This commit is contained in:
xross
2022-07-05 12:05:31 +01:00
parent 5441081927
commit 438c24d436
18 changed files with 0 additions and 0 deletions

View File

@@ -0,0 +1,97 @@
TARGET = xk-audio-216-mc.xn
USED_MODULES = lib_xua lib_i2c lib_logging
BUILD_FLAGS = -O0 -g -lflash -DXUD_SERIES_SUPPORT=4 -DXUD_CORE_CLOCK=600 -fxscope -save-temps -march=xs2a -DUSB_TILE=tile[1]
BUILD_FLAGS_i2s_master_2in_2out_48khz = $(BUILD_FLAGS) \
-D ADAT_RX=0 -D ADAT_TX=0 -D SPDIF_RX=0 -D SPDIF_TX=0 -D MIDI=0 \
-D NUM_USB_CHAN_IN=2 -D NUM_USB_CHAN_OUT=2 -DI2S_CHANS_ADC=2 -DI2S_CHANS_DAC=2 \
-D DEFAULT_FREQ=48000
BUILD_FLAGS_i2s_slave_2in_2out_48khz = $(BUILD_FLAGS) \
-D ADAT_RX=0 -D ADAT_TX=0 -D SPDIF_RX=0 -D SPDIF_TX=0 -D MIDI=0 \
-D NUM_USB_CHAN_IN=2 -D NUM_USB_CHAN_OUT=2 -DI2S_CHANS_ADC=2 -DI2S_CHANS_DAC=2 \
-D DEFAULT_FREQ=48000 -DCODEC_MASTER=1
BUILD_FLAGS_i2s_master_2in_2out_192khz = $(BUILD_FLAGS) \
-D ADAT_RX=0 -D ADAT_TX=0 -D SPDIF_RX=0 -D SPDIF_TX=0 -D MIDI=0 \
-D NUM_USB_CHAN_IN=2 -D NUM_USB_CHAN_OUT=2 -D I2S_CHANS_ADC=2 -D I2S_CHANS_DAC=2 \
-D DEFAULT_FREQ=192000
BUILD_FLAGS_i2s_slave_2in_2out_192khz = $(BUILD_FLAGS) \
-D ADAT_RX=0 -D ADAT_TX=0 -D SPDIF_RX=0 -D SPDIF_TX=0 -D MIDI=0 \
-D NUM_USB_CHAN_IN=2 -D NUM_USB_CHAN_OUT=2 -DI2S_CHANS_ADC=2 -DI2S_CHANS_DAC=2 \
-D DEFAULT_FREQ=192000 -DCODEC_MASTER=1
BUILD_FLAGS_i2s_master_8in_8out_48khz = $(BUILD_FLAGS) \
-D ADAT_RX=0 -D ADAT_TX=0 -D SPDIF_RX=0 -D SPDIF_TX=0 -D MIDI=0 \
-D NUM_USB_CHAN_IN=8 -D NUM_USB_CHAN_OUT=8 -D I2S_CHANS_ADC=8 -D I2S_CHANS_DAC=8 \
-D DEFAULT_FREQ=48000
BUILD_FLAGS_i2s_slave_8in_8out_48khz = $(BUILD_FLAGS) \
-D ADAT_RX=0 -D ADAT_TX=0 -D SPDIF_RX=0 -D SPDIF_TX=0 -D MIDI=0 \
-D NUM_USB_CHAN_IN=8 -D NUM_USB_CHAN_OUT=8 -D I2S_CHANS_ADC=8 -D I2S_CHANS_DAC=8 \
-D DEFAULT_FREQ=48000 -DCODEC_MASTER=1
BUILD_FLAGS_i2s_master_8in_8out_192khz = $(BUILD_FLAGS) \
-D ADAT_RX=0 -D ADAT_TX=0 -D SPDIF_RX=0 -D SPDIF_TX=0 -D MIDI=0 \
-D NUM_USB_CHAN_IN=8 -D NUM_USB_CHAN_OUT=8 -D I2S_CHANS_ADC=8 -D I2S_CHANS_DAC=8 \
-D DEFAULT_FREQ=192000 \
-O2 # optimisations to meet timing
BUILD_FLAGS_i2s_slave_8in_8out_192khz = $(BUILD_FLAGS) \
-D ADAT_RX=0 -D ADAT_TX=0 -D SPDIF_RX=0 -D SPDIF_TX=0 -D MIDI=0 \
-D NUM_USB_CHAN_IN=8 -D NUM_USB_CHAN_OUT=8 -D I2S_CHANS_ADC=8 -D I2S_CHANS_DAC=8 \
-D DEFAULT_FREQ=192000 -DCODEC_MASTER=1 \
-O2 # optimisations to meet timing
BUILD_FLAGS_tdm_master_8in_8out_48khz = $(BUILD_FLAGS) -D I2S_MODE_TDM=1 \
-D ADAT_RX=0 -D ADAT_TX=0 -D SPDIF_RX=0 -D SPDIF_TX=0 -D MIDI=0 \
-D NUM_USB_CHAN_IN=8 -D NUM_USB_CHAN_OUT=8 -D I2S_CHANS_ADC=8 -D I2S_CHANS_DAC=8 \
-D DEFAULT_FREQ=48000 \
-O2 # optimisations to meet timing
BUILD_FLAGS_tdm_slave_8in_8out_48khz = $(BUILD_FLAGS) -D I2S_MODE_TDM=1 \
-D ADAT_RX=0 -D ADAT_TX=0 -D SPDIF_RX=0 -D SPDIF_TX=0 -D MIDI=0 \
-D NUM_USB_CHAN_IN=8 -D NUM_USB_CHAN_OUT=8 -D I2S_CHANS_ADC=8 -D I2S_CHANS_DAC=8 \
-D DEFAULT_FREQ=48000 -DCODEC_MASTER=1 \
-O2 # optimisations to meet timing
BUILD_FLAGS_tdm_master_16in_16out_48khz = $(BUILD_FLAGS) -D I2S_MODE_TDM=1 \
-D ADAT_RX=0 -D ADAT_TX=0 -D SPDIF_RX=0 -D SPDIF_TX=0 -D MIDI=0 \
-D NUM_USB_CHAN_IN=16 -D NUM_USB_CHAN_OUT=16 -D I2S_CHANS_ADC=16 -D I2S_CHANS_DAC=16 \
-D DEFAULT_FREQ=48000 \
-O2 # optimisations to meet timing
BUILD_FLAGS_tdm_slave_16in_16out_48khz = $(BUILD_FLAGS) -D I2S_MODE_TDM=1 \
-D ADAT_RX=0 -D ADAT_TX=0 -D SPDIF_RX=0 -D SPDIF_TX=0 -D MIDI=0 \
-D NUM_USB_CHAN_IN=16 -D NUM_USB_CHAN_OUT=16 -D I2S_CHANS_ADC=16 -D I2S_CHANS_DAC=16 \
-D DEFAULT_FREQ=48000 -DCODEC_MASTER=1 \
-O2 # optimisations to meet timing
#XCC_FLAGS_hardware_i2s_master_2in_2out_48khz = -D HARDWARE $(BUILD_FLAGS_i2s_master_2in_2out_48khz)
#XCC_FLAGS_hardware_i2s_master_2in_2out_192khz = -D HARDWARE $(BUILD_FLAGS_i2s_master_2in_2out_192khz)
#XCC_FLAGS_hardware_i2s_master_8in_8out_48khz = -D HARDWARE $(BUILD_FLAGS_i2s_master_8in_8out_48khz)
#XCC_FLAGS_hardware_i2s_master_8in_8out_192khz = -D HARDWARE $(BUILD_FLAGS_i2s_master_8in_8out_192khz)
#XCC_FLAGS_hardware_tdm_master_8in_8out_48khz = -D HARDWARE $(BUILD_FLAGS_tdm_master_8in_8out_48khz)
XCC_FLAGS_simulation_i2s_master_2in_2out_48khz = -D SIMULATION $(BUILD_FLAGS_i2s_master_2in_2out_48khz)
XCC_FLAGS_simulation_i2s_slave_2in_2out_48khz = -D SIMULATION $(BUILD_FLAGS_i2s_slave_2in_2out_48khz)
XCC_FLAGS_simulation_i2s_master_2in_2out_192khz = -D SIMULATION $(BUILD_FLAGS_i2s_master_2in_2out_192khz)
XCC_FLAGS_simulation_i2s_slave_2in_2out_192khz = -D SIMULATION $(BUILD_FLAGS_i2s_slave_2in_2out_192khz)
XCC_FLAGS_simulation_i2s_master_8in_8out_48khz = -D SIMULATION $(BUILD_FLAGS_i2s_master_8in_8out_48khz)
XCC_FLAGS_simulation_i2s_slave_8in_8out_48khz = -D SIMULATION $(BUILD_FLAGS_i2s_slave_8in_8out_48khz)
XCC_FLAGS_simulation_i2s_master_8in_8out_192khz = -D SIMULATION $(BUILD_FLAGS_i2s_master_8in_8out_192khz)
XCC_FLAGS_simulation_i2s_slave_8in_8out_192khz = -D SIMULATION $(BUILD_FLAGS_i2s_slave_8in_8out_192khz)
XCC_FLAGS_simulation_tdm_master_8in_8out_48khz = -D SIMULATION $(BUILD_FLAGS_tdm_master_8in_8out_48khz)
XCC_FLAGS_simulation_tdm_slave_8in_8out_48khz = -D SIMULATION $(BUILD_FLAGS_tdm_slave_8in_8out_48khz)
XCC_FLAGS_simulation_tdm_master_16in_16out_48khz = -D SIMULATION $(BUILD_FLAGS_tdm_master_16in_16out_48khz)
XCC_FLAGS_simulation_tdm_slave_16in_16out_48khz = -D SIMULATION $(BUILD_FLAGS_tdm_slave_16in_16out_48khz)
XMOS_MAKE_PATH ?= ../..
-include $(XMOS_MAKE_PATH)/xcommon/module_xcommon/build/Makefile.common

View File

@@ -0,0 +1,9 @@
// Copyright 2016-2021 XMOS LIMITED.
// This Software is subject to the terms of the XMOS Public Licence: Version 1.
#ifndef __debug_conf_h__
#define __debug_conf_h__
#define DEBUG_PRINT_ENABLE_MAIN 1
#define DEBUG_PRINT_ENABLE_AUDIO_IO 0
#endif // __debug_conf_h__

View File

@@ -0,0 +1,167 @@
// Copyright 2021-2022 XMOS LIMITED.
// This Software is subject to the terms of the XMOS Public Licence: Version 1.
#ifndef __hid_report_descriptor_h__
#define __hid_report_descriptor_h__
#include "xua_hid_report.h"
#if 0
/* Existing static report descriptor kept for reference */
unsigned char hidReportDescriptor[] =
{
0x05, 0x0c, /* Usage Page (Consumer Device) */
0x09, 0x01, /* Usage (Consumer Control) */
0xa1, 0x01, /* Collection (Application) */
0x15, 0x00, /* Logical Minimum (0) */
0x25, 0x01, /* Logical Maximum (1) */
0x09, 0xb0, /* Usage (Play) */
0x09, 0xb5, /* Usage (Scan Next Track) */
0x09, 0xb6, /* Usage (Scan Previous Track) */
0x09, 0xe9, /* Usage (Volume Up) */
0x09, 0xea, /* Usage (Volume Down) */
0x09, 0xe2, /* Usage (Mute) */
0x75, 0x01, /* Report Size (1) */
0x95, 0x06, /* Report Count (6) */
0x81, 0x02, /* Input (Data, Var, Abs) */
0x95, 0x02, /* Report Count (2) */
0x81, 0x01, /* Input (Cnst, Ary, Abs) */
0xc0 /* End collection */
};
#endif
/*
* Define non-configurable items in the HID Report descriptor.
*/
static const USB_HID_Short_Item_t hidCollectionApplication = {
.header = HID_REPORT_SET_HEADER(1, HID_REPORT_ITEM_TYPE_MAIN, HID_REPORT_ITEM_TAG_COLLECTION),
.data = { 0x01, 0x00 } };
static const USB_HID_Short_Item_t hidCollectionEnd = {
.header = HID_REPORT_SET_HEADER(0, HID_REPORT_ITEM_TYPE_MAIN, HID_REPORT_ITEM_TAG_END_COLLECTION),
.data = { 0x00, 0x00 } };
static const USB_HID_Short_Item_t hidInputConstArray = {
.header = HID_REPORT_SET_HEADER(1, HID_REPORT_ITEM_TYPE_MAIN, HID_REPORT_ITEM_TAG_INPUT),
.data = { 0x01, 0x00 } };
static const USB_HID_Short_Item_t hidInputDataVar = {
.header = HID_REPORT_SET_HEADER(1, HID_REPORT_ITEM_TYPE_MAIN, HID_REPORT_ITEM_TAG_INPUT),
.data = { 0x02, 0x00 } };
static const USB_HID_Short_Item_t hidLogicalMaximum0 = {
.header = HID_REPORT_SET_HEADER(1, HID_REPORT_ITEM_TYPE_GLOBAL, HID_REPORT_ITEM_TAG_LOGICAL_MAXIMUM),
.data = { 0x00, 0x00 } };
static const USB_HID_Short_Item_t hidLogicalMaximum1 = {
.header = HID_REPORT_SET_HEADER(1, HID_REPORT_ITEM_TYPE_GLOBAL, HID_REPORT_ITEM_TAG_LOGICAL_MAXIMUM),
.data = { 0x01, 0x00 } };
static const USB_HID_Short_Item_t hidLogicalMinimum0 = {
.header = HID_REPORT_SET_HEADER(1, HID_REPORT_ITEM_TYPE_GLOBAL, HID_REPORT_ITEM_TAG_LOGICAL_MINIMUM),
.data = { 0x00, 0x00 } };
static const USB_HID_Short_Item_t hidReportCount2 = {
.header = HID_REPORT_SET_HEADER(1, HID_REPORT_ITEM_TYPE_GLOBAL, HID_REPORT_ITEM_TAG_REPORT_COUNT),
.data = { 0x02, 0x00 } };
static const USB_HID_Short_Item_t hidReportCount6 = {
.header = HID_REPORT_SET_HEADER(1, HID_REPORT_ITEM_TYPE_GLOBAL, HID_REPORT_ITEM_TAG_REPORT_COUNT),
.data = { 0x06, 0x00 } };
static const USB_HID_Short_Item_t hidReportSize1 = {
.header = HID_REPORT_SET_HEADER(1, HID_REPORT_ITEM_TYPE_GLOBAL, HID_REPORT_ITEM_TAG_REPORT_SIZE),
.data = { 0x01, 0x00 } };
static const USB_HID_Short_Item_t hidUsageConsumerControl = {
.header = HID_REPORT_SET_HEADER(1, HID_REPORT_ITEM_TYPE_LOCAL, HID_REPORT_ITEM_TAG_USAGE),
.data = { 0x01, 0x00 } };
/*
* Define the HID Report Descriptor Item, Usage Page, Report ID and length for each HID Report
* For internal purposes, a report element with ID of 0 must be included if report IDs are not being used.
*/
static const USB_HID_Report_Element_t hidReportPageConsumer = {
.item.header = HID_REPORT_SET_HEADER(1, HID_REPORT_ITEM_TYPE_GLOBAL, HID_REPORT_ITEM_TAG_USAGE_PAGE),
.item.data = { USB_HID_USAGE_PAGE_ID_CONSUMER, 0x00 },
.location = HID_REPORT_SET_LOC( 0, 1, 0, 0 ) };
/*
* Define configurable items in the HID Report descriptor.
*/
static USB_HID_Report_Element_t hidUsageByte0Bit5 = {
.item.header = HID_REPORT_SET_HEADER(1, HID_REPORT_ITEM_TYPE_LOCAL, HID_REPORT_ITEM_TAG_USAGE),
.item.data = { 0xE2, 0x00 },
.location = HID_REPORT_SET_LOC( 0, 0, 0, 5 )
}; // Mute
static USB_HID_Report_Element_t hidUsageByte0Bit4 = {
.item.header = HID_REPORT_SET_HEADER(1, HID_REPORT_ITEM_TYPE_LOCAL, HID_REPORT_ITEM_TAG_USAGE),
.item.data = { 0xEA, 0x00 },
.location = HID_REPORT_SET_LOC( 0, 0, 0, 4 )
}; // Vol-
static USB_HID_Report_Element_t hidUsageByte0Bit3 = {
.item.header = HID_REPORT_SET_HEADER(1, HID_REPORT_ITEM_TYPE_LOCAL, HID_REPORT_ITEM_TAG_USAGE),
.item.data = { 0xE9, 0x00 },
.location = HID_REPORT_SET_LOC( 0, 0, 0, 3 )
}; // Vol+
static USB_HID_Report_Element_t hidUsageByte0Bit2 = {
.item.header = HID_REPORT_SET_HEADER(1, HID_REPORT_ITEM_TYPE_LOCAL, HID_REPORT_ITEM_TAG_USAGE),
.item.data = { 0xB6, 0x00 },
.location = HID_REPORT_SET_LOC( 0, 0, 0, 2 )
}; // Scan Prev
static USB_HID_Report_Element_t hidUsageByte0Bit1 = {
.item.header = HID_REPORT_SET_HEADER(1, HID_REPORT_ITEM_TYPE_LOCAL, HID_REPORT_ITEM_TAG_USAGE),
.item.data = { 0xB5, 0x00 },
.location = HID_REPORT_SET_LOC( 0, 0, 0, 1 )
}; // Scan Next
static USB_HID_Report_Element_t hidUsageByte0Bit0 = {
.item.header = HID_REPORT_SET_HEADER(1, HID_REPORT_ITEM_TYPE_LOCAL, HID_REPORT_ITEM_TAG_USAGE),
.item.data = { 0xB0, 0x00 },
.location = HID_REPORT_SET_LOC( 0, 0, 0, 0 )
}; // Play
/*
* List the configurable items in the HID Report descriptor.
*/
static USB_HID_Report_Element_t* const hidConfigurableElements[] = {
&hidUsageByte0Bit0,
&hidUsageByte0Bit1,
&hidUsageByte0Bit2,
&hidUsageByte0Bit3,
&hidUsageByte0Bit4,
&hidUsageByte0Bit5
};
/*
* List HID Reports, one per Report ID. This should be a usage page item with the relevant
* If not using report IDs - still have one with report ID 0
*/
static const USB_HID_Report_Element_t* const hidReports[] = {
&hidReportPageConsumer
};
/*
* List all items in the HID Report descriptor.
*/
static const USB_HID_Short_Item_t * const hidReportDescriptorItems[] = {
&(hidReportPageConsumer.item),
&hidUsageConsumerControl,
&hidCollectionApplication,
&hidLogicalMinimum0,
&hidLogicalMaximum1,
&(hidUsageByte0Bit0.item),
&(hidUsageByte0Bit1.item),
&(hidUsageByte0Bit2.item),
&(hidUsageByte0Bit3.item),
&(hidUsageByte0Bit4.item),
&(hidUsageByte0Bit5.item),
&hidReportSize1,
&hidReportCount6,
&hidInputDataVar,
&hidLogicalMaximum0,
&hidReportCount2,
&hidInputConstArray,
&hidCollectionEnd
};
/*
* Define the number of HID Reports
* Due to XC not supporting designated initializers, this constant has a hard-coded value.
* It must equal ( sizeof hidReports / sizeof ( USB_HID_Report_Element_t* ))
*/
#define HID_REPORT_COUNT ( 1 )
#endif // __hid_report_descriptor_h__

View File

@@ -0,0 +1,238 @@
// Copyright 2016-2022 XMOS LIMITED.
// This Software is subject to the terms of the XMOS Public Licence: Version 1.
#include <platform.h>
#include <stdlib.h>
#include <print.h>
#include <timer.h>
#include "xua.h"
#define DEBUG_UNIT MAIN
#include "debug_print.h"
/* Port declarations. Note, the defines come from the xn file */
#if I2S_WIRES_DAC > 0
on tile[AUDIO_IO_TILE] : buffered out port:32 p_i2s_dac[I2S_WIRES_DAC] =
{PORT_I2S_DAC0,
#endif
#if I2S_WIRES_DAC > 1
PORT_I2S_DAC1,
#endif
#if I2S_WIRES_DAC > 2
PORT_I2S_DAC2,
#endif
#if I2S_WIRES_DAC > 3
PORT_I2S_DAC3,
#endif
#if I2S_WIRES_DAC > 4
PORT_I2S_DAC4,
#endif
#if I2S_WIRES_DAC > 5
PORT_I2S_DAC5,
#endif
#if I2S_WIRES_DAC > 6
PORT_I2S_DAC6,
#endif
#if I2S_WIRES_DAC > 7
#error I2S_WIRES_DAC value is too large!
#endif
#if I2S_WIRES_DAC > 0
};
#endif
#if I2S_WIRES_ADC > 0
on tile[AUDIO_IO_TILE] : buffered in port:32 p_i2s_adc[I2S_WIRES_ADC] =
{PORT_I2S_ADC0,
#endif
#if I2S_WIRES_ADC > 1
PORT_I2S_ADC1,
#endif
#if I2S_WIRES_ADC > 2
PORT_I2S_ADC2,
#endif
#if I2S_WIRES_ADC > 3
PORT_I2S_ADC3,
#endif
#if I2S_WIRES_ADC > 4
PORT_I2S_ADC4,
#endif
#if I2S_WIRES_ADC > 5
PORT_I2S_ADC5,
#endif
#if I2S_WIRES_ADC > 6
PORT_I2S_ADC6,
#endif
#if I2S_WIRES_ADC > 7
#error I2S_WIRES_ADC value is too large!
#endif
#if I2S_WIRES_ADC > 0
};
#endif
#if CODEC_MASTER
buffered in port:32 p_lrclk = PORT_I2S_LRCLK;
buffered in port:32 p_bclk = PORT_I2S_BCLK;
#else
buffered out port:32 p_lrclk = PORT_I2S_LRCLK; /* I2S Bit-clock */
buffered out port:32 p_bclk = PORT_I2S_BCLK; /* I2S L/R-clock */
#endif
in port p_mclk_in = PORT_MCLK_IN;
/* Clock-block declarations */
clock clk_audio_bclk = on tile[AUDIO_IO_TILE]: XS1_CLKBLK_1; /* Bit clock */
clock clk_audio_mclk = on tile[AUDIO_IO_TILE]: XS1_CLKBLK_2; /* Master clock */
#ifdef SIMULATION
#define INITIAL_SKIP_FRAMES 10
#define TOTAL_TEST_FRAMES 100
#else
#define INITIAL_SKIP_FRAMES 1000
#define TOTAL_TEST_FRAMES (5 * DEFAULT_FREQ)
#endif
#define SAMPLE(frame_count, channel_num) (((frame_count) << 8) | ((channel_num) & 0xFF))
#define SAMPLE_FRAME_NUM(test_word) ((test_word) >> 8)
#define SAMPLE_CHANNEL_NUM(test_word) ((test_word) & 0xFF)
void generator(chanend c_checker, chanend c_out)
{
unsigned frame_count;
int underflow_word;
int fail;
int i;
frame_count = 0;
while (1) {
underflow_word = inuint(c_out);
#pragma loop unroll
for (i = 0; i < NUM_USB_CHAN_OUT; i++) {
outuint(c_out, SAMPLE(frame_count, i));
}
fail = inuint(c_checker);
#pragma loop unroll
for (i = 0; i < NUM_USB_CHAN_IN; i++) {
outuint(c_checker, inuint(c_out));
}
if (frame_count == TOTAL_TEST_FRAMES) {
if (!fail) {
debug_printf("PASS\n");
}
outct(c_out, AUDIO_STOP_FOR_DFU);
//inuint(c_out); //This causes the DFUhandler to be called with exceptiopn in slave mode so skip this - we are out of here anyhow
exit(0);
}
frame_count++;
}
}
void checker(chanend c_checker, int disable)
{
unsigned x[NUM_USB_CHAN_IN];
int last_frame_number;
unsigned frame_count;
int fail;
int i;
if (disable)
debug_printf("checker disabled\n");
/*debug_printf("%s %d/%d %d\n",
I2S_MODE_TDM ? "TDM" : "I2S", NUM_USB_CHAN_IN, NUM_USB_CHAN_OUT, DEFAULT_FREQ);*/
fail = 0;
frame_count = 0;
last_frame_number = -1;
while (1) {
outuint(c_checker, fail);
#pragma loop unroll
for (i = 0; i < NUM_USB_CHAN_IN; i++) {
x[i] = inuint(c_checker);
}
if (frame_count > INITIAL_SKIP_FRAMES) {
// check that frame number is incrementing
if (!disable && SAMPLE_FRAME_NUM(x[0]) != last_frame_number + 1) {
debug_printf("%d: 0x%x (%d)\n", frame_count, x[0], last_frame_number);
fail = 1;
}
for (i = 0; i < NUM_USB_CHAN_IN; i++) {
// check channel numbers are 0 to N-1 in a frame
if (!disable && SAMPLE_CHANNEL_NUM(x[i]) != i) {
debug_printf("%d,%d: 0x%x\n", frame_count, i, x[i]);
fail = 1;
}
// check frame number doesn't change in a frame
if (!disable && SAMPLE_FRAME_NUM(x[i]) != SAMPLE_FRAME_NUM(x[0])) {
debug_printf("%d,%d: 0x%x (0x%x)\n", frame_count, i, x[i], x[0]);
fail = 1;
}
}
}
last_frame_number = SAMPLE_FRAME_NUM(x[0]);
frame_count++;
}
}
#ifdef SIMULATION
out port p_mclk_gen = on tile[AUDIO_IO_TILE] : XS1_PORT_1A;
clock clk_audio_mclk_gen = on tile[AUDIO_IO_TILE] : XS1_CLKBLK_3;
void master_mode_clk_setup(void);
#if CODEC_MASTER
out port p_bclk_gen = on tile[AUDIO_IO_TILE] : XS1_PORT_1B;
clock clk_audio_bclk_gen = on tile[AUDIO_IO_TILE] : XS1_CLKBLK_4;
out port p_lrclk_gen = on tile[AUDIO_IO_TILE] : XS1_PORT_1C;
clock clk_audio_lrclk_gen = on tile[AUDIO_IO_TILE] : XS1_CLKBLK_5;
void slave_mode_clk_setup(const unsigned samFreq, const unsigned chans_per_frame);
#endif
#endif
#if I2S_MODE_TDM
const int i2s_tdm_mode = 8;
#else
const int i2s_tdm_mode = 2;
#endif
int main(void)
{
chan c_checker;
chan c_out;
par
{
on tile[AUDIO_IO_TILE]:
{
par
{
XUA_AudioHub(c_out, clk_audio_mclk, clk_audio_bclk, p_mclk_in, p_lrclk, p_bclk, p_i2s_dac, p_i2s_adc);
generator(c_checker, c_out);
checker(c_checker, 0);
#ifdef SIMULATION
#if CODEC_MASTER
slave_mode_clk_setup(DEFAULT_FREQ, i2s_tdm_mode);
#else
master_mode_clk_setup();
#endif
#endif
}
}
}
return 0;
}

View File

@@ -0,0 +1,65 @@
// Copyright 2016-2022 XMOS LIMITED.
// This Software is subject to the terms of the XMOS Public Licence: Version 1.
#ifdef SIMULATION
#include <platform.h>
#include <print.h>
extern port p_mclk_in;
extern port p_mclk25mhz;
extern clock clk_mclk25mhz;
void AudioHwConfig(unsigned samFreq, unsigned mClk, unsigned dsdMode, unsigned sampRes_DAC, unsigned sampRes_ADC)
{
// nothing
}
void AudioHwInit()
{
// nothing
}
extern clock clk_audio_mclk_gen;
extern out port p_mclk_gen;
void master_mode_clk_setup(void)
{
configure_clock_rate(clk_audio_mclk_gen, 25, 1); // Slighly faster than typical MCLK of 24.576MHz
configure_port_clock_output(p_mclk_gen, clk_audio_mclk_gen);
start_clock(clk_audio_mclk_gen);
//printstrln("Starting mclk");
delay_seconds(-1); //prevent destructor ruining clock gen
}
#if CODEC_MASTER
extern out port p_bclk_gen;
extern clock clk_audio_bclk_gen;
extern out port p_lrclk_gen;
extern clock clk_audio_lrclk_gen;
void slave_mode_clk_setup(const unsigned samFreq, const unsigned chans_per_frame){
const unsigned data_bits = 32;
const unsigned mclk_freq = 24576000;
const unsigned mclk_bclk_ratio = mclk_freq / (chans_per_frame * samFreq * data_bits);
const unsigned bclk_lrclk_ratio = (chans_per_frame * data_bits); // 48.828Hz LRCLK
//bclk
configure_clock_src_divide(clk_audio_bclk_gen, p_mclk_gen, mclk_bclk_ratio/2);
configure_port_clock_output(p_bclk_gen, clk_audio_bclk_gen);
start_clock(clk_audio_bclk_gen);
//lrclk
configure_clock_src_divide(clk_audio_lrclk_gen, p_bclk_gen, bclk_lrclk_ratio/2);
configure_port_clock_output(p_lrclk_gen, clk_audio_lrclk_gen);
start_clock(clk_audio_lrclk_gen);
//mclk
master_mode_clk_setup();
}
#endif
#endif

View File

@@ -0,0 +1,25 @@
// Copyright 2016-2021 XMOS LIMITED.
// This Software is subject to the terms of the XMOS Public Licence: Version 1.
#ifndef __usb_device_h__
#define __usb_device_h__
#include <xs1.h>
#include <xccompat.h>
#include "usb_std_requests.h"
#include "xud.h"
XUD_Result_t USB_GetSetupPacket(XUD_ep ep_out, XUD_ep ep_in, REFERENCE_PARAM(USB_SetupPacket_t, sp));
XUD_Result_t USB_StandardRequests(XUD_ep ep_out, XUD_ep ep_in,
NULLABLE_ARRAY_OF(unsigned char, devDesc_hs), int devDescLength_hs,
NULLABLE_ARRAY_OF(unsigned char, cfgDesc_hs), int cfgDescLength_hs,
NULLABLE_ARRAY_OF(unsigned char, devDesc_fs), int devDescLength_fs,
NULLABLE_ARRAY_OF(unsigned char, cfgDesc_fs), int cfgDescLength_fs,
#ifdef __XC__
char * unsafe strDescs[],
#else
char * strDescs[],
#endif
int strDescsLength, REFERENCE_PARAM(USB_SetupPacket_t, sp), XUD_BusSpeed_t usbBusSpeed);
#endif // __usb_device_h__

View File

@@ -0,0 +1,33 @@
// Copyright 2018-2021 XMOS LIMITED.
// This Software is subject to the terms of the XMOS Public Licence: Version 1.
#if 0
#include <xs1.h>
#include <xccompat.h>
#include "usb_std_requests.h"
#include "xud.h"
#include "usb_device.h"
unsigned char g_currentConfig = 0;
unsigned char g_interfaceAlt[16];
XUD_Result_t USB_GetSetupPacket(XUD_ep ep_out, XUD_ep ep_in, REFERENCE_PARAM(USB_SetupPacket_t, sp))
{
return XUD_RES_OKAY;
}
XUD_Result_t USB_StandardRequests(XUD_ep ep_out, XUD_ep ep_in,
NULLABLE_ARRAY_OF(unsigned char, devDesc_hs), int devDescLength_hs,
NULLABLE_ARRAY_OF(unsigned char, cfgDesc_hs), int cfgDescLength_hs,
NULLABLE_ARRAY_OF(unsigned char, devDesc_fs), int devDescLength_fs,
NULLABLE_ARRAY_OF(unsigned char, cfgDesc_fs), int cfgDescLength_fs,
#ifdef __XC__
char * unsafe strDescs[],
#else
char * strDescs[],
#endif
int strDescsLength, REFERENCE_PARAM(USB_SetupPacket_t, sp), XUD_BusSpeed_t usbBusSpeed)
{
return XUD_RES_OKAY;
}
#endif

View File

@@ -0,0 +1,385 @@
// Copyright 2016-2022 XMOS LIMITED.
// This Software is subject to the terms of the XMOS Public Licence: Version 1.
#ifdef HARDWARE
#include <xs1.h>
#include <assert.h>
#include "devicedefines.h"
#include <platform.h>
#include "gpio_access.h"
#include "i2c.h"
#include "cs4384.h"
#include "cs5368.h"
#include "cs2100.h"
#include "print.h"
#include "dsd_support.h"
/* The number of timer ticks to wait for the audio PLL to lock */
/* CS2100 lists typical lock time as 100 * input period */
#define AUDIO_PLL_LOCK_DELAY (40000000)
#if defined(SPDIF_RX) || defined(ADAT_RX)
#define USE_FRACTIONAL_N 1
#endif
on tile[0] : out port p_gpio = XS1_PORT_8C;
port p_i2c = on tile[0]:PORT_I2C;
#define DAC_REGWRITE(reg, val) {result = i2c.write_reg(CS4384_I2C_ADDR, reg, val);}
#define ADC_REGWRITE(reg, val) {result = i2c.write_reg(CS5368_I2C_ADDR, reg, val);}
#ifdef USE_FRACTIONAL_N
#if !(defined(SPDIF_RX) || defined(ADAT_RX))
/* Choose a frequency the xcore can easily generate internally */
#define PLL_SYNC_FREQ 1000000
#else
#define PLL_SYNC_FREQ 300
#endif
#define CS2100_REGREAD(reg, data) {data[0] = i2c.read_reg(CS2100_I2C_DEVICE_ADDR, reg, result);}
#define CS2100_REGREAD_ASSERT(reg, data, expected) {data[0] = i2c.read_reg(CS2100_I2C_DEVICE_ADDR, reg, result); assert(data[0] == expected);}
#define CS2100_REGWRITE(reg, val) {result = i2c.write_reg(CS2100_I2C_DEVICE_ADDR, reg, val);}
/* Init of CS2100 */
void PllInit(client interface i2c_master_if i2c)
{
unsigned char data[1] = {0};
i2c_regop_res_t result;
#if XCORE_200_MC_AUDIO_HW_VERSION < 2
/* Enable init */
CS2100_REGWRITE(CS2100_DEVICE_CONFIG_1, 0x05);
#else
CS2100_REGWRITE(CS2100_DEVICE_CONFIG_1, 0x07);
#endif
CS2100_REGWRITE(CS2100_GLOBAL_CONFIG, 0x01);
CS2100_REGWRITE(CS2100_FUNC_CONFIG_1, 0x08);
CS2100_REGWRITE(CS2100_FUNC_CONFIG_2, 0x00); //0x10 for always gen clock even when unlocked
/* Read back and check */
#if XCORE_200_MC_AUDIO_HW_VERSION < 2
CS2100_REGREAD_ASSERT(CS2100_DEVICE_CONFIG_1, data, 0x05);
#else
CS2100_REGREAD_ASSERT(CS2100_DEVICE_CONFIG_1, data, 0x07);
#endif
CS2100_REGREAD_ASSERT(CS2100_GLOBAL_CONFIG, data, 0x01);
CS2100_REGREAD_ASSERT(CS2100_FUNC_CONFIG_1, data, 0x08);
CS2100_REGREAD_ASSERT(CS2100_FUNC_CONFIG_2, data, 0x00);
i2c.shutdown();
}
/* Setup PLL multiplier */
void PllMult(unsigned output, unsigned ref, client interface i2c_master_if i2c)
{
unsigned char data[1] = {0};
i2c_regop_res_t result;
/* PLL expects 12:20 format, convert output and ref to 12:20 */
/* Shift up the dividend by 12 to retain format... */
unsigned mult = (unsigned) ((((unsigned long long)output) << 32) / (((unsigned long long)ref) << 20));
CS2100_REGWRITE(CS2100_RATIO_1, (mult >> 24) & 0xFF);
CS2100_REGWRITE(CS2100_RATIO_2, (mult >> 16) & 0xFF);
CS2100_REGWRITE(CS2100_RATIO_3, (mult >> 8) & 0xFF);
CS2100_REGWRITE(CS2100_RATIO_4, (mult & 0xFF));
/* Read back and check */
CS2100_REGREAD_ASSERT(CS2100_RATIO_1, data, ((mult >> 24) & 0xFF));
CS2100_REGREAD_ASSERT(CS2100_RATIO_2, data, ((mult >> 16) & 0xFF));
CS2100_REGREAD_ASSERT(CS2100_RATIO_3, data, ((mult >> 8) & 0xFF));
CS2100_REGREAD_ASSERT(CS2100_RATIO_4, data, (mult & 0xFF));
}
#endif
#if !(defined(SPDIF_RX) || defined(ADAT_RX)) && defined(USE_FRACTIONAL_N)
on tile[AUDIO_IO_TILE] : out port p_pll_clk = PORT_PLL_REF;
on tile[AUDIO_IO_TILE] : clock clk_pll_sync = XS1_CLKBLK_5;
#endif
void wait_us(int microseconds)
{
timer t;
unsigned time;
t :> time;
t when timerafter(time + (microseconds * 100)) :> void;
}
void AudioHwInit(chanend ?c_codec)
{
#if !(defined(SPDIF_RX) || defined(ADAT_RX)) && defined(USE_FRACTIONAL_N)
/* Output a fixed sync clock to the pll */
configure_clock_rate(clk_pll_sync, 100, 100/(PLL_SYNC_FREQ/1000000));
configure_port_clock_output(p_pll_clk, clk_pll_sync);
start_clock(clk_pll_sync);
#endif
/* Assert reset to ADC and DAC */
set_gpio(P_GPIO_DAC_RST_N, 0);
set_gpio(P_GPIO_ADC_RST_N, 0);
/* 0b11 : USB B */
/* 0b01 : Lightning */
/* 0b10 : USB A */
#ifdef USB_SEL_A
set_gpio(P_GPIO_USB_SEL0, 0);
set_gpio(P_GPIO_USB_SEL1, 1);
#else
set_gpio(P_GPIO_USB_SEL0, 1);
set_gpio(P_GPIO_USB_SEL1, 1);
#endif
#ifdef USE_FRACTIONAL_N
/* If we have any digital input then use the external PLL - selected via MUX */
set_gpio(P_GPIO_PLL_SEL, 1);
/* Initialise external PLL */
i2c_master_if i2c[1];
par
{
i2c_master_single_port(i2c, 1, p_i2c, 10, 0, 1, 0);
PllInit(i2c[0]);
}
#endif
#ifdef IAP
/* Enable VBUS output */
set_gpio(P_GPIO_VBUS_EN, 1);
#endif
}
/* Configures the external audio hardware for the required sample frequency.
* See gpio.h for I2C helper functions and gpio access
*/
void AudioHwConfig2(unsigned samFreq, unsigned mClk, chanend ?c_codec, unsigned dsdMode,
unsigned sampRes_DAC, unsigned sampRes_ADC, client interface i2c_master_if i2c)
{
unsigned char data[1] = {0};
i2c_regop_res_t result;
/* Put ADC and DAC into reset */
set_gpio(P_GPIO_ADC_RST_N, 0);
set_gpio(P_GPIO_DAC_RST_N, 0);
/* Set master clock select appropriately */
#if defined(USE_FRACTIONAL_N)
/* Configure external fractional-n clock multiplier for 300Hz -> mClkFreq */
PllMult(mClk, PLL_SYNC_FREQ, i2c);
#endif
/* Allow some time for mclk to lock and MCLK to stabilise - this is important to avoid glitches at start of stream */
{
timer t;
unsigned time;
t :> time;
t when timerafter(time+AUDIO_PLL_LOCK_DELAY) :> void;
}
#if defined(USE_FRACTIONAL_N)
while(1)
{
/* Read Unlock Indicator in PLL as sanity check... */
CS2100_REGREAD(CS2100_DEVICE_CONTROL, data);
if(!(data[0] & 0x80))
{
break;
}
}
#else
if (mClk == MCLK_441)
{
set_gpio(P_GPIO_MCLK_FSEL, 0);
}
else
{
set_gpio(P_GPIO_MCLK_FSEL, 1); //mClk = MCLK_48
}
/* Allow MCLK to settle */
wait_us(20000);
#endif
#if 1
if((dsdMode == DSD_MODE_NATIVE) || (dsdMode == DSD_MODE_DOP))
{
/* Enable DSD 8ch out mode on mux */
//set_gpio(p_adrst_cksel_dsd, P_DSD_MODE, 1);
/* DAC out out reset, note ADC left in reset in for DSD mode */
set_gpio(P_GPIO_DAC_RST_N, 1);
/* Configure DAC values required for DSD mode */
/* Mode Control 1 (Address: 0x02) */
/* bit[7] : Control Port Enable (CPEN) : Set to 1 for enable
* bit[6] : Freeze controls (FREEZE) : Set to 1 for freeze
* bit[5] : PCM/DSD Selection (DSD/PCM) : Set to 1 for DSD
* bit[4:1] : DAC Pair Disable (DACx_DIS) : All Dac Pairs enabled
* bit[0] : Power Down (PDN) : Powered down
*/
DAC_REGWRITE(CS4384_MODE_CTRL, 0xe1);
if (samFreq > 3000000)
{
/* DSD128 */
/* DSD Control (Address: 0x04) */
/* bit[7:5] : DSD Digital Inteface Format (DSD_DIF) : 128x over samples with 4x MCLK
* bit[4] : Direct DSD Conversion: Set to 0, data sent to DSD processor
* bit[3] : Static DSD detect : 1 for enabled
* bit[2] : Invalid DSD Detect : 1 for enabled
* bit[1] : DSD Phase Modulation Mode Select
* bit[0] : DSD Phase Modulation Enable
*/
DAC_REGWRITE(CS4384_DSD_CTRL, 0b11001100);
}
else
{
/* DSD64 */
/* DSD Control (Address: 0x04) */
/* bit[7:5] : DSD Digital Inteface Format (DSD_DIF) : 64x over samples with 8x MCLK
* bit[4] : Direct DSD Conversion: Set to 0, data sent to DSD processor
* bit[3] : Static DSD detect : 1 for enabled
* bit[2] : Invalid DSD Detect : 1 for enabled
* bit[1] : DSD Phase Modulation Mode Select
* bit[0] : DSD Phase Modulation Enable
*/
DAC_REGWRITE(CS4384_DSD_CTRL, 0b01001100);
}
/* Mode Control 1 (Address: 0x02) */
/* bit[7] : Control Port Enable (CPEN) : Set to 1 for enable
* bit[6] : Freeze controls (FREEZE) : Set to 0 for not freeze
* bit[5] : PCM/DSD Selection (DSD/PCM) : Set to 1 for DSD
* bit[4:1] : DAC Pair Disable (DACx_DIS) : All Dac Pairs enabled
* bit[0] : Power Down (PDN) : Power down disabled
*/
DAC_REGWRITE(CS4384_MODE_CTRL, 0xA0);
/* Note: ADC kept in reset, no config sent. DSD mode is output only 0*/
}
else
{
/* dsdMode == 0 */
/* Set MUX to PCM mode (muxes ADC I2S data lines) */
set_gpio(P_GPIO_DSD_MODE, 0);
/* Take ADC out of reset */
set_gpio(P_GPIO_ADC_RST_N, 1);
{
unsigned dif = 0, mode = 0;
#ifdef I2S_MODE_TDM
dif = 0x02; /* TDM */
#else
dif = 0x01; /* I2S */
#endif
#ifdef CODEC_MASTER
/* Note, only the ADC device supports being I2S master.
* Set ADC as master and run DAC as slave */
if(samFreq < 54000)
mode = 0x00; /* Single-speed Mode Master */
else if(samFreq < 108000)
mode = 0x01; /* Double-speed Mode Master */
else if(samFreq < 216000)
mode = 0x02; /* Quad-speed Mode Master */
#else
mode = 0x03; /* Slave mode all speeds */
#endif
/* Reg 0x01: (GCTL) Global Mode Control Register */
/* Bit[7]: CP-EN: Manages control-port mode
* Bit[6]: CLKMODE: Setting puts part in 384x mode
* Bit[5:4]: MDIV[1:0]: Set to 01 for /2
* Bit[3:2]: DIF[1:0]: Data Format: 0x01 for I2S, 0x02 for TDM
* Bit[1:0]: MODE[1:0]: Mode: 0x11 for slave mode
*/
ADC_REGWRITE(CS5368_GCTL_MDE, 0b10010000 | (dif << 2) | mode);
}
/* Reg 0x06: (PDN) Power Down Register */
/* Bit[7:6]: Reserved
* Bit[5]: PDN-BG: When set, this bit powers-own the bandgap reference
* Bit[4]: PDM-OSC: Controls power to internal oscillator core
* Bit[3:0]: PDN: When any bit is set all clocks going to that channel pair are turned off
*/
ADC_REGWRITE(CS5368_PWR_DN, 0b00000000);
#ifdef CODEC_MASTER
/* Allow some time for clocks from ADC to become stable */
wait_us(500);
#endif
/* Configure DAC with PCM values. Note 2 writes to mode control to enable/disable freeze/power down */
set_gpio(P_GPIO_DAC_RST_N, 1);//De-assert DAC reset
wait_us(500);
/* Mode Control 1 (Address: 0x02) */
/* bit[7] : Control Port Enable (CPEN) : Set to 1 for enable
* bit[6] : Freeze controls (FREEZE) : Set to 1 for freeze
* bit[5] : PCM/DSD Selection (DSD/PCM) : Set to 0 for PCM
* bit[4:1] : DAC Pair Disable (DACx_DIS) : All Dac Pairs enabled
* bit[0] : Power Down (PDN) : Powered down
*/
DAC_REGWRITE(CS4384_MODE_CTRL, 0b11000001);
#ifdef I2S_MODE_TDM
/* PCM Control (Address: 0x03) */
/* bit[7:4] : Digital Interface Format (DIF) : 0b1100 for TDM
* bit[3:2] : Reserved
* bit[1:0] : Functional Mode (FM) : 0x11 for auto-speed detect (32 to 200kHz)
*/
DAC_REGWRITE(CS4384_PCM_CTRL, 0b11000011);
#else
/* PCM Control (Address: 0x03) */
/* bit[7:4] : Digital Interface Format (DIF) : 0b0001 for I2S up to 24bit
* bit[3:2] : Reserved
* bit[1:0] : Functional Mode (FM) : 0x00 - single-speed mode (4-50kHz)
* : 0x01 - double-speed mode (50-100kHz)
* : 0x10 - quad-speed mode (100-200kHz)
* : 0x11 - auto-speed detect (32 to 200kHz)
* (note, some Mclk/SR ratios not supported in auto)
*
*/
unsigned char regVal = 0;
if(samFreq < 50000)
regVal = 0b00010100;
else if(samFreq < 100000)
regVal = 0b00010101;
else //if(samFreq < 200000)
regVal = 0b00010110;
DAC_REGWRITE(CS4384_PCM_CTRL, regVal);
#endif
/* Mode Control 1 (Address: 0x02) */
/* bit[7] : Control Port Enable (CPEN) : Set to 1 for enable
* bit[6] : Freeze controls (FREEZE) : Set to 0 for freeze
* bit[5] : PCM/DSD Selection (DSD/PCM) : Set to 0 for PCM
* bit[4:1] : DAC Pair Disable (DACx_DIS) : All Dac Pairs enabled
* bit[0] : Power Down (PDN) : Not powered down
*/
DAC_REGWRITE(CS4384_MODE_CTRL, 0b10000000);
}
#endif
i2c.shutdown();
return;
}
void AudioHwConfig(unsigned samFreq, unsigned mClk, chanend ?c_codec, unsigned dsdMode,
unsigned sampRes_DAC, unsigned sampRes_ADC)
{
i2c_master_if i2c[1];
par
{
i2c_master_single_port(i2c, 1, p_i2c, 10, 0, 1, 0);
AudioHwConfig2(samFreq, mClk, c_codec, dsdMode, sampRes_DAC, sampRes_ADC, i2c[0]);
}
}
#endif

View File

@@ -0,0 +1,13 @@
// Copyright 2018-2021 XMOS LIMITED.
// This Software is subject to the terms of the XMOS Public Licence: Version 1.
#define CS2100_I2C_DEVICE_ADDR (0x9c>>1)
#define CS2100_DEVICE_CONTROL 0x02
#define CS2100_DEVICE_CONFIG_1 0x03
#define CS2100_GLOBAL_CONFIG 0x05
#define CS2100_RATIO_1 0x06
#define CS2100_RATIO_2 0x07
#define CS2100_RATIO_3 0x08
#define CS2100_RATIO_4 0x09
#define CS2100_FUNC_CONFIG_1 0x16
#define CS2100_FUNC_CONFIG_2 0x17

View File

@@ -0,0 +1,33 @@
// Copyright 2017-2021 XMOS LIMITED.
// This Software is subject to the terms of the XMOS Public Licence: Version 1.
#ifndef CS4384_H_
#define CS4384_H_
//Address on I2C bus
#define CS4384_I2C_ADDR (0x18)
//Register Addresess
#define CS4384_CHIP_REV 0x01
#define CS4384_MODE_CTRL 0x02
#define CS4384_PCM_CTRL 0x03
#define CS4384_DSD_CTRL 0x04
#define CS4384_FLT_CTRL 0x05
#define CS4384_INV_CTRL 0x06
#define CS4384_GRP_CTRL 0x07
#define CS4384_RMP_MUTE 0x08
#define CS4384_MUTE_CTRL 0x09
#define CS4384_MIX_PR1 0x0a
#define CS4384_VOL_A1 0x0b
#define CS4384_VOL_B1 0x0c
#define CS4384_MIX_PR2 0x0d
#define CS4384_VOL_A2 0x0e
#define CS4384_VOL_B2 0x0f
#define CS4384_MIX_PR3 0x10
#define CS4384_VOL_A3 0x11
#define CS4384_VOL_B3 0x12
#define CS4384_MIX_PR4 0x13
#define CS4384_VOL_A4 0x14
#define CS4384_VOL_B4 0x15
#define CS4384_CM_MODE 0x16
#endif /* CS4384_H_ */

View File

@@ -0,0 +1,19 @@
// Copyright 2017-2021 XMOS LIMITED.
// This Software is subject to the terms of the XMOS Public Licence: Version 1.
#ifndef _CS5368_H_
#define _CS5368_H_
//Address on I2C bus
#define CS5368_I2C_ADDR (0x4C)
//Register Addresess
#define CS5368_CHIP_REV 0x00
#define CS5368_GCTL_MDE 0x01
#define CS5368_OVFL_ST 0x02
#define CS5368_OVFL_MSK 0x03
#define CS5368_HPF_CTRL 0x04
#define CS5368_PWR_DN 0x06
#define CS5368_MUTE_CTRL 0x08
#define CS5368_SDO_EN 0x0a
#endif /* _CS5368_H_ */

View File

@@ -0,0 +1,42 @@
// Copyright 2016-2021 XMOS LIMITED.
// This Software is subject to the terms of the XMOS Public Licence: Version 1.
#ifdef HARDWARE
#include <xs1.h>
#include "gpio_access.h"
void p_gpio_lock()
{
}
void p_gpio_unlock()
{
}
unsigned p_gpio_peek()
{
unsigned portId, x;
asm("ldw %0, dp[p_gpio]":"=r"(portId));
asm volatile("peek %0, res[%1]":"=r"(x):"r"(portId));
return x;
}
void p_gpio_out(unsigned x)
{
unsigned portId;
asm("ldw %0, dp[p_gpio]":"=r"(portId));
asm volatile("out res[%0], %1"::"r"(portId),"r"(x));
}
void set_gpio(unsigned bit, unsigned value)
{
unsigned port_shadow;
port_shadow = p_gpio_peek(); // Read port pin value
if (value == 0) port_shadow &= ~bit; // If writing a 0, generate mask and AND with current val
else port_shadow |= bit; // Else use mask and OR to set bit
p_gpio_out(port_shadow); // Write back to port. Will make port an output if not already
}
#endif

View File

@@ -0,0 +1,53 @@
// Copyright 2016-2021 XMOS LIMITED.
// This Software is subject to the terms of the XMOS Public Licence: Version 1.
#ifndef __gpio_access_h__
#define __gpio_access_h__
#include "customdefines.h"
#if XCORE_200_MC_AUDIO_HW_VERSION == 2
/* General output port bit definitions */
#define P_GPIO_DSD_MODE (1 << 0) /* DSD mode select 0 = 8i/8o I2S, 1 = 8o DSD*/
#define P_GPIO_DAC_RST_N (1 << 1)
#define P_GPIO_USB_SEL0 (1 << 2)
#define P_GPIO_USB_SEL1 (1 << 3)
#define P_GPIO_VBUS_EN (1 << 4)
#define P_GPIO_PLL_SEL (1 << 5) /* 1 = CS2100, 0 = Phaselink clock source */
#define P_GPIO_ADC_RST_N (1 << 6)
#define P_GPIO_MCLK_FSEL (1 << 7) /* Select frequency on Phaselink clock. 0 = 24.576MHz for 48k, 1 = 22.5792MHz for 44.1k.*/
#else
/* General output port bit definitions */
#define P_GPIO_DSD_MODE (1 << 0) /* DSD mode select 0 = 8i/8o I2S, 1 = 8o DSD*/
#define P_GPIO_DAC_RST_N (1 << 1)
#define P_GPIO_ADC_RST_N (1 << 2)
#define P_GPIO_USB_SEL0 (1 << 3)
#define P_GPIO_USB_SEL1 (1 << 4)
#define P_GPIO_VBUS_EN (1 << 5)
#define P_GPIO_MCLK_FSEL (1 << 6) /* Select frequency on Phaselink clock. 0 = 24.576MHz for 48k, 1 = 22.5792MHz for 44.1k.*/
#define P_GPIO_PLL_SEL (1 << 7) /* 1 = CS2100, 0 = Phaselink clock source */
#endif
/*LED array defines*/
#define LED_ALL_ON 0xf00f
#define LED_SQUARE_BIG 0x9009
#define LED_SQUARE_SML 0x6006
#define LED_ROW_1 0xf001
#define LED_ROW_2 0xf003
#define LED_ROW_3 0xf007
#define ALL_OFF 0x0000
// LED array masks
#define LED_MASK_COL_OFF 0x7fff
#define LED_MASK_DISABLE 0xffff
void set_gpio(unsigned bit, unsigned value);
void p_gpio_lock();
void p_gpio_unlock();
unsigned p_gpio_peek();
void p_gpio_out(unsigned x);
#endif // __gpio_access_h__

View File

@@ -0,0 +1,98 @@
<?xml version="1.0" encoding="UTF-8"?>
<Network xmlns="http://www.xmos.com" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.xmos.com http://www.xmos.com" ManuallySpecifiedRouting="true">
<Type>Board</Type>
<Name>XS2 MC Audio</Name>
<Declarations>
<Declaration>tileref tile[2]</Declaration>
<Declaration>tileref usb_tile</Declaration>
</Declarations>
<Packages>
<Package id="0" Type="XS2-UnA-512-FB236">
<Nodes>
<Node Id="0" InPackageId="0" Type="XS2-L16A-512" Oscillator="24MHz" SystemFrequency="500MHz" referencefrequency="100MHz">
<Boot>
<Source Location="SPI:bootFlash"/>
</Boot>
<Tile Number="0" Reference="tile[0]">
<Port Location="XS1_PORT_1B" Name="PORT_SQI_CS"/>
<Port Location="XS1_PORT_1C" Name="PORT_SQI_SCLK"/>
<Port Location="XS1_PORT_4B" Name="PORT_SQI_SIO"/>
<!-- Audio Ports -->
<Port Location="XS1_PORT_1A" Name="PORT_PLL_REF"/>
<Port Location="XS1_PORT_1F" Name="PORT_MCLK_IN"/>
<Port Location="XS1_PORT_1G" Name="PORT_I2S_LRCLK"/>
<Port Location="XS1_PORT_1H" Name="PORT_I2S_BCLK"/>
<Port Location="XS1_PORT_1M" Name="PORT_I2S_DAC0"/>
<port Location="XS1_PORT_1N" Name="PORT_I2S_DAC1"/>
<port Location="XS1_PORT_1O" Name="PORT_I2S_DAC2"/>
<port Location="XS1_PORT_1P" Name="PORT_I2S_DAC3"/>
<Port Location="XS1_PORT_1I" Name="PORT_I2S_ADC0"/>
<Port Location="XS1_PORT_1J" Name="PORT_I2S_ADC1"/>
<Port Location="XS1_PORT_1K" Name="PORT_I2S_ADC2"/>
<Port Location="XS1_PORT_1L" Name="PORT_I2S_ADC3"/>
<Port Location="XS1_PORT_4A" Name="PORT_I2C"/>
<Port Location="XS1_PORT_1M" Name="PORT_DSD_DAC0"/>
<port Location="XS1_PORT_1N" Name="PORT_DSD_DAC1"/>
<Port Location="XS1_PORT_1G" Name="PORT_DSD_CLK"/>
<Port Location="XS1_PORT_1E" Name="PORT_ADAT_OUT"/>--> <!-- D: COAX E: OPT -->
<Port Location="XS1_PORT_1D" Name="PORT_SPDIF_OUT"/>--> <!-- D: COAX E: OPT -->
</Tile>
<Tile Number="1" Reference="tile[1]">
<Port Location="XS1_PORT_1H" Name="PORT_USB_TX_READYIN"/>
<Port Location="XS1_PORT_1J" Name="PORT_USB_CLK"/>
<Port Location="XS1_PORT_1K" Name="PORT_USB_TX_READYOUT"/>
<Port Location="XS1_PORT_1I" Name="PORT_USB_RX_READY"/>
<Port Location="XS1_PORT_1E" Name="PORT_USB_FLAG0"/>
<Port Location="XS1_PORT_1F" Name="PORT_USB_FLAG1"/>
<Port Location="XS1_PORT_1G" Name="PORT_USB_FLAG2"/>
<Port Location="XS1_PORT_8A" Name="PORT_USB_TXD"/>
<Port Location="XS1_PORT_8B" Name="PORT_USB_RXD"/>
<!-- Audio Ports -->
<Port Location="XS1_PORT_16B" Name="PORT_MCLK_COUNT"/>
<Port Location="XS1_PORT_1L" Name="PORT_MCLK_IN2"/>
<Port Location="XS1_PORT_1M" Name="PORT_MIDI_IN"/>
<Port Location="XS1_PORT_1N" Name="PORT_MIDI_OUT"/>
<Port Location="XS1_PORT_1O" Name="PORT_ADAT_IN"/>--> <!-- P: COAX O: OPT -->
<Port Location="XS1_PORT_1P" Name="PORT_SPDIF_IN"/>--> <!-- P: COAX O: OPT -->
</Tile>
</Node>
<Node Id="1" InPackageId="1" Type="periph:XS1-SU" Reference="usb_tile" Oscillator="24MHz">
</Node>
</Nodes>
<Links>
<Link Encoding="5wire">
<LinkEndpoint NodeId="0" Link="8" Delays="52clk,52clk"/>
<LinkEndpoint NodeId="1" Link="XL0" Delays="1clk,1clk"/>
</Link>
</Links>
</Package>
</Packages>
<Nodes>
<Node Id="2" Type="device:" RoutingId="0x8000">
<Service Id="0" Proto="xscope_host_data(chanend c);">
<Chanend Identifier="c" end="3"/>
</Service>
</Node>
</Nodes>
<Links>
<Link Encoding="2wire" Delays="4,4" Flags="XSCOPE">
<LinkEndpoint NodeId="0" Link="XL0"/>
<LinkEndpoint NodeId="2" Chanend="1"/>
</Link>
</Links>
<ExternalDevices>
<Device NodeId="0" Tile="0" Class="SQIFlash" Name="bootFlash" Type="S25FL116K" PageSize="256" SectorSize="4096" NumPages="8192">
<Attribute Name="PORT_SQI_CS" Value="PORT_SQI_CS"/>
<Attribute Name="PORT_SQI_SCLK" Value="PORT_SQI_SCLK"/>
<Attribute Name="PORT_SQI_SIO" Value="PORT_SQI_SIO"/>
<Attribute Name="QE_REGISTER" Value="flash_qe_location_status_reg_0"/>
<Attribute Name="QE_BIT" Value="flash_qe_bit_6"/>
</Device>
</ExternalDevices>
<JTAGChain>
<JTAGDevice NodeId="0"/>
<JTAGDevice NodeId="1"/>
</JTAGChain>
</Network>

View File

@@ -0,0 +1,29 @@
// Copyright 2016-2021 XMOS LIMITED.
// This Software is subject to the terms of the XMOS Public Licence: Version 1.
#ifndef __custom_defines_h__
#define __custom_defines_h__
#define EXCLUDE_USB_AUDIO_MAIN
#define XUA_NUM_PDM_MICS 0
#define XUD_TILE 1
#define AUDIO_IO_TILE 0
#define MIXER 0
#define MCLK_441 (512 * 44100)
#define MCLK_48 (512 * 48000)
#define MIN_FREQ 44100
#define MAX_FREQ 192000
#define SPDIF_TX_INDEX 0
#define VENDOR_STR "XMOS"
#define VENDOR_ID 0x20B1
#define PRODUCT_STR_A2 "Test device"
#define PRODUCT_STR_A1 "Test device"
#define PID_AUDIO_1 1
#define PID_AUDIO_2 2
#define AUDIO_CLASS 2
#define AUDIO_CLASS_FALLBACK 0
#define BCD_DEVICE 0x1234
#define XUA_DFU_EN 0
#define MIC_DUAL_ENABLED 1 //Use single thread, dual PDM mic
#define XUA_MIC_FRAME_SIZE 240
#endif // __custom_defines_h__

1
tests/pass.expect Normal file
View File

@@ -0,0 +1 @@
PASS

23
tests/runtests.py Executable file
View File

@@ -0,0 +1,23 @@
#!/usr/bin/env python2.7
# Copyright 2018-2021 XMOS LIMITED.
# This Software is subject to the terms of the XMOS Public Licence: Version 1.
import xmostest
import os.path
if __name__ == "__main__":
xmostest.init()
xmostest.register_group("lib_xua",
"i2s_loopback_sim_tests",
"I2S loopback simulator tests",
"""
Tests are performed by running the audiohub code connected to a
loopback plugin
""")
xmostest.runtests()
xmostest.finish()

View File

@@ -0,0 +1,51 @@
#!/usr/bin/env python
# Copyright 2018-2021 XMOS LIMITED.
# This Software is subject to the terms of the XMOS Public Licence: Version 1.
import xmostest
def runtest_one_config(env, format, i2s_role, num_chans_in, num_chans_out, sample_rate):
testlevel = 'smoke'
resources = xmostest.request_resource('xsim')
binary = 'app_test_i2s_loopback/bin/{env}_{format}_{i2s_role}_{num_chans_in}in_{num_chans_out}out_{sample_rate}/app_test_i2s_loopback_{env}_{format}_{i2s_role}_{num_chans_in}in_{num_chans_out}out_{sample_rate}.xe'.format(env=env, format=format, i2s_role=i2s_role, num_chans_in=num_chans_in, num_chans_out=num_chans_out, sample_rate=sample_rate)
tester = xmostest.ComparisonTester(open('pass.expect'),
'lib_xua',
'i2s_loopback_sim_tests',
'i2s_loopback',
{'env':env,
'format':format,
'i2s_role':i2s_role,
'num_chans_in':num_chans_in,
'num_chans_out':num_chans_out,
'sample_rate':sample_rate})
tester.set_min_testlevel(testlevel)
loopback_args= '-port tile[0] XS1_PORT_1M 1 0 -port tile[0] XS1_PORT_1I 1 0 ' + \
'-port tile[0] XS1_PORT_1N 1 0 -port tile[0] XS1_PORT_1J 1 0 ' + \
'-port tile[0] XS1_PORT_1O 1 0 -port tile[0] XS1_PORT_1K 1 0 ' + \
'-port tile[0] XS1_PORT_1P 1 0 -port tile[0] XS1_PORT_1L 1 0 ' + \
'-port tile[0] XS1_PORT_1A 1 0 -port tile[0] XS1_PORT_1F 1 0 '
if i2s_role == 'slave':
loopback_args += '-port tile[0] XS1_PORT_1B 1 0 -port tile[0] XS1_PORT_1H 1 0 ' #bclk
loopback_args += '-port tile[0] XS1_PORT_1C 1 0 -port tile[0] XS1_PORT_1G 1 0 ' #lrclk
max_cycles = 1500000 #enough to reach the 10 skip + 100 test in sim at 48kHz
xmostest.run_on_simulator(resources['xsim'], binary, tester=tester, simargs=['--max-cycles', str(max_cycles), '--plugin', 'LoopbackPort.dll', loopback_args])
def runtest():
runtest_one_config('simulation', 'i2s', 'master', 2, 2, '48khz')
runtest_one_config('simulation', 'i2s', 'slave', 2, 2, '48khz')
runtest_one_config('simulation', 'i2s', 'master', 2, 2, '192khz')
runtest_one_config('simulation', 'i2s', 'slave', 2, 2, '192khz')
runtest_one_config('simulation', 'i2s', 'master', 8, 8, '48khz')
runtest_one_config('simulation', 'i2s', 'slave', 8, 8, '48khz')
runtest_one_config('simulation', 'i2s', 'master', 8, 8, '192khz')
runtest_one_config('simulation', 'i2s', 'slave', 8, 8, '192khz')
runtest_one_config('simulation', 'tdm', 'master', 8, 8, '48khz')
runtest_one_config('simulation', 'tdm', 'slave', 8, 8, '48khz')
runtest_one_config('simulation', 'tdm', 'master', 16, 16, '48khz')
runtest_one_config('simulation', 'tdm', 'slave', 16, 16, '48khz')