From 9401bfff83177b2348e0d713985afa7f31849dec Mon Sep 17 00:00:00 2001 From: xross Date: Tue, 5 Jul 2022 18:14:05 +0100 Subject: [PATCH] - Rename app_test_i2s_loopback to test_i2s_loopback - Port test_i2s_loopback from xmostest to pytest and test_support --- .gitignore | 1 + tests/conftest.py | 9 + tests/test_i2s_loopback.py | 180 ++++++++++++++---- .../Makefile | 0 .../debug_conf.h | 0 .../hid_report_descriptor.h | 0 .../main.xc | 2 +- .../simulation.xc | 0 .../usb_device.h | 0 .../usb_device.xc | 0 .../xk_216_mc/audiohw.xc | 0 .../xk_216_mc/cs2100.h | 0 .../xk_216_mc/cs4384.h | 0 .../xk_216_mc/cs5368.h | 0 .../xk_216_mc/gpio_access.c | 0 .../xk_216_mc/gpio_access.h | 0 .../xk_216_mc/xk-audio-216-mc.xn | 0 .../xua_conf.h | 19 +- 18 files changed, 162 insertions(+), 49 deletions(-) create mode 100644 tests/conftest.py rename tests/{app_test_i2s_loopback => test_i2s_loopback}/Makefile (100%) rename tests/{app_test_i2s_loopback => test_i2s_loopback}/debug_conf.h (100%) rename tests/{app_test_i2s_loopback => test_i2s_loopback}/hid_report_descriptor.h (100%) rename tests/{app_test_i2s_loopback => test_i2s_loopback}/main.xc (99%) rename tests/{app_test_i2s_loopback => test_i2s_loopback}/simulation.xc (100%) rename tests/{app_test_i2s_loopback => test_i2s_loopback}/usb_device.h (100%) rename tests/{app_test_i2s_loopback => test_i2s_loopback}/usb_device.xc (100%) rename tests/{app_test_i2s_loopback => test_i2s_loopback}/xk_216_mc/audiohw.xc (100%) rename tests/{app_test_i2s_loopback => test_i2s_loopback}/xk_216_mc/cs2100.h (100%) rename tests/{app_test_i2s_loopback => test_i2s_loopback}/xk_216_mc/cs4384.h (100%) rename tests/{app_test_i2s_loopback => test_i2s_loopback}/xk_216_mc/cs5368.h (100%) rename tests/{app_test_i2s_loopback => test_i2s_loopback}/xk_216_mc/gpio_access.c (100%) rename tests/{app_test_i2s_loopback => test_i2s_loopback}/xk_216_mc/gpio_access.h (100%) rename tests/{app_test_i2s_loopback => test_i2s_loopback}/xk_216_mc/xk-audio-216-mc.xn (100%) rename tests/{app_test_i2s_loopback => test_i2s_loopback}/xua_conf.h (77%) diff --git a/.gitignore b/.gitignore index a10bd6ad..9ba242e9 100644 --- a/.gitignore +++ b/.gitignore @@ -23,6 +23,7 @@ _build* **/.vscode/** **.egg-info *.pdf +*/logs/* # waf build files .lock-waf_* diff --git a/tests/conftest.py b/tests/conftest.py new file mode 100644 index 00000000..c302dd8d --- /dev/null +++ b/tests/conftest.py @@ -0,0 +1,9 @@ +import pytest + +def pytest_addoption(parser): + parser.addoption("--enabletracing", action="store_true", default=False, help="Enable xsim tracing") + + +@pytest.fixture +def options(request): + yield request.config.option diff --git a/tests/test_i2s_loopback.py b/tests/test_i2s_loopback.py index 3e65e2f6..dc521d54 100644 --- a/tests/test_i2s_loopback.py +++ b/tests/test_i2s_loopback.py @@ -1,51 +1,147 @@ -#!/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 +import pytest +import Pyxsim +from Pyxsim import testers +import os +import sys -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 +@pytest.fixture() +def test_file(request): + return str(request.node.fspath) - 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') +def create_if_needed(folder): + if not os.path.exists(folder): + os.makedirs(folder) + return folder - 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') +def get_sim_args(testname, desc, options): + sim_args = [] - runtest_one_config('simulation', 'i2s', 'master', 8, 8, '192khz') - runtest_one_config('simulation', 'i2s', 'slave', 8, 8, '192khz') + if options.enabletracing: + log_folder = create_if_needed("logs") - runtest_one_config('simulation', 'tdm', 'master', 8, 8, '48khz') - runtest_one_config('simulation', 'tdm', 'slave', 8, 8, '48khz') + filename = "{log}/xsim_trace_{test}_{desc}".format( + log=log_folder, + test=testname, + desc=desc, + ) - runtest_one_config('simulation', 'tdm', 'master', 16, 16, '48khz') - runtest_one_config('simulation', 'tdm', 'slave', 16, 16, '48khz') + sim_args += [ + "--trace-to", + "{0}.txt".format(filename), + "--enable-fnop-tracing", + ] + + vcd_args = "-o {0}.vcd".format(filename) + vcd_args += ( + " -tile tile[0] -ports -ports-detailed -instructions" + " -functions -cycles -clock-blocks -pads -cores -usb" + ) + + sim_args += ["--vcd-tracing", vcd_args] + + return sim_args + + +def run_on_simulator(xe, simthreads, **kwargs): + for k in ["do_xe_prebuild", "build_env", "clean_before_build"]: + if k in kwargs: + kwargs.pop(k) + + Pyxsim.run_with_pyxsim(xe, simthreads, **kwargs) + + +def do_test(pcm_format, i2s_role, channel_count, sample_rate, test_file, capfd, options): + + build_options = [] + output = [] + testname, _ = os.path.splitext(os.path.basename(test_file)) + + desc = f"simulation_{pcm_format}_{i2s_role}_{channel_count}in_{channel_count}out_{sample_rate}" + binary = f"{testname}/bin/{desc}/{testname}_{desc}.xe" + + build_success, _ = Pyxsim._build( + binary, do_clean=False, build_options=build_options + ) + + if build_success: + + tester = testers.ComparisonTester( + open("pass.expect"), + "lib_xua", + "xua_sim_tests", + testname, + { + "speed": "500MHz", + "arch": "XS2", + }, # TODO run tests on XS3 and other core freqs + ) + + 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 + + simargs = get_sim_args(testname, desc, options) + simargs = simargs + [ + "--max-cycles", + str(max_cycles), + "--plugin", + "LoopbackPort.dll", + loopback_args, + ] + + simthreads = [] + run_on_simulator(binary, simthreads, simargs=simargs) + + cap_output, err = capfd.readouterr() + output.append(cap_output.split("\n")) + + sys.stdout.write("\n") + + results = Pyxsim.run_tester(output, [tester]) + + return results + + else: + print("Build Failed") + + return [False] + + +@pytest.mark.parametrize("i2s_role", ["master", "slave"]) +@pytest.mark.parametrize("pcm_format", ["i2s", "tdm"]) +@pytest.mark.parametrize("channel_count", [2, 8, 16]) +@pytest.mark.parametrize("sample_rate", ["48khz", "192khz"]) +def test_i2s_loopback( + i2s_role, pcm_format, channel_count, sample_rate, test_file, capfd, options +): + + if pcm_format == "i2s" and channel_count == 16: + pytest.skip("Invalid parameter combination") + + if pcm_format == "tdm" and channel_count == 2: + pytest.skip("Invalid parameter combination") + + if pcm_format == "tdm" and sample_rate == "192khz": + pytest.skip("Invalid parameter combination") + + results = do_test( + pcm_format, i2s_role, channel_count, sample_rate, test_file, capfd, options + ) + + assert results[0] diff --git a/tests/app_test_i2s_loopback/Makefile b/tests/test_i2s_loopback/Makefile similarity index 100% rename from tests/app_test_i2s_loopback/Makefile rename to tests/test_i2s_loopback/Makefile diff --git a/tests/app_test_i2s_loopback/debug_conf.h b/tests/test_i2s_loopback/debug_conf.h similarity index 100% rename from tests/app_test_i2s_loopback/debug_conf.h rename to tests/test_i2s_loopback/debug_conf.h diff --git a/tests/app_test_i2s_loopback/hid_report_descriptor.h b/tests/test_i2s_loopback/hid_report_descriptor.h similarity index 100% rename from tests/app_test_i2s_loopback/hid_report_descriptor.h rename to tests/test_i2s_loopback/hid_report_descriptor.h diff --git a/tests/app_test_i2s_loopback/main.xc b/tests/test_i2s_loopback/main.xc similarity index 99% rename from tests/app_test_i2s_loopback/main.xc rename to tests/test_i2s_loopback/main.xc index bfef1fd1..73a24db1 100644 --- a/tests/app_test_i2s_loopback/main.xc +++ b/tests/test_i2s_loopback/main.xc @@ -203,7 +203,7 @@ void slave_mode_clk_setup(const unsigned samFreq, const unsigned chans_per_frame #endif -#if I2S_MODE_TDM +#if XUA_PCM_FORMAT == XUA_PCM_FORMAT_TDM const int i2s_tdm_mode = 8; #else const int i2s_tdm_mode = 2; diff --git a/tests/app_test_i2s_loopback/simulation.xc b/tests/test_i2s_loopback/simulation.xc similarity index 100% rename from tests/app_test_i2s_loopback/simulation.xc rename to tests/test_i2s_loopback/simulation.xc diff --git a/tests/app_test_i2s_loopback/usb_device.h b/tests/test_i2s_loopback/usb_device.h similarity index 100% rename from tests/app_test_i2s_loopback/usb_device.h rename to tests/test_i2s_loopback/usb_device.h diff --git a/tests/app_test_i2s_loopback/usb_device.xc b/tests/test_i2s_loopback/usb_device.xc similarity index 100% rename from tests/app_test_i2s_loopback/usb_device.xc rename to tests/test_i2s_loopback/usb_device.xc diff --git a/tests/app_test_i2s_loopback/xk_216_mc/audiohw.xc b/tests/test_i2s_loopback/xk_216_mc/audiohw.xc similarity index 100% rename from tests/app_test_i2s_loopback/xk_216_mc/audiohw.xc rename to tests/test_i2s_loopback/xk_216_mc/audiohw.xc diff --git a/tests/app_test_i2s_loopback/xk_216_mc/cs2100.h b/tests/test_i2s_loopback/xk_216_mc/cs2100.h similarity index 100% rename from tests/app_test_i2s_loopback/xk_216_mc/cs2100.h rename to tests/test_i2s_loopback/xk_216_mc/cs2100.h diff --git a/tests/app_test_i2s_loopback/xk_216_mc/cs4384.h b/tests/test_i2s_loopback/xk_216_mc/cs4384.h similarity index 100% rename from tests/app_test_i2s_loopback/xk_216_mc/cs4384.h rename to tests/test_i2s_loopback/xk_216_mc/cs4384.h diff --git a/tests/app_test_i2s_loopback/xk_216_mc/cs5368.h b/tests/test_i2s_loopback/xk_216_mc/cs5368.h similarity index 100% rename from tests/app_test_i2s_loopback/xk_216_mc/cs5368.h rename to tests/test_i2s_loopback/xk_216_mc/cs5368.h diff --git a/tests/app_test_i2s_loopback/xk_216_mc/gpio_access.c b/tests/test_i2s_loopback/xk_216_mc/gpio_access.c similarity index 100% rename from tests/app_test_i2s_loopback/xk_216_mc/gpio_access.c rename to tests/test_i2s_loopback/xk_216_mc/gpio_access.c diff --git a/tests/app_test_i2s_loopback/xk_216_mc/gpio_access.h b/tests/test_i2s_loopback/xk_216_mc/gpio_access.h similarity index 100% rename from tests/app_test_i2s_loopback/xk_216_mc/gpio_access.h rename to tests/test_i2s_loopback/xk_216_mc/gpio_access.h diff --git a/tests/app_test_i2s_loopback/xk_216_mc/xk-audio-216-mc.xn b/tests/test_i2s_loopback/xk_216_mc/xk-audio-216-mc.xn similarity index 100% rename from tests/app_test_i2s_loopback/xk_216_mc/xk-audio-216-mc.xn rename to tests/test_i2s_loopback/xk_216_mc/xk-audio-216-mc.xn diff --git a/tests/app_test_i2s_loopback/xua_conf.h b/tests/test_i2s_loopback/xua_conf.h similarity index 77% rename from tests/app_test_i2s_loopback/xua_conf.h rename to tests/test_i2s_loopback/xua_conf.h index a1120f49..dc381a65 100644 --- a/tests/app_test_i2s_loopback/xua_conf.h +++ b/tests/test_i2s_loopback/xua_conf.h @@ -1,17 +1,24 @@ -// Copyright 2016-2021 XMOS LIMITED. +// Copyright 2016-2022 XMOS LIMITED. // This Software is subject to the terms of the XMOS Public Licence: Version 1. -#ifndef __custom_defines_h__ -#define __custom_defines_h__ +#ifndef _XUA_CONF_H_ +#define _XUA_CONF_H_ #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) -#define MIN_FREQ 44100 -#define MAX_FREQ 192000 +#endif + +#define MIN_FREQ (44100) +#define MAX_FREQ (192000) #define SPDIF_TX_INDEX 0 #define VENDOR_STR "XMOS" #define VENDOR_ID 0x20B1 @@ -26,4 +33,4 @@ #define MIC_DUAL_ENABLED 1 //Use single thread, dual PDM mic #define XUA_MIC_FRAME_SIZE 240 -#endif // __custom_defines_h__ +#endif