Merge remote-tracking branch 'upstream' into feature/ai_examples

This commit is contained in:
xross
2022-08-08 16:39:19 +01:00
41 changed files with 712 additions and 189 deletions

4
.gitignore vendored
View File

@@ -32,3 +32,7 @@ build/
.build* .build*
*.pyc *.pyc
xscope.xmt xscope.xmt
# Traces
*.gtkw
*.vcd

14
Jenkinsfile vendored
View File

@@ -27,15 +27,21 @@ pipeline {
xcoreLibraryChecks("${REPO}") xcoreLibraryChecks("${REPO}")
} }
} }
stage('XS2 Tests') { stage('Testing') {
failFast true failFast true
parallel { parallel {
stage('Legacy tests') { stage('Tests') {
steps { steps {
runXmostest("${REPO}", 'legacy_tests') dir("${REPO}/tests"){
viewEnv(){
withVenv{
runPytest('--numprocesses=4')
}
}
}
} }
} }
stage('Unit tests') { stage('Unity tests') {
steps { steps {
dir("${REPO}") { dir("${REPO}") {
dir('tests') { dir('tests') {

View File

@@ -1,23 +0,0 @@
#!/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

@@ -1,51 +0,0 @@
#!/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')

View File

@@ -789,12 +789,11 @@ void XUA_AudioHub(chanend ?c_aud, clock ?clk_audio_mclk, clock ?clk_audio_bclk,
null, null,
p_dsd_clk, p_dsd_clk,
#endif #endif
divide, curSamFreq, dsdMode); p_mclk_in, clk_audio_bclk, divide, curSamFreq, dsdMode);
} }
else else
#endif #endif
{ {
ConfigAudioPortsWrapper( ConfigAudioPortsWrapper(
#if (I2S_CHANS_DAC != 0) #if (I2S_CHANS_DAC != 0)
p_i2s_dac, p_i2s_dac,
@@ -813,7 +812,7 @@ void XUA_AudioHub(chanend ?c_aud, clock ?clk_audio_mclk, clock ?clk_audio_bclk,
p_bclk, p_bclk,
#endif #endif
#endif #endif
divide, curSamFreq, dsdMode); p_mclk_in, clk_audio_bclk, divide, curSamFreq, dsdMode);
} }

View File

@@ -3,8 +3,7 @@
#include "xua.h" #include "xua.h"
#if XUA_USB_EN #if XUA_USB_EN
#include <xs1.h> #include <xs1.h>
#include <print.h> #include <stdint.h>
#ifdef MIDI #ifdef MIDI
#include "usb_midi.h" #include "usb_midi.h"
@@ -357,7 +356,21 @@ void XUA_Buffer_Ep(register chanend c_aud_out,
#endif #endif
#endif #endif
timer tmr; #if (XUA_SYNCMODE == XUA_SYNCMODE_SYNC)
#ifndef LOCAL_CLOCK_INCREMENT
#define LOCAL_CLOCK_INCREMENT (100000) /* 500Hz */
#endif
#ifndef LOCAL_CLOCK_MARGIN
#define LOCAL_CLOCK_MARGIN (1000)
#endif
int sofClockValid = 0;
timer t_sofCheck;
unsigned timeLastEdge;
unsigned timeNextEdge;
t_sofCheck :> timeLastEdge;
timeNextEdge + LOCAL_CLOCK_INCREMENT;
i_pll_ref.toggle();
#endif
while(1) while(1)
{ {
@@ -502,6 +515,13 @@ void XUA_Buffer_Ep(register chanend c_aud_out,
} }
break; break;
} }
#if (XUA_SYNCMODE == XUA_SYNCMODE_SYNC)
case t_sofCheck when timerafter(timeNextEdge) :> void:
i_pll_ref.toggle();
timeLastEdge = timeNextEdge;
timeNextEdge += LOCAL_CLOCK_INCREMENT;
break;
#endif
#define MASK_16_13 (7) /* Bits that should not be transmitted as part of feedback */ #define MASK_16_13 (7) /* Bits that should not be transmitted as part of feedback */
#define MASK_16_10 (127) /* For Audio 1.0 we use a mask 1 bit longer than expected to avoid Windows LSB issues */ #define MASK_16_10 (127) /* For Audio 1.0 we use a mask 1 bit longer than expected to avoid Windows LSB issues */
@@ -517,12 +537,11 @@ void XUA_Buffer_Ep(register chanend c_aud_out,
int framesPerSec; int framesPerSec;
GET_SHARED_GLOBAL(usbSpeed, g_curUsbSpeed); GET_SHARED_GLOBAL(usbSpeed, g_curUsbSpeed);
static int sofCount = 0; static int sofCount = 0;
static unsigned syncPinVal = 0;
framesPerSec = (usbSpeed == XUD_SPEED_HS) ? 8000 : 1000; framesPerSec = (usbSpeed == XUD_SPEED_HS) ? 8000 : 1000;
float float_clocks = (float) sampleFreq/framesPerSec ;
clocks = (unsigned) (float_clocks * (1 << 16)); clocks = ((int64_t) sampleFreq << 16) / framesPerSec;
asm volatile("stw %0, dp[g_speed]"::"r"(clocks)); asm volatile("stw %0, dp[g_speed]"::"r"(clocks));
sofCount += 1000; sofCount += 1000;
@@ -530,7 +549,9 @@ void XUA_Buffer_Ep(register chanend c_aud_out,
{ {
/* Port is accessed via interface to allow flexibilty with location */ /* Port is accessed via interface to allow flexibilty with location */
i_pll_ref.toggle(); i_pll_ref.toggle();
t_sofCheck :> timeLastEdge;
sofCount = 0; sofCount = 0;
timeNextEdge = timeLastEdge + LOCAL_CLOCK_INCREMENT + LOCAL_CLOCK_MARGIN;
} }
#else #else
@@ -889,6 +910,7 @@ void XUA_Buffer_Ep(register chanend c_aud_out,
case XUD_SetData_Select(c_hid, ep_hid, result): case XUD_SetData_Select(c_hid, ep_hid, result):
hid_ready_flag = 0U; hid_ready_flag = 0U;
unsigned reportTime; unsigned reportTime;
timer tmr;
tmr :> reportTime; tmr :> reportTime;
hidCaptureReportTime(hid_ready_id, reportTime); hidCaptureReportTime(hid_ready_id, reportTime);
hidCalcNextReportTime(hid_ready_id); hidCalcNextReportTime(hid_ready_id);

View File

@@ -485,20 +485,14 @@ void clockGen (streaming chanend ?c_spdif_rx, chanend ?c_adat_rx, client interfa
timeNextClockDetection = timeNextEdge + (LOCAL_CLOCK_INCREMENT/2); timeNextClockDetection = timeNextEdge + (LOCAL_CLOCK_INCREMENT/2);
timeNextEdge += LOCAL_CLOCK_INCREMENT; timeNextEdge += LOCAL_CLOCK_INCREMENT;
/* If we are in an external clock mode and this fire, then clock invalid */ /* If we are in an external clock mode and this fire, then clock invalid
* reset counters in case we are moved to digital clock - we want a well timed
* first edge */
#if (XUA_SPDIF_RX_EN) #if (XUA_SPDIF_RX_EN)
// if(clkMode == CLOCK_SPDIF) spdifCounters.receivedSamples = 0;
{
/* We must have lost valid S/PDIF stream, reset counters, so we dont produce a double edge */
spdifCounters.receivedSamples = 0;
}
#endif #endif
#if ADAT_RX #if ADAT_RX
//if(clkMode == CLOCK_ADAT) adatCounters.receivedSamples = 0;
{
adatCounters.receivedSamples = 0;
}
#endif #endif
#ifdef CLOCK_VALIDITY_CALL #ifdef CLOCK_VALIDITY_CALL

View File

@@ -1,4 +1,4 @@
// Copyright 2013-2021 XMOS LIMITED. // Copyright 2013-2022 XMOS LIMITED.
// This Software is subject to the terms of the XMOS Public Licence: Version 1. // This Software is subject to the terms of the XMOS Public Licence: Version 1.
#include <xs1.h> #include <xs1.h>
@@ -6,7 +6,6 @@
#include <platform.h> #include <platform.h>
#undef __ASSEMBLER__ #undef __ASSEMBLER__
#include "audioports.h" #include "audioports.h"
#include <xccompat.h>
#include "xua.h" #include "xua.h"
/* Note since DSD ports could be reused for I2S ports we do all the setup manually in C */ /* Note since DSD ports could be reused for I2S ports we do all the setup manually in C */
@@ -46,7 +45,7 @@ void ConfigAudioPortsWrapper(
port p_lrclk, port p_lrclk,
port p_bclk, port p_bclk,
#endif #endif
unsigned int divide, unsigned curSamFreq, unsigned int dsdMode) port p_mclk_in, clock clk_audio_bclk, unsigned int divide, unsigned curSamFreq, unsigned int dsdMode)
{ {
ConfigAudioPorts( ConfigAudioPorts(
#if (I2S_CHANS_DAC != 0) || (DSD_CHANS_DAC != 0) #if (I2S_CHANS_DAC != 0) || (DSD_CHANS_DAC != 0)
@@ -61,6 +60,6 @@ unsigned int divide, unsigned curSamFreq, unsigned int dsdMode)
p_lrclk, p_lrclk,
p_bclk, p_bclk,
#endif #endif
divide, curSamFreq); p_mclk_in, clk_audio_bclk, divide, curSamFreq);
} }

View File

@@ -1,9 +1,12 @@
// Copyright 2011-2021 XMOS LIMITED. // Copyright 2011-2022 XMOS LIMITED.
// This Software is subject to the terms of the XMOS Public Licence: Version 1. // This Software is subject to the terms of the XMOS Public Licence: Version 1.
#ifndef _AUDIOPORTS_H_ #ifndef _AUDIOPORTS_H_
#define _AUDIOPORTS_H_ #define _AUDIOPORTS_H_
#include <xccompat.h> #include <xccompat.h>
#ifdef __STDC__
typedef unsigned clock;
#endif
#include "xua.h" #include "xua.h"
#ifdef __XC__ #ifdef __XC__
@@ -28,7 +31,7 @@ void ConfigAudioPorts(
in port p_bclk, in port p_bclk,
#endif #endif
#endif #endif
unsigned int divide, unsigned int curSamFreq); in port p_mclk_in, clock clk_audio_bclk, unsigned int divide, unsigned int curSamFreq);
#else #else
void ConfigAudioPorts( void ConfigAudioPorts(
@@ -51,7 +54,7 @@ void ConfigAudioPorts(
port p_bclk, port p_bclk,
#endif #endif
#endif #endif
unsigned int divide, unsigned int curSamFreq); port p_mclk_in, clock clk_audio_bclk, unsigned int divide, unsigned int curSamFreq);
#endif /* __XC__*/ #endif /* __XC__*/
@@ -76,7 +79,7 @@ void ConfigAudioPortsWrapper(
buffered in port:32 p_bclk, buffered in port:32 p_bclk,
#endif #endif
#endif #endif
unsigned int divide, unsigned curSamFreq, unsigned int dsdMode); in port p_mclk_in, clock clk_audio_bclk, unsigned int divide, unsigned curSamFreq, unsigned int dsdMode);
#else #else
void ConfigAudioPortsWrapper( void ConfigAudioPortsWrapper(
@@ -92,7 +95,7 @@ void ConfigAudioPortsWrapper(
port p_lrclk, port p_lrclk,
port p_bclk, port p_bclk,
#endif #endif
unsigned int divide, unsigned curSamFreq, unsigned int dsdMode); port p_mclk_in, clock clk_audio_bclk, unsigned int divide, unsigned curSamFreq, unsigned int dsdMode);
#endif /* __XC__*/ #endif /* __XC__*/

View File

@@ -1,4 +1,4 @@
// Copyright 2011-2021 XMOS LIMITED. // Copyright 2011-2022 XMOS LIMITED.
// This Software is subject to the terms of the XMOS Public Licence: Version 1. // This Software is subject to the terms of the XMOS Public Licence: Version 1.
#include <xs1.h> #include <xs1.h>
#include <platform.h> #include <platform.h>
@@ -6,11 +6,9 @@
#include "xua.h" #include "xua.h"
#include "audioports.h" #include "audioports.h"
//extern in port p_mclk_in;
extern in port p_mclk_in;
extern clock clk_audio_mclk; extern clock clk_audio_mclk;
extern clock clk_audio_bclk; //extern clock clk_audio_bclk;
void ConfigAudioPorts( void ConfigAudioPorts(
#if (I2S_CHANS_DAC != 0) || (DSD_CHANS_DAC != 0) #if (I2S_CHANS_DAC != 0) || (DSD_CHANS_DAC != 0)
@@ -32,7 +30,7 @@ void ConfigAudioPorts(
in port p_bclk, in port p_bclk,
#endif #endif
#endif #endif
unsigned int divide, unsigned curSamFreq) in port p_mclk_in, clock clk_audio_bclk, unsigned int divide, unsigned curSamFreq)
{ {
#if (I2S_CHANS_DAC != 0) || (I2S_CHANS_ADC != 0) #if (I2S_CHANS_DAC != 0) || (I2S_CHANS_ADC != 0)

View File

@@ -34,3 +34,4 @@ pytest-xdist==1.34.0
# of its own setup.py file, then this list must include an entry for that # of its own setup.py file, then this list must include an entry for that
# setup.py file, e.g., '-e .' or '-e ./python' (without the quotes). # setup.py file, e.g., '-e .' or '-e ./python' (without the quotes).
-e ./python -e ./python
-e ./../test_support

24
tests/conftest.py Normal file
View File

@@ -0,0 +1,24 @@
# Copyright 2022 XMOS LIMITED.
# This Software is subject to the terms of the XMOS Public Licence: Version 1.
import pytest
def pytest_addoption(parser):
parser.addoption(
"--enabletracing",
action="store_true",
default=False,
help="Run tests with instruction tracing",
)
parser.addoption(
"--enablevcdtracing",
action="store_true",
default=False,
help="Run tests with vcd tracing",
)
@pytest.fixture
def options(request):
yield request.config.option

View File

@@ -0,0 +1,81 @@
# Copyright 2018-2022 XMOS LIMITED.
# This Software is subject to the terms of the XMOS Public Licence: Version 1.
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(
pcm_format, i2s_role, channel_count, sample_rate, test_file, options, capfd
):
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"
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_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 = [
"--max-cycles",
str(max_cycles),
"--plugin",
"LoopbackPort.dll",
loopback_args,
]
result = Pyxsim.run_on_simulator(
binary, simthreads=[], tester=tester, simargs=simargs, capfd=capfd
)
return result
@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, options, capfd
):
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")
result = do_test(
pcm_format, i2s_role, channel_count, sample_rate, test_file, options, capfd
)
assert result

View File

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

View File

@@ -1,4 +1,4 @@
// Copyright 2016-2021 XMOS LIMITED. // Copyright 2016-2022 XMOS LIMITED.
// This Software is subject to the terms of the XMOS Public Licence: Version 1. // This Software is subject to the terms of the XMOS Public Licence: Version 1.
#ifndef __usb_device_h__ #ifndef __usb_device_h__
#define __usb_device_h__ #define __usb_device_h__

View File

@@ -1,4 +1,4 @@
// Copyright 2018-2021 XMOS LIMITED. // Copyright 2018-2022 XMOS LIMITED.
// This Software is subject to the terms of the XMOS Public Licence: Version 1. // This Software is subject to the terms of the XMOS Public Licence: Version 1.
#if 0 #if 0
#include <xs1.h> #include <xs1.h>

View File

@@ -1,4 +1,4 @@
// Copyright 2018-2021 XMOS LIMITED. // Copyright 2018-2022 XMOS LIMITED.
// This Software is subject to the terms of the XMOS Public Licence: Version 1. // This Software is subject to the terms of the XMOS Public Licence: Version 1.
#define CS2100_I2C_DEVICE_ADDR (0x9c>>1) #define CS2100_I2C_DEVICE_ADDR (0x9c>>1)

View File

@@ -1,4 +1,4 @@
// Copyright 2017-2021 XMOS LIMITED. // Copyright 2017-2022 XMOS LIMITED.
// This Software is subject to the terms of the XMOS Public Licence: Version 1. // This Software is subject to the terms of the XMOS Public Licence: Version 1.
#ifndef CS4384_H_ #ifndef CS4384_H_
#define CS4384_H_ #define CS4384_H_

View File

@@ -1,4 +1,4 @@
// Copyright 2017-2021 XMOS LIMITED. // Copyright 2017-2022 XMOS LIMITED.
// This Software is subject to the terms of the XMOS Public Licence: Version 1. // This Software is subject to the terms of the XMOS Public Licence: Version 1.
#ifndef _CS5368_H_ #ifndef _CS5368_H_
#define _CS5368_H_ #define _CS5368_H_

View File

@@ -1,4 +1,4 @@
// Copyright 2016-2021 XMOS LIMITED. // Copyright 2016-2022 XMOS LIMITED.
// This Software is subject to the terms of the XMOS Public Licence: Version 1. // This Software is subject to the terms of the XMOS Public Licence: Version 1.
#ifdef HARDWARE #ifdef HARDWARE
#include <xs1.h> #include <xs1.h>

View File

@@ -1,4 +1,4 @@
// Copyright 2016-2021 XMOS LIMITED. // Copyright 2016-2022 XMOS LIMITED.
// This Software is subject to the terms of the XMOS Public Licence: Version 1. // This Software is subject to the terms of the XMOS Public Licence: Version 1.
#ifndef __gpio_access_h__ #ifndef __gpio_access_h__
#define __gpio_access_h__ #define __gpio_access_h__

View File

@@ -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. // This Software is subject to the terms of the XMOS Public Licence: Version 1.
#ifndef __custom_defines_h__ #ifndef _XUA_CONF_H_
#define __custom_defines_h__ #define _XUA_CONF_H_
#define EXCLUDE_USB_AUDIO_MAIN #define EXCLUDE_USB_AUDIO_MAIN
#define XUA_NUM_PDM_MICS 0 #define XUA_NUM_PDM_MICS 0
#define XUD_TILE 1 #define XUD_TILE 1
#define AUDIO_IO_TILE 0 #define AUDIO_IO_TILE 0
#define MIXER 0 #define MIXER 0
#ifndef MCLK_441
#define MCLK_441 (512 * 44100) #define MCLK_441 (512 * 44100)
#endif
#ifndef MCLK_48
#define MCLK_48 (512 * 48000) #define MCLK_48 (512 * 48000)
#define MIN_FREQ 44100 #endif
#define MAX_FREQ 192000
#define MIN_FREQ (44100)
#define MAX_FREQ (192000)
#define SPDIF_TX_INDEX 0 #define SPDIF_TX_INDEX 0
#define VENDOR_STR "XMOS" #define VENDOR_STR "XMOS"
#define VENDOR_ID 0x20B1 #define VENDOR_ID 0x20B1
@@ -26,4 +33,4 @@
#define MIC_DUAL_ENABLED 1 //Use single thread, dual PDM mic #define MIC_DUAL_ENABLED 1 //Use single thread, dual PDM mic
#define XUA_MIC_FRAME_SIZE 240 #define XUA_MIC_FRAME_SIZE 240
#endif // __custom_defines_h__ #endif

View File

@@ -0,0 +1,58 @@
# Copyright 2022 XMOS LIMITED.
# This Software is subject to the terms of the XMOS Public Licence: Version 1.
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(bus_speed, test_file, options, capfd):
testname, _ = os.path.splitext(os.path.basename(test_file))
binary = f"{testname}/bin/{bus_speed}/{testname}_{bus_speed}.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
@pytest.mark.parametrize("bus_speed", ["FS", "HS"])
def test_sync_clk_basic(bus_speed, test_file, options, capfd):
result = do_test(bus_speed, test_file, options, capfd)
assert result

View File

@@ -0,0 +1,17 @@
TEST_FLAGS ?=
XCC_FLAGS_HS = -O3 -g -DXUD_CORE_CLOCK=600 -save-temps -DUSB_TILE=tile[0] -DLOCAL_CLOCK_INCREMENT=10000 -DLOCAL_CLOCK_MARGIN=100 \
-DBUS_SPEED=2 \
$(TEST_FLAGS)
XCC_FLAGS_FS = -O3 -g -DXUD_CORE_CLOCK=600 -save-temps -DUSB_TILE=tile[0] -DLOCAL_CLOCK_INCREMENT=10000 -DLOCAL_CLOCK_MARGIN=100 \
-DBUS_SPEED=1 \
$(TEST_FLAGS)
TARGET = test_xs3_600.xn
USED_MODULES = lib_xua
XMOS_MAKE_PATH ?= ../..
-include $(XMOS_MAKE_PATH)/xcommon/module_xcommon/build/Makefile.common

View File

@@ -0,0 +1,196 @@
// Copyright 2022 XMOS LIMITED.
// This Software is subject to the terms of the XMOS Public Licence: Version 1.
/* Simple test to ensure reference clock to CS2100 device continues when SOF clock not available
* Note, this test uses "nice" numbers (i.e. MISSIG_SOFS %8 == 0) and therefore doesn't check
* for a graceful change over from internal to SOF clock
*/
#include "platform.h"
#include "xua.h"
#include "print.h"
#include "xud.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; /* Note, this is externally looped back using the loopback plugin */
/* Purely for debug/viewing on VCD */
out port p_test0 = XS1_PORT_1C;
out port p_test1 = XS1_PORT_1D;
#ifndef BUS_SPEED
#error BUS_SPEED should be defined
#endif
/* To speed this test up we divide all delays by 10. This is also the case for the delays in the clock generation code */
#if(BUS_SPEED == 2) // XUD_SPEED_HS
#define SOF_PERIOD_TICKS (12500/10)
#define SOF_DIVIDE (1)
#else
#define SOF_PERIOD_TICKS ((12500*8)/10)
#define SOF_DIVIDE (8)
#endif
#ifndef MISSING_SOF_PERIOD
/* By default skip a whole number of SOF periods (easy case)
* Note, app_test_sync_plugin/Makefiles sets this to something more nasty */
#define MISSING_SOF_PERIOD (8 * SOF_PERIOD_TICKS)
#endif
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 frame = 0;
/* For HS frame should only increment every 8 SOFs, but this is a "dont care" */
for(int i = 0; i < count; i++)
{
outuint(c_sof, frame++);
delay(SOF_PERIOD_TICKS);
}
}
void fake_xud(chanend c_out[], chanend c_in[], chanend c_sof)
{
timer t;
unsigned time;
/* Makes traces a bit nicer to look at */
t :> time;
t when timerafter(SOF_PERIOD_TICKS * 2) :> int x;
p_test0 <: 1;
/* 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, 32/SOF_DIVIDE);
p_test0 <: 0;
/* Sim missing SOFs */
delay(MISSING_SOF_PERIOD);
p_test0 <: 1;
driveSofs(c_sof, 16/SOF_DIVIDE);
p_test0 <: 0;
delay(MISSING_SOF_PERIOD);
p_test0 <: 1;
driveSofs(c_sof, 16/SOF_DIVIDE);
p_test0 <: 0;
}
extern XUD_BusSpeed_t g_curUsbSpeed;
#define MARGIN (1500/10)
#define EXPECTED_PERIOD (100000/10)
void checker()
{
timer t;
unsigned t0, t1;
unsigned x = 0;
int fail = 0;
p_test1 <: 1;
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 < 12; i++)
{
p_pll_loop when pinsneq(x) :> x;
t :> t0;
p_pll_loop when pinsneq(x) :> x;
t :> t1;
int period = t1-t0;
/* Check the period of the reference clock we are generating */
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");
p_test1 <: 0;
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 = BUS_SPEED;
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();
}
}

View File

@@ -0,0 +1,24 @@
<?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">
<Declarations>
<Declaration>tileref tile[2]</Declaration>
</Declarations>
<Packages>
<Package id="0" Type="XS3-UnA-1024-FB265">
<Nodes>
<Node Id="0" InPackageId="0" Type="XS3-L16A-1024" Oscillator="24MHz" SystemFrequency="600MHz" ReferenceFrequency="100MHz">
<Tile Number="0" Reference="tile[0]"/>
<Tile Number="1" Reference="tile[1]"/>
</Node>
</Nodes>
</Package>
</Packages>
<JTAGChain>
<JTAGDevice NodeId="0"/>
</JTAGChain>
</Network>

View File

@@ -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

View File

@@ -0,0 +1,12 @@
# Copyright 2022 XMOS LIMITED.
# This Software is subject to the terms of the XMOS Public Licence: Version 1.
import pytest
from test_sync_clk_basic import do_test
from test_sync_clk_basic import test_file
@pytest.mark.parametrize("bus_speed", ["FS", "HS"])
def test_sync_clk_plugin(bus_speed, test_file, options, capfd):
pytest.xfail("This is a known failure due to issue #275")
result = do_test(bus_speed, test_file, options, capfd)
assert result

View File

@@ -0,0 +1,4 @@
TEST_FLAGS = -DMISSING_SOF_PERIOD=7500
include ../test_sync_clk_basic/Makefile

View File

@@ -0,0 +1,8 @@
// Copyright 2022 XMOS LIMITED.
// This Software is subject to the terms of the XMOS Public Licence: Version 1.
/* This tests for a smooth transition from internal to SOF clock.
* Unlike test_sync_clk_basic it does not use a "nice" value for MISSING_SOFS
*/
#include "../test_sync_clk_basic/src/main.xc"

View File

@@ -0,0 +1,24 @@
<?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">
<Declarations>
<Declaration>tileref tile[2]</Declaration>
</Declarations>
<Packages>
<Package id="0" Type="XS3-UnA-1024-FB265">
<Nodes>
<Node Id="0" InPackageId="0" Type="XS3-L16A-1024" Oscillator="24MHz" SystemFrequency="600MHz" ReferenceFrequency="100MHz">
<Tile Number="0" Reference="tile[0]"/>
<Tile Number="1" Reference="tile[1]"/>
</Node>
</Nodes>
</Package>
</Packages>
<JTAGChain>
<JTAGDevice NodeId="0"/>
</JTAGChain>
</Network>

View File

@@ -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

View File

@@ -1,4 +1,4 @@
# Copyright 2021 XMOS LIMITED. # Copyright 2021-2022 XMOS LIMITED.
# This Software is subject to the terms of the XMOS Public Licence: Version 1. # This Software is subject to the terms of the XMOS Public Licence: Version 1.
from __future__ import print_function from __future__ import print_function
from builtins import str from builtins import str
@@ -6,16 +6,17 @@ import os.path
import pytest import pytest
import subprocess import subprocess
target = os.environ.get('TARGET', 'all_possible') target = os.environ.get("TARGET", "all_possible")
print("target = ", target) print("target = ", target)
def pytest_collect_file(parent, path): def pytest_collect_file(parent, path):
if(path.ext == ".xe"): if path.ext == ".xe":
if(target == 'all_possible'): if target == "all_possible":
return UnityTestSource.from_parent(parent, fspath=path) return UnityTestSource.from_parent(parent, fspath=path)
if(target == 'XCOREAI' and ('xcoreai' in path.basename)): if target == "XCOREAI" and ("xcoreai" in path.basename):
return UnityTestSource.from_parent(parent, fspath=path) return UnityTestSource.from_parent(parent, fspath=path)
if(target == 'XCORE200' and ('xcore200' in path.basename)): if target == "XCORE200" and ("xcore200" in path.basename):
return UnityTestSource.from_parent(parent, fspath=path) return UnityTestSource.from_parent(parent, fspath=path)
@@ -31,7 +32,7 @@ class UnityTestSource(pytest.File):
# |-- src/ <- Unity test functions # |-- src/ <- Unity test functions
# `-- wscript <- Build system file used to generate/build runners # `-- wscript <- Build system file used to generate/build runners
xe_name = ((os.path.basename(self.name)).split("."))[0] + ".xe" xe_name = ((os.path.basename(self.name)).split("."))[0] + ".xe"
test_bin_path = os.path.join('bin', xe_name) test_bin_path = os.path.join("bin", xe_name)
yield UnityTestExecutable.from_parent(self, name=self.name) yield UnityTestExecutable.from_parent(self, name=self.name)
@@ -46,12 +47,16 @@ class UnityTestExecutable(pytest.Item):
simulator_fail = False simulator_fail = False
test_output = None test_output = None
try: try:
if('xcore200' in self.name): if "xcore200" in self.name:
print("run axe for executable ", self.name) print("run axe for executable ", self.name)
test_output = subprocess.check_output(['axe', self.name], text=True) test_output = subprocess.check_output(["axe", self.name], text=True)
else: else:
print("run xrun for executable ", self.name) print("run xrun for executable ", self.name)
test_output = subprocess.check_output(['xrun', '--io', '--id', '0', self.name], text=True, stderr=subprocess.STDOUT) test_output = subprocess.check_output(
["xrun", "--io", "--id", "0", self.name],
text=True,
stderr=subprocess.STDOUT,
)
except subprocess.CalledProcessError as e: except subprocess.CalledProcessError as e:
# Unity exits non-zero if an assertion fails # Unity exits non-zero if an assertion fails
simulator_fail = True simulator_fail = True
@@ -59,10 +64,10 @@ class UnityTestExecutable(pytest.Item):
# Parse the Unity output # Parse the Unity output
unity_pass = False unity_pass = False
test_output = test_output.split('\n') test_output = test_output.split("\n")
for line in test_output: for line in test_output:
if 'test' in line: if "test" in line:
test_report = line.split(':') test_report = line.split(":")
# Unity output is as follows: # Unity output is as follows:
# <test_source>:<line_number>:<test_case>:PASS # <test_source>:<line_number>:<test_case>:PASS
# <test_source>:<line_number>:<test_case>:FAIL:<failure_reason> # <test_source>:<line_number>:<test_case>:FAIL:<failure_reason>
@@ -71,34 +76,43 @@ class UnityTestExecutable(pytest.Item):
test_case = test_report[2] test_case = test_report[2]
result = test_report[3] result = test_report[3]
failure_reason = None failure_reason = None
print(('\n {}()'.format(test_case)), end=' ') print(("\n {}()".format(test_case)), end=" ")
if result == 'PASS': if result == "PASS":
unity_pass = True unity_pass = True
continue continue
if result == 'FAIL': if result == "FAIL":
failure_reason = test_report[4] failure_reason = test_report[4]
print('') # Insert line break after test_case print print("") # Insert line break after test_case print
raise UnityTestException(self, {'test_source': test_source, raise UnityTestException(
'line_number': line_number, self,
'test_case': test_case, {
'failure_reason': "test_source": test_source,
failure_reason}) "line_number": line_number,
"test_case": test_case,
"failure_reason": failure_reason,
},
)
if simulator_fail: if simulator_fail:
raise Exception(self, "Simulation failed.") raise Exception(self, "Simulation failed.")
if not unity_pass: if not unity_pass:
raise Exception(self, "Unity test output not found.") raise Exception(self, "Unity test output not found.")
print('') # Insert line break after final test_case which passed print("") # Insert line break after final test_case which passed
def repr_failure(self, excinfo): def repr_failure(self, excinfo):
if isinstance(excinfo.value, UnityTestException): if isinstance(excinfo.value, UnityTestException):
return '\n'.join([str(self.parent).strip('<>'), return "\n".join(
'{}:{}:{}()'.format( [
excinfo.value[1]['test_source'], str(self.parent).strip("<>"),
excinfo.value[1]['line_number'], "{}:{}:{}()".format(
excinfo.value[1]['test_case']), excinfo.value[1]["test_source"],
'Failure reason:', excinfo.value[1]["line_number"],
excinfo.value[1]['failure_reason']]) excinfo.value[1]["test_case"],
),
"Failure reason:",
excinfo.value[1]["failure_reason"],
]
)
else: else:
return str(excinfo.value) return str(excinfo.value)

View File

@@ -1,40 +1,43 @@
# Copyright 2021 XMOS LIMITED. # Copyright 2021-2022 XMOS LIMITED.
# This Software is subject to the terms of the XMOS Public Licence: Version 1. # This Software is subject to the terms of the XMOS Public Licence: Version 1.
import glob import glob
import os.path import os.path
import subprocess import subprocess
import sys import sys
UNITY_TEST_DIR = 'src' UNITY_TEST_DIR = "src"
UNITY_TEST_PREFIX = 'test_' UNITY_TEST_PREFIX = "test_"
UNITY_RUNNER_DIR = 'runners' UNITY_RUNNER_DIR = "runners"
UNITY_RUNNER_SUFFIX = '_Runner' UNITY_RUNNER_SUFFIX = "_Runner"
project_root = os.path.join('..', '..', '..') project_root = os.path.join("..", "..", "..")
def get_ruby(): def get_ruby():
""" """
Check ruby is avaliable and return the command to invoke it. Check ruby is avaliable and return the command to invoke it.
""" """
interpreter_name = 'ruby' interpreter_name = "ruby"
try: try:
dev_null = open(os.devnull, 'w') dev_null = open(os.devnull, "w")
# Call the version command to check the interpreter can be run # Call the version command to check the interpreter can be run
subprocess.check_call([interpreter_name, '--version'], subprocess.check_call(
stdout=dev_null, [interpreter_name, "--version"], stdout=dev_null, close_fds=True
close_fds=True) )
except OSError as e: except OSError as e:
print("Failed to run Ruby interpreter: {}".format(e), file=sys.stderr) print("Failed to run Ruby interpreter: {}".format(e), file=sys.stderr)
exit(1) # TODO: Check this is the correct way to kill xwaf on error exit(1) # TODO: Check this is the correct way to kill xwaf on error
return interpreter_name return interpreter_name
def get_unity_runner_generator(project_root_path): def get_unity_runner_generator(project_root_path):
""" """
Check the Unity generate_test_runner script is avaliable, and return the Check the Unity generate_test_runner script is avaliable, and return the
path to it. path to it.
""" """
unity_runner_generator = os.path.join( unity_runner_generator = os.path.join(
project_root_path, 'Unity', 'auto', 'generate_test_runner.rb') project_root_path, "Unity", "auto", "generate_test_runner.rb"
)
if not os.path.exists(unity_runner_generator): if not os.path.exists(unity_runner_generator):
print("Unity repo not found in workspace", file=sys.stderr) print("Unity repo not found in workspace", file=sys.stderr)
exit(1) # TODO: Check this is the correct way to kill xwaf on error exit(1) # TODO: Check this is the correct way to kill xwaf on error
@@ -52,32 +55,41 @@ def get_file_type(filename):
""" """
Return the extension from the filename. Return the extension from the filename.
""" """
return filename.rsplit('.')[-1:][0] return filename.rsplit(".")[-1:][0]
def generate_unity_runner(project_root_path, unity_test_path, unity_runner_dir, def generate_unity_runner(
unity_runner_suffix): project_root_path, unity_test_path, unity_runner_dir, unity_runner_suffix
):
""" """
Invoke the Unity runner generation script for the given test file, and Invoke the Unity runner generation script for the given test file, and
return the path to the generated file. The output directory will be created return the path to the generated file. The output directory will be created
if it does not already exist. if it does not already exist.
""" """
runner_path = os.path.join(os.path.join(unity_runner_dir, get_test_name(unity_test_path))) runner_path = os.path.join(
os.path.join(unity_runner_dir, get_test_name(unity_test_path))
)
if not os.path.exists(runner_path): if not os.path.exists(runner_path):
os.makedirs(runner_path) os.makedirs(runner_path)
unity_runner_path = os.path.join( unity_runner_path = os.path.join(
runner_path, get_test_name(unity_test_path) + unity_runner_suffix runner_path, get_test_name(unity_test_path) + unity_runner_suffix + "." + "c"
+ '.' + 'c') )
try: try:
subprocess.check_call([get_ruby(), subprocess.check_call(
get_unity_runner_generator(project_root_path), [
unity_test_path, get_ruby(),
unity_runner_path]) get_unity_runner_generator(project_root_path),
unity_test_path,
unity_runner_path,
]
)
except OSError as e: except OSError as e:
print("Ruby generator failed for {}\n\t{}".format(unity_test_path, e), print(
file=sys.stderr) "Ruby generator failed for {}\n\t{}".format(unity_test_path, e),
file=sys.stderr,
)
exit(1) # TODO: Check this is the correct way to kill xwaf on error exit(1) # TODO: Check this is the correct way to kill xwaf on error
@@ -86,7 +98,7 @@ def find_unity_test_paths(unity_test_dir, unity_test_prefix):
Return a list of all file paths with the unity_test_prefix found in the Return a list of all file paths with the unity_test_prefix found in the
unity_test_dir. unity_test_dir.
""" """
return glob.glob(os.path.join(unity_test_dir, unity_test_prefix+'*')) return glob.glob(os.path.join(unity_test_dir, unity_test_prefix + "*"))
def find_unity_tests(unity_test_dir, unity_test_prefix): def find_unity_tests(unity_test_dir, unity_test_prefix):
@@ -95,25 +107,27 @@ def find_unity_tests(unity_test_dir, unity_test_prefix):
unity_test_prefix found in the unity_test_dir. unity_test_prefix found in the unity_test_dir.
""" """
unity_test_paths = find_unity_test_paths(unity_test_dir, unity_test_prefix) unity_test_paths = find_unity_test_paths(unity_test_dir, unity_test_prefix)
print('unity_test_paths = ', unity_test_paths) print("unity_test_paths = ", unity_test_paths)
return {get_test_name(path): get_file_type(path) return {get_test_name(path): get_file_type(path) for path in unity_test_paths}
for path in unity_test_paths}
def find_unity_test_paths(unity_test_dir, unity_test_prefix): def find_unity_test_paths(unity_test_dir, unity_test_prefix):
""" """
Return a list of all file paths with the unity_test_prefix found in the Return a list of all file paths with the unity_test_prefix found in the
unity_test_dir. unity_test_dir.
""" """
return glob.glob(os.path.join(unity_test_dir, unity_test_prefix+'*')) return glob.glob(os.path.join(unity_test_dir, unity_test_prefix + "*"))
def generate_runners(): def generate_runners():
UNITY_TESTS = find_unity_tests(UNITY_TEST_DIR, UNITY_TEST_PREFIX) UNITY_TESTS = find_unity_tests(UNITY_TEST_DIR, UNITY_TEST_PREFIX)
print('UNITY_TESTS = ',UNITY_TESTS) print("UNITY_TESTS = ", UNITY_TESTS)
unity_test_paths = find_unity_test_paths(UNITY_TEST_DIR, UNITY_TEST_PREFIX) unity_test_paths = find_unity_test_paths(UNITY_TEST_DIR, UNITY_TEST_PREFIX)
print('unity_test_paths = ',unity_test_paths) print("unity_test_paths = ", unity_test_paths)
for unity_test_path in unity_test_paths: for unity_test_path in unity_test_paths:
generate_unity_runner(project_root, unity_test_path, UNITY_RUNNER_DIR, UNITY_RUNNER_SUFFIX) generate_unity_runner(
project_root, unity_test_path, UNITY_RUNNER_DIR, UNITY_RUNNER_SUFFIX
)
if __name__ == "__main__": if __name__ == "__main__":