diff --git a/.gitignore b/.gitignore index 979a2930..0cffca23 100644 --- a/.gitignore +++ b/.gitignore @@ -32,3 +32,7 @@ build/ .build* *.pyc xscope.xmt + +# Traces +*.gtkw +*.vcd diff --git a/tests/test_sync.py b/tests/test_sync.py new file mode 100644 index 00000000..45c9ae22 --- /dev/null +++ b/tests/test_sync.py @@ -0,0 +1,49 @@ +import pytest +import Pyxsim +from Pyxsim import testers +import os +import sys + + +@pytest.fixture() +def test_file(request): + return str(request.node.fspath) + + +def do_test(test_file, options, capfd): + + testname, _ = os.path.splitext(os.path.basename(test_file)) + + binary = f"{testname}/bin/{testname}.xe" + + tester = testers.ComparisonTester(open("pass.expect")) + + 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_1B 1 0 " + ) + + + max_cycles = 15000000 # enough to reach the 10 skip + 100 test in sim at 48kHz + + simargs = [ + "--max-cycles", + str(max_cycles), + "--plugin", + "LoopbackPort.dll", + loopback_args, + ] + + result = Pyxsim.run_on_simulator(binary, tester=tester, simargs=simargs, capfd=capfd, instTracing=options.enabletracing, vcdTracing=options.enablevcdtracing) + + return result + + +def test_sync(test_file, options, capfd): + + result = do_test(test_file, options, capfd) + + assert result diff --git a/tests/test_sync/Makefile b/tests/test_sync/Makefile new file mode 100644 index 00000000..e175efba --- /dev/null +++ b/tests/test_sync/Makefile @@ -0,0 +1,9 @@ + +XCC_FLAGS = -O3 -g -DXUD_CORE_CLOCK=600 -save-temps -DUSB_TILE=tile[0] -DLOCAL_CLOCK_INCREMENT=10000 -DLOCAL_CLOCK_MARGIN=100 + +TARGET = test_xs3_600.xn + +USED_MODULES = lib_xua lib_xud lib_logging + +XMOS_MAKE_PATH ?= ../.. +-include $(XMOS_MAKE_PATH)/xcommon/module_xcommon/build/Makefile.common diff --git a/tests/test_sync/src/debug_conf.h b/tests/test_sync/src/debug_conf.h new file mode 100644 index 00000000..aadb0014 --- /dev/null +++ b/tests/test_sync/src/debug_conf.h @@ -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__ diff --git a/tests/test_sync/src/main.xc b/tests/test_sync/src/main.xc new file mode 100644 index 00000000..12c6509d --- /dev/null +++ b/tests/test_sync/src/main.xc @@ -0,0 +1,160 @@ +// Copyright 2022 XMOS LIMITED. +// This Software is subject to the terms of the XMOS Public Licence: Version 1. + +/* Simples test to ensure reference clock to CS2100 device continues when SOF clock not available + * Note, this test uses "nice" numbers and it doesn't check for graceful change over from internal to SOF clock + */ + +#include "platform.h" +#include "xua.h" +#include "uac_hwresources.h" +#include "print.h" + +#define EP_COUNT_IN 3 +#define EP_COUNT_OUT 3 + +out port p_pll_ref = XS1_PORT_1A; +in port p_off_mclk = XS1_PORT_1M; +in port p_pll_loop = XS1_PORT_1B; + +/* Purely for debug/viewing on VCD */ +out port p_test = XS1_PORT_1C; + +/* To speed this test up we divide all delays by 10. This is also the case for the delays in the clock generation code */ +#define SOF_PERIOD_TICKS (12500/10) + +void exit(int); + +void delay(unsigned d) +{ + timer t; + unsigned time; + t :> time; + t when timerafter(time + d) :> int x; +} + +/* From lib_xud */ +void SetupEndpoints(chanend c_ep_out[], int noEpOut, chanend c_ep_in[], int noEpIn, XUD_EpType epTypeTableOut[], XUD_EpType epTypeTableIn[]); + +void AudioHwInit() +{ + return; +} + +void AudioHwConfig(unsigned samFreq, unsigned mClk, unsigned dsdMode, + unsigned sampRes_DAC, unsigned sampRes_ADC) +{ + return; +} + +void driveSofs(chanend c_sof, int count) +{ + static int sof = 0; + for(int i = 0; i < count; i++) + { + outuint(c_sof, sof++); + delay(SOF_PERIOD_TICKS); + } +} + +void fake_xud(chanend c_out[], chanend c_in[], chanend c_sof) +{ + timer t; + unsigned time; + + p_test <: 1; + + /* Makes traces a bit nicer to look at */ + t :> time; + t when timerafter(SOF_PERIOD_TICKS * 2) :> int x; + + /* Endpoint type tables */ + XUD_EpType epTypeTableOut[EP_COUNT_OUT] = {XUD_EPTYPE_CTL, XUD_EPTYPE_ISO, XUD_EPTYPE_DIS}; + XUD_EpType epTypeTableIn[EP_COUNT_IN] = {XUD_EPTYPE_CTL, XUD_EPTYPE_ISO, XUD_EPTYPE_ISO}; + + SetupEndpoints(c_out, EP_COUNT_OUT, c_in, EP_COUNT_IN, epTypeTableOut, epTypeTableIn); + + driveSofs(c_sof, 24); + + p_test <: 0; + /* Sim missing SOFs */ + delay(SOF_PERIOD_TICKS*8); + p_test <: 1; + + driveSofs(c_sof, 16); + + p_test <: 0; +} + +extern XUD_BusSpeed_t g_curUsbSpeed; + +#define MARGIN (1500/10) +#define EXPECTED_PERIOD (100000/10) // Test runs as HS - so 8 * 125000 + +void checker() +{ + timer t; + unsigned t0, t1; + unsigned x = 0; + + int fail = 0; + + p_pll_loop when pinseq(1) :> x; + p_pll_loop when pinseq(0) :> x; + p_pll_loop when pinseq(1) :> x; + + for(int i = 0; i < 8; i++) + { + p_pll_loop when pinsneq(x) :> x; + t :> t0; + p_pll_loop when pinsneq(x) :> x; + t :> t1; + + int period = t1-t0; + + if(period > (EXPECTED_PERIOD + MARGIN)) + { + printstr("Period too long: "); + printintln(period); + fail = 1; + } + else if(period < (EXPECTED_PERIOD - MARGIN)) + { + printstr("Period too short: "); + printintln(period); + fail = 1; + } + } + if(!fail) + printstrln("PASS"); + + exit(0); +} + + +int main() +{ + chan c_out[EP_COUNT_OUT]; + chan c_in[EP_COUNT_IN]; + chan c_sof; + chan c_aud_ctl; + + interface pll_ref_if i_pll_ref; + + par + { + PllRefPinTask(i_pll_ref, p_pll_ref); + + { + g_curUsbSpeed = XUD_SPEED_HS; + XUA_Buffer_Ep(c_out[1], /* USB Audio Out*/ + c_in[1], /* USB Audio In */ + c_sof, c_aud_ctl, p_off_mclk, i_pll_ref + ); + } + + fake_xud(c_out, c_in, c_sof); + + checker(); + } +} diff --git a/tests/test_sync/src/test_xs3_600.xn b/tests/test_sync/src/test_xs3_600.xn new file mode 100644 index 00000000..20e8eeb6 --- /dev/null +++ b/tests/test_sync/src/test_xs3_600.xn @@ -0,0 +1,24 @@ + + + + tileref tile[2] + + + + + + + + + + + + + + + + + + diff --git a/tests/test_sync/src/usb_device.h b/tests/test_sync/src/usb_device.h new file mode 100644 index 00000000..1f5aaa89 --- /dev/null +++ b/tests/test_sync/src/usb_device.h @@ -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 +#include +#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__ diff --git a/tests/test_sync/src/xua_conf.h b/tests/test_sync/src/xua_conf.h new file mode 100644 index 00000000..616262b7 --- /dev/null +++ b/tests/test_sync/src/xua_conf.h @@ -0,0 +1,44 @@ +// Copyright 2016-2022 XMOS LIMITED. +// This Software is subject to the terms of the XMOS Public Licence: Version 1. +#ifndef _XUA_CONF_H_ +#define _XUA_CONF_H_ + +#define NUM_USB_CHAN_OUT (2) +#define NUM_USB_CHAN_IN (2) +#define I2S_CHANS_DAC (2) +#define I2S_CHANS_ADC (2) + +#define XUA_SYNCMODE XUA_SYNCMODE_SYNC +#define UAC_FORCE_FEEDBACK_EP (0) + +#define EXCLUDE_USB_AUDIO_MAIN +#define XUA_NUM_PDM_MICS 0 +#define XUD_TILE 1 +#define AUDIO_IO_TILE 0 +#define MIXER 0 + +#ifndef MCLK_441 +#define MCLK_441 (512 * 44100) +#endif + +#ifndef MCLK_48 +#define MCLK_48 (512 * 48000) +#endif + +#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