forked from PAWPAW-Mirror/lib_xua
4
.gitignore
vendored
4
.gitignore
vendored
@@ -48,3 +48,7 @@ host_usb_mixer_control/xmos_mixer
|
|||||||
**/.vscode/**
|
**/.vscode/**
|
||||||
**.egg-info
|
**.egg-info
|
||||||
*tests/logs/*
|
*tests/logs/*
|
||||||
|
midi_tx_cmds.txt
|
||||||
|
midi_rx_cmds.txt
|
||||||
|
trace.txt
|
||||||
|
tests/xua_unit_tests/src.runners
|
||||||
|
|||||||
19
Jenkinsfile
vendored
19
Jenkinsfile
vendored
@@ -1,4 +1,4 @@
|
|||||||
@Library('xmos_jenkins_shared_library@v0.24.0') _
|
@Library('xmos_jenkins_shared_library@v0.27.0') _
|
||||||
|
|
||||||
getApproval()
|
getApproval()
|
||||||
|
|
||||||
@@ -7,6 +7,7 @@ pipeline {
|
|||||||
environment {
|
environment {
|
||||||
REPO = 'lib_xua'
|
REPO = 'lib_xua'
|
||||||
VIEW = getViewName(REPO)
|
VIEW = getViewName(REPO)
|
||||||
|
TOOLS_VERSION = "15.2.1" // For unit tests
|
||||||
}
|
}
|
||||||
options {
|
options {
|
||||||
skipDefaultCheckout()
|
skipDefaultCheckout()
|
||||||
@@ -35,7 +36,8 @@ pipeline {
|
|||||||
dir("${REPO}/tests"){
|
dir("${REPO}/tests"){
|
||||||
viewEnv(){
|
viewEnv(){
|
||||||
withVenv{
|
withVenv{
|
||||||
runPytest('--numprocesses=4')
|
sh "xmake -C test_midi -j" // Xdist does not like building so do here
|
||||||
|
runPytest('--numprocesses=auto -vvv')
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -43,13 +45,13 @@ pipeline {
|
|||||||
}
|
}
|
||||||
stage('Unity tests') {
|
stage('Unity tests') {
|
||||||
steps {
|
steps {
|
||||||
dir("${REPO}") {
|
dir("${REPO}/tests/xua_unit_tests") {
|
||||||
dir('tests') {
|
withTools("${env.TOOLS_VERSION}") {
|
||||||
dir('xua_unit_tests') {
|
|
||||||
withVenv {
|
withVenv {
|
||||||
runWaf('.', "configure clean build --target=xcore200")
|
withEnv(["XMOS_CMAKE_PATH=${WORKSPACE}/xcommon_cmake"]) {
|
||||||
viewEnv() {
|
sh "cmake -G 'Unix Makefiles' -B build"
|
||||||
runPython("TARGET=XCORE200 pytest -s --junitxml=pytest_unity.xml")
|
sh 'xmake -C build -j'
|
||||||
|
runPython("pytest -s --junitxml=pytest_unity.xml")
|
||||||
junit "pytest_unity.xml"
|
junit "pytest_unity.xml"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -59,7 +61,6 @@ pipeline {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
stage('xCORE builds') {
|
stage('xCORE builds') {
|
||||||
steps {
|
steps {
|
||||||
dir("${REPO}") {
|
dir("${REPO}") {
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
// Copyright 2011-2021 XMOS LIMITED.
|
// Copyright 2011-2024 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 MIDIINPARSE_XH
|
#ifndef MIDIINPARSE_XH
|
||||||
#define MIDIINPARSE_XH
|
#define MIDIINPARSE_XH
|
||||||
@@ -19,8 +19,11 @@ struct midi_in_parse_state {
|
|||||||
unsigned codeIndexNumber;
|
unsigned codeIndexNumber;
|
||||||
};
|
};
|
||||||
|
|
||||||
void dump_midi_in_parse_state(struct midi_in_parse_state &s);
|
|
||||||
|
#ifdef __XC__
|
||||||
void reset_midi_state(struct midi_in_parse_state &mips);
|
void reset_midi_state(struct midi_in_parse_state &mips);
|
||||||
|
void dump_midi_in_parse_state(struct midi_in_parse_state &s);
|
||||||
{unsigned int , unsigned int} midi_in_parse(struct midi_in_parse_state &mips, unsigned cable_number, unsigned char b);
|
{unsigned int , unsigned int} midi_in_parse(struct midi_in_parse_state &mips, unsigned cable_number, unsigned char b);
|
||||||
|
#endif
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
// Copyright 2013-2021 XMOS LIMITED.
|
// Copyright 2013-2024 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 QUEUE_H_
|
#ifndef QUEUE_H_
|
||||||
#define QUEUE_H_
|
#define QUEUE_H_
|
||||||
@@ -14,6 +14,8 @@ typedef struct queue_t {
|
|||||||
unsigned mask;
|
unsigned mask;
|
||||||
} queue_t;
|
} queue_t;
|
||||||
|
|
||||||
|
#ifdef __XC__
|
||||||
|
|
||||||
inline int is_power_of_2(unsigned x) {
|
inline int is_power_of_2(unsigned x) {
|
||||||
return x != 0 && (x & (x - 1)) == 0;
|
return x != 0 && (x & (x - 1)) == 0;
|
||||||
}
|
}
|
||||||
@@ -64,4 +66,6 @@ inline unsigned queue_space(const queue_t &q) {
|
|||||||
return q.size - queue_items(q);
|
return q.size - queue_items(q);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#endif // __XC__
|
||||||
|
|
||||||
#endif /* QUEUE_H_ */
|
#endif /* QUEUE_H_ */
|
||||||
|
|||||||
@@ -1,8 +1,11 @@
|
|||||||
# Copyright 2022-2023 XMOS LIMITED.
|
# Copyright 2022-2024 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 pytest
|
import pytest
|
||||||
import time
|
import time
|
||||||
|
import Pyxsim
|
||||||
|
from pathlib import Path
|
||||||
|
from midi_test_helpers import MIDI_TEST_CONFIGS
|
||||||
|
import subprocess
|
||||||
|
|
||||||
@pytest.fixture()
|
@pytest.fixture()
|
||||||
def test_file(request):
|
def test_file(request):
|
||||||
@@ -39,3 +42,16 @@ def pytest_addoption(parser):
|
|||||||
@pytest.fixture
|
@pytest.fixture
|
||||||
def options(request):
|
def options(request):
|
||||||
yield request.config.option
|
yield request.config.option
|
||||||
|
|
||||||
|
# We use the same binary multiple times so just build once for all MIDI tests
|
||||||
|
@pytest.fixture(scope="session")
|
||||||
|
def build_midi():
|
||||||
|
cmd = "xmake -C test_midi -j"
|
||||||
|
# result = subprocess.run(cmd, capture_output=True, text=True, shell=True)
|
||||||
|
# return_code = result.returncode
|
||||||
|
return_code = 0
|
||||||
|
|
||||||
|
assert return_code == 0, f"{result.stderr}\n{result.stdout}"
|
||||||
|
|
||||||
|
return str(Path(__file__).parent / f"test_midi/bin/")
|
||||||
|
|
||||||
|
|||||||
81
tests/midi_test_helpers.py
Normal file
81
tests/midi_test_helpers.py
Normal file
@@ -0,0 +1,81 @@
|
|||||||
|
# Copyright 2024 XMOS LIMITED.
|
||||||
|
# This Software is subject to the terms of the XMOS Public Licence: Version 1.
|
||||||
|
|
||||||
|
import contextlib
|
||||||
|
import os
|
||||||
|
import shutil
|
||||||
|
import tempfile
|
||||||
|
|
||||||
|
MIDI_TEST_CONFIGS = ["xs2", "xs3"]
|
||||||
|
MIDI_RATE = 31250
|
||||||
|
|
||||||
|
@contextlib.contextmanager
|
||||||
|
def cd(newdir, cleanup=lambda: True):
|
||||||
|
prevdir = os.getcwd()
|
||||||
|
os.chdir(os.path.expanduser(newdir))
|
||||||
|
try:
|
||||||
|
yield
|
||||||
|
finally:
|
||||||
|
os.chdir(prevdir)
|
||||||
|
cleanup()
|
||||||
|
|
||||||
|
@contextlib.contextmanager
|
||||||
|
def tempdir():
|
||||||
|
dirpath = tempfile.mkdtemp(dir=os.getcwd())
|
||||||
|
def cleanup():
|
||||||
|
shutil.rmtree(dirpath)
|
||||||
|
with cd(dirpath, cleanup):
|
||||||
|
yield dirpath
|
||||||
|
|
||||||
|
class midi_expect_tx:
|
||||||
|
def __init(self):
|
||||||
|
pass
|
||||||
|
|
||||||
|
def expect(self, commands):
|
||||||
|
expected = ""
|
||||||
|
for command in commands:
|
||||||
|
while len(command) < 3:
|
||||||
|
command.append(0)
|
||||||
|
expected += "uart_tx_checker: " + " ".join([f"0x{byte:02x}" for byte in command]) + "\n"
|
||||||
|
|
||||||
|
return expected + "\n"
|
||||||
|
|
||||||
|
class midi_expect_rx:
|
||||||
|
def __init(self):
|
||||||
|
pass
|
||||||
|
|
||||||
|
def expect(self, commands):
|
||||||
|
expected = ""
|
||||||
|
for command in commands:
|
||||||
|
while len(command) < 3:
|
||||||
|
command.append(0)
|
||||||
|
expected += "dut_midi_rx: " + " ".join([f"{byte}" for byte in command]) + "\n"
|
||||||
|
|
||||||
|
return expected + "\n"
|
||||||
|
|
||||||
|
midi_tx_file = "midi_tx_cmds.txt"
|
||||||
|
midi_rx_file = "midi_rx_cmds.txt"
|
||||||
|
|
||||||
|
def create_midi_tx_file(commands=None):
|
||||||
|
with open(midi_tx_file, "wt") as mt:
|
||||||
|
if commands is None:
|
||||||
|
return
|
||||||
|
for command in commands:
|
||||||
|
while len(command) < 3:
|
||||||
|
command.append(0)
|
||||||
|
text = " ".join([str(byte) for byte in command]) + "\n"
|
||||||
|
mt.write(text)
|
||||||
|
|
||||||
|
def create_midi_rx_file(num_commands=0):
|
||||||
|
with open(midi_rx_file, "wt") as mr:
|
||||||
|
text = f"{num_commands}\n"
|
||||||
|
mr.write(text)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# Test/dev only
|
||||||
|
if __name__ == "__main__":
|
||||||
|
with tempdir() as td:
|
||||||
|
print(td)
|
||||||
|
create_midi_tx_file()
|
||||||
|
input("PRESS ENTER TO CONTINUE")
|
||||||
37
tests/test_midi/Makefile
Normal file
37
tests/test_midi/Makefile
Normal file
@@ -0,0 +1,37 @@
|
|||||||
|
# The TARGET variable determines what target system the application is
|
||||||
|
# compiled for. It either refers to an XN file in the source directories
|
||||||
|
# or a valid argument for the --target option when compiling.
|
||||||
|
|
||||||
|
ifeq ($(CONFIG), xs2)
|
||||||
|
TARGET = XCORE-200-EXPLORER
|
||||||
|
else
|
||||||
|
TARGET = XCORE-AI-EXPLORER #for xs3 and also loopback test
|
||||||
|
endif
|
||||||
|
|
||||||
|
# The APP_NAME variable determines the name of the final .xe file. It should
|
||||||
|
# not include the .xe postfix. If left blank the name will default to
|
||||||
|
# the project name
|
||||||
|
|
||||||
|
APP_NAME =
|
||||||
|
|
||||||
|
# The flags passed to xcc when building the application
|
||||||
|
# You can also set the following to override flags for a particular language:
|
||||||
|
#
|
||||||
|
# XCC_XC_FLAGS, XCC_C_FLAGS, XCC_ASM_FLAGS, XCC_CPP_FLAGS
|
||||||
|
#
|
||||||
|
# If the variable XCC_MAP_FLAGS is set it overrides the flags passed to
|
||||||
|
# xcc for the final link (mapping) stage.
|
||||||
|
XCC_FLAGS_xs2 = $(EXTRA_BUILD_FLAGS) -O2 -g
|
||||||
|
XCC_FLAGS_xs3 = $(EXTRA_BUILD_FLAGS) -O2 -g
|
||||||
|
XCC_FLAGS_LOOPBACK = $(EXTRA_BUILD_FLAGS) -O2 -g -DMIDI_LOOPBACK=1
|
||||||
|
|
||||||
|
# The USED_MODULES variable lists other module used by the application.
|
||||||
|
USED_MODULES = lib_xua
|
||||||
|
|
||||||
|
|
||||||
|
#=============================================================================
|
||||||
|
# The following part of the Makefile includes the common build infrastructure
|
||||||
|
# for compiling XMOS applications. You should not need to edit below here.
|
||||||
|
|
||||||
|
XMOS_MAKE_PATH ?= ../..
|
||||||
|
include $(XMOS_MAKE_PATH)/xcommon/module_xcommon/build/Makefile.common
|
||||||
186
tests/test_midi/src/app_midi_simple.xc
Normal file
186
tests/test_midi/src/app_midi_simple.xc
Normal file
@@ -0,0 +1,186 @@
|
|||||||
|
// Copyright 2024 XMOS LIMITED.
|
||||||
|
// This Software is subject to the terms of the XMOS Public Licence: Version 1.
|
||||||
|
|
||||||
|
/* A very simple *example* of a USB audio application (and as such is un-verified for production)
|
||||||
|
*
|
||||||
|
* It uses the main blocks from the lib_xua
|
||||||
|
*
|
||||||
|
* - 2 channels out I2S only
|
||||||
|
* - No DFU
|
||||||
|
* - I2S only
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <xs1.h>
|
||||||
|
#include <platform.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <xclib.h>
|
||||||
|
|
||||||
|
#include "xua.h"
|
||||||
|
#include "xud_device.h"
|
||||||
|
#include "midiinparse.h"
|
||||||
|
#include "midioutparse.h"
|
||||||
|
|
||||||
|
on tile[MIDI_TILE] : port p_midi_tx = XS1_PORT_4C;
|
||||||
|
#if(MIDI_RX_PORT_WIDTH == 4)
|
||||||
|
on tile[MIDI_TILE] : buffered in port:4 p_midi_rx = XS1_PORT_1F;
|
||||||
|
#elif(MIDI_RX_PORT_WIDTH == 1)
|
||||||
|
on tile[MIDI_TILE] : buffered in port:1 p_midi_rx = XS1_PORT_1F;
|
||||||
|
#endif
|
||||||
|
#define CLKBLK_MIDI XS1_CLKBLK_2
|
||||||
|
on tile[MIDI_TILE] : clock clk_midi = CLKBLK_MIDI;
|
||||||
|
|
||||||
|
#define MAX_TEST_COMMANDS 100
|
||||||
|
#define TEST_COMMAND_FILE_TX "midi_tx_cmds.txt"
|
||||||
|
#define TEST_COMMAND_FILE_RX "midi_rx_cmds.txt"
|
||||||
|
|
||||||
|
#define DEBUG 0 // Prints for debugging. Turn off for actual test
|
||||||
|
|
||||||
|
#if DEBUG
|
||||||
|
#define dprintf(...) printf(__VA_ARGS__)
|
||||||
|
#else
|
||||||
|
#define dprintf(...)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* See hwsupport.xc */
|
||||||
|
void board_setup();
|
||||||
|
|
||||||
|
#define CABLE_NUM 0
|
||||||
|
|
||||||
|
|
||||||
|
unsigned midi_in_parse_helper(unsigned midi[3]){
|
||||||
|
struct midi_in_parse_state m_state;
|
||||||
|
reset_midi_state(m_state);
|
||||||
|
|
||||||
|
unsigned valid = 0;
|
||||||
|
unsigned packed = 0;
|
||||||
|
|
||||||
|
for(int i = 0; i < 3; i++){
|
||||||
|
dprintf("Packing byte %d 0x%x\n", i, midi[i]);
|
||||||
|
{valid, packed} = midi_in_parse(m_state, CABLE_NUM, midi[i]);
|
||||||
|
if(valid){
|
||||||
|
return packed;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
{unsigned, unsigned} read_config_file(uint8_t commands[MAX_TEST_COMMANDS][3])
|
||||||
|
{
|
||||||
|
unsigned tx_line_count = 0;
|
||||||
|
|
||||||
|
FILE * movable fptr_tx = fopen(TEST_COMMAND_FILE_TX,"rt");
|
||||||
|
if (fptr_tx == NULL) {
|
||||||
|
dprintf("WARNING: TX command file %s not found or unable to open.\n", TEST_COMMAND_FILE_TX);
|
||||||
|
} else {
|
||||||
|
unsigned a,b,c;
|
||||||
|
while (fscanf(fptr_tx, "%u %u %u\n", &a, &b, &c) == 3) {
|
||||||
|
commands[tx_line_count][0] = a;
|
||||||
|
commands[tx_line_count][1] = b;
|
||||||
|
commands[tx_line_count][2] = c;
|
||||||
|
//printf("Line %u params: 0x%x 0x%x 0x%x\n", tx_line_count, commands[tx_line_count][0], commands[tx_line_count][1], commands[tx_line_count][2]);
|
||||||
|
tx_line_count++;
|
||||||
|
if(tx_line_count > MAX_TEST_COMMANDS){
|
||||||
|
printf("ERROR: Too many lines in TX command file\n");
|
||||||
|
tx_line_count = MAX_TEST_COMMANDS;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fclose(move(fptr_tx));
|
||||||
|
|
||||||
|
|
||||||
|
unsigned rx_cmd_count = 0;
|
||||||
|
|
||||||
|
FILE * movable fptr_rx = fopen(TEST_COMMAND_FILE_RX,"rt");
|
||||||
|
if (fptr_rx == NULL) {
|
||||||
|
dprintf("WARNING: RX command file %s not found or unable to open.\n", TEST_COMMAND_FILE_RX);
|
||||||
|
} else {
|
||||||
|
if(fscanf(fptr_rx, "%u\n", &rx_cmd_count) != 1){
|
||||||
|
printf("ERROR: Not enough or too many items in RX command file line\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fclose(move(fptr_rx));
|
||||||
|
|
||||||
|
return {tx_line_count, rx_cmd_count};
|
||||||
|
}
|
||||||
|
|
||||||
|
void test(chanend c_midi){
|
||||||
|
uint8_t commands[MAX_TEST_COMMANDS][3] = {{0}};
|
||||||
|
unsigned num_to_tx = 0;
|
||||||
|
unsigned num_to_rx = 0;
|
||||||
|
{num_to_tx, num_to_rx} = read_config_file(commands);
|
||||||
|
dprintf("Sending %u MIDI command line(s) and receiving %u MIDI command(s)\n", num_to_tx, num_to_rx);
|
||||||
|
|
||||||
|
// For MIDI Rx
|
||||||
|
int is_ack;
|
||||||
|
unsigned rx_packet;
|
||||||
|
|
||||||
|
// Counters for Rx and Tx
|
||||||
|
unsigned tx_cmd_count = 0;
|
||||||
|
unsigned rx_cmd_count = 0;
|
||||||
|
|
||||||
|
timer tmr;
|
||||||
|
|
||||||
|
int t_tx; // Used for delay between Txs
|
||||||
|
int tx_end; // Used to wait for packet to have fully left
|
||||||
|
tmr :> t_tx;
|
||||||
|
tmr :> tx_end;
|
||||||
|
|
||||||
|
const int max_tx_time = XS1_TIMER_HZ / 31250 * 3 * (8 + 1 + 1); // 30 bits at 31.25 kbps is 0.96ms
|
||||||
|
const int tx_interval = XS1_TIMER_HZ / 8000; // SoF rate on HS
|
||||||
|
tx_end += max_tx_time; // One whole packet
|
||||||
|
|
||||||
|
while(tx_cmd_count < num_to_tx || rx_cmd_count < num_to_rx ){
|
||||||
|
select{
|
||||||
|
case midi_get_ack_or_data(c_midi, is_ack, rx_packet):
|
||||||
|
if(is_ack){
|
||||||
|
dprintf("ACK from Tx\n");
|
||||||
|
tx_cmd_count++;
|
||||||
|
} else {
|
||||||
|
unsigned midi_data[3] = {0};
|
||||||
|
unsigned byte_count = 0;
|
||||||
|
{midi_data[0], midi_data[1], midi_data[2], byte_count} = midi_out_parse(byterev(rx_packet));
|
||||||
|
// Note this needs to always print for capfd in pytest to pick it up
|
||||||
|
printf("dut_midi_rx: %u %u %u\n", midi_data[0], midi_data[1], midi_data[2]);
|
||||||
|
rx_cmd_count++;
|
||||||
|
midi_send_ack(c_midi);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case tx_cmd_count < num_to_tx => tmr when timerafter(t_tx) :> int _:
|
||||||
|
unsigned midi[] = {commands[tx_cmd_count][0], commands[tx_cmd_count][1], commands[tx_cmd_count][2]};
|
||||||
|
unsigned tx_packet = midi_in_parse_helper(midi);
|
||||||
|
outuint(c_midi, byterev(tx_packet));
|
||||||
|
dprintf("Sent packet to midi: %u %u %u\n", commands[tx_cmd_count][0], commands[tx_cmd_count][1], commands[tx_cmd_count][2]);
|
||||||
|
t_tx += tx_interval;
|
||||||
|
tx_end += max_tx_time;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
dprintf("Tx and Rx count met - exiting after last tx complete.\n");
|
||||||
|
tmr when timerafter(tx_end) :> int _; // wait until packet definitely departed
|
||||||
|
|
||||||
|
exit(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int main(void)
|
||||||
|
{
|
||||||
|
chan c_midi;
|
||||||
|
|
||||||
|
par
|
||||||
|
{
|
||||||
|
on tile[0]: test(c_midi);
|
||||||
|
on tile[1]: usb_midi(p_midi_rx, p_midi_tx, clk_midi, c_midi, 0);
|
||||||
|
|
||||||
|
// Setup HW so we can run this on the MC board
|
||||||
|
on tile[0]: board_setup();
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
47
tests/test_midi/src/hwsupport.xc
Normal file
47
tests/test_midi/src/hwsupport.xc
Normal file
@@ -0,0 +1,47 @@
|
|||||||
|
// Copyright 2017-2024 XMOS LIMITED.
|
||||||
|
// This Software is subject to the terms of the XMOS Public Licence: Version 1.
|
||||||
|
#include <xs1.h>
|
||||||
|
#include <platform.h>
|
||||||
|
#include "xua.h"
|
||||||
|
|
||||||
|
|
||||||
|
on tile[0]: out port p_ctrl = XS1_PORT_8D; /* p_ctrl:
|
||||||
|
* [0:3] - Unused
|
||||||
|
* [4] - EN_3v3_N (1v0 hardware only)
|
||||||
|
* [5] - EN_3v3A
|
||||||
|
* [6] - EXT_PLL_SEL (CS2100:0, SI: 1)
|
||||||
|
* [7] - MCLK_DIR (Out:0, In: 1)
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define USE_FRACTIONAL_N (0)
|
||||||
|
|
||||||
|
#if (USE_FRACTIONAL_N)
|
||||||
|
#define EXT_PLL_SEL__MCLK_DIR (0x00)
|
||||||
|
#else
|
||||||
|
#define EXT_PLL_SEL__MCLK_DIR (0x80)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Board setup for XU316 MC Audio (1v1) */
|
||||||
|
void board_setup()
|
||||||
|
{
|
||||||
|
/* "Drive high mode" - drive high for 1, non-driving for 0 */
|
||||||
|
set_port_drive_high(p_ctrl);
|
||||||
|
|
||||||
|
/* Drive control port to turn on 3V3 and mclk direction appropriately.
|
||||||
|
* Bits set to low will be high-z, pulled down */
|
||||||
|
p_ctrl <: EXT_PLL_SEL__MCLK_DIR | 0x20;
|
||||||
|
|
||||||
|
/* Wait for power supplies to be up and stable */
|
||||||
|
delay_milliseconds(10);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Configures the external audio hardware at startup. Note this runs on Tile[1] */
|
||||||
|
void AudioHwInit()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Configures the external audio hardware for the required sample frequency */
|
||||||
|
void AudioHwConfig(unsigned samFreq, unsigned mClk, unsigned dsdMode, unsigned sampRes_DAC, unsigned sampRes_ADC)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
28
tests/test_midi/src/xua_conf.h
Normal file
28
tests/test_midi/src/xua_conf.h
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
// Copyright 2017-2024 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 /* Number of channels from host to device */
|
||||||
|
#define NUM_USB_CHAN_IN 0 /* Number of channels from device to host */
|
||||||
|
#define I2S_CHANS_DAC 2 /* Number of I2S channels out of xCORE */
|
||||||
|
#define I2S_CHANS_ADC 0 /* Number of I2S channels in to xCORE */
|
||||||
|
#define MCLK_441 (512 * 44100) /* 44.1kHz family master clock frequency */
|
||||||
|
#define MCLK_48 (512 * 48000) /* 48kHz family master clock frequency */
|
||||||
|
#define MIN_FREQ 48000 /* Minimum sample rate */
|
||||||
|
#define MAX_FREQ 48000 /* Maximum sample rate */
|
||||||
|
|
||||||
|
#define EXCLUDE_USB_AUDIO_MAIN
|
||||||
|
|
||||||
|
#define MIDI 1
|
||||||
|
#define MIDI_TILE 1
|
||||||
|
#define VENDOR_STR "XMOS"
|
||||||
|
#define VENDOR_ID 0x20B1
|
||||||
|
#define PRODUCT_STR_A2 "XUA Example"
|
||||||
|
#define PRODUCT_STR_A1 "XUA Example"
|
||||||
|
#define PID_AUDIO_1 1
|
||||||
|
#define PID_AUDIO_2 2
|
||||||
|
#define XUA_DFU_EN 0 /* Disable DFU (for simplicity of example */
|
||||||
|
|
||||||
|
#endif
|
||||||
8
tests/test_midi/src/xud_conf.h
Normal file
8
tests/test_midi/src/xud_conf.h
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
// Copyright 2017-2024 XMOS LIMITED.
|
||||||
|
// This Software is subject to the terms of the XMOS Public Licence: Version 1.
|
||||||
|
|
||||||
|
#include "xua_conf.h"
|
||||||
|
|
||||||
|
/* TODO */
|
||||||
|
#define XUD_UAC_NUM_USB_CHAN_OUT NUM_USB_CHAN_OUT
|
||||||
|
#define XUD_UAC_NUM_USB_CHAN_IN NUM_USB_CHAN_IN
|
||||||
60
tests/test_midi_loopback.py
Normal file
60
tests/test_midi_loopback.py
Normal file
@@ -0,0 +1,60 @@
|
|||||||
|
# Copyright 2014-2024 XMOS LIMITED.
|
||||||
|
# This Software is subject to the terms of the XMOS Public Licence: Version 1.
|
||||||
|
|
||||||
|
import pytest
|
||||||
|
import Pyxsim
|
||||||
|
from Pyxsim import testers
|
||||||
|
from pathlib import Path
|
||||||
|
from uart_rx_checker import UARTRxChecker
|
||||||
|
from midi_test_helpers import midi_expect_rx, create_midi_rx_file, create_midi_tx_file, tempdir, MIDI_RATE
|
||||||
|
from distutils.dir_util import copy_tree # we're using python 3.7 and dirs_exist_ok=True isn't available until 3.8 :(
|
||||||
|
|
||||||
|
MAX_CYCLES = 15000000
|
||||||
|
|
||||||
|
|
||||||
|
#####
|
||||||
|
# This test takes the built binary, copies it to a tmp dir and runs the midi loopback test which sends some commands
|
||||||
|
# the firmware receives them, prints and compares with the expected output
|
||||||
|
#####
|
||||||
|
def test_midi_loopback(capfd, build_midi):
|
||||||
|
# Need tempdir as we use the same config files and this causes issues when using xdist
|
||||||
|
with tempdir() as tmpdirname:
|
||||||
|
config = "LOOPBACK"
|
||||||
|
copy_tree(build_midi, tmpdirname)
|
||||||
|
xe = str(Path(tmpdirname) / f"{config}/test_midi_{config}.xe")
|
||||||
|
|
||||||
|
midi_commands = [
|
||||||
|
[0x90, 60, 81], #note on
|
||||||
|
[0xc0, 15], #instr select
|
||||||
|
[0xe0, 0, 96], #pitch bend
|
||||||
|
[0xff], #MIDI reset
|
||||||
|
[0x80, 60, 81], #note off
|
||||||
|
]
|
||||||
|
create_midi_rx_file(len(midi_commands))
|
||||||
|
create_midi_tx_file(midi_commands)
|
||||||
|
|
||||||
|
expected = midi_expect_rx().expect(midi_commands)
|
||||||
|
tester = testers.ComparisonTester(expected, ordered = True)
|
||||||
|
|
||||||
|
simthreads = []
|
||||||
|
|
||||||
|
simargs = ["--max-cycles", str(MAX_CYCLES)]
|
||||||
|
#This is just for local debug so we can capture the traces if needed. It slows xsim down so not needed
|
||||||
|
# simargs.extend(["--trace-to", "trace.txt", "--vcd-tracing", "-tile tile[1] -ports -o trace.vcd"])
|
||||||
|
|
||||||
|
Pyxsim.run_with_pyxsim(
|
||||||
|
xe,
|
||||||
|
simthreads=simthreads,
|
||||||
|
timeout=120,
|
||||||
|
simargs=simargs,
|
||||||
|
)
|
||||||
|
capture = capfd.readouterr().out
|
||||||
|
result = tester.run(capture.split("\n"))
|
||||||
|
|
||||||
|
# Print to console
|
||||||
|
# with capfd.disabled():
|
||||||
|
# print("++++", capture, "++++")
|
||||||
|
# print("----", expected, "----")
|
||||||
|
|
||||||
|
|
||||||
|
assert result
|
||||||
61
tests/test_midi_rx.py
Normal file
61
tests/test_midi_rx.py
Normal file
@@ -0,0 +1,61 @@
|
|||||||
|
# Copyright 2014-2024 XMOS LIMITED.
|
||||||
|
# This Software is subject to the terms of the XMOS Public Licence: Version 1.
|
||||||
|
|
||||||
|
import pytest
|
||||||
|
import Pyxsim
|
||||||
|
from Pyxsim import testers
|
||||||
|
from pathlib import Path
|
||||||
|
from uart_rx_checker import UARTRxChecker
|
||||||
|
from midi_test_helpers import midi_expect_rx, create_midi_rx_file, create_midi_tx_file, tempdir, MIDI_TEST_CONFIGS, MIDI_RATE
|
||||||
|
from distutils.dir_util import copy_tree # we're using python 3.7 and dirs_exist_ok=True isn't available until 3.8 :(
|
||||||
|
|
||||||
|
MAX_CYCLES = 15000000
|
||||||
|
|
||||||
|
|
||||||
|
#####
|
||||||
|
# This test takes the built binary, copies it to a tmp dir and runs the midi Rx test which sends some commands
|
||||||
|
# to using the UARTRX checker and the firmware receives them
|
||||||
|
#####
|
||||||
|
@pytest.mark.parametrize("config", MIDI_TEST_CONFIGS)
|
||||||
|
def test_rx(capfd, config, build_midi):
|
||||||
|
# Need tempdir as we use the same config files and this causes issues when using xdist
|
||||||
|
with tempdir() as tmpdirname:
|
||||||
|
copy_tree(build_midi, tmpdirname)
|
||||||
|
xe = str(Path(tmpdirname) / f"{config}/test_midi_{config}.xe")
|
||||||
|
|
||||||
|
midi_commands = [[0x90, 60, 81]]
|
||||||
|
create_midi_rx_file(len(midi_commands))
|
||||||
|
create_midi_tx_file()
|
||||||
|
|
||||||
|
expected = midi_expect_rx().expect(midi_commands)
|
||||||
|
tester = testers.ComparisonTester(expected, ordered = True)
|
||||||
|
|
||||||
|
rx_port = "tile[1]:XS1_PORT_1F"
|
||||||
|
tx_port = "tile[1]:XS1_PORT_4C" # Needed so that UARTRxChecker (a transmitter) knows when to start
|
||||||
|
baud = MIDI_RATE
|
||||||
|
bpb = 8
|
||||||
|
parity = 0
|
||||||
|
stop = 1
|
||||||
|
|
||||||
|
midi_commands_flattened = [item for row in midi_commands for item in row]
|
||||||
|
# midi_commands_flattened.append(0x00) # send a null afterwards to give RXChecker to complete
|
||||||
|
|
||||||
|
simthreads = [
|
||||||
|
UARTRxChecker(tx_port, rx_port, parity, baud, stop, bpb, midi_commands_flattened, debug=False)
|
||||||
|
]
|
||||||
|
|
||||||
|
simargs = ["--max-cycles", str(MAX_CYCLES)]
|
||||||
|
#This is just for local debug so we can capture the traces if needed. It slows xsim down so not good for Jenkins
|
||||||
|
# simargs.extend(["--trace-to", "trace.txt", "--vcd-tracing", "-tile tile[1] -ports -o trace.vcd"])
|
||||||
|
|
||||||
|
# with capfd.disabled(): # use to see xsim and tester output
|
||||||
|
Pyxsim.run_with_pyxsim(
|
||||||
|
xe,
|
||||||
|
simthreads=simthreads,
|
||||||
|
timeout=120,
|
||||||
|
simargs=simargs,
|
||||||
|
)
|
||||||
|
capture = capfd.readouterr().out
|
||||||
|
result = tester.run(capture.split("\n"))
|
||||||
|
|
||||||
|
assert result, f"expected: {expected}\n capture: {capture}"
|
||||||
59
tests/test_midi_tx.py
Normal file
59
tests/test_midi_tx.py
Normal file
@@ -0,0 +1,59 @@
|
|||||||
|
# Copyright 2014-2024 XMOS LIMITED.
|
||||||
|
# This Software is subject to the terms of the XMOS Public Licence: Version 1.
|
||||||
|
|
||||||
|
import pytest
|
||||||
|
import Pyxsim
|
||||||
|
from Pyxsim import testers
|
||||||
|
from pathlib import Path
|
||||||
|
from uart_tx_checker import UARTTxChecker
|
||||||
|
from midi_test_helpers import midi_expect_tx, create_midi_tx_file, create_midi_rx_file, tempdir, MIDI_TEST_CONFIGS, MIDI_RATE
|
||||||
|
from distutils.dir_util import copy_tree # we're using python 3.7 and dirs_exist_ok=True isn't available until 3.8 :(
|
||||||
|
|
||||||
|
MAX_CYCLES = 15000000
|
||||||
|
|
||||||
|
#####
|
||||||
|
# This test takes the built binary, copies it to a tmp dir and runs the midi Tx test which sends some commands
|
||||||
|
# to the firmware and then receives them using the UARTTX checker
|
||||||
|
#####
|
||||||
|
@pytest.mark.parametrize("config", MIDI_TEST_CONFIGS)
|
||||||
|
def test_tx(capfd, config, build_midi):
|
||||||
|
|
||||||
|
# Need tempdir as we use the same config files and this causes issues when using xdist
|
||||||
|
with tempdir() as tmpdirname:
|
||||||
|
copy_tree(build_midi, tmpdirname)
|
||||||
|
xe = str(Path(tmpdirname) / f"{config}/test_midi_{config}.xe")
|
||||||
|
|
||||||
|
midi_commands = [[0x90, 60, 81]]
|
||||||
|
create_midi_tx_file(midi_commands)
|
||||||
|
create_midi_rx_file()
|
||||||
|
|
||||||
|
expected = midi_expect_tx().expect(midi_commands)
|
||||||
|
tester = testers.ComparisonTester(expected, ordered = True)
|
||||||
|
|
||||||
|
tx_port = "tile[1]:XS1_PORT_4C"
|
||||||
|
baud = MIDI_RATE
|
||||||
|
bpb = 8
|
||||||
|
parity = 0
|
||||||
|
stop = 1
|
||||||
|
length_of_test = sum(len(cmd) for cmd in midi_commands)
|
||||||
|
|
||||||
|
simthreads = [
|
||||||
|
UARTTxChecker(tx_port, parity, baud, length_of_test, stop, bpb, debug=False)
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
|
simargs = ["--max-cycles", str(MAX_CYCLES)]
|
||||||
|
#This is just for local debug so we can capture the traces if needed. It slows xsim down so not needed
|
||||||
|
# simargs.extend(["--trace-to", "trace.txt", "--vcd-tracing", "-tile tile[1] -ports -o trace.vcd"])
|
||||||
|
|
||||||
|
# with capfd.disabled(): # use to see xsim and tester output
|
||||||
|
Pyxsim.run_with_pyxsim(
|
||||||
|
xe,
|
||||||
|
simthreads=simthreads,
|
||||||
|
timeout=120,
|
||||||
|
simargs=simargs,
|
||||||
|
)
|
||||||
|
capture = capfd.readouterr().out
|
||||||
|
result = tester.run(capture.split("\n"))
|
||||||
|
|
||||||
|
assert result, f"expected: {expected}\n capture: {capture}"
|
||||||
178
tests/uart_rx_checker.py
Normal file
178
tests/uart_rx_checker.py
Normal file
@@ -0,0 +1,178 @@
|
|||||||
|
# Copyright 2022-2024 XMOS LIMITED.
|
||||||
|
# This Software is subject to the terms of the XMOS Public Licence: Version 1.
|
||||||
|
import Pyxsim as px
|
||||||
|
from typing import Sequence
|
||||||
|
from functools import partial
|
||||||
|
|
||||||
|
# We need to disable output buffering for this test to work on MacOS; this has
|
||||||
|
# no effect on Linux systems. Let's redefine print once to avoid putting the
|
||||||
|
# same argument everywhere.
|
||||||
|
print = partial(print, flush=True)
|
||||||
|
|
||||||
|
Parity = dict(
|
||||||
|
UART_PARITY_EVEN=0,
|
||||||
|
UART_PARITY_ODD=1,
|
||||||
|
UART_PARITY_NONE=2,
|
||||||
|
UART_PARITY_BAD=3
|
||||||
|
)
|
||||||
|
|
||||||
|
# From tools 15.2.1 we need to add an extra factor to go from ps to fs
|
||||||
|
time_scaling_factor = 1000
|
||||||
|
|
||||||
|
class DriveHigh(px.SimThread):
|
||||||
|
def __init__(self, p):
|
||||||
|
self._p = p
|
||||||
|
|
||||||
|
def run(self):
|
||||||
|
xsi = self.xsi
|
||||||
|
|
||||||
|
xsi.drive_port_pins(self._p, 1);
|
||||||
|
|
||||||
|
|
||||||
|
class UARTRxChecker(px.SimThread):
|
||||||
|
def __init__(self, tx_port, rx_port, parity, baud, stop_bits, bpb, data=[0x7f, 0x00, 0x2f, 0xff],
|
||||||
|
intermittent=False, debug=False):
|
||||||
|
"""
|
||||||
|
Create a UARTRxChecker instance.
|
||||||
|
|
||||||
|
:param rx_port: Receive port of the UART device under test.
|
||||||
|
:param parity: Parity of the UART connection.
|
||||||
|
:param baud: BAUD rate of the UART connection.
|
||||||
|
:param stop_bits: Number of stop_bits for each UART byte.
|
||||||
|
:param bpb: Number of data bits per "byte" of UART data.
|
||||||
|
:param data: A list of bytes to send (default: [0x7f, 0x00, 0x2f, 0xff])
|
||||||
|
:param intermittent: Add a random delay between sent bytes.
|
||||||
|
"""
|
||||||
|
self._tx_port = tx_port
|
||||||
|
self._rx_port = rx_port
|
||||||
|
self._parity = parity
|
||||||
|
self._baud = baud
|
||||||
|
self._stop_bits = stop_bits
|
||||||
|
self._bits_per_byte = bpb
|
||||||
|
self._data = data
|
||||||
|
self._intermittent = intermittent
|
||||||
|
# Hex value of stop bits, as MSB 1st char, e.g. 0b11 : 0xC0
|
||||||
|
|
||||||
|
def send_byte(self, xsi, byte):
|
||||||
|
"""
|
||||||
|
Send a byte to the rx_port
|
||||||
|
|
||||||
|
:param xsi: XMOS Simulator Instance.
|
||||||
|
:param byte: Byte to send
|
||||||
|
"""
|
||||||
|
# Send start bit
|
||||||
|
self.send_start(xsi)
|
||||||
|
|
||||||
|
# Send data
|
||||||
|
self.send_data(xsi, byte)
|
||||||
|
|
||||||
|
# Send parity
|
||||||
|
self.send_parity(xsi, byte)
|
||||||
|
|
||||||
|
# Send stop bit(s)
|
||||||
|
self.send_stop(xsi)
|
||||||
|
|
||||||
|
|
||||||
|
def send_start(self, xsi):
|
||||||
|
"""
|
||||||
|
Send a start bit.
|
||||||
|
|
||||||
|
:param xsi: XMOS Simulator Instance.
|
||||||
|
"""
|
||||||
|
xsi.drive_port_pins(self._rx_port, 0)
|
||||||
|
self.wait_baud_time(xsi)
|
||||||
|
|
||||||
|
def send_data(self, xsi, byte):
|
||||||
|
"""
|
||||||
|
Write the data bits to the rx_port
|
||||||
|
|
||||||
|
:param xsi: XMOS Simulator Instance.
|
||||||
|
:param byte: Data to send.
|
||||||
|
"""
|
||||||
|
# print(f"Checker sent 0x{byte:02x}")
|
||||||
|
for x in range(self._bits_per_byte):
|
||||||
|
# print(f" Sending bit {x}")
|
||||||
|
xsi.drive_port_pins(self._rx_port, (byte & (0x01 << x)) >= 1)
|
||||||
|
# print(f" (x): {((byte & (0x01 << x))>=1)}")
|
||||||
|
self.wait_baud_time(xsi)
|
||||||
|
|
||||||
|
def send_parity(self, xsi, byte):
|
||||||
|
"""
|
||||||
|
Send the parity bit to the rx_port
|
||||||
|
|
||||||
|
:param xsi: XMOS Simulator Instance.
|
||||||
|
:param byte: Data to send parity of.
|
||||||
|
"""
|
||||||
|
parity = (self._parity - 1) % 3 #parity enum in lib_uart (old XC) different from SDK
|
||||||
|
if parity < 2:
|
||||||
|
crc_sum = 0
|
||||||
|
for x in range(self._bits_per_byte):
|
||||||
|
crc_sum += ((byte & (0x01 << x)) >= 1)
|
||||||
|
crc_sum += parity
|
||||||
|
# print "Parity for 0x%02x: %d" % (byte, crc_sum%2)
|
||||||
|
xsi.drive_port_pins(self._rx_port, crc_sum % 2)
|
||||||
|
self.wait_baud_time(xsi)
|
||||||
|
elif parity == Parity['UART_PARITY_BAD']:
|
||||||
|
# print "Sending bad parity bit"
|
||||||
|
self.send_bad_parity(xsi)
|
||||||
|
|
||||||
|
def send_stop(self, xsi):
|
||||||
|
"""
|
||||||
|
Send the stop bit(s) to the rx_port
|
||||||
|
|
||||||
|
:param xsi: XMOS Simulator Instance.
|
||||||
|
"""
|
||||||
|
for x in range(self._stop_bits):
|
||||||
|
xsi.drive_port_pins(self._rx_port, 1)
|
||||||
|
self.wait_baud_time(xsi)
|
||||||
|
|
||||||
|
def send_bad_parity(self, xsi):
|
||||||
|
"""
|
||||||
|
Send a parity bit of 1 to simulate an incorrect parity state.
|
||||||
|
|
||||||
|
:param xsi: XMOS Simulator Instance.
|
||||||
|
"""
|
||||||
|
# Always send a parity bit of 1
|
||||||
|
xsi.drive_port_pins(self._rx_port, 0)
|
||||||
|
self.wait_baud_time(xsi)
|
||||||
|
|
||||||
|
def get_bit_time(self):
|
||||||
|
"""
|
||||||
|
Returns the expected time between bits for the currently set BAUD rate.
|
||||||
|
|
||||||
|
Returns float value in nanoseconds.
|
||||||
|
"""
|
||||||
|
# Return float value in ps
|
||||||
|
return (1.0 / self._baud) * 1e12 * time_scaling_factor
|
||||||
|
|
||||||
|
def wait_baud_time(self, xsi):
|
||||||
|
"""
|
||||||
|
Wait for 1 bit time, as determined by the baud rate.
|
||||||
|
"""
|
||||||
|
self.wait_until(xsi.get_time() + self.get_bit_time())
|
||||||
|
|
||||||
|
def wait_half_baud_time(self, xsi):
|
||||||
|
"""
|
||||||
|
Wait for half a bit time, as determined by the baud rate.
|
||||||
|
"""
|
||||||
|
self.wait_until(xsi.get_time() + (self.get_bit_time() / 2))
|
||||||
|
|
||||||
|
def run(self):
|
||||||
|
xsi = self.xsi
|
||||||
|
# Drive the uart line high.
|
||||||
|
xsi.drive_port_pins(self._rx_port, 1)
|
||||||
|
|
||||||
|
# Wait for the device to bring up it's tx port, indicating it is ready
|
||||||
|
self.wait((lambda _x: self.xsi.is_port_driving(self._tx_port)))
|
||||||
|
|
||||||
|
# If we're doing an intermittent send, add a delay between each byte
|
||||||
|
# sent. Delay is in ns. 20,000ns = 20ms, 100,000ns = 100ms. Delays could
|
||||||
|
# be more variable, but it hurts test time substantially.
|
||||||
|
if self._intermittent:
|
||||||
|
for x in self._data:
|
||||||
|
k = randint(20000, 100000)
|
||||||
|
self.wait_until(xsi.get_time() + k)
|
||||||
|
self.send_byte(xsi, x)
|
||||||
|
else:
|
||||||
|
for x in self._data:
|
||||||
|
self.send_byte(xsi, x)
|
||||||
246
tests/uart_tx_checker.py
Normal file
246
tests/uart_tx_checker.py
Normal file
@@ -0,0 +1,246 @@
|
|||||||
|
# Copyright 2022-2024 XMOS LIMITED.
|
||||||
|
# This Software is subject to the terms of the XMOS Public Licence: Version 1.
|
||||||
|
import Pyxsim as px
|
||||||
|
from typing import Sequence
|
||||||
|
from functools import partial
|
||||||
|
|
||||||
|
# We need to disable output buffering for this test to work on MacOS; this has
|
||||||
|
# no effect on Linux systems. Let's redefine print once to avoid putting the
|
||||||
|
# same argument everywhere.
|
||||||
|
print = partial(print, flush=True)
|
||||||
|
|
||||||
|
# From tools 15.2.1 we need to add an extra factor to go from ps to fs
|
||||||
|
time_scaling_factor = 1000
|
||||||
|
|
||||||
|
class UARTTxChecker(px.SimThread):
|
||||||
|
"""
|
||||||
|
This simulator thread will act as a UART device, and will check sent and
|
||||||
|
transations caused by the device, by looking at the tx pins.
|
||||||
|
"""
|
||||||
|
|
||||||
|
def __init__(self, tx_port, parity, baud, length, stop_bits, bpb, debug=False):
|
||||||
|
"""
|
||||||
|
Create a UARTTxChecker instance.
|
||||||
|
|
||||||
|
:param tx_port: Transmit port of the UART device under test.
|
||||||
|
:param parity: Parity of the UART connection.
|
||||||
|
:param baud: BAUD rate of the UART connection.
|
||||||
|
:param length: Length of transmission to check.
|
||||||
|
:param stop_bits: Number of stop_bits for each UART byte.
|
||||||
|
:param bpb: Number of data bits per "byte" of UART data.
|
||||||
|
"""
|
||||||
|
self._tx_port = tx_port
|
||||||
|
self._parity = parity
|
||||||
|
self._baud = baud
|
||||||
|
self._length = length
|
||||||
|
self._stop_bits = stop_bits
|
||||||
|
self._bits_per_byte = bpb
|
||||||
|
# Hex value of stop bits, as MSB 1st char, e.g. 0b11 : 0xC0
|
||||||
|
self.debug = debug
|
||||||
|
|
||||||
|
def get_port_val(self, xsi, port):
|
||||||
|
"""
|
||||||
|
Sample the state of a port
|
||||||
|
|
||||||
|
:rtype: int
|
||||||
|
:param xsi: XMOS Simulator Instance.
|
||||||
|
:param port: Port to sample.
|
||||||
|
"""
|
||||||
|
is_driving = xsi.is_port_driving(port)
|
||||||
|
if not is_driving:
|
||||||
|
return 1
|
||||||
|
else:
|
||||||
|
return xsi.sample_port_pins(port)
|
||||||
|
|
||||||
|
def get_bit_time(self):
|
||||||
|
"""
|
||||||
|
Returns the expected time between bits for the currently set BAUD rate.
|
||||||
|
|
||||||
|
Returns float value in nanoseconds.
|
||||||
|
:rtype: float
|
||||||
|
"""
|
||||||
|
# Return float value in ps
|
||||||
|
return (1.0/self._baud) * 1e12 * time_scaling_factor
|
||||||
|
|
||||||
|
def wait_baud_time(self, xsi):
|
||||||
|
"""
|
||||||
|
Wait for 1 bit time, as determined by the baud rate.
|
||||||
|
"""
|
||||||
|
self.wait_until(xsi.get_time() + self.get_bit_time())
|
||||||
|
return True
|
||||||
|
|
||||||
|
def wait_half_baud_time(self, xsi):
|
||||||
|
"""
|
||||||
|
Wait for half a bit time, as determined by the baud rate.
|
||||||
|
"""
|
||||||
|
self.wait_until(xsi.get_time() + (self.get_bit_time() / 2))
|
||||||
|
|
||||||
|
def read_packet(self, xsi, parity, length=4):
|
||||||
|
"""
|
||||||
|
Read a given number of bytes of UART traffic sent by the device.
|
||||||
|
|
||||||
|
Returns a list of bytes sent by the device.
|
||||||
|
|
||||||
|
:rtype: list
|
||||||
|
:param xsi: XMOS Simulator Instance.
|
||||||
|
:param parity: The UART partiy setting. See Parity.
|
||||||
|
:param length: The number of bytes to read. Defaults to 4.
|
||||||
|
"""
|
||||||
|
packet = []
|
||||||
|
start_time = 0
|
||||||
|
got_start_bit = False
|
||||||
|
|
||||||
|
initial_port_val = self.get_port_val(xsi, self._tx_port)
|
||||||
|
if self.debug: print("tx starts high: %s" % ("True" if initial_port_val else "False"))
|
||||||
|
|
||||||
|
for x in range(length):
|
||||||
|
packet.append(chr(self.read_byte(xsi, parity)))
|
||||||
|
return packet
|
||||||
|
|
||||||
|
def read_byte(self, xsi, parity):
|
||||||
|
"""
|
||||||
|
Read 1 byte of UART traffic sent by the device
|
||||||
|
|
||||||
|
Returns an int, representing a byte read from the uart. Should be in the range 0 <= x < 2^bits_per_byte
|
||||||
|
|
||||||
|
:rtype: int
|
||||||
|
:param xsi: XMOS Simulator Instance.
|
||||||
|
:param parity: The UART partiy setting. See Parity.
|
||||||
|
"""
|
||||||
|
byte = 0
|
||||||
|
val = 0
|
||||||
|
|
||||||
|
# Recv start bit
|
||||||
|
initial_port_val = self.get_port_val(xsi, self._tx_port)
|
||||||
|
|
||||||
|
if initial_port_val == 1:
|
||||||
|
self.wait_for_port_pins_change([self._tx_port])
|
||||||
|
#else go for it as assume tx has just fallen with no interframe gap
|
||||||
|
|
||||||
|
# The tx line should go low for 1 bit time
|
||||||
|
if self.get_val_timeout(xsi, self._tx_port) == 0:
|
||||||
|
if self.debug: print("Start bit recv'd")
|
||||||
|
else:
|
||||||
|
print("Start bit issue")
|
||||||
|
return False
|
||||||
|
|
||||||
|
# recv the byte
|
||||||
|
crc_sum = 0
|
||||||
|
for j in range(self._bits_per_byte):
|
||||||
|
val = self.get_val_timeout(xsi, self._tx_port)
|
||||||
|
byte += (val << j)
|
||||||
|
crc_sum += val
|
||||||
|
|
||||||
|
if self.debug: print(f"Sampled {self._bits_per_byte} data bits: 0x{hex(byte)}")
|
||||||
|
|
||||||
|
# Check the parity if needs be
|
||||||
|
self.check_parity(xsi, crc_sum, parity)
|
||||||
|
|
||||||
|
# Get the stop bit
|
||||||
|
self.check_stopbit(xsi)
|
||||||
|
|
||||||
|
# Print a new line to split bytes in output
|
||||||
|
if self.debug: print()
|
||||||
|
|
||||||
|
return byte
|
||||||
|
|
||||||
|
def check_parity(self, xsi, crc_sum, parity):
|
||||||
|
"""
|
||||||
|
Read the parity bit and check it against a crc sum. Print correctness.
|
||||||
|
|
||||||
|
:param xsi: XMOS Simulator Instance.
|
||||||
|
:param crc_sum: The checksum to test parity against.
|
||||||
|
:param parity: The UART partiy setting. See Parity.
|
||||||
|
"""
|
||||||
|
if parity > 0:
|
||||||
|
parity_val = 0 if parity == 1 else 1
|
||||||
|
read = self.get_val_timeout(xsi, self._tx_port)
|
||||||
|
if read == (crc_sum + parity_val) % 2:
|
||||||
|
print("Parity bit correct")
|
||||||
|
else:
|
||||||
|
print("Parity bit incorrect. Got %d, expected %d" % (read, (crc_sum + parity_val) % 2))
|
||||||
|
else:
|
||||||
|
if self.debug: print("Parity bit correct")
|
||||||
|
|
||||||
|
def check_stopbit(self, xsi):
|
||||||
|
"""
|
||||||
|
Read the stop bit(s) of a UART transmission and print correctness.
|
||||||
|
|
||||||
|
:param xsi: XMOS Simulator Instance.
|
||||||
|
"""
|
||||||
|
stop_bits_correct = True
|
||||||
|
for i in range(self._stop_bits):
|
||||||
|
# The stop bits should stay high for this time
|
||||||
|
if self.get_val_timeout(xsi, self._tx_port) == 0:
|
||||||
|
stop_bits_correct = False
|
||||||
|
if self.debug: print("Stop bit correct: %s" % ("True" if stop_bits_correct else "False"))
|
||||||
|
|
||||||
|
def get_val_timeout(self, xsi, port):
|
||||||
|
"""
|
||||||
|
Get a value from a given port of the device, with a timeout determined
|
||||||
|
by the BAUD rate.
|
||||||
|
|
||||||
|
Returns whether the pin is high (True) or low (False)
|
||||||
|
|
||||||
|
:rtype: bool
|
||||||
|
:param xsi: XMOS Simulator Instance.
|
||||||
|
:param port: The port to sample.
|
||||||
|
"""
|
||||||
|
# This intentionally has a 0.3% slop. It is per-byte and gives some
|
||||||
|
# wiggle-room if the clock doesn't divide into ns nicely.
|
||||||
|
timeout = self.get_bit_time() * 0.5
|
||||||
|
short_timeout = self.get_bit_time() * 0.2485
|
||||||
|
|
||||||
|
# Allow for "rise" time
|
||||||
|
self.wait_until(xsi.get_time() + short_timeout)
|
||||||
|
|
||||||
|
# Get val
|
||||||
|
K = self.wait_time_or_pin_change(xsi, timeout, port)
|
||||||
|
|
||||||
|
# Allow for "fall" time
|
||||||
|
self.wait_until(xsi.get_time() + short_timeout)
|
||||||
|
return K
|
||||||
|
|
||||||
|
def wait_time_or_pin_change(self, xsi, timeout, port):
|
||||||
|
"""
|
||||||
|
Waits for a given timeout, or until a port changes state. Which ever
|
||||||
|
occurs 1st. Prints an error if the former causes the function to break.
|
||||||
|
|
||||||
|
Returns whether the pin is high (True) or low (False)
|
||||||
|
|
||||||
|
:rtype: bool
|
||||||
|
:param xsi: XMOS Simulator Instance.
|
||||||
|
:param timeout: Time to wait.
|
||||||
|
:param port: Port to sample.
|
||||||
|
"""
|
||||||
|
start_time = xsi.get_time()
|
||||||
|
start_val = self.get_port_val(xsi, port)
|
||||||
|
transitioned_during_wait = False
|
||||||
|
|
||||||
|
def _continue(_timeout, _start_time, _start_val):
|
||||||
|
if xsi.get_time() >= _start_time + _timeout:
|
||||||
|
return True
|
||||||
|
if self.get_port_val(xsi, port) != _start_val:
|
||||||
|
transitioned_during_wait = True
|
||||||
|
return True
|
||||||
|
return False
|
||||||
|
wait_fun = (lambda x: _continue(timeout, start_time, start_val))
|
||||||
|
self.wait(wait_fun)
|
||||||
|
|
||||||
|
# Start value should *not* have changed during timeout
|
||||||
|
if transitioned_during_wait:
|
||||||
|
print("FAIL :: Unexpected Transition.")
|
||||||
|
|
||||||
|
return start_val
|
||||||
|
|
||||||
|
def run(self):
|
||||||
|
# Wait for the xcore to bring the uart tx port up
|
||||||
|
self.wait((lambda x: self.xsi.is_port_driving(self._tx_port)))
|
||||||
|
self.wait((lambda x: self.get_port_val(self.xsi, self._tx_port) == 1))
|
||||||
|
|
||||||
|
K = self.read_packet(self.xsi, self._parity, self._length)
|
||||||
|
|
||||||
|
# Print each member of K as a hex byte
|
||||||
|
# inline lambda function mapped over a list? awh yiss.
|
||||||
|
print("uart_tx_checker:", " ".join(map((lambda x: "0x%02x" % ord(x)), K)))
|
||||||
|
|
||||||
@@ -1,103 +1,96 @@
|
|||||||
cmake_minimum_required(VERSION 3.13)
|
cmake_minimum_required(VERSION 3.21)
|
||||||
|
include($ENV{XMOS_CMAKE_PATH}/xcommon.cmake)
|
||||||
|
|
||||||
set(XMOS_TOOLS_PATH $ENV{XMOS_TOOL_PATH}/bin)
|
# Auto-generate schedule and top level config files
|
||||||
|
if( NOT ${Python3_FOUND} )
|
||||||
#**********************
|
message(FATAL_ERROR "Python3 not found for running . ")
|
||||||
# Setup XMOS toolchain
|
|
||||||
#**********************
|
|
||||||
if(NOT DEFINED ENV{XUA_PATH})
|
|
||||||
message(FATAL_ERROR "XUA_PATH environment variable not defined")
|
|
||||||
# some more commands
|
|
||||||
endif()
|
endif()
|
||||||
include("$ENV{XUA_PATH}/cmake_utils/xmos_toolchain.cmake")
|
|
||||||
|
|
||||||
#**********************
|
#copy conftest.py in the build directory since pytest_collect_file only collects tests from the directory tree where conftest.py is present
|
||||||
# Project
|
configure_file( conftest.py conftest.py COPYONLY )
|
||||||
#**********************
|
|
||||||
# Disable in-source build.
|
|
||||||
#if("${CMAKE_SOURCE_DIR}" STREQUAL "${CMAKE_BINARY_DIR}")
|
|
||||||
# message(FATAL_ERROR "In-source build is not allowed! Please specify a build folder.\n\tex:cmake -B build")
|
|
||||||
#endif()
|
|
||||||
|
|
||||||
|
## executable output directory
|
||||||
|
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/bin)
|
||||||
|
|
||||||
## Define project
|
# Set unity runner generate script
|
||||||
project(xua_unit_tests VERSION 0.1.0)
|
set(GEN_RUNNER_SCRIPT ${CMAKE_CURRENT_SOURCE_DIR}/generate_unity_runner.py)
|
||||||
|
|
||||||
## Enable languages for project
|
# Create directory for runner files
|
||||||
enable_language(CXX XC C ASM)
|
set(RUNNERS_DIR ${CMAKE_CURRENT_LIST_DIR}/src.runners )
|
||||||
|
file(MAKE_DIRECTORY ${RUNNERS_DIR} )
|
||||||
|
|
||||||
message(STATUS "CAME HERE")
|
# Find unit test files
|
||||||
add_custom_target("runners" ALL)
|
file(GLOB_RECURSE TEST_SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/src/test_*/*.c)
|
||||||
|
|
||||||
|
# For every source file in xua_unit_tests/
|
||||||
|
foreach(TESTFILE ${TEST_SOURCES})
|
||||||
|
set(XMOS_SANDBOX_DIR ${CMAKE_CURRENT_LIST_DIR}/../../..)
|
||||||
|
|
||||||
|
# Get test name from C file stem
|
||||||
|
cmake_path(GET TESTFILE STEM TESTNAME)
|
||||||
|
project(${TESTNAME})
|
||||||
|
message(STATUS "Processing unit test: ${TESTNAME}")
|
||||||
|
|
||||||
|
# Create runner file directory
|
||||||
|
file(MAKE_DIRECTORY ${RUNNERS_DIR}/${TESTNAME})
|
||||||
|
|
||||||
|
#####################
|
||||||
|
## Create runner file
|
||||||
|
#####################
|
||||||
|
set( RUNNER_FILE ${RUNNERS_DIR}/${TESTNAME}/${TESTNAME}_Runner.c )
|
||||||
|
set( GEN_RUNNER_SCRIPT_BYPRODUCTS ${RUNNER_FILE})
|
||||||
|
|
||||||
|
unset(GEN_RUNNER_SCRIPT_ARGS)
|
||||||
|
list(APPEND GEN_RUNNER_SCRIPT_ARGS --project-root ${XMOS_SANDBOX_DIR})
|
||||||
|
list(APPEND GEN_RUNNER_SCRIPT_ARGS --source-file ${TESTFILE})
|
||||||
|
list(APPEND GEN_RUNNER_SCRIPT_ARGS --runner-file ${RUNNER_FILE})
|
||||||
|
|
||||||
|
## Add command to generate runner file
|
||||||
add_custom_command(
|
add_custom_command(
|
||||||
TARGET runners
|
OUTPUT ${RUNNER_FILE}
|
||||||
COMMAND python generate_unity_runners.py
|
COMMAND python ${GEN_RUNNER_SCRIPT} ${GEN_RUNNER_SCRIPT_ARGS}
|
||||||
COMMENT "generate unity runners"
|
COMMENT "Generate XUA Unit Test Runner" )
|
||||||
|
|
||||||
|
##########################
|
||||||
|
## Do xcommon cmake build
|
||||||
|
##########################
|
||||||
|
set(APP_HW_TARGET XK-EVK-XU316)
|
||||||
|
set(APP_DEPENDENT_MODULES "lib_xua"
|
||||||
|
"lib_unity(2.5.2)")
|
||||||
|
# set(APP_PCA_ENABLE ON)
|
||||||
|
set(APP_COMPILER_FLAGS ${EXTRA_BUILD_FLAGS} -fcomment-asm
|
||||||
|
-Wall
|
||||||
|
-O2
|
||||||
|
-report
|
||||||
|
-g
|
||||||
|
-fxscope
|
||||||
|
-DUSB_TILE=tile[0]
|
||||||
|
-DUNITY_SUPPORT_64
|
||||||
|
-DUNITY_INCLUDE_DOUBLE
|
||||||
|
-DXUD_CORE_CLOCK=600
|
||||||
|
-DXUD_SERIES_SUPPORT=4
|
||||||
)
|
)
|
||||||
|
|
||||||
message(STATUS "CAME HERE 1")
|
# For HID tests only enable HID
|
||||||
file( GLOB APP_SOURCES src/test*.xc )
|
if(${TESTFILE} MATCHES ".+hid.*")
|
||||||
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/bin)
|
list(APPEND APP_COMPILER_FLAGS "-DHID_CONTROLS=1")
|
||||||
foreach( testsourcefile ${APP_SOURCES} )
|
endif()
|
||||||
get_filename_component(ITEM_NAME ${testsourcefile} NAME_WE)
|
|
||||||
message(STATUS "item_name " ${ITEM_NAME})
|
|
||||||
add_executable(${ITEM_NAME})
|
# Workaround for xcommon cmake pre-pending CMAKE_CURRENT_LIST_DIR
|
||||||
set(APP_COMPILER_FLAGS
|
string(REPLACE ${CMAKE_CURRENT_LIST_DIR} "" UNIT_TEST_SOURCE_RELATIVE ${TESTFILE})
|
||||||
"-O2"
|
string(REPLACE ${CMAKE_CURRENT_LIST_DIR} "" RUNNER_FILE_RELATIVE ${RUNNER_FILE})
|
||||||
"-g"
|
|
||||||
"-Wall"
|
set(APP_C_SRCS ${RUNNER_FILE_RELATIVE}
|
||||||
"-report"
|
${UNIT_TEST_SOURCE_RELATIVE}
|
||||||
"-fxscope"
|
|
||||||
"-target=XCORE-AI-EXPLORER"
|
|
||||||
"${CMAKE_CURRENT_SOURCE_DIR}/config.xscope"
|
|
||||||
"-DHID_CONTROLS=1"
|
|
||||||
"-DUNITY_SUPPORT_64"
|
|
||||||
"-DUNITY_INCLUDE_DOUBLE"
|
|
||||||
)
|
|
||||||
set_source_files_properties(
|
|
||||||
"runners/${ITEM_NAME}/${ITEM_NAME}_Runner.c"
|
|
||||||
PROPERTIES GENERATED TRUE
|
|
||||||
)
|
)
|
||||||
|
|
||||||
set(APP_SRCS
|
|
||||||
${testsourcefile}
|
|
||||||
"runners/${ITEM_NAME}/${ITEM_NAME}_Runner.c"
|
|
||||||
"${CMAKE_CURRENT_SOURCE_DIR}/../../../Unity/src/unity.c"
|
|
||||||
)
|
|
||||||
set(APP_INCLUDES
|
|
||||||
"src"
|
|
||||||
"${CMAKE_CURRENT_SOURCE_DIR}/../../../Unity/src"
|
|
||||||
)
|
|
||||||
set(APP_DEPENDENT_MODULES
|
|
||||||
"lib_xua(>=2.0.0)"
|
|
||||||
"lib_logging(>=3.0.0)"
|
|
||||||
"lib_xassert(>=4.0.0)"
|
|
||||||
"lib_xud(>=2.0.0)"
|
|
||||||
"lib_spdif(>=4.0.0)"
|
|
||||||
"lib_mic_array(>=4.0.0)"
|
|
||||||
)
|
|
||||||
|
|
||||||
include("$ENV{XUA_PATH}/cmake_utils/xua.cmake")
|
get_filename_component(TEST_FILE_DIR ${TESTFILE} DIRECTORY)
|
||||||
set_target_properties(${ITEM_NAME} PROPERTIES OUTPUT_NAME ${ITEM_NAME}.xe)
|
set(APP_INCLUDES ${CMAKE_CURRENT_LIST_DIR}/src
|
||||||
target_compile_options(${ITEM_NAME} PRIVATE ${APP_COMPILER_FLAGS})
|
${TEST_FILE_DIR}
|
||||||
|
${XMOS_SANDBOX_DIR}/lib_xud/lib_xud/src/user/class)
|
||||||
|
|
||||||
target_include_directories(${ITEM_NAME}
|
XMOS_REGISTER_APP()
|
||||||
PRIVATE ${APP_INCLUDES}
|
|
||||||
PRIVATE ${XUA_INCLUDES_ALL}
|
|
||||||
)
|
|
||||||
|
|
||||||
target_sources(${ITEM_NAME}
|
endforeach()
|
||||||
PRIVATE ${APP_SRCS}
|
|
||||||
PRIVATE ${XUA_SRCS_ALL}
|
|
||||||
)
|
|
||||||
add_dependencies(${ITEM_NAME} runners)
|
|
||||||
target_link_options(${ITEM_NAME} PRIVATE ${APP_COMPILER_FLAGS})
|
|
||||||
## Set any additional flags only for C++
|
|
||||||
set(CMAKE_CXX_FLAGS "-std=c++11")
|
|
||||||
|
|
||||||
endforeach( testsourcefile ${APP_SOURCES} )
|
|
||||||
|
|
||||||
message(STATUS ${APP_SOURCES})
|
|
||||||
|
|
||||||
message(STATUS "CAME HERE 2")
|
|
||||||
## Register the application
|
|
||||||
#XMOS_REGISTER_APP()
|
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
# Copyright 2021-2022 XMOS LIMITED.
|
# Copyright 2021-2024 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
|
||||||
@@ -28,7 +28,7 @@ class UnityTestSource(pytest.File):
|
|||||||
# unit_tests/ <- Test root directory
|
# unit_tests/ <- Test root directory
|
||||||
# |-- bin/ <- Compiled binaries of the test runners
|
# |-- bin/ <- Compiled binaries of the test runners
|
||||||
# |-- conftest.py <- This file
|
# |-- conftest.py <- This file
|
||||||
# |-- runners/ <- Auto-generated buildable source of test binaries
|
# |-- src.runners <- Auto-generated buildable source of test binaries
|
||||||
# |-- 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"
|
||||||
@@ -51,9 +51,9 @@ class UnityTestExecutable(pytest.Item):
|
|||||||
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 xsim for executable ", self.name)
|
||||||
test_output = subprocess.check_output(
|
test_output = subprocess.check_output(
|
||||||
["xrun", "--io", "--id", "0", self.name],
|
["xsim", self.name],
|
||||||
text=True,
|
text=True,
|
||||||
stderr=subprocess.STDOUT,
|
stderr=subprocess.STDOUT,
|
||||||
)
|
)
|
||||||
|
|||||||
59
tests/xua_unit_tests/generate_unity_runner.py
Executable file
59
tests/xua_unit_tests/generate_unity_runner.py
Executable file
@@ -0,0 +1,59 @@
|
|||||||
|
# Copyright 2024 XMOS LIMITED.
|
||||||
|
# This Software is subject to the terms of the XMOS Public Licence: Version 1.
|
||||||
|
|
||||||
|
import glob
|
||||||
|
import os.path
|
||||||
|
import subprocess
|
||||||
|
import sys
|
||||||
|
import argparse
|
||||||
|
|
||||||
|
def parse_arguments():
|
||||||
|
parser = argparse.ArgumentParser()
|
||||||
|
parser.add_argument("--project-root", nargs='?', help="Project root directory")
|
||||||
|
parser.add_argument("--source-file", nargs='?', help="source file.")
|
||||||
|
parser.add_argument("--runner-file", nargs='?', help="runner file.")
|
||||||
|
args = parser.parse_args()
|
||||||
|
return args
|
||||||
|
|
||||||
|
def get_ruby():
|
||||||
|
"""
|
||||||
|
Check ruby is avaliable and return the command to invoke it.
|
||||||
|
"""
|
||||||
|
interpreter_name = 'ruby'
|
||||||
|
try:
|
||||||
|
dev_null = open(os.devnull, 'w')
|
||||||
|
# Call the version command to check the interpreter can be run
|
||||||
|
subprocess.check_call([interpreter_name, '--version'],
|
||||||
|
stdout=dev_null,
|
||||||
|
close_fds=True)
|
||||||
|
except OSError as e:
|
||||||
|
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
|
||||||
|
|
||||||
|
return interpreter_name
|
||||||
|
|
||||||
|
def get_unity_runner_generator(project_root_path):
|
||||||
|
"""
|
||||||
|
Check the Unity generate_test_runner script is avaliable, and return the
|
||||||
|
path to it.
|
||||||
|
"""
|
||||||
|
unity_runner_generator = os.path.join(
|
||||||
|
project_root_path, 'Unity', 'auto', 'generate_test_runner.rb')
|
||||||
|
if not os.path.exists(unity_runner_generator):
|
||||||
|
print("Unity repo not found in workspace", file=sys.stderr)
|
||||||
|
exit(1) # TODO: Check this is the correct way to kill xwaf on error
|
||||||
|
return unity_runner_generator
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
args = parse_arguments()
|
||||||
|
print(f"in python: root {args.project_root}, source {args.source_file}, runner {args.runner_file}")
|
||||||
|
|
||||||
|
try:
|
||||||
|
subprocess.check_call([get_ruby(),
|
||||||
|
get_unity_runner_generator(args.project_root),
|
||||||
|
args.source_file,
|
||||||
|
args.runner_file])
|
||||||
|
except OSError as e:
|
||||||
|
print("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
|
||||||
@@ -1,134 +0,0 @@
|
|||||||
# Copyright 2021-2022 XMOS LIMITED.
|
|
||||||
# This Software is subject to the terms of the XMOS Public Licence: Version 1.
|
|
||||||
import glob
|
|
||||||
import os.path
|
|
||||||
import subprocess
|
|
||||||
import sys
|
|
||||||
|
|
||||||
UNITY_TEST_DIR = "src"
|
|
||||||
UNITY_TEST_PREFIX = "test_"
|
|
||||||
UNITY_RUNNER_DIR = "runners"
|
|
||||||
UNITY_RUNNER_SUFFIX = "_Runner"
|
|
||||||
project_root = os.path.join("..", "..", "..")
|
|
||||||
|
|
||||||
|
|
||||||
def get_ruby():
|
|
||||||
"""
|
|
||||||
Check ruby is avaliable and return the command to invoke it.
|
|
||||||
"""
|
|
||||||
interpreter_name = "ruby"
|
|
||||||
try:
|
|
||||||
dev_null = open(os.devnull, "w")
|
|
||||||
# Call the version command to check the interpreter can be run
|
|
||||||
subprocess.check_call(
|
|
||||||
[interpreter_name, "--version"], stdout=dev_null, close_fds=True
|
|
||||||
)
|
|
||||||
except OSError as e:
|
|
||||||
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
|
|
||||||
|
|
||||||
return interpreter_name
|
|
||||||
|
|
||||||
|
|
||||||
def get_unity_runner_generator(project_root_path):
|
|
||||||
"""
|
|
||||||
Check the Unity generate_test_runner script is avaliable, and return the
|
|
||||||
path to it.
|
|
||||||
"""
|
|
||||||
unity_runner_generator = os.path.join(
|
|
||||||
project_root_path, "Unity", "auto", "generate_test_runner.rb"
|
|
||||||
)
|
|
||||||
if not os.path.exists(unity_runner_generator):
|
|
||||||
print("Unity repo not found in workspace", file=sys.stderr)
|
|
||||||
exit(1) # TODO: Check this is the correct way to kill xwaf on error
|
|
||||||
return unity_runner_generator
|
|
||||||
|
|
||||||
|
|
||||||
def get_test_name(test_path):
|
|
||||||
"""
|
|
||||||
Return the test name by removing the extension from the filename.
|
|
||||||
"""
|
|
||||||
return os.path.splitext(os.path.basename(test_path))[0]
|
|
||||||
|
|
||||||
|
|
||||||
def get_file_type(filename):
|
|
||||||
"""
|
|
||||||
Return the extension from the filename.
|
|
||||||
"""
|
|
||||||
return filename.rsplit(".")[-1:][0]
|
|
||||||
|
|
||||||
|
|
||||||
def generate_unity_runner(
|
|
||||||
project_root_path, unity_test_path, unity_runner_dir, unity_runner_suffix
|
|
||||||
):
|
|
||||||
"""
|
|
||||||
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
|
|
||||||
if it does not already exist.
|
|
||||||
"""
|
|
||||||
runner_path = os.path.join(
|
|
||||||
os.path.join(unity_runner_dir, get_test_name(unity_test_path))
|
|
||||||
)
|
|
||||||
if not os.path.exists(runner_path):
|
|
||||||
os.makedirs(runner_path)
|
|
||||||
|
|
||||||
unity_runner_path = os.path.join(
|
|
||||||
runner_path, get_test_name(unity_test_path) + unity_runner_suffix + "." + "c"
|
|
||||||
)
|
|
||||||
|
|
||||||
try:
|
|
||||||
subprocess.check_call(
|
|
||||||
[
|
|
||||||
get_ruby(),
|
|
||||||
get_unity_runner_generator(project_root_path),
|
|
||||||
unity_test_path,
|
|
||||||
unity_runner_path,
|
|
||||||
]
|
|
||||||
)
|
|
||||||
except OSError as e:
|
|
||||||
print(
|
|
||||||
"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
|
|
||||||
|
|
||||||
|
|
||||||
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
|
|
||||||
unity_test_dir.
|
|
||||||
"""
|
|
||||||
return glob.glob(os.path.join(unity_test_dir, unity_test_prefix + "*"))
|
|
||||||
|
|
||||||
|
|
||||||
def find_unity_tests(unity_test_dir, unity_test_prefix):
|
|
||||||
"""
|
|
||||||
Return a dictionary of all {test names, test language} pairs with the
|
|
||||||
unity_test_prefix found in the unity_test_dir.
|
|
||||||
"""
|
|
||||||
unity_test_paths = find_unity_test_paths(unity_test_dir, unity_test_prefix)
|
|
||||||
print("unity_test_paths = ", unity_test_paths)
|
|
||||||
return {get_test_name(path): get_file_type(path) for path in unity_test_paths}
|
|
||||||
|
|
||||||
|
|
||||||
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
|
|
||||||
unity_test_dir.
|
|
||||||
"""
|
|
||||||
return glob.glob(os.path.join(unity_test_dir, unity_test_prefix + "*"))
|
|
||||||
|
|
||||||
|
|
||||||
def generate_runners():
|
|
||||||
UNITY_TESTS = find_unity_tests(UNITY_TEST_DIR, UNITY_TEST_PREFIX)
|
|
||||||
print("UNITY_TESTS = ", UNITY_TESTS)
|
|
||||||
unity_test_paths = find_unity_test_paths(UNITY_TEST_DIR, UNITY_TEST_PREFIX)
|
|
||||||
print("unity_test_paths = ", 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
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
|
||||||
generate_runners()
|
|
||||||
183
tests/xua_unit_tests/src/test_midi_parse/test_midi_parse.c
Normal file
183
tests/xua_unit_tests/src/test_midi_parse/test_midi_parse.c
Normal file
@@ -0,0 +1,183 @@
|
|||||||
|
// Copyright 2024 XMOS LIMITED.
|
||||||
|
// This Software is subject to the terms of the XMOS Public Licence: Version 1.
|
||||||
|
#include <stddef.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
#include "xua_unit_tests.h"
|
||||||
|
#include "../../../lib_xua/src/midi/midiinparse.h"
|
||||||
|
|
||||||
|
#define NUM_CHANS 16
|
||||||
|
#define NOTE_OFF 128
|
||||||
|
#define NOTE_ON 144
|
||||||
|
#define PRESSURE 160
|
||||||
|
#define CONTROL 176
|
||||||
|
#define PROGRAM 192
|
||||||
|
#define PRESSURE_VAL 208
|
||||||
|
#define RANGE 224
|
||||||
|
#define MANUFACTURE_ID 240
|
||||||
|
|
||||||
|
#define DATA_RANGE 128
|
||||||
|
#define DATA_MASK (DATA_RANGE - 1)
|
||||||
|
|
||||||
|
#define NUM_TESTS_PER_TEST 30
|
||||||
|
|
||||||
|
#define CABLE_NUM 2
|
||||||
|
#define RANDOM_SEED 6031769
|
||||||
|
|
||||||
|
unsigned midi_in_parse_ut(unsigned midi[3]){
|
||||||
|
// printf("Composing data: 0x%x 0x%x 0x%x\n", midi[0], midi[1], midi[2]);
|
||||||
|
|
||||||
|
struct midi_in_parse_state m_state;
|
||||||
|
void * mips = &m_state;
|
||||||
|
reset_midi_state_c_wrapper(mips);
|
||||||
|
|
||||||
|
unsigned valid = 0;
|
||||||
|
unsigned packed = 0;
|
||||||
|
|
||||||
|
midi_in_parse_c_wrapper(mips, CABLE_NUM, midi[0], &valid, &packed);
|
||||||
|
// printf("Valid: %d data: %u\n", valid, packed);
|
||||||
|
if(valid){
|
||||||
|
return packed;
|
||||||
|
}
|
||||||
|
midi_in_parse_c_wrapper(mips, CABLE_NUM, midi[1], &valid, &packed);
|
||||||
|
// printf("Valid: %d data: %u\n", valid, packed);
|
||||||
|
if(valid){
|
||||||
|
return packed;
|
||||||
|
}
|
||||||
|
midi_in_parse_c_wrapper(mips, CABLE_NUM, midi[2], &valid, &packed);
|
||||||
|
// printf("Valid: %d data: %u\n", valid, packed);
|
||||||
|
if(valid){
|
||||||
|
return packed;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned rndm = RANDOM_SEED;
|
||||||
|
|
||||||
|
|
||||||
|
void test_midi_note(void) {
|
||||||
|
for(int cmd = NOTE_OFF; cmd < NOTE_ON + NUM_CHANS; cmd++){
|
||||||
|
for(int test = 0; test < NUM_TESTS_PER_TEST; test++){
|
||||||
|
unsigned midi_ref[3] = {cmd, random(&rndm) & DATA_MASK, random(&rndm) & DATA_MASK};
|
||||||
|
unsigned packed = midi_in_parse_ut(midi_ref);
|
||||||
|
unsigned midi_dut[3] = {0};
|
||||||
|
unsigned size = 0;
|
||||||
|
midi_out_parse_c_wrapper(packed, midi_dut, &size);
|
||||||
|
// printf("size: %d data: 0x%x 0x%x 0x%x\n", size, midi_ref[0], midi_ref[1], midi_ref[2]);
|
||||||
|
// printf("size: %d data: 0x%x 0x%x 0x%x\n", size, midi_dut[0], midi_dut[1], midi_dut[2]);
|
||||||
|
//TEST_ASSERT_EQUAL_UINT32_ARRAY not working!?
|
||||||
|
for(int i = 0; i < size; i++){
|
||||||
|
TEST_ASSERT_EQUAL_UINT32(midi_ref[i], midi_dut[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void test_midi_pressure(void) {
|
||||||
|
for(int cmd = PRESSURE; cmd < PRESSURE + NUM_CHANS; cmd++){
|
||||||
|
for(int test = 0; test < NUM_TESTS_PER_TEST; test++){
|
||||||
|
unsigned midi_ref[3] = {cmd, random(&rndm) & DATA_MASK, random(&rndm) & DATA_MASK};
|
||||||
|
unsigned packed = midi_in_parse_ut(midi_ref);
|
||||||
|
unsigned midi_dut[3] = {0};
|
||||||
|
unsigned size = 0;
|
||||||
|
midi_out_parse_c_wrapper(packed, midi_dut, &size);
|
||||||
|
// printf("size: %d data: 0x%x 0x%x 0x%x\n", size, midi_ref[0], midi_ref[1], midi_ref[2]);
|
||||||
|
// printf("size: %d data: 0x%x 0x%x 0x%x\n", size, midi_dut[0], midi_dut[1], midi_dut[2]);
|
||||||
|
//TEST_ASSERT_EQUAL_UINT32_ARRAY not working!?
|
||||||
|
for(int i = 0; i < size; i++){
|
||||||
|
TEST_ASSERT_EQUAL_UINT32(midi_ref[i], midi_dut[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void test_midi_control(void) {
|
||||||
|
for(int cmd = CONTROL; cmd < CONTROL + NUM_CHANS; cmd++){
|
||||||
|
for(int test = 0; test < NUM_TESTS_PER_TEST; test++){
|
||||||
|
unsigned midi_ref[3] = {cmd, random(&rndm) & DATA_MASK, random(&rndm) & DATA_MASK};
|
||||||
|
unsigned packed = midi_in_parse_ut(midi_ref);
|
||||||
|
unsigned midi_dut[3] = {0};
|
||||||
|
unsigned size = 0;
|
||||||
|
midi_out_parse_c_wrapper(packed, midi_dut, &size);
|
||||||
|
// printf("size: %d data: 0x%x 0x%x 0x%x\n", size, midi_ref[0], midi_ref[1], midi_ref[2]);
|
||||||
|
// printf("size: %d data: 0x%x 0x%x 0x%x\n", size, midi_dut[0], midi_dut[1], midi_dut[2]);
|
||||||
|
//TEST_ASSERT_EQUAL_UINT32_ARRAY not working!?
|
||||||
|
for(int i = 0; i < size; i++){
|
||||||
|
TEST_ASSERT_EQUAL_UINT32(midi_ref[i], midi_dut[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void test_midi_program(void) {
|
||||||
|
for(int cmd = PROGRAM; cmd < PROGRAM + NUM_CHANS; cmd++){
|
||||||
|
for(int test = 0; test < NUM_TESTS_PER_TEST; test++){
|
||||||
|
unsigned midi_ref[3] = {cmd, random(&rndm) & DATA_MASK, random(&rndm) & DATA_MASK};
|
||||||
|
unsigned packed = midi_in_parse_ut(midi_ref);
|
||||||
|
unsigned midi_dut[3] = {0};
|
||||||
|
unsigned size = 0;
|
||||||
|
midi_out_parse_c_wrapper(packed, midi_dut, &size);
|
||||||
|
// printf("size: %d data: 0x%x 0x%x 0x%x\n", size, midi_ref[0], midi_ref[1], midi_ref[2]);
|
||||||
|
// printf("size: %d data: 0x%x 0x%x 0x%x\n", size, midi_dut[0], midi_dut[1], midi_dut[2]);
|
||||||
|
//TEST_ASSERT_EQUAL_UINT32_ARRAY not working!?
|
||||||
|
for(int i = 0; i < size; i++){
|
||||||
|
TEST_ASSERT_EQUAL_UINT32(midi_ref[i], midi_dut[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void test_midi_pressure_val(void) {
|
||||||
|
for(int cmd = PRESSURE_VAL; cmd < PRESSURE_VAL + NUM_CHANS; cmd++){
|
||||||
|
for(int test = 0; test < NUM_TESTS_PER_TEST; test++){
|
||||||
|
unsigned midi_ref[3] = {cmd, random(&rndm) & DATA_MASK, random(&rndm) & DATA_MASK};
|
||||||
|
unsigned packed = midi_in_parse_ut(midi_ref);
|
||||||
|
unsigned midi_dut[3] = {0};
|
||||||
|
unsigned size = 0;
|
||||||
|
midi_out_parse_c_wrapper(packed, midi_dut, &size);
|
||||||
|
// printf("size: %d data: 0x%x 0x%x 0x%x\n", size, midi_ref[0], midi_ref[1], midi_ref[2]);
|
||||||
|
// printf("size: %d data: 0x%x 0x%x 0x%x\n", size, midi_dut[0], midi_dut[1], midi_dut[2]);
|
||||||
|
//TEST_ASSERT_EQUAL_UINT32_ARRAY not working!?
|
||||||
|
for(int i = 0; i < size; i++){
|
||||||
|
TEST_ASSERT_EQUAL_UINT32(midi_ref[i], midi_dut[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void test_midi_range(void) {
|
||||||
|
for(int cmd = RANGE; cmd < RANGE + NUM_CHANS; cmd++){
|
||||||
|
for(int test = 0; test < NUM_TESTS_PER_TEST; test++){
|
||||||
|
unsigned midi_ref[3] = {cmd, random(&rndm) & DATA_MASK, random(&rndm) & DATA_MASK};
|
||||||
|
unsigned packed = midi_in_parse_ut(midi_ref);
|
||||||
|
unsigned midi_dut[3] = {0};
|
||||||
|
unsigned size = 0;
|
||||||
|
midi_out_parse_c_wrapper(packed, midi_dut, &size);
|
||||||
|
// printf("size: %d data: 0x%x 0x%x 0x%x\n", size, midi_ref[0], midi_ref[1], midi_ref[2]);
|
||||||
|
// printf("size: %d data: 0x%x 0x%x 0x%x\n", size, midi_dut[0], midi_dut[1], midi_dut[2]);
|
||||||
|
//TEST_ASSERT_EQUAL_UINT32_ARRAY not working!?
|
||||||
|
for(int i = 0; i < size; i++){
|
||||||
|
TEST_ASSERT_EQUAL_UINT32(midi_ref[i], midi_dut[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void test_midi_manufacturer_id(void) {
|
||||||
|
for(int cmd = MANUFACTURE_ID; cmd < MANUFACTURE_ID + NUM_CHANS; cmd++){
|
||||||
|
for(int test = 0; test < NUM_TESTS_PER_TEST; test++){
|
||||||
|
unsigned midi_ref[3] = {cmd, random(&rndm) & DATA_MASK, random(&rndm) & DATA_MASK};
|
||||||
|
unsigned packed = midi_in_parse_ut(midi_ref);
|
||||||
|
unsigned midi_dut[3] = {0};
|
||||||
|
unsigned size = 0;
|
||||||
|
midi_out_parse_c_wrapper(packed, midi_dut, &size);
|
||||||
|
// printf("size: %d data: 0x%x 0x%x 0x%x\n", size, midi_ref[0], midi_ref[1], midi_ref[2]);
|
||||||
|
// printf("size: %d data: 0x%x 0x%x 0x%x\n", size, midi_dut[0], midi_dut[1], midi_dut[2]);
|
||||||
|
//TEST_ASSERT_EQUAL_UINT32_ARRAY not working!?
|
||||||
|
for(int i = 0; i < size; i++){
|
||||||
|
TEST_ASSERT_EQUAL_UINT32(midi_ref[i], midi_dut[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
77
tests/xua_unit_tests/src/test_midi_queue/test_midi_queue.c
Normal file
77
tests/xua_unit_tests/src/test_midi_queue/test_midi_queue.c
Normal file
@@ -0,0 +1,77 @@
|
|||||||
|
// Copyright 2024 XMOS LIMITED.
|
||||||
|
// This Software is subject to the terms of the XMOS Public Licence: Version 1.
|
||||||
|
#include <stddef.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
#include "xua_unit_tests.h"
|
||||||
|
#include "../../../lib_xua/src/midi/queue.h"
|
||||||
|
|
||||||
|
#define DEBUG 0
|
||||||
|
|
||||||
|
#if DEBUG
|
||||||
|
#define dprintf(...) printf(__VA_ARGS__)
|
||||||
|
#else
|
||||||
|
#define dprintf(...)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
#define RANDOM_SEED 55378008
|
||||||
|
#define USB_MIDI_DEVICE_OUT_FIFO_SIZE 1024
|
||||||
|
#define ARRAY_SIZE(x) (sizeof(x) / sizeof(x[0]))
|
||||||
|
|
||||||
|
unsigned rndm = RANDOM_SEED;
|
||||||
|
|
||||||
|
|
||||||
|
void test_midi_queue_init(void) {
|
||||||
|
queue_t symbol_fifo;
|
||||||
|
unsigned symbol_fifo_storage[USB_MIDI_DEVICE_OUT_FIFO_SIZE];
|
||||||
|
queue_init_c_wrapper(&symbol_fifo, ARRAY_SIZE(symbol_fifo_storage));
|
||||||
|
|
||||||
|
int empty = queue_is_empty_c_wrapper(&symbol_fifo);
|
||||||
|
TEST_ASSERT_EQUAL_INT32(1, empty);
|
||||||
|
|
||||||
|
int full = queue_is_full_c_wrapper(&symbol_fifo);
|
||||||
|
TEST_ASSERT_EQUAL_INT32(0, full);
|
||||||
|
|
||||||
|
unsigned items = queue_items_c_wrapper(&symbol_fifo);
|
||||||
|
TEST_ASSERT_EQUAL_UINT32(0, items);
|
||||||
|
|
||||||
|
unsigned space = queue_space_c_wrapper(&symbol_fifo);
|
||||||
|
TEST_ASSERT_EQUAL_UINT32(USB_MIDI_DEVICE_OUT_FIFO_SIZE, space);
|
||||||
|
}
|
||||||
|
|
||||||
|
void test_midi_queue_push_pop(void) {
|
||||||
|
queue_t symbol_fifo;
|
||||||
|
unsigned symbol_fifo_storage[USB_MIDI_DEVICE_OUT_FIFO_SIZE];
|
||||||
|
queue_init_c_wrapper(&symbol_fifo, ARRAY_SIZE(symbol_fifo_storage));
|
||||||
|
|
||||||
|
for(unsigned i = 0; i < USB_MIDI_DEVICE_OUT_FIFO_SIZE; i++){
|
||||||
|
int items = queue_items_c_wrapper(&symbol_fifo);
|
||||||
|
dprintf("Pre i: %u items: %d\n", i, items);
|
||||||
|
TEST_ASSERT_EQUAL_UINT32(i, items);
|
||||||
|
|
||||||
|
unsigned entry = i + 1000;
|
||||||
|
queue_push_word_c_wrapper(&symbol_fifo, symbol_fifo_storage, entry);
|
||||||
|
dprintf("pushed: %u\n", entry);
|
||||||
|
|
||||||
|
items = queue_items_c_wrapper(&symbol_fifo);
|
||||||
|
TEST_ASSERT_EQUAL_UINT32(i + 1, items);
|
||||||
|
|
||||||
|
dprintf("Post items: %d\n", items);
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned counter = 0;
|
||||||
|
for(int i = USB_MIDI_DEVICE_OUT_FIFO_SIZE; i > 0; i--){
|
||||||
|
int items = queue_items_c_wrapper(&symbol_fifo);
|
||||||
|
dprintf("i: %u items: %d\n", i, items);
|
||||||
|
TEST_ASSERT_EQUAL_UINT32(i, items);
|
||||||
|
|
||||||
|
unsigned entry = queue_pop_word_c_wrapper(&symbol_fifo, symbol_fifo_storage);
|
||||||
|
unsigned expected = 1000 + counter;
|
||||||
|
|
||||||
|
dprintf("expected: %u got: %d\n", expected, entry);
|
||||||
|
TEST_ASSERT_EQUAL_UINT32(expected, entry);
|
||||||
|
|
||||||
|
counter++;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
// Copyright 2021-2022 XMOS LIMITED.
|
// Copyright 2021-2024 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 <stddef.h>
|
#include <stddef.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
@@ -47,23 +47,26 @@ static unsigned construct_usage_header( unsigned size )
|
|||||||
return header;
|
return header;
|
||||||
}
|
}
|
||||||
|
|
||||||
void setUp( void )
|
void test_init( void )
|
||||||
{
|
{
|
||||||
hidReportInit();
|
hidReportInit();
|
||||||
hidResetReportDescriptor();
|
hidResetReportDescriptor();
|
||||||
}
|
}
|
||||||
|
|
||||||
void test_validate_report( void ) {
|
void test_validate_report( void ) {
|
||||||
|
test_init();
|
||||||
unsigned retVal = hidReportValidate();
|
unsigned retVal = hidReportValidate();
|
||||||
TEST_ASSERT_EQUAL_UINT( HID_STATUS_GOOD, retVal );
|
TEST_ASSERT_EQUAL_UINT( HID_STATUS_GOOD, retVal );
|
||||||
}
|
}
|
||||||
|
|
||||||
void test_reportid_in_use( void ) {
|
void test_reportid_in_use( void ) {
|
||||||
|
test_init();
|
||||||
unsigned reportIdInUse = hidIsReportIdInUse();
|
unsigned reportIdInUse = hidIsReportIdInUse();
|
||||||
TEST_ASSERT_EQUAL_UINT( 1, reportIdInUse );
|
TEST_ASSERT_EQUAL_UINT( 1, reportIdInUse );
|
||||||
}
|
}
|
||||||
|
|
||||||
void test_get_next_valid_report_id( void ) {
|
void test_get_next_valid_report_id( void ) {
|
||||||
|
test_init();
|
||||||
unsigned reportId = 0U;
|
unsigned reportId = 0U;
|
||||||
|
|
||||||
reportId = hidGetNextValidReportId(reportId);
|
reportId = hidGetNextValidReportId(reportId);
|
||||||
@@ -80,6 +83,7 @@ void test_get_next_valid_report_id( void ) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void test_is_report_id_valid( void ) {
|
void test_is_report_id_valid( void ) {
|
||||||
|
test_init();
|
||||||
unsigned isValid = 0;
|
unsigned isValid = 0;
|
||||||
|
|
||||||
unsigned reportId = 0;
|
unsigned reportId = 0;
|
||||||
@@ -106,6 +110,7 @@ void test_is_report_id_valid( void ) {
|
|||||||
// Basic report descriptor tests
|
// Basic report descriptor tests
|
||||||
void test_unprepared_hidGetReportDescriptor( void )
|
void test_unprepared_hidGetReportDescriptor( void )
|
||||||
{
|
{
|
||||||
|
test_init();
|
||||||
unsigned char* reportDescPtr = hidGetReportDescriptor();
|
unsigned char* reportDescPtr = hidGetReportDescriptor();
|
||||||
TEST_ASSERT_NULL( reportDescPtr );
|
TEST_ASSERT_NULL( reportDescPtr );
|
||||||
|
|
||||||
@@ -118,6 +123,7 @@ void test_unprepared_hidGetReportDescriptor( void )
|
|||||||
|
|
||||||
void test_prepared_hidGetReportDescriptor( void )
|
void test_prepared_hidGetReportDescriptor( void )
|
||||||
{
|
{
|
||||||
|
test_init();
|
||||||
hidPrepareReportDescriptor();
|
hidPrepareReportDescriptor();
|
||||||
unsigned char* reportDescPtr = hidGetReportDescriptor();
|
unsigned char* reportDescPtr = hidGetReportDescriptor();
|
||||||
TEST_ASSERT_NOT_NULL( reportDescPtr );
|
TEST_ASSERT_NOT_NULL( reportDescPtr );
|
||||||
@@ -137,6 +143,7 @@ void test_prepared_hidGetReportDescriptor( void )
|
|||||||
|
|
||||||
void test_reset_unprepared_hidGetReportDescriptor( void )
|
void test_reset_unprepared_hidGetReportDescriptor( void )
|
||||||
{
|
{
|
||||||
|
test_init();
|
||||||
hidPrepareReportDescriptor();
|
hidPrepareReportDescriptor();
|
||||||
hidResetReportDescriptor();
|
hidResetReportDescriptor();
|
||||||
unsigned char* reportDescPtr = hidGetReportDescriptor();
|
unsigned char* reportDescPtr = hidGetReportDescriptor();
|
||||||
@@ -145,6 +152,7 @@ void test_reset_unprepared_hidGetReportDescriptor( void )
|
|||||||
|
|
||||||
void test_reset_prepared_hidGetReportDescriptor( void )
|
void test_reset_prepared_hidGetReportDescriptor( void )
|
||||||
{
|
{
|
||||||
|
test_init();
|
||||||
hidPrepareReportDescriptor();
|
hidPrepareReportDescriptor();
|
||||||
hidResetReportDescriptor();
|
hidResetReportDescriptor();
|
||||||
hidPrepareReportDescriptor();
|
hidPrepareReportDescriptor();
|
||||||
@@ -154,6 +162,7 @@ void test_reset_prepared_hidGetReportDescriptor( void )
|
|||||||
|
|
||||||
void test_report_id_limit( void )
|
void test_report_id_limit( void )
|
||||||
{
|
{
|
||||||
|
test_init();
|
||||||
unsigned reportIdLimit = hidGetReportIdLimit();
|
unsigned reportIdLimit = hidGetReportIdLimit();
|
||||||
TEST_ASSERT_EQUAL_UINT( HID_REPORTID_LIMIT, reportIdLimit );
|
TEST_ASSERT_EQUAL_UINT( HID_REPORTID_LIMIT, reportIdLimit );
|
||||||
}
|
}
|
||||||
@@ -161,6 +170,7 @@ void test_report_id_limit( void )
|
|||||||
// Basic item tests
|
// Basic item tests
|
||||||
void test_max_loc_hidGetReportItem( void )
|
void test_max_loc_hidGetReportItem( void )
|
||||||
{
|
{
|
||||||
|
test_init();
|
||||||
unsigned char data[ HID_REPORT_ITEM_MAX_SIZE ];
|
unsigned char data[ HID_REPORT_ITEM_MAX_SIZE ];
|
||||||
unsigned char header;
|
unsigned char header;
|
||||||
unsigned char page;
|
unsigned char page;
|
||||||
@@ -199,6 +209,7 @@ void test_max_loc_hidGetReportItem( void )
|
|||||||
|
|
||||||
void test_min_loc_hidGetReportItem( void )
|
void test_min_loc_hidGetReportItem( void )
|
||||||
{
|
{
|
||||||
|
test_init();
|
||||||
unsigned char data[ HID_REPORT_ITEM_MAX_SIZE ];
|
unsigned char data[ HID_REPORT_ITEM_MAX_SIZE ];
|
||||||
unsigned char header;
|
unsigned char header;
|
||||||
unsigned char page;
|
unsigned char page;
|
||||||
@@ -236,6 +247,7 @@ void test_min_loc_hidGetReportItem( void )
|
|||||||
|
|
||||||
void test_invalid_report_id( void )
|
void test_invalid_report_id( void )
|
||||||
{
|
{
|
||||||
|
test_init();
|
||||||
unsigned char data[ HID_REPORT_ITEM_MAX_SIZE ] = { 0xBA, 0xD2 };
|
unsigned char data[ HID_REPORT_ITEM_MAX_SIZE ] = { 0xBA, 0xD2 };
|
||||||
unsigned char header = 0x33;
|
unsigned char header = 0x33;
|
||||||
unsigned char page = 0x44;
|
unsigned char page = 0x44;
|
||||||
@@ -253,6 +265,7 @@ void test_invalid_report_id( void )
|
|||||||
|
|
||||||
void test_unused_report_id( void )
|
void test_unused_report_id( void )
|
||||||
{
|
{
|
||||||
|
test_init();
|
||||||
unsigned char data[ HID_REPORT_ITEM_MAX_SIZE ] = { 0xBA, 0xD2 };
|
unsigned char data[ HID_REPORT_ITEM_MAX_SIZE ] = { 0xBA, 0xD2 };
|
||||||
unsigned char header = 0x33;
|
unsigned char header = 0x33;
|
||||||
unsigned char page = 0x44;
|
unsigned char page = 0x44;
|
||||||
@@ -270,6 +283,7 @@ void test_unused_report_id( void )
|
|||||||
|
|
||||||
void test_overflow_bit_hidGetReportItem( void )
|
void test_overflow_bit_hidGetReportItem( void )
|
||||||
{
|
{
|
||||||
|
test_init();
|
||||||
unsigned char data[ HID_REPORT_ITEM_MAX_SIZE ] = { 0xBA, 0xD1 };
|
unsigned char data[ HID_REPORT_ITEM_MAX_SIZE ] = { 0xBA, 0xD1 };
|
||||||
unsigned char header = 0xAA;
|
unsigned char header = 0xAA;
|
||||||
unsigned char page = 0x44;
|
unsigned char page = 0x44;
|
||||||
@@ -307,6 +321,7 @@ void test_overflow_bit_hidGetReportItem( void )
|
|||||||
|
|
||||||
void test_overflow_byte_hidGetReportItem( void )
|
void test_overflow_byte_hidGetReportItem( void )
|
||||||
{
|
{
|
||||||
|
test_init();
|
||||||
unsigned char data[ HID_REPORT_ITEM_MAX_SIZE ] = { 0xBA, 0xD1 };
|
unsigned char data[ HID_REPORT_ITEM_MAX_SIZE ] = { 0xBA, 0xD1 };
|
||||||
unsigned char header = 0xAA;
|
unsigned char header = 0xAA;
|
||||||
unsigned char page = 0x44;
|
unsigned char page = 0x44;
|
||||||
@@ -344,6 +359,7 @@ void test_overflow_byte_hidGetReportItem( void )
|
|||||||
|
|
||||||
void test_underflow_bit_hidGetReportItem( void )
|
void test_underflow_bit_hidGetReportItem( void )
|
||||||
{
|
{
|
||||||
|
test_init();
|
||||||
unsigned char data[ HID_REPORT_ITEM_MAX_SIZE ] = { 0xBA, 0xD1 };
|
unsigned char data[ HID_REPORT_ITEM_MAX_SIZE ] = { 0xBA, 0xD1 };
|
||||||
unsigned char header = 0xAA;
|
unsigned char header = 0xAA;
|
||||||
unsigned char page = 0x44;
|
unsigned char page = 0x44;
|
||||||
@@ -381,6 +397,7 @@ void test_underflow_bit_hidGetReportItem( void )
|
|||||||
|
|
||||||
void test_underflow_byte_hidGetReportItem( void )
|
void test_underflow_byte_hidGetReportItem( void )
|
||||||
{
|
{
|
||||||
|
test_init();
|
||||||
unsigned char data[ HID_REPORT_ITEM_MAX_SIZE ] = { 0xBA, 0xD1 };
|
unsigned char data[ HID_REPORT_ITEM_MAX_SIZE ] = { 0xBA, 0xD1 };
|
||||||
unsigned char header = 0xAA;
|
unsigned char header = 0xAA;
|
||||||
unsigned char page = 0x44;
|
unsigned char page = 0x44;
|
||||||
@@ -419,6 +436,7 @@ void test_underflow_byte_hidGetReportItem( void )
|
|||||||
// Configurable and non-configurable item tests
|
// Configurable and non-configurable item tests
|
||||||
void test_configurable_item_hidSetReportItem( void )
|
void test_configurable_item_hidSetReportItem( void )
|
||||||
{
|
{
|
||||||
|
test_init();
|
||||||
const unsigned reportId = 1;
|
const unsigned reportId = 1;
|
||||||
const unsigned bit = REPORT1_MIN_VALID_BIT;
|
const unsigned bit = REPORT1_MIN_VALID_BIT;
|
||||||
const unsigned byte = REPORT1_MIN_VALID_BYTE;
|
const unsigned byte = REPORT1_MIN_VALID_BYTE;
|
||||||
@@ -440,6 +458,7 @@ void test_configurable_item_hidSetReportItem( void )
|
|||||||
// Testing that the high byte of the report gets correctly cleared
|
// Testing that the high byte of the report gets correctly cleared
|
||||||
void test_configurable_item_hidSetReportItem_multibyte_orig( void )
|
void test_configurable_item_hidSetReportItem_multibyte_orig( void )
|
||||||
{
|
{
|
||||||
|
test_init();
|
||||||
const unsigned reportId = 2;
|
const unsigned reportId = 2;
|
||||||
const unsigned bit = 1; // This byte&bit combo is originally set be 2 bytes long in the header
|
const unsigned bit = 1; // This byte&bit combo is originally set be 2 bytes long in the header
|
||||||
const unsigned byte = 0;
|
const unsigned byte = 0;
|
||||||
@@ -460,6 +479,7 @@ void test_configurable_item_hidSetReportItem_multibyte_orig( void )
|
|||||||
|
|
||||||
void test_nonconfigurable_item_hidSetReportItem( void )
|
void test_nonconfigurable_item_hidSetReportItem( void )
|
||||||
{
|
{
|
||||||
|
test_init();
|
||||||
const unsigned reportId = 1;
|
const unsigned reportId = 1;
|
||||||
const unsigned bit = 1; // This bit and byte combination should not appear in the
|
const unsigned bit = 1; // This bit and byte combination should not appear in the
|
||||||
const unsigned byte = 0; // hidConfigurableElements list in hid_report_descriptors.c.
|
const unsigned byte = 0; // hidConfigurableElements list in hid_report_descriptors.c.
|
||||||
@@ -474,6 +494,7 @@ void test_nonconfigurable_item_hidSetReportItem( void )
|
|||||||
// Bit range tests
|
// Bit range tests
|
||||||
void test_max_bit_hidSetReportItem( void )
|
void test_max_bit_hidSetReportItem( void )
|
||||||
{
|
{
|
||||||
|
test_init();
|
||||||
const unsigned char header = construct_usage_header( 0 );
|
const unsigned char header = construct_usage_header( 0 );
|
||||||
|
|
||||||
unsigned reportId = 1;
|
unsigned reportId = 1;
|
||||||
@@ -500,6 +521,7 @@ void test_max_bit_hidSetReportItem( void )
|
|||||||
|
|
||||||
void test_min_bit_hidSetReportItem( void )
|
void test_min_bit_hidSetReportItem( void )
|
||||||
{
|
{
|
||||||
|
test_init();
|
||||||
const unsigned char header = construct_usage_header( 0 );
|
const unsigned char header = construct_usage_header( 0 );
|
||||||
|
|
||||||
unsigned reportId = 1;
|
unsigned reportId = 1;
|
||||||
@@ -526,6 +548,7 @@ void test_min_bit_hidSetReportItem( void )
|
|||||||
|
|
||||||
void test_overflow_bit_hidSetReportItem( void )
|
void test_overflow_bit_hidSetReportItem( void )
|
||||||
{
|
{
|
||||||
|
test_init();
|
||||||
const unsigned char header = construct_usage_header( 0 );
|
const unsigned char header = construct_usage_header( 0 );
|
||||||
|
|
||||||
unsigned reportId = 1;
|
unsigned reportId = 1;
|
||||||
@@ -552,6 +575,7 @@ void test_overflow_bit_hidSetReportItem( void )
|
|||||||
|
|
||||||
void test_underflow_bit_hidSetReportItem( void )
|
void test_underflow_bit_hidSetReportItem( void )
|
||||||
{
|
{
|
||||||
|
test_init();
|
||||||
const unsigned char header = construct_usage_header( 0 );
|
const unsigned char header = construct_usage_header( 0 );
|
||||||
|
|
||||||
unsigned reportId = 1;
|
unsigned reportId = 1;
|
||||||
@@ -578,6 +602,7 @@ void test_underflow_bit_hidSetReportItem( void )
|
|||||||
|
|
||||||
void test_overflow_byte_hidSetReportItem( void )
|
void test_overflow_byte_hidSetReportItem( void )
|
||||||
{
|
{
|
||||||
|
test_init();
|
||||||
const unsigned char header = construct_usage_header( 0 );
|
const unsigned char header = construct_usage_header( 0 );
|
||||||
|
|
||||||
unsigned reportId = 1;
|
unsigned reportId = 1;
|
||||||
@@ -604,6 +629,7 @@ void test_overflow_byte_hidSetReportItem( void )
|
|||||||
|
|
||||||
void test_underflow_byte_hidSetReportItem( void )
|
void test_underflow_byte_hidSetReportItem( void )
|
||||||
{
|
{
|
||||||
|
test_init();
|
||||||
const unsigned char header = construct_usage_header( 0 );
|
const unsigned char header = construct_usage_header( 0 );
|
||||||
|
|
||||||
unsigned reportId = 1;
|
unsigned reportId = 1;
|
||||||
@@ -631,6 +657,7 @@ void test_underflow_byte_hidSetReportItem( void )
|
|||||||
// Size range tests
|
// Size range tests
|
||||||
void test_max_size_hidSetReportItem( void )
|
void test_max_size_hidSetReportItem( void )
|
||||||
{
|
{
|
||||||
|
test_init();
|
||||||
const unsigned reportId = 1;
|
const unsigned reportId = 1;
|
||||||
const unsigned bit = REPORT1_MIN_VALID_BIT;
|
const unsigned bit = REPORT1_MIN_VALID_BIT;
|
||||||
const unsigned byte = REPORT1_MIN_VALID_BYTE;
|
const unsigned byte = REPORT1_MIN_VALID_BYTE;
|
||||||
@@ -644,6 +671,7 @@ void test_max_size_hidSetReportItem( void )
|
|||||||
|
|
||||||
void test_min_size_hidSetReportItem( void )
|
void test_min_size_hidSetReportItem( void )
|
||||||
{
|
{
|
||||||
|
test_init();
|
||||||
const unsigned reportId = 1;
|
const unsigned reportId = 1;
|
||||||
const unsigned bit = REPORT1_MIN_VALID_BIT;
|
const unsigned bit = REPORT1_MIN_VALID_BIT;
|
||||||
const unsigned byte = REPORT1_MIN_VALID_BYTE;
|
const unsigned byte = REPORT1_MIN_VALID_BYTE;
|
||||||
@@ -656,6 +684,7 @@ void test_min_size_hidSetReportItem( void )
|
|||||||
|
|
||||||
void test_unsupported_size_hidSetReportItem( void )
|
void test_unsupported_size_hidSetReportItem( void )
|
||||||
{
|
{
|
||||||
|
test_init();
|
||||||
const unsigned reportId = 0;
|
const unsigned reportId = 0;
|
||||||
const unsigned bit = REPORT1_MIN_VALID_BIT;
|
const unsigned bit = REPORT1_MIN_VALID_BIT;
|
||||||
const unsigned byte = REPORT1_MIN_VALID_BYTE;
|
const unsigned byte = REPORT1_MIN_VALID_BYTE;
|
||||||
@@ -669,6 +698,7 @@ void test_unsupported_size_hidSetReportItem( void )
|
|||||||
// Combined function tests
|
// Combined function tests
|
||||||
void test_initial_modification_without_subsequent_preparation( void )
|
void test_initial_modification_without_subsequent_preparation( void )
|
||||||
{
|
{
|
||||||
|
test_init();
|
||||||
const unsigned reportId = 2;
|
const unsigned reportId = 2;
|
||||||
const unsigned bit = REPORT2_MIN_VALID_BIT;
|
const unsigned bit = REPORT2_MIN_VALID_BIT;
|
||||||
const unsigned byte = REPORT2_MIN_VALID_BYTE;
|
const unsigned byte = REPORT2_MIN_VALID_BYTE;
|
||||||
@@ -685,6 +715,7 @@ void test_initial_modification_without_subsequent_preparation( void )
|
|||||||
|
|
||||||
void test_initial_modification_with_subsequent_preparation( void )
|
void test_initial_modification_with_subsequent_preparation( void )
|
||||||
{
|
{
|
||||||
|
test_init();
|
||||||
const unsigned reportId = 2;
|
const unsigned reportId = 2;
|
||||||
const unsigned bit = REPORT2_MIN_VALID_BIT;
|
const unsigned bit = REPORT2_MIN_VALID_BIT;
|
||||||
const unsigned byte = REPORT2_MIN_VALID_BYTE;
|
const unsigned byte = REPORT2_MIN_VALID_BYTE;
|
||||||
@@ -702,6 +733,7 @@ void test_initial_modification_with_subsequent_preparation( void )
|
|||||||
|
|
||||||
void test_initial_modification_with_subsequent_verification_1( void )
|
void test_initial_modification_with_subsequent_verification_1( void )
|
||||||
{
|
{
|
||||||
|
test_init();
|
||||||
const unsigned reportId = 2;
|
const unsigned reportId = 2;
|
||||||
const unsigned bit = REPORT2_MIN_VALID_BIT;
|
const unsigned bit = REPORT2_MIN_VALID_BIT;
|
||||||
const unsigned byte = REPORT2_MIN_VALID_BYTE;
|
const unsigned byte = REPORT2_MIN_VALID_BYTE;
|
||||||
@@ -727,6 +759,7 @@ void test_initial_modification_with_subsequent_verification_1( void )
|
|||||||
|
|
||||||
void test_initial_modification_with_subsequent_verification_2( void )
|
void test_initial_modification_with_subsequent_verification_2( void )
|
||||||
{
|
{
|
||||||
|
test_init();
|
||||||
const unsigned reportId = 3;
|
const unsigned reportId = 3;
|
||||||
const unsigned bit = REPORT3_MIN_VALID_BIT;
|
const unsigned bit = REPORT3_MIN_VALID_BIT;
|
||||||
const unsigned byte = REPORT3_MIN_VALID_BYTE;
|
const unsigned byte = REPORT3_MIN_VALID_BYTE;
|
||||||
@@ -775,6 +808,7 @@ void test_initial_modification_with_subsequent_verification_2( void )
|
|||||||
//setIdle and associated timing functionality tests
|
//setIdle and associated timing functionality tests
|
||||||
void test_set_idle( void )
|
void test_set_idle( void )
|
||||||
{
|
{
|
||||||
|
test_init();
|
||||||
unsigned reportId = 1;
|
unsigned reportId = 1;
|
||||||
unsigned reportId2 = 2;
|
unsigned reportId2 = 2;
|
||||||
|
|
||||||
@@ -794,6 +828,7 @@ void test_set_idle( void )
|
|||||||
|
|
||||||
void test_set_all_idle( void )
|
void test_set_all_idle( void )
|
||||||
{
|
{
|
||||||
|
test_init();
|
||||||
unsigned reportId = 1;
|
unsigned reportId = 1;
|
||||||
unsigned reportId2 = 2;
|
unsigned reportId2 = 2;
|
||||||
|
|
||||||
@@ -812,6 +847,7 @@ void test_set_all_idle( void )
|
|||||||
|
|
||||||
void test_change_pending( void )
|
void test_change_pending( void )
|
||||||
{
|
{
|
||||||
|
test_init();
|
||||||
unsigned reportId = 1;
|
unsigned reportId = 1;
|
||||||
unsigned reportId2 = 2;
|
unsigned reportId2 = 2;
|
||||||
|
|
||||||
@@ -831,6 +867,7 @@ void test_change_pending( void )
|
|||||||
|
|
||||||
void test_change_pending_all( void )
|
void test_change_pending_all( void )
|
||||||
{
|
{
|
||||||
|
test_init();
|
||||||
unsigned reportId = 1;
|
unsigned reportId = 1;
|
||||||
|
|
||||||
unsigned changePending = hidIsChangePending( reportId );
|
unsigned changePending = hidIsChangePending( reportId );
|
||||||
@@ -845,6 +882,7 @@ void test_change_pending_all( void )
|
|||||||
|
|
||||||
void test_report_time( void )
|
void test_report_time( void )
|
||||||
{
|
{
|
||||||
|
test_init();
|
||||||
unsigned reportTime1 = 123;
|
unsigned reportTime1 = 123;
|
||||||
unsigned reportTime2 = 456;
|
unsigned reportTime2 = 456;
|
||||||
|
|
||||||
@@ -859,6 +897,7 @@ void test_report_time( void )
|
|||||||
|
|
||||||
void test_report_time_calc( void )
|
void test_report_time_calc( void )
|
||||||
{
|
{
|
||||||
|
test_init();
|
||||||
unsigned reportTime1 = 123;
|
unsigned reportTime1 = 123;
|
||||||
unsigned reportTime2 = 456;
|
unsigned reportTime2 = 456;
|
||||||
unsigned reportPeriod1 = 10;
|
unsigned reportPeriod1 = 10;
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
// Copyright 2021-2022 XMOS LIMITED.
|
// Copyright 2021-2024 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 <stddef.h>
|
#include <stddef.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
@@ -34,23 +34,26 @@ static unsigned construct_usage_header( unsigned size )
|
|||||||
return header;
|
return header;
|
||||||
}
|
}
|
||||||
|
|
||||||
void setUp( void )
|
void test_init( void )
|
||||||
{
|
{
|
||||||
hidReportInit();
|
hidReportInit();
|
||||||
hidResetReportDescriptor();
|
hidResetReportDescriptor();
|
||||||
}
|
}
|
||||||
|
|
||||||
void test_validate_report( void ) {
|
void test_validate_report( void ) {
|
||||||
|
test_init();
|
||||||
unsigned retVal = hidReportValidate();
|
unsigned retVal = hidReportValidate();
|
||||||
TEST_ASSERT_EQUAL_UINT( HID_STATUS_GOOD, retVal );
|
TEST_ASSERT_EQUAL_UINT( HID_STATUS_GOOD, retVal );
|
||||||
}
|
}
|
||||||
|
|
||||||
void test_reportid_in_use( void ) {
|
void test_reportid_in_use( void ) {
|
||||||
|
test_init();
|
||||||
unsigned reportIdInUse = hidIsReportIdInUse();
|
unsigned reportIdInUse = hidIsReportIdInUse();
|
||||||
TEST_ASSERT_EQUAL_UINT( 0, reportIdInUse );
|
TEST_ASSERT_EQUAL_UINT( 0, reportIdInUse );
|
||||||
}
|
}
|
||||||
|
|
||||||
void test_get_next_valid_report_id( void ) {
|
void test_get_next_valid_report_id( void ) {
|
||||||
|
test_init();
|
||||||
unsigned reportId = 0U;
|
unsigned reportId = 0U;
|
||||||
|
|
||||||
reportId = hidGetNextValidReportId(reportId);
|
reportId = hidGetNextValidReportId(reportId);
|
||||||
@@ -61,6 +64,7 @@ void test_get_next_valid_report_id( void ) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void test_is_report_id_valid( void ) {
|
void test_is_report_id_valid( void ) {
|
||||||
|
test_init();
|
||||||
unsigned isValid = 0;
|
unsigned isValid = 0;
|
||||||
|
|
||||||
unsigned reportId = 0;
|
unsigned reportId = 0;
|
||||||
@@ -75,6 +79,7 @@ void test_is_report_id_valid( void ) {
|
|||||||
// Basic report descriptor tests
|
// Basic report descriptor tests
|
||||||
void test_unprepared_hidGetReportDescriptor( void )
|
void test_unprepared_hidGetReportDescriptor( void )
|
||||||
{
|
{
|
||||||
|
test_init();
|
||||||
const unsigned reportId = 0;
|
const unsigned reportId = 0;
|
||||||
unsigned char* reportDescPtr = hidGetReportDescriptor();
|
unsigned char* reportDescPtr = hidGetReportDescriptor();
|
||||||
TEST_ASSERT_NULL( reportDescPtr );
|
TEST_ASSERT_NULL( reportDescPtr );
|
||||||
@@ -85,6 +90,7 @@ void test_unprepared_hidGetReportDescriptor( void )
|
|||||||
|
|
||||||
void test_prepared_hidGetReportDescriptor( void )
|
void test_prepared_hidGetReportDescriptor( void )
|
||||||
{
|
{
|
||||||
|
test_init();
|
||||||
const unsigned reportId = 0;
|
const unsigned reportId = 0;
|
||||||
|
|
||||||
hidPrepareReportDescriptor();
|
hidPrepareReportDescriptor();
|
||||||
@@ -97,6 +103,7 @@ void test_prepared_hidGetReportDescriptor( void )
|
|||||||
|
|
||||||
void test_reset_unprepared_hidGetReportDescriptor( void )
|
void test_reset_unprepared_hidGetReportDescriptor( void )
|
||||||
{
|
{
|
||||||
|
test_init();
|
||||||
hidPrepareReportDescriptor();
|
hidPrepareReportDescriptor();
|
||||||
hidResetReportDescriptor();
|
hidResetReportDescriptor();
|
||||||
unsigned char* reportDescPtr = hidGetReportDescriptor();
|
unsigned char* reportDescPtr = hidGetReportDescriptor();
|
||||||
@@ -105,6 +112,7 @@ void test_reset_unprepared_hidGetReportDescriptor( void )
|
|||||||
|
|
||||||
void test_reset_prepared_hidGetReportDescriptor( void )
|
void test_reset_prepared_hidGetReportDescriptor( void )
|
||||||
{
|
{
|
||||||
|
test_init();
|
||||||
hidPrepareReportDescriptor();
|
hidPrepareReportDescriptor();
|
||||||
hidResetReportDescriptor();
|
hidResetReportDescriptor();
|
||||||
hidPrepareReportDescriptor();
|
hidPrepareReportDescriptor();
|
||||||
@@ -114,6 +122,7 @@ void test_reset_prepared_hidGetReportDescriptor( void )
|
|||||||
|
|
||||||
void test_report_id_limit( void )
|
void test_report_id_limit( void )
|
||||||
{
|
{
|
||||||
|
test_init();
|
||||||
unsigned reportIdLimit = hidGetReportIdLimit();
|
unsigned reportIdLimit = hidGetReportIdLimit();
|
||||||
TEST_ASSERT_EQUAL_UINT( HID_REPORTID_LIMIT, reportIdLimit );
|
TEST_ASSERT_EQUAL_UINT( HID_REPORTID_LIMIT, reportIdLimit );
|
||||||
}
|
}
|
||||||
@@ -121,6 +130,7 @@ void test_report_id_limit( void )
|
|||||||
// Basic item tests
|
// Basic item tests
|
||||||
void test_max_loc_hidGetReportItem( void )
|
void test_max_loc_hidGetReportItem( void )
|
||||||
{
|
{
|
||||||
|
test_init();
|
||||||
const unsigned reportId = 0;
|
const unsigned reportId = 0;
|
||||||
const unsigned bit = MAX_VALID_BIT;
|
const unsigned bit = MAX_VALID_BIT;
|
||||||
const unsigned byte = MAX_VALID_BYTE;
|
const unsigned byte = MAX_VALID_BYTE;
|
||||||
@@ -138,6 +148,7 @@ void test_max_loc_hidGetReportItem( void )
|
|||||||
|
|
||||||
void test_min_loc_hidGetReportItem( void )
|
void test_min_loc_hidGetReportItem( void )
|
||||||
{
|
{
|
||||||
|
test_init();
|
||||||
const unsigned reportId = 0;
|
const unsigned reportId = 0;
|
||||||
const unsigned bit = MIN_VALID_BIT;
|
const unsigned bit = MIN_VALID_BIT;
|
||||||
const unsigned byte = MIN_VALID_BYTE;
|
const unsigned byte = MIN_VALID_BYTE;
|
||||||
@@ -155,6 +166,7 @@ void test_min_loc_hidGetReportItem( void )
|
|||||||
|
|
||||||
void test_overflow_bit_hidGetReportItem( void )
|
void test_overflow_bit_hidGetReportItem( void )
|
||||||
{
|
{
|
||||||
|
test_init();
|
||||||
const unsigned reportId = 0;
|
const unsigned reportId = 0;
|
||||||
const unsigned bit = MAX_VALID_BIT + 1;
|
const unsigned bit = MAX_VALID_BIT + 1;
|
||||||
const unsigned byte = MAX_VALID_BYTE;
|
const unsigned byte = MAX_VALID_BYTE;
|
||||||
@@ -172,6 +184,7 @@ void test_overflow_bit_hidGetReportItem( void )
|
|||||||
|
|
||||||
void test_overflow_byte_hidGetReportItem( void )
|
void test_overflow_byte_hidGetReportItem( void )
|
||||||
{
|
{
|
||||||
|
test_init();
|
||||||
const unsigned reportId = 0;
|
const unsigned reportId = 0;
|
||||||
const unsigned bit = MAX_VALID_BIT;
|
const unsigned bit = MAX_VALID_BIT;
|
||||||
const unsigned byte = MAX_VALID_BYTE + 1;
|
const unsigned byte = MAX_VALID_BYTE + 1;
|
||||||
@@ -189,6 +202,7 @@ void test_overflow_byte_hidGetReportItem( void )
|
|||||||
|
|
||||||
void test_underflow_bit_hidGetReportItem( void )
|
void test_underflow_bit_hidGetReportItem( void )
|
||||||
{
|
{
|
||||||
|
test_init();
|
||||||
const unsigned reportId = 0;
|
const unsigned reportId = 0;
|
||||||
const int bit = MIN_VALID_BIT - 1;
|
const int bit = MIN_VALID_BIT - 1;
|
||||||
const unsigned byte = MIN_VALID_BYTE;
|
const unsigned byte = MIN_VALID_BYTE;
|
||||||
@@ -206,6 +220,7 @@ void test_underflow_bit_hidGetReportItem( void )
|
|||||||
|
|
||||||
void test_underflow_byte_hidGetReportItem( void )
|
void test_underflow_byte_hidGetReportItem( void )
|
||||||
{
|
{
|
||||||
|
test_init();
|
||||||
const unsigned reportId = 0;
|
const unsigned reportId = 0;
|
||||||
const unsigned bit = MIN_VALID_BIT;
|
const unsigned bit = MIN_VALID_BIT;
|
||||||
const int byte = MIN_VALID_BYTE - 1;
|
const int byte = MIN_VALID_BYTE - 1;
|
||||||
@@ -224,6 +239,7 @@ void test_underflow_byte_hidGetReportItem( void )
|
|||||||
// Configurable and non-configurable item tests
|
// Configurable and non-configurable item tests
|
||||||
void test_configurable_item_hidSetReportItem( void )
|
void test_configurable_item_hidSetReportItem( void )
|
||||||
{
|
{
|
||||||
|
test_init();
|
||||||
const unsigned reportId = 0;
|
const unsigned reportId = 0;
|
||||||
const unsigned bit = MIN_VALID_BIT;
|
const unsigned bit = MIN_VALID_BIT;
|
||||||
const unsigned byte = MIN_VALID_BYTE;
|
const unsigned byte = MIN_VALID_BYTE;
|
||||||
@@ -237,6 +253,7 @@ void test_configurable_item_hidSetReportItem( void )
|
|||||||
|
|
||||||
void test_nonconfigurable_item_hidSetReportItem( void )
|
void test_nonconfigurable_item_hidSetReportItem( void )
|
||||||
{
|
{
|
||||||
|
test_init();
|
||||||
const unsigned reportId = 0;
|
const unsigned reportId = 0;
|
||||||
const unsigned bit = MAX_VALID_BIT; // This bit and byte combination should not appear in the
|
const unsigned bit = MAX_VALID_BIT; // This bit and byte combination should not appear in the
|
||||||
const unsigned byte = MIN_VALID_BYTE; // hidConfigurableElements list in hid_report_descriptors.c.
|
const unsigned byte = MIN_VALID_BYTE; // hidConfigurableElements list in hid_report_descriptors.c.
|
||||||
@@ -251,6 +268,7 @@ void test_nonconfigurable_item_hidSetReportItem( void )
|
|||||||
// Bit range tests
|
// Bit range tests
|
||||||
void test_max_bit_hidSetReportItem( void )
|
void test_max_bit_hidSetReportItem( void )
|
||||||
{
|
{
|
||||||
|
test_init();
|
||||||
const unsigned reportId = 0;
|
const unsigned reportId = 0;
|
||||||
const unsigned bit = MAX_VALID_BIT; // Only byte 1 has bit 7 not reserved, See the
|
const unsigned bit = MAX_VALID_BIT; // Only byte 1 has bit 7 not reserved, See the
|
||||||
const unsigned byte = MAX_VALID_BYTE; // hidConfigurableElements list in hid_report_descriptors.c.
|
const unsigned byte = MAX_VALID_BYTE; // hidConfigurableElements list in hid_report_descriptors.c.
|
||||||
@@ -263,6 +281,7 @@ void test_max_bit_hidSetReportItem( void )
|
|||||||
|
|
||||||
void test_min_bit_hidSetReportItem( void )
|
void test_min_bit_hidSetReportItem( void )
|
||||||
{
|
{
|
||||||
|
test_init();
|
||||||
const unsigned reportId = 0;
|
const unsigned reportId = 0;
|
||||||
const unsigned bit = MIN_VALID_BIT;
|
const unsigned bit = MIN_VALID_BIT;
|
||||||
const unsigned byte = MIN_VALID_BYTE;
|
const unsigned byte = MIN_VALID_BYTE;
|
||||||
@@ -275,6 +294,7 @@ void test_min_bit_hidSetReportItem( void )
|
|||||||
|
|
||||||
void test_overflow_bit_hidSetReportItem( void )
|
void test_overflow_bit_hidSetReportItem( void )
|
||||||
{
|
{
|
||||||
|
test_init();
|
||||||
const unsigned reportId = 0;
|
const unsigned reportId = 0;
|
||||||
const unsigned bit = MAX_VALID_BIT + 1;
|
const unsigned bit = MAX_VALID_BIT + 1;
|
||||||
const unsigned byte = MIN_VALID_BYTE;
|
const unsigned byte = MIN_VALID_BYTE;
|
||||||
@@ -287,6 +307,7 @@ void test_overflow_bit_hidSetReportItem( void )
|
|||||||
|
|
||||||
void test_underflow_bit_hidSetReportItem( void )
|
void test_underflow_bit_hidSetReportItem( void )
|
||||||
{
|
{
|
||||||
|
test_init();
|
||||||
const unsigned reportId = 0;
|
const unsigned reportId = 0;
|
||||||
const int bit = MIN_VALID_BIT - 1;
|
const int bit = MIN_VALID_BIT - 1;
|
||||||
const unsigned byte = MIN_VALID_BYTE;
|
const unsigned byte = MIN_VALID_BYTE;
|
||||||
@@ -300,6 +321,7 @@ void test_underflow_bit_hidSetReportItem( void )
|
|||||||
// Byte range tests
|
// Byte range tests
|
||||||
void test_max_byte_hidSetReportItem( void )
|
void test_max_byte_hidSetReportItem( void )
|
||||||
{
|
{
|
||||||
|
test_init();
|
||||||
const unsigned reportId = 0;
|
const unsigned reportId = 0;
|
||||||
const unsigned bit = MIN_VALID_BIT;
|
const unsigned bit = MIN_VALID_BIT;
|
||||||
const unsigned byte = MAX_VALID_BYTE;
|
const unsigned byte = MAX_VALID_BYTE;
|
||||||
@@ -312,6 +334,7 @@ void test_max_byte_hidSetReportItem( void )
|
|||||||
|
|
||||||
void test_min_byte_hidSetReportItem( void )
|
void test_min_byte_hidSetReportItem( void )
|
||||||
{
|
{
|
||||||
|
test_init();
|
||||||
const unsigned reportId = 0;
|
const unsigned reportId = 0;
|
||||||
const unsigned bit = MIN_VALID_BIT;
|
const unsigned bit = MIN_VALID_BIT;
|
||||||
const unsigned byte = MIN_VALID_BYTE;
|
const unsigned byte = MIN_VALID_BYTE;
|
||||||
@@ -324,6 +347,7 @@ void test_min_byte_hidSetReportItem( void )
|
|||||||
|
|
||||||
void test_overflow_byte_hidSetReportItem( void )
|
void test_overflow_byte_hidSetReportItem( void )
|
||||||
{
|
{
|
||||||
|
test_init();
|
||||||
const unsigned reportId = 0;
|
const unsigned reportId = 0;
|
||||||
const unsigned bit = MIN_VALID_BIT;
|
const unsigned bit = MIN_VALID_BIT;
|
||||||
const unsigned byte = MAX_VALID_BYTE + 1;
|
const unsigned byte = MAX_VALID_BYTE + 1;
|
||||||
@@ -336,6 +360,7 @@ void test_overflow_byte_hidSetReportItem( void )
|
|||||||
|
|
||||||
void test_underflow_byte_hidSetReportItem( void )
|
void test_underflow_byte_hidSetReportItem( void )
|
||||||
{
|
{
|
||||||
|
test_init();
|
||||||
const unsigned reportId = 0;
|
const unsigned reportId = 0;
|
||||||
const unsigned bit = MIN_VALID_BIT;
|
const unsigned bit = MIN_VALID_BIT;
|
||||||
const int byte = MIN_VALID_BYTE - 1;
|
const int byte = MIN_VALID_BYTE - 1;
|
||||||
@@ -349,6 +374,7 @@ void test_underflow_byte_hidSetReportItem( void )
|
|||||||
// Size range tests
|
// Size range tests
|
||||||
void test_max_size_hidSetReportItem( void )
|
void test_max_size_hidSetReportItem( void )
|
||||||
{
|
{
|
||||||
|
test_init();
|
||||||
const unsigned reportId = 0;
|
const unsigned reportId = 0;
|
||||||
const unsigned bit = MIN_VALID_BIT;
|
const unsigned bit = MIN_VALID_BIT;
|
||||||
const unsigned byte = MIN_VALID_BYTE;
|
const unsigned byte = MIN_VALID_BYTE;
|
||||||
@@ -362,6 +388,7 @@ void test_max_size_hidSetReportItem( void )
|
|||||||
|
|
||||||
void test_min_size_hidSetReportItem( void )
|
void test_min_size_hidSetReportItem( void )
|
||||||
{
|
{
|
||||||
|
test_init();
|
||||||
const unsigned reportId = 0;
|
const unsigned reportId = 0;
|
||||||
const unsigned bit = MIN_VALID_BIT;
|
const unsigned bit = MIN_VALID_BIT;
|
||||||
const unsigned byte = MIN_VALID_BYTE;
|
const unsigned byte = MIN_VALID_BYTE;
|
||||||
@@ -374,6 +401,7 @@ void test_min_size_hidSetReportItem( void )
|
|||||||
|
|
||||||
void test_unsupported_size_hidSetReportItem( void )
|
void test_unsupported_size_hidSetReportItem( void )
|
||||||
{
|
{
|
||||||
|
test_init();
|
||||||
const unsigned reportId = 0;
|
const unsigned reportId = 0;
|
||||||
const unsigned bit = MIN_VALID_BIT;
|
const unsigned bit = MIN_VALID_BIT;
|
||||||
const unsigned byte = MIN_VALID_BYTE;
|
const unsigned byte = MIN_VALID_BYTE;
|
||||||
@@ -387,6 +415,7 @@ void test_unsupported_size_hidSetReportItem( void )
|
|||||||
// Header tag and type tests
|
// Header tag and type tests
|
||||||
void test_bad_tag_hidSetReportItem( void )
|
void test_bad_tag_hidSetReportItem( void )
|
||||||
{
|
{
|
||||||
|
test_init();
|
||||||
const unsigned reportId = 0;
|
const unsigned reportId = 0;
|
||||||
const unsigned bit = MIN_VALID_BIT;
|
const unsigned bit = MIN_VALID_BIT;
|
||||||
const unsigned byte = MIN_VALID_BYTE;
|
const unsigned byte = MIN_VALID_BYTE;
|
||||||
@@ -402,6 +431,7 @@ void test_bad_tag_hidSetReportItem( void )
|
|||||||
|
|
||||||
void test_global_type_hidSetReportItem( void )
|
void test_global_type_hidSetReportItem( void )
|
||||||
{
|
{
|
||||||
|
test_init();
|
||||||
const unsigned reportId = 0;
|
const unsigned reportId = 0;
|
||||||
const unsigned bit = MIN_VALID_BIT;
|
const unsigned bit = MIN_VALID_BIT;
|
||||||
const unsigned byte = MIN_VALID_BYTE;
|
const unsigned byte = MIN_VALID_BYTE;
|
||||||
@@ -415,6 +445,7 @@ void test_global_type_hidSetReportItem( void )
|
|||||||
|
|
||||||
void test_local_type_hidSetReportItem( void )
|
void test_local_type_hidSetReportItem( void )
|
||||||
{
|
{
|
||||||
|
test_init();
|
||||||
const unsigned reportId = 0;
|
const unsigned reportId = 0;
|
||||||
const unsigned bit = MIN_VALID_BIT;
|
const unsigned bit = MIN_VALID_BIT;
|
||||||
const unsigned byte = MIN_VALID_BYTE;
|
const unsigned byte = MIN_VALID_BYTE;
|
||||||
@@ -428,6 +459,7 @@ void test_local_type_hidSetReportItem( void )
|
|||||||
|
|
||||||
void test_main_type_hidSetReportItem( void )
|
void test_main_type_hidSetReportItem( void )
|
||||||
{
|
{
|
||||||
|
test_init();
|
||||||
const unsigned reportId = 0;
|
const unsigned reportId = 0;
|
||||||
const unsigned bit = MIN_VALID_BIT;
|
const unsigned bit = MIN_VALID_BIT;
|
||||||
const unsigned byte = MIN_VALID_BYTE;
|
const unsigned byte = MIN_VALID_BYTE;
|
||||||
@@ -441,6 +473,7 @@ void test_main_type_hidSetReportItem( void )
|
|||||||
|
|
||||||
void test_reserved_type_hidSetReportItem( void )
|
void test_reserved_type_hidSetReportItem( void )
|
||||||
{
|
{
|
||||||
|
test_init();
|
||||||
const unsigned reportId = 0;
|
const unsigned reportId = 0;
|
||||||
const unsigned bit = MIN_VALID_BIT;
|
const unsigned bit = MIN_VALID_BIT;
|
||||||
const unsigned byte = MIN_VALID_BYTE;
|
const unsigned byte = MIN_VALID_BYTE;
|
||||||
@@ -455,6 +488,7 @@ void test_reserved_type_hidSetReportItem( void )
|
|||||||
// Combined function tests
|
// Combined function tests
|
||||||
void test_initial_modification_without_subsequent_preparation( void )
|
void test_initial_modification_without_subsequent_preparation( void )
|
||||||
{
|
{
|
||||||
|
test_init();
|
||||||
const unsigned reportId = 0;
|
const unsigned reportId = 0;
|
||||||
const unsigned bit = MIN_VALID_BIT;
|
const unsigned bit = MIN_VALID_BIT;
|
||||||
const unsigned byte = MIN_VALID_BYTE;
|
const unsigned byte = MIN_VALID_BYTE;
|
||||||
@@ -471,6 +505,7 @@ void test_initial_modification_without_subsequent_preparation( void )
|
|||||||
|
|
||||||
void test_initial_modification_with_subsequent_preparation( void )
|
void test_initial_modification_with_subsequent_preparation( void )
|
||||||
{
|
{
|
||||||
|
test_init();
|
||||||
const unsigned reportId = 0;
|
const unsigned reportId = 0;
|
||||||
const unsigned bit = MIN_VALID_BIT;
|
const unsigned bit = MIN_VALID_BIT;
|
||||||
const unsigned byte = MIN_VALID_BYTE;
|
const unsigned byte = MIN_VALID_BYTE;
|
||||||
@@ -488,6 +523,7 @@ void test_initial_modification_with_subsequent_preparation( void )
|
|||||||
|
|
||||||
void test_initial_modification_with_subsequent_verification_1( void )
|
void test_initial_modification_with_subsequent_verification_1( void )
|
||||||
{
|
{
|
||||||
|
test_init();
|
||||||
const unsigned reportId = 0;
|
const unsigned reportId = 0;
|
||||||
const unsigned bit = MIN_VALID_BIT;
|
const unsigned bit = MIN_VALID_BIT;
|
||||||
const unsigned byte = MIN_VALID_BYTE;
|
const unsigned byte = MIN_VALID_BYTE;
|
||||||
@@ -513,6 +549,7 @@ void test_initial_modification_with_subsequent_verification_1( void )
|
|||||||
|
|
||||||
void test_initial_modification_with_subsequent_verification_2( void )
|
void test_initial_modification_with_subsequent_verification_2( void )
|
||||||
{
|
{
|
||||||
|
test_init();
|
||||||
const unsigned reportId = 0;
|
const unsigned reportId = 0;
|
||||||
const unsigned bit = MIN_VALID_BIT;
|
const unsigned bit = MIN_VALID_BIT;
|
||||||
const unsigned byte = MIN_VALID_BYTE;
|
const unsigned byte = MIN_VALID_BYTE;
|
||||||
@@ -560,6 +597,7 @@ void test_initial_modification_with_subsequent_verification_2( void )
|
|||||||
|
|
||||||
void test_modification_without_subsequent_preparation( void )
|
void test_modification_without_subsequent_preparation( void )
|
||||||
{
|
{
|
||||||
|
test_init();
|
||||||
hidPrepareReportDescriptor();
|
hidPrepareReportDescriptor();
|
||||||
unsigned char* reportDescPtr = hidGetReportDescriptor();
|
unsigned char* reportDescPtr = hidGetReportDescriptor();
|
||||||
TEST_ASSERT_NOT_NULL( reportDescPtr );
|
TEST_ASSERT_NOT_NULL( reportDescPtr );
|
||||||
@@ -581,6 +619,7 @@ void test_modification_without_subsequent_preparation( void )
|
|||||||
|
|
||||||
void test_modification_with_subsequent_preparation( void )
|
void test_modification_with_subsequent_preparation( void )
|
||||||
{
|
{
|
||||||
|
test_init();
|
||||||
hidPrepareReportDescriptor();
|
hidPrepareReportDescriptor();
|
||||||
unsigned char* reportDescPtr = hidGetReportDescriptor();
|
unsigned char* reportDescPtr = hidGetReportDescriptor();
|
||||||
TEST_ASSERT_NOT_NULL( reportDescPtr );
|
TEST_ASSERT_NOT_NULL( reportDescPtr );
|
||||||
@@ -604,6 +643,7 @@ void test_modification_with_subsequent_preparation( void )
|
|||||||
//setIdle functionality tests
|
//setIdle functionality tests
|
||||||
void test_set_idle( void )
|
void test_set_idle( void )
|
||||||
{
|
{
|
||||||
|
test_init();
|
||||||
unsigned reportId = 0;
|
unsigned reportId = 0;
|
||||||
|
|
||||||
unsigned setIdle = hidIsIdleActive( reportId );
|
unsigned setIdle = hidIsIdleActive( reportId );
|
||||||
@@ -616,6 +656,7 @@ void test_set_idle( void )
|
|||||||
|
|
||||||
void test_change_pending( void )
|
void test_change_pending( void )
|
||||||
{
|
{
|
||||||
|
test_init();
|
||||||
unsigned reportId = 0;
|
unsigned reportId = 0;
|
||||||
|
|
||||||
unsigned changePending = hidIsChangePending( reportId );
|
unsigned changePending = hidIsChangePending( reportId );
|
||||||
@@ -632,6 +673,7 @@ void test_change_pending( void )
|
|||||||
|
|
||||||
void test_report_time( void )
|
void test_report_time( void )
|
||||||
{
|
{
|
||||||
|
test_init();
|
||||||
unsigned reportTime = 123;
|
unsigned reportTime = 123;
|
||||||
unsigned reportPeriod = 10;
|
unsigned reportPeriod = 10;
|
||||||
|
|
||||||
|
|||||||
@@ -1,10 +1,13 @@
|
|||||||
// Copyright 2021 XMOS LIMITED.
|
// Copyright 2021-2024 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 __XC__
|
#ifdef __XC__
|
||||||
|
|
||||||
#include <xs1.h>
|
#include <xs1.h>
|
||||||
#include <platform.h>
|
#include <platform.h>
|
||||||
#include <xclib.h>
|
#include <xclib.h>
|
||||||
|
#include "../../../lib_xua/src/midi/midiinparse.h"
|
||||||
|
#include "../../../lib_xua/src/midi/midioutparse.h"
|
||||||
|
#include "../../../lib_xua/src/midi/queue.h"
|
||||||
|
|
||||||
#endif // __XC__
|
#endif // __XC__
|
||||||
|
|
||||||
@@ -26,3 +29,87 @@ void AudioHwInit()
|
|||||||
{
|
{
|
||||||
; // nothing
|
; // nothing
|
||||||
}
|
}
|
||||||
|
|
||||||
|
unsigned random(unsigned &x){
|
||||||
|
crc32(x, -1, 0xEB31D82E);
|
||||||
|
return x;
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////// Wrappers for midi parse because C doesn't support return tuples
|
||||||
|
void midi_in_parse_c_wrapper(void * unsafe mips, unsigned cable_number, unsigned char b, unsigned * unsafe valid, unsigned *unsafe packed){
|
||||||
|
unsafe{
|
||||||
|
struct midi_in_parse_state * unsafe ptr = mips;
|
||||||
|
{*valid, *packed} = midi_in_parse(*ptr, cable_number, b);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void midi_out_parse_c_wrapper(unsigned tx_data, unsigned midi[3], unsigned * unsafe size){
|
||||||
|
unsafe{
|
||||||
|
{midi[0], midi[1], midi[2], *size} = midi_out_parse(tx_data);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void reset_midi_state_c_wrapper(void * unsafe mips){
|
||||||
|
unsafe{
|
||||||
|
struct midi_in_parse_state * unsafe ptr = mips;
|
||||||
|
reset_midi_state(*ptr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/////////////////////// Wrappers for queue test
|
||||||
|
|
||||||
|
|
||||||
|
void queue_init_c_wrapper(queue_t *q, unsigned size) {
|
||||||
|
unsafe{
|
||||||
|
queue_init(*q, size);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int queue_is_empty_c_wrapper(queue_t *unsafe q) {
|
||||||
|
unsafe{
|
||||||
|
return queue_is_empty(*q);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int queue_is_full_c_wrapper(queue_t *unsafe q) {
|
||||||
|
unsafe{
|
||||||
|
return queue_is_full(*q);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void queue_push_word_c_wrapper(queue_t *q, unsigned array[], unsigned data){
|
||||||
|
unsafe{
|
||||||
|
queue_push_word(*q, array, data);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned queue_pop_word_c_wrapper(queue_t *q, unsigned array[]){
|
||||||
|
unsafe{
|
||||||
|
return queue_pop_word(*q, array);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void queue_push_byte_c_wrapper(queue_t *q, unsigned char array[], unsigned data){
|
||||||
|
unsafe{
|
||||||
|
queue_push_byte(*q, array, data);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned queue_pop_byte_c_wrapper(queue_t *q, unsigned char array[]){
|
||||||
|
unsafe{
|
||||||
|
return queue_pop_byte(*q, array);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned queue_items_c_wrapper(const queue_t *q){
|
||||||
|
unsafe{
|
||||||
|
return queue_items(*q);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned queue_space_c_wrapper(const queue_t *q){
|
||||||
|
unsafe{
|
||||||
|
return queue_space(*q);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,9 +1,28 @@
|
|||||||
// Copyright 2021 XMOS LIMITED.
|
// Copyright 2021-2024 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 XUA_UNIT_TESTS_H_
|
#ifndef XUA_UNIT_TESTS_H_
|
||||||
#define XUA_UNIT_TESTS_H_
|
#define XUA_UNIT_TESTS_H_
|
||||||
|
|
||||||
#include "unity.h"
|
#include "unity.h"
|
||||||
#include "xua_conf.h"
|
#include "xua_conf.h"
|
||||||
|
#include "../../../lib_xua/src/midi/queue.h"
|
||||||
|
|
||||||
|
#ifndef __XC__
|
||||||
|
void midi_in_parse_c_wrapper(void * mips, unsigned cable_number, unsigned char b, unsigned * valid, unsigned * packed);
|
||||||
|
void midi_out_parse_c_wrapper(unsigned tx_data, unsigned midi[3], unsigned * size);
|
||||||
|
void reset_midi_state_c_wrapper(void *mips);
|
||||||
|
unsigned random(unsigned *x);
|
||||||
|
|
||||||
|
void queue_init_c_wrapper(queue_t *q, unsigned size);
|
||||||
|
int queue_is_empty_c_wrapper(const queue_t *q);
|
||||||
|
int queue_is_full_c_wrapper(const queue_t *q);
|
||||||
|
void queue_push_word_c_wrapper(queue_t *q, unsigned array[], unsigned data);
|
||||||
|
unsigned queue_pop_word_c_wrapper(queue_t *q, unsigned array[]);
|
||||||
|
void queue_push_byte_c_wrapper(queue_t *q, unsigned char array[], unsigned data);
|
||||||
|
unsigned queue_pop_byte_c_wrapper(queue_t *q, unsigned char array[]);
|
||||||
|
unsigned queue_items_c_wrapper(const queue_t *q);
|
||||||
|
unsigned queue_space_c_wrapper(const queue_t *q);
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
#endif /* XUA_UNIT_TESTS_H_ */
|
#endif /* XUA_UNIT_TESTS_H_ */
|
||||||
|
|||||||
@@ -1,260 +0,0 @@
|
|||||||
from __future__ import print_function
|
|
||||||
import glob
|
|
||||||
import os.path
|
|
||||||
import subprocess
|
|
||||||
import sys
|
|
||||||
from waflib import Options
|
|
||||||
from waflib.Build import BuildContext, CleanContext
|
|
||||||
|
|
||||||
TARGETS = ['xcore200', 'xcoreai']
|
|
||||||
|
|
||||||
def get_ruby():
|
|
||||||
"""
|
|
||||||
Check ruby is avaliable and return the command to invoke it.
|
|
||||||
"""
|
|
||||||
interpreter_name = 'ruby'
|
|
||||||
try:
|
|
||||||
dev_null = open(os.devnull, 'w')
|
|
||||||
# Call the version command to check the interpreter can be run
|
|
||||||
subprocess.check_call([interpreter_name, '--version'],
|
|
||||||
stdout=dev_null,
|
|
||||||
close_fds=True)
|
|
||||||
except OSError as e:
|
|
||||||
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
|
|
||||||
|
|
||||||
return interpreter_name
|
|
||||||
|
|
||||||
|
|
||||||
def get_unity_runner_generator(project_root_path):
|
|
||||||
"""
|
|
||||||
Check the Unity generate_test_runner script is avaliable, and return the
|
|
||||||
path to it.
|
|
||||||
"""
|
|
||||||
unity_runner_generator = os.path.join(
|
|
||||||
project_root_path, 'Unity', 'auto', 'generate_test_runner.rb')
|
|
||||||
if not os.path.exists(unity_runner_generator):
|
|
||||||
print("Unity repo not found in workspace", file=sys.stderr)
|
|
||||||
exit(1) # TODO: Check this is the correct way to kill xwaf on error
|
|
||||||
return unity_runner_generator
|
|
||||||
|
|
||||||
|
|
||||||
def get_test_name(test_path):
|
|
||||||
"""
|
|
||||||
Return the test name by removing the extension from the filename.
|
|
||||||
"""
|
|
||||||
return os.path.splitext(os.path.basename(test_path))[0]
|
|
||||||
|
|
||||||
|
|
||||||
def get_file_type(filename):
|
|
||||||
"""
|
|
||||||
Return the extension from the filename.
|
|
||||||
"""
|
|
||||||
return filename.rsplit('.')[-1:][0]
|
|
||||||
|
|
||||||
|
|
||||||
def generate_unity_runner(project_root_path, unity_test_path, unity_runner_dir,
|
|
||||||
unity_runner_suffix):
|
|
||||||
"""
|
|
||||||
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
|
|
||||||
if it does not already exist.
|
|
||||||
"""
|
|
||||||
runner_path = os.path.join(os.path.join(unity_runner_dir, get_test_name(unity_test_path)))
|
|
||||||
if not os.path.exists(runner_path):
|
|
||||||
os.makedirs(runner_path)
|
|
||||||
|
|
||||||
unity_runner_path = os.path.join(
|
|
||||||
runner_path, get_test_name(unity_test_path) + unity_runner_suffix
|
|
||||||
+ '.' + 'c')
|
|
||||||
|
|
||||||
try:
|
|
||||||
subprocess.check_call([get_ruby(),
|
|
||||||
get_unity_runner_generator(project_root_path),
|
|
||||||
unity_test_path,
|
|
||||||
unity_runner_path])
|
|
||||||
except OSError as e:
|
|
||||||
print("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
|
|
||||||
|
|
||||||
|
|
||||||
def add_unity_runner_build_config(waf_conf, project_root_path, unity_test_path,
|
|
||||||
unity_runner_build_flags, target):
|
|
||||||
"""
|
|
||||||
Add a config to xwaf to build each Unity test runner into an xCORE
|
|
||||||
executable.
|
|
||||||
"""
|
|
||||||
print(f"get_test_name(unity_test_path) = {get_test_name(unity_test_path)}. target = {target}")
|
|
||||||
waf_conf.setenv(get_test_name(unity_test_path) + '_' + target)
|
|
||||||
waf_conf.load('xwaf.compiler_xcc')
|
|
||||||
waf_conf.env.XCC_FLAGS = unity_runner_build_flags
|
|
||||||
waf_conf.env.PROJECT_ROOT = project_root_path
|
|
||||||
# TODO: can the xwaf boilerplate help here?
|
|
||||||
|
|
||||||
|
|
||||||
def prepare_unity_test_for_build(waf_conf, project_root_path, unity_test_path,
|
|
||||||
unity_runner_dir, unity_runner_suffix, target):
|
|
||||||
print("unity_test_path: " + str(unity_test_path))
|
|
||||||
generate_unity_runner(project_root_path, unity_test_path,
|
|
||||||
unity_runner_dir, unity_runner_suffix)
|
|
||||||
runner_build_flags = '' # Could extract flags from the test name
|
|
||||||
add_unity_runner_build_config(waf_conf, project_root_path, unity_test_path,
|
|
||||||
runner_build_flags, target)
|
|
||||||
|
|
||||||
|
|
||||||
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
|
|
||||||
unity_test_dir.
|
|
||||||
"""
|
|
||||||
file_list = []
|
|
||||||
for root, dirs, files in os.walk(unity_test_dir):
|
|
||||||
for f in files:
|
|
||||||
if f.startswith(unity_test_prefix):
|
|
||||||
file_list.append(os.path.join(root,f))
|
|
||||||
return file_list
|
|
||||||
|
|
||||||
|
|
||||||
def find_unity_tests(unity_test_dir, unity_test_prefix):
|
|
||||||
"""
|
|
||||||
Return a dictionary of all {test names, test language} pairs with the
|
|
||||||
unity_test_prefix found in the unity_test_dir.
|
|
||||||
"""
|
|
||||||
unity_test_paths = find_unity_test_paths(unity_test_dir, unity_test_prefix)
|
|
||||||
return {get_test_name(path): {"language": get_file_type(path), "dir": os.path.dirname(path)}
|
|
||||||
for path in unity_test_paths}
|
|
||||||
|
|
||||||
|
|
||||||
def generate_all_unity_runners(waf_conf, project_root_path,
|
|
||||||
unity_test_dir, unity_test_prefix,
|
|
||||||
unity_runner_dir, unity_runner_suffix):
|
|
||||||
"""
|
|
||||||
Generate a runner and a build config for each test file in the
|
|
||||||
unity_test_dir.
|
|
||||||
"""
|
|
||||||
# FIXME: pass unity_tests in?
|
|
||||||
unity_test_paths = find_unity_test_paths(unity_test_dir, unity_test_prefix)
|
|
||||||
for trgt in TARGETS:
|
|
||||||
for unity_test_path in unity_test_paths:
|
|
||||||
prepare_unity_test_for_build(waf_conf, project_root_path,
|
|
||||||
unity_test_path,
|
|
||||||
unity_runner_dir, unity_runner_suffix, trgt)
|
|
||||||
|
|
||||||
|
|
||||||
# TODO: can the xwaf boilerplate help here?
|
|
||||||
def create_waf_contexts(configs):
|
|
||||||
for trgt in TARGETS:
|
|
||||||
for test_name, params in configs.items():
|
|
||||||
print(f"test_name {test_name}, test_language {params['language']}")
|
|
||||||
for ctx in (BuildContext, CleanContext):
|
|
||||||
raw_context = ctx.__name__.replace('Context', '').lower()
|
|
||||||
|
|
||||||
class tmp(ctx):
|
|
||||||
cmd = raw_context + '_' + test_name + '_' + trgt
|
|
||||||
variant = test_name + '_' + trgt
|
|
||||||
#cmd = raw_context + '_' + test_name
|
|
||||||
#variant = test_name
|
|
||||||
language = params["language"]
|
|
||||||
target = trgt
|
|
||||||
runner = test_name
|
|
||||||
directory = params["dir"]
|
|
||||||
print(f"cmd {cmd}, variant {variant}, language {language}")
|
|
||||||
|
|
||||||
|
|
||||||
UNITY_TEST_DIR = 'src'
|
|
||||||
UNITY_TEST_PREFIX = 'test_'
|
|
||||||
UNITY_RUNNER_DIR = 'runners'
|
|
||||||
UNITY_RUNNER_SUFFIX = '_Runner'
|
|
||||||
UNITY_TESTS = find_unity_tests(UNITY_TEST_DIR, UNITY_TEST_PREFIX)
|
|
||||||
|
|
||||||
print("UNITY_TESTS: " + str(UNITY_TESTS))
|
|
||||||
|
|
||||||
create_waf_contexts(UNITY_TESTS)
|
|
||||||
|
|
||||||
def options(opt):
|
|
||||||
opt.add_option('--target', action='store', default='xcore200')
|
|
||||||
opt.load('xwaf.xcommon')
|
|
||||||
|
|
||||||
def configure(conf):
|
|
||||||
# TODO: move the call to generate_all_unity_runners() to build()
|
|
||||||
project_root = os.path.join('..', '..', '..')
|
|
||||||
generate_all_unity_runners(conf, project_root,
|
|
||||||
UNITY_TEST_DIR, UNITY_TEST_PREFIX,
|
|
||||||
UNITY_RUNNER_DIR, UNITY_RUNNER_SUFFIX)
|
|
||||||
conf.load('xwaf.xcommon')
|
|
||||||
|
|
||||||
def build(bld):
|
|
||||||
if not bld.variant:
|
|
||||||
print('Adding test runners to build queue')
|
|
||||||
trgt = [
|
|
||||||
c for c in TARGETS if c == bld.options.target
|
|
||||||
]
|
|
||||||
|
|
||||||
if len(trgt) == 0:
|
|
||||||
bld.fatal('specify a target with --target.\nAvailable targets: {}'.format(', '.join(TARGETS)))
|
|
||||||
return
|
|
||||||
|
|
||||||
for name in UNITY_TESTS:
|
|
||||||
Options.commands.insert(0, 'build_' + name + '_' + trgt[0])
|
|
||||||
#Options.commands.insert(0, 'build_' + name)
|
|
||||||
print('Build queue {}'.format(Options.commands))
|
|
||||||
else:
|
|
||||||
print('Building runner {}'.format(bld.runner))
|
|
||||||
bld.env.XSCOPE = bld.path.find_resource('config.xscope')
|
|
||||||
|
|
||||||
depends_on = ['lib_xua',
|
|
||||||
'lib_xud',
|
|
||||||
'lib_spdif',
|
|
||||||
'lib_mic_array',
|
|
||||||
'lib_logging',
|
|
||||||
'lib_xassert',
|
|
||||||
'Unity']
|
|
||||||
|
|
||||||
makefile_opts = {}
|
|
||||||
makefile_opts['SOURCE_DIRS'] = ['src', bld.directory, os.path.join('runners',bld.runner)]
|
|
||||||
if(bld.target == 'xcoreai'):
|
|
||||||
print('TARGET XCOREAI')
|
|
||||||
makefile_opts['TARGET'] = ['XCORE-AI-EXPLORER']
|
|
||||||
else:
|
|
||||||
print('TARGET XCORE200')
|
|
||||||
makefile_opts['TARGET'] = ['XCORE-200-EXPLORER']
|
|
||||||
|
|
||||||
makefile_opts['INCLUDE_DIRS'] = ['src',
|
|
||||||
bld.directory,
|
|
||||||
'../../lib_xua/api',
|
|
||||||
'../../lib_xua/src/core/pdm_mics',
|
|
||||||
'../../lib_xua/src/hid',
|
|
||||||
'../../../lib_xud/lib_xud/src/user/class']
|
|
||||||
|
|
||||||
makefile_opts['XCC_FLAGS'] = ['-O2',
|
|
||||||
'-g',
|
|
||||||
'-Wall',
|
|
||||||
'-DHID_CONTROLS=1',
|
|
||||||
'-DUNITY_SUPPORT_64',
|
|
||||||
'-DUNITY_INCLUDE_DOUBLE',
|
|
||||||
'-DXUD_CORE_CLOCK=600',
|
|
||||||
'-DXUD_SERIES_SUPPORT=4']
|
|
||||||
|
|
||||||
makefile_opts['APP_NAME'] = [bld.variant]
|
|
||||||
makefile_opts['USED_MODULES'] = depends_on
|
|
||||||
makefile_opts['XCOMMON_MAKEFILE'] = ['Makefile.common']
|
|
||||||
bld.do_xcommon(makefile_opts)
|
|
||||||
|
|
||||||
|
|
||||||
def test(bld):
|
|
||||||
# Call pytest to run Unity tests inside axe or xsim
|
|
||||||
try:
|
|
||||||
test_output = subprocess.check_output(['pytest'])
|
|
||||||
except subprocess.CalledProcessError as e:
|
|
||||||
# pytest exits non-zero if an assertion fails
|
|
||||||
test_output = e.output
|
|
||||||
print(test_output)
|
|
||||||
|
|
||||||
|
|
||||||
# TODO: ensure clean deletes the runners dir/
|
|
||||||
def dist(ctx):
|
|
||||||
ctx.load('xwaf.xcommon')
|
|
||||||
|
|
||||||
def distcheck(ctx):
|
|
||||||
ctx.load('xwaf.xcommon')
|
|
||||||
Reference in New Issue
Block a user