Merge pull request #205 from xmos/develop

Release pre for XVF3610
This commit is contained in:
Ed
2021-07-22 15:00:09 +01:00
committed by GitHub
70 changed files with 2648 additions and 371 deletions

View File

@@ -1,6 +1,30 @@
lib_xua Change Log
==================
2.0.0
-----
* ADDED: Function to get a Report item description
* CHANGED: Check HID Usage Page when changing a Report item description
* CHANGED: HID event ID from list to bit and byte location in HID Report
* CHANGED: Interface to UserHIDRecordEvent()
* ADDED: Support for multiple flash specs defined by DFU_FLASH_DEVICE
* ADDED: Nullable c_aud_ctl chan-end optimisation for fixed rate devices
1.3.0
-----
* CHANGED: Move HID descriptors to ease maintenance
* CHANGED: Move legacy tests to separate directory
* CHANGED: Replace unused GPI-specific HID event names with generic ones
* ADDED: Build default HID Report descriptor at boot-time
* ADDED: Function to return length of HID Report
* CHANGED: HID Report to return multiple bytes
* CHANGED: NO_USB conditional compilation switch with XUA_USB_EN
* REMOVED: XS1 support
* CHANGED: Clock blocks used for BCLK and MCLK
* REMOVED: Arguments no longer supported by XUD_Main
1.2.0
-----

65
Jenkinsfile vendored
View File

@@ -27,11 +27,70 @@ pipeline {
xcoreLibraryChecks("${REPO}")
}
}
stage('Tests') {
steps {
runXmostest("${REPO}", 'tests')
stage('XS2 Tests') {
failFast true
parallel {
stage('Legacy tests') {
steps {
runXmostest("${REPO}", 'legacy_tests')
}
}
stage('Unit tests') {
steps {
dir("${REPO}") {
dir('tests') {
dir('xua_unit_tests') {
withVenv {
runWaf('.', "configure clean build --target=xcore200")
// runWaf('.', "configure clean build --target=xcoreai")
// stash name: 'xua_unit_tests', includes: 'bin/*xcoreai.xe, '
viewEnv() {
runPython("TARGET=XCORE200 pytest -n 1")
}
}
}
}
}
}
}
}
}
// stage('xcore.ai Verification') {
// agent {
// label 'xcore.ai-explorer'
// }
// options {
// skipDefaultCheckout()
// }
// stages{
// stage('Get View') {
// steps {
// xcorePrepareSandbox("${VIEW}", "${REPO}")
// }
// }
// stage('Unit tests') {
// steps {
// dir("${REPO}") {
// dir('tests') {
// dir('xua_unit_tests') {
// withVenv {
// unstash 'xua_unit_tests'
// viewEnv() {
// runPython("TARGET=XCOREAI pytest -s")
// }
// }
// }
// }
// }
// }
// }
// } // stages
// post {
// cleanup {
// cleanWs()
// }
// }
// }
stage('xCORE builds') {
steps {
dir("${REPO}") {

View File

@@ -3,8 +3,9 @@ APP_NAME = app_xua_simple
TARGET = xk-audio-216-mc.xn
# The flags passed to xcc when building the application
XCC_FLAGS = -fcomment-asm -Xmapper --map -Xmapper MAPFILE -O3 -report -fsubword-select -save-temps \
-g -Wno-unused-function -Wno-timing -DXUD_SERIES_SUPPORT=XUD_X200_SERIES -DUSB_TILE=tile[1] -fxscope
XCC_FLAGS = -fcomment-asm -Xmapper --map -Xmapper MAPFILE -O3 -report -save-temps \
-g -Wno-unused-function -Wno-timing -DXUD_SERIES_SUPPORT=XUD_X200_SERIES \
-DXUD_CORE_CLOCK=600 -DUSB_TILE=tile[1] -fxscope
#-DSDA_HIGH=2 -DSCL_HIGH=1 -fxscope

View File

@@ -60,7 +60,6 @@ int main()
/* Low level USB device layer core */
on tile[1]: XUD_Main(c_ep_out, 2, c_ep_in, 2,
c_sof, epTypeTableOut, epTypeTableIn,
null, null, -1 ,
XUD_SPEED_HS, XUD_PWR_SELF);
/* Endpoint 0 core from lib_xua */

View File

@@ -0,0 +1,112 @@
// Copyright 2021 XMOS LIMITED.
// This Software is subject to the terms of the XMOS Public Licence: Version 1.
#ifndef __hid_report_descriptor_h__
#define __hid_report_descriptor_h__
#include "xua_hid_report_descriptor.h"
#if 0
/* Existing static report descriptor kept for reference */
unsigned char hidReportDescriptor[] =
{
0x05, 0x0c, /* Usage Page (Consumer Device) */
0x09, 0x01, /* Usage (Consumer Control) */
0xa1, 0x01, /* Collection (Application) */
0x15, 0x00, /* Logical Minimum (0) */
0x25, 0x01, /* Logical Maximum (1) */
0x09, 0xb0, /* Usage (Play) */
0x09, 0xb5, /* Usage (Scan Next Track) */
0x09, 0xb6, /* Usage (Scan Previous Track) */
0x09, 0xe9, /* Usage (Volume Up) */
0x09, 0xea, /* Usage (Volume Down) */
0x09, 0xe2, /* Usage (Mute) */
0x75, 0x01, /* Report Size (1) */
0x95, 0x06, /* Report Count (6) */
0x81, 0x02, /* Input (Data, Var, Abs) */
0x95, 0x02, /* Report Count (2) */
0x81, 0x01, /* Input (Cnst, Ary, Abs) */
0xc0 /* End collection */
};
#endif
/*
* Define non-configurable items in the HID Report descriptor.
*/
static const USB_HID_Short_Item_t hidCollectionApplication = { .header = 0xA1, .data = { 0x01, 0x00 }, .location = 0x00 };
static const USB_HID_Short_Item_t hidCollectionEnd = { .header = 0xC0, .data = { 0x00, 0x00 }, .location = 0x00 };
static const USB_HID_Short_Item_t hidInputConstArray = { .header = 0x81, .data = { 0x01, 0x00 }, .location = 0x00 };
static const USB_HID_Short_Item_t hidInputDataVar = { .header = 0x81, .data = { 0x02, 0x00 }, .location = 0x00 };
static const USB_HID_Short_Item_t hidLogicalMaximum0 = { .header = 0x25, .data = { 0x00, 0x00 }, .location = 0x00 };
static const USB_HID_Short_Item_t hidLogicalMaximum1 = { .header = 0x25, .data = { 0x01, 0x00 }, .location = 0x00 };
static const USB_HID_Short_Item_t hidLogicalMinimum0 = { .header = 0x15, .data = { 0x00, 0x00 }, .location = 0x00 };
static const USB_HID_Short_Item_t hidReportCount2 = { .header = 0x95, .data = { 0x02, 0x00 }, .location = 0x00 };
static const USB_HID_Short_Item_t hidReportCount6 = { .header = 0x95, .data = { 0x06, 0x00 }, .location = 0x00 };
static const USB_HID_Short_Item_t hidReportSize1 = { .header = 0x75, .data = { 0x01, 0x00 }, .location = 0x00 };
static const USB_HID_Short_Item_t hidUsageConsumerControl = { .header = 0x09, .data = { 0x01, 0x00 }, .location = 0x00 };
static const USB_HID_Short_Item_t hidUsagePageConsumer = { .header = 0x05, .data = { 0x0C, 0x00 }, .location = 0x00 };
/*
* Define configurable items in the HID Report descriptor.
*/
static USB_HID_Short_Item_t hidUsageByte0Bit5 = { .header = 0x09, .data = { 0xE2, 0x00 }, .location = 0x50 }; // Mute
static USB_HID_Short_Item_t hidUsageByte0Bit4 = { .header = 0x09, .data = { 0xEA, 0x00 }, .location = 0x40 }; // Vol-
static USB_HID_Short_Item_t hidUsageByte0Bit3 = { .header = 0x09, .data = { 0xE9, 0x00 }, .location = 0x30 }; // Vol+
static USB_HID_Short_Item_t hidUsageByte0Bit2 = { .header = 0x09, .data = { 0xB6, 0x00 }, .location = 0x20 }; // Scan Prev
static USB_HID_Short_Item_t hidUsageByte0Bit1 = { .header = 0x09, .data = { 0xB5, 0x00 }, .location = 0x10 }; // Scan Next
static USB_HID_Short_Item_t hidUsageByte0Bit0 = { .header = 0x09, .data = { 0xB0, 0x00 }, .location = 0x00 }; // Play
/*
* List the configurable items in the HID Report descriptor.
*/
static USB_HID_Short_Item_t* const hidConfigurableItems[] = {
&hidUsageByte0Bit0,
&hidUsageByte0Bit1,
&hidUsageByte0Bit2,
&hidUsageByte0Bit3,
&hidUsageByte0Bit4,
&hidUsageByte0Bit5
};
/*
* List Usage pages in the HID Report descriptor, one per byte.
*/
static const USB_HID_Short_Item_t* const hidUsagePages[] = {
&hidUsagePageConsumer
};
/*
* List all items in the HID Report descriptor.
*/
static const USB_HID_Short_Item_t* const hidReportDescriptorItems[] = {
&hidUsagePageConsumer,
&hidUsageConsumerControl,
&hidCollectionApplication,
&hidLogicalMinimum0,
&hidLogicalMaximum1,
&hidUsageByte0Bit0,
&hidUsageByte0Bit1,
&hidUsageByte0Bit2,
&hidUsageByte0Bit3,
&hidUsageByte0Bit4,
&hidUsageByte0Bit5,
&hidReportSize1,
&hidReportCount6,
&hidInputDataVar,
&hidLogicalMaximum0,
&hidReportCount2,
&hidInputConstArray,
&hidCollectionEnd
};
/*
* Define the length of the HID Report.
* This value must match the number of Report bytes defined by hidReportDescriptorItems.
*/
#define HID_REPORT_LENGTH ( 1 )
#endif // __hid_report_descriptor_h__

View File

@@ -75,7 +75,7 @@
</Link>
</Links>
<ExternalDevices>
<Device NodeId="0" Tile="0" Class="SQIFlash" Name="bootFlash" Type="S25FL116K">
<Device NodeId="0" Tile="0" Class="SQIFlash" Name="bootFlash" Type="S25FL116K" PageSize="256" SectorSize="4096" NumPages="8192">
<Attribute Name="PORT_SQI_CS" Value="PORT_SQI_CS"/>
<Attribute Name="PORT_SQI_SCLK" Value="PORT_SQI_SCLK"/>
<Attribute Name="PORT_SQI_SIO" Value="PORT_SQI_SIO"/>

View File

@@ -3,9 +3,9 @@ APP_NAME = app_xua_simple
TARGET = xk-audio-216-mc.xn
# The flags passed to xcc when building the application
XCC_FLAGS = -fcomment-asm -Xmapper --map -Xmapper MAPFILE -O3 -report -fsubword-select -save-temps \
-g -Wno-unused-function -Wno-timing -DXUD_SERIES_SUPPORT=XUD_X200_SERIES -DUSB_TILE=tile[1] \
-DSDA_HIGH=2 -DSCL_HIGH=1 -fxscope
XCC_FLAGS = -fcomment-asm -Xmapper --map -Xmapper MAPFILE -O3 -report -save-temps \
-g -Wno-unused-function -Wno-timing -DXUD_SERIES_SUPPORT=XUD_X200_SERIES \
-DXUD_CORE_CLOCK=600 -DUSB_TILE=tile[1] -DSDA_HIGH=2 -DSCL_HIGH=1 -fxscope
# The USED_MODULES variable lists other module used by the application. These
# modules will extend the SOURCE_DIRS, INCLUDE_DIRS and LIB_DIRS variables.

View File

@@ -61,7 +61,7 @@ int main()
par
{
/* Low level USB device layer core */
on tile[1]: XUD_Main(c_ep_out, 2, c_ep_in, 2, c_sof, epTypeTableOut, epTypeTableIn, null, null, -1, XUD_SPEED_HS, XUD_PWR_SELF);
on tile[1]: XUD_Main(c_ep_out, 2, c_ep_in, 2, c_sof, epTypeTableOut, epTypeTableIn, XUD_SPEED_HS, XUD_PWR_SELF);
/* Endpoint 0 core from lib_xua */
/* Note, since we are not using many features we pass in null for quite a few params.. */

View File

@@ -0,0 +1,112 @@
// Copyright 2021 XMOS LIMITED.
// This Software is subject to the terms of the XMOS Public Licence: Version 1.
#ifndef __hid_report_descriptor_h__
#define __hid_report_descriptor_h__
#include "xua_hid_report_descriptor.h"
#if 0
/* Existing static report descriptor kept for reference */
unsigned char hidReportDescriptor[] =
{
0x05, 0x0c, /* Usage Page (Consumer Device) */
0x09, 0x01, /* Usage (Consumer Control) */
0xa1, 0x01, /* Collection (Application) */
0x15, 0x00, /* Logical Minimum (0) */
0x25, 0x01, /* Logical Maximum (1) */
0x09, 0xb0, /* Usage (Play) */
0x09, 0xb5, /* Usage (Scan Next Track) */
0x09, 0xb6, /* Usage (Scan Previous Track) */
0x09, 0xe9, /* Usage (Volume Up) */
0x09, 0xea, /* Usage (Volume Down) */
0x09, 0xe2, /* Usage (Mute) */
0x75, 0x01, /* Report Size (1) */
0x95, 0x06, /* Report Count (6) */
0x81, 0x02, /* Input (Data, Var, Abs) */
0x95, 0x02, /* Report Count (2) */
0x81, 0x01, /* Input (Cnst, Ary, Abs) */
0xc0 /* End collection */
};
#endif
/*
* Define non-configurable items in the HID Report descriptor.
*/
static const USB_HID_Short_Item_t hidCollectionApplication = { .header = 0xA1, .data = { 0x01, 0x00 }, .location = 0x00 };
static const USB_HID_Short_Item_t hidCollectionEnd = { .header = 0xC0, .data = { 0x00, 0x00 }, .location = 0x00 };
static const USB_HID_Short_Item_t hidInputConstArray = { .header = 0x81, .data = { 0x01, 0x00 }, .location = 0x00 };
static const USB_HID_Short_Item_t hidInputDataVar = { .header = 0x81, .data = { 0x02, 0x00 }, .location = 0x00 };
static const USB_HID_Short_Item_t hidLogicalMaximum0 = { .header = 0x25, .data = { 0x00, 0x00 }, .location = 0x00 };
static const USB_HID_Short_Item_t hidLogicalMaximum1 = { .header = 0x25, .data = { 0x01, 0x00 }, .location = 0x00 };
static const USB_HID_Short_Item_t hidLogicalMinimum0 = { .header = 0x15, .data = { 0x00, 0x00 }, .location = 0x00 };
static const USB_HID_Short_Item_t hidReportCount2 = { .header = 0x95, .data = { 0x02, 0x00 }, .location = 0x00 };
static const USB_HID_Short_Item_t hidReportCount6 = { .header = 0x95, .data = { 0x06, 0x00 }, .location = 0x00 };
static const USB_HID_Short_Item_t hidReportSize1 = { .header = 0x75, .data = { 0x01, 0x00 }, .location = 0x00 };
static const USB_HID_Short_Item_t hidUsageConsumerControl = { .header = 0x09, .data = { 0x01, 0x00 }, .location = 0x00 };
static const USB_HID_Short_Item_t hidUsagePageConsumer = { .header = 0x05, .data = { 0x0C, 0x00 }, .location = 0x00 };
/*
* Define configurable items in the HID Report descriptor.
*/
static USB_HID_Short_Item_t hidUsageByte0Bit5 = { .header = 0x09, .data = { 0xE2, 0x00 }, .location = 0x50 }; // Mute
static USB_HID_Short_Item_t hidUsageByte0Bit4 = { .header = 0x09, .data = { 0xEA, 0x00 }, .location = 0x40 }; // Vol-
static USB_HID_Short_Item_t hidUsageByte0Bit3 = { .header = 0x09, .data = { 0xE9, 0x00 }, .location = 0x30 }; // Vol+
static USB_HID_Short_Item_t hidUsageByte0Bit2 = { .header = 0x09, .data = { 0xB6, 0x00 }, .location = 0x20 }; // Scan Prev
static USB_HID_Short_Item_t hidUsageByte0Bit1 = { .header = 0x09, .data = { 0xB5, 0x00 }, .location = 0x10 }; // Scan Next
static USB_HID_Short_Item_t hidUsageByte0Bit0 = { .header = 0x09, .data = { 0xB0, 0x00 }, .location = 0x00 }; // Play
/*
* List the configurable items in the HID Report descriptor.
*/
static USB_HID_Short_Item_t* const hidConfigurableItems[] = {
&hidUsageByte0Bit0,
&hidUsageByte0Bit1,
&hidUsageByte0Bit2,
&hidUsageByte0Bit3,
&hidUsageByte0Bit4,
&hidUsageByte0Bit5
};
/*
* List Usage pages in the HID Report descriptor, one per byte.
*/
static const USB_HID_Short_Item_t* const hidUsagePages[] = {
&hidUsagePageConsumer
};
/*
* List all items in the HID Report descriptor.
*/
static const USB_HID_Short_Item_t* const hidReportDescriptorItems[] = {
&hidUsagePageConsumer,
&hidUsageConsumerControl,
&hidCollectionApplication,
&hidLogicalMinimum0,
&hidLogicalMaximum1,
&hidUsageByte0Bit0,
&hidUsageByte0Bit1,
&hidUsageByte0Bit2,
&hidUsageByte0Bit3,
&hidUsageByte0Bit4,
&hidUsageByte0Bit5,
&hidReportSize1,
&hidReportCount6,
&hidInputDataVar,
&hidLogicalMaximum0,
&hidReportCount2,
&hidInputConstArray,
&hidCollectionEnd
};
/*
* Define the length of the HID Report.
* This value must match the number of Report bytes defined by hidReportDescriptorItems.
*/
#define HID_REPORT_LENGTH ( 1 )
#endif // __hid_report_descriptor_h__

View File

@@ -22,7 +22,6 @@ out port p_gpio = on tile[0]:XS1_PORT_8C;
void AudioHwConfig(unsigned samFreq, unsigned mClk, unsigned dsdMode,
unsigned sampRes_DAC, unsigned sampRes_ADC)
{
unsigned char data[1] = {0};
unsigned char gpioVal = 0;
/* Set master clock select appropriately and put ADC and DAC into reset */

View File

@@ -75,7 +75,7 @@
</Link>
</Links>
<ExternalDevices>
<Device NodeId="0" Tile="0" Class="SQIFlash" Name="bootFlash" Type="S25FL116K">
<Device NodeId="0" Tile="0" Class="SQIFlash" Name="bootFlash" Type="S25FL116K" PageSize="256" SectorSize="4096" NumPages="8192">
<Attribute Name="PORT_SQI_CS" Value="PORT_SQI_CS"/>
<Attribute Name="PORT_SQI_SCLK" Value="PORT_SQI_SCLK"/>
<Attribute Name="PORT_SQI_SIO" Value="PORT_SQI_SIO"/>

View File

@@ -3,9 +3,9 @@ APP_NAME = app_xua_simple
TARGET = mic_array_ref.xn
# The flags passed to xcc when building the application
XCC_FLAGS = -fcomment-asm -Xmapper --map -Xmapper MAPFILE -O3 -report -fsubword-select -save-temps \
-g -Wno-unused-function -Wno-timing -DXUD_SERIES_SUPPORT=XUD_X200_SERIES -DUSB_TILE=tile[1] \
-DSDA_HIGH=2 -DSCL_HIGH=1 -fxscope
XCC_FLAGS = -fcomment-asm -Xmapper --map -Xmapper MAPFILE -O3 -report -save-temps \
-g -Wno-unused-function -Wno-timing -DXUD_SERIES_SUPPORT=XUD_X200_SERIES \
-DXUD_CORE_CLOCK=600 -DUSB_TILE=tile[1] -DSDA_HIGH=2 -DSCL_HIGH=1 -fxscope
# The USED_MODULES variable lists other module used by the application. These
# modules will extend the SOURCE_DIRS, INCLUDE_DIRS and LIB_DIRS variables.

View File

@@ -65,7 +65,7 @@ int main()
par
{
/* Low level USB device layer core */
on tile[1]: XUD_Main(c_ep_out, 2, c_ep_in, 2, c_sof, epTypeTableOut, epTypeTableIn, null, null, -1, XUD_SPEED_HS, XUD_PWR_BUS);
on tile[1]: XUD_Main(c_ep_out, 2, c_ep_in, 2, c_sof, epTypeTableOut, epTypeTableIn, XUD_SPEED_HS, XUD_PWR_BUS);
/* Endpoint 0 core from lib_xua */
/* Note, since we are not using many features we pass in null for quite a few params.. */

View File

@@ -0,0 +1,112 @@
// Copyright 2021 XMOS LIMITED.
// This Software is subject to the terms of the XMOS Public Licence: Version 1.
#ifndef __hid_report_descriptor_h__
#define __hid_report_descriptor_h__
#include "xua_hid_report_descriptor.h"
#if 0
/* Existing static report descriptor kept for reference */
unsigned char hidReportDescriptor[] =
{
0x05, 0x0c, /* Usage Page (Consumer Device) */
0x09, 0x01, /* Usage (Consumer Control) */
0xa1, 0x01, /* Collection (Application) */
0x15, 0x00, /* Logical Minimum (0) */
0x25, 0x01, /* Logical Maximum (1) */
0x09, 0xb0, /* Usage (Play) */
0x09, 0xb5, /* Usage (Scan Next Track) */
0x09, 0xb6, /* Usage (Scan Previous Track) */
0x09, 0xe9, /* Usage (Volume Up) */
0x09, 0xea, /* Usage (Volume Down) */
0x09, 0xe2, /* Usage (Mute) */
0x75, 0x01, /* Report Size (1) */
0x95, 0x06, /* Report Count (6) */
0x81, 0x02, /* Input (Data, Var, Abs) */
0x95, 0x02, /* Report Count (2) */
0x81, 0x01, /* Input (Cnst, Ary, Abs) */
0xc0 /* End collection */
};
#endif
/*
* Define non-configurable items in the HID Report descriptor.
*/
static const USB_HID_Short_Item_t hidCollectionApplication = { .header = 0xA1, .data = { 0x01, 0x00 }, .location = 0x00 };
static const USB_HID_Short_Item_t hidCollectionEnd = { .header = 0xC0, .data = { 0x00, 0x00 }, .location = 0x00 };
static const USB_HID_Short_Item_t hidInputConstArray = { .header = 0x81, .data = { 0x01, 0x00 }, .location = 0x00 };
static const USB_HID_Short_Item_t hidInputDataVar = { .header = 0x81, .data = { 0x02, 0x00 }, .location = 0x00 };
static const USB_HID_Short_Item_t hidLogicalMaximum0 = { .header = 0x25, .data = { 0x00, 0x00 }, .location = 0x00 };
static const USB_HID_Short_Item_t hidLogicalMaximum1 = { .header = 0x25, .data = { 0x01, 0x00 }, .location = 0x00 };
static const USB_HID_Short_Item_t hidLogicalMinimum0 = { .header = 0x15, .data = { 0x00, 0x00 }, .location = 0x00 };
static const USB_HID_Short_Item_t hidReportCount2 = { .header = 0x95, .data = { 0x02, 0x00 }, .location = 0x00 };
static const USB_HID_Short_Item_t hidReportCount6 = { .header = 0x95, .data = { 0x06, 0x00 }, .location = 0x00 };
static const USB_HID_Short_Item_t hidReportSize1 = { .header = 0x75, .data = { 0x01, 0x00 }, .location = 0x00 };
static const USB_HID_Short_Item_t hidUsageConsumerControl = { .header = 0x09, .data = { 0x01, 0x00 }, .location = 0x00 };
static const USB_HID_Short_Item_t hidUsagePageConsumer = { .header = 0x05, .data = { 0x0C, 0x00 }, .location = 0x00 };
/*
* Define configurable items in the HID Report descriptor.
*/
static USB_HID_Short_Item_t hidUsageByte0Bit5 = { .header = 0x09, .data = { 0xE2, 0x00 }, .location = 0x50 }; // Mute
static USB_HID_Short_Item_t hidUsageByte0Bit4 = { .header = 0x09, .data = { 0xEA, 0x00 }, .location = 0x40 }; // Vol-
static USB_HID_Short_Item_t hidUsageByte0Bit3 = { .header = 0x09, .data = { 0xE9, 0x00 }, .location = 0x30 }; // Vol+
static USB_HID_Short_Item_t hidUsageByte0Bit2 = { .header = 0x09, .data = { 0xB6, 0x00 }, .location = 0x20 }; // Scan Prev
static USB_HID_Short_Item_t hidUsageByte0Bit1 = { .header = 0x09, .data = { 0xB5, 0x00 }, .location = 0x10 }; // Scan Next
static USB_HID_Short_Item_t hidUsageByte0Bit0 = { .header = 0x09, .data = { 0xB0, 0x00 }, .location = 0x00 }; // Play
/*
* List the configurable items in the HID Report descriptor.
*/
static USB_HID_Short_Item_t* const hidConfigurableItems[] = {
&hidUsageByte0Bit0,
&hidUsageByte0Bit1,
&hidUsageByte0Bit2,
&hidUsageByte0Bit3,
&hidUsageByte0Bit4,
&hidUsageByte0Bit5
};
/*
* List Usage pages in the HID Report descriptor, one per byte.
*/
static const USB_HID_Short_Item_t* const hidUsagePages[] = {
&hidUsagePageConsumer
};
/*
* List all items in the HID Report descriptor.
*/
static const USB_HID_Short_Item_t* const hidReportDescriptorItems[] = {
&hidUsagePageConsumer,
&hidUsageConsumerControl,
&hidCollectionApplication,
&hidLogicalMinimum0,
&hidLogicalMaximum1,
&hidUsageByte0Bit0,
&hidUsageByte0Bit1,
&hidUsageByte0Bit2,
&hidUsageByte0Bit3,
&hidUsageByte0Bit4,
&hidUsageByte0Bit5,
&hidReportSize1,
&hidReportCount6,
&hidInputDataVar,
&hidLogicalMaximum0,
&hidReportCount2,
&hidInputConstArray,
&hidCollectionEnd
};
/*
* Define the length of the HID Report.
* This value must match the number of Report bytes defined by hidReportDescriptorItems.
*/
#define HID_REPORT_LENGTH ( 1 )
#endif // __hid_report_descriptor_h__

View File

@@ -81,7 +81,7 @@
</Link>
</Links>
<ExternalDevices>
<Device NodeId="0" Tile="0" Class="SQIFlash" Name="bootFlash" Type="S25FL116K">
<Device NodeId="0" Tile="0" Class="SQIFlash" Name="bootFlash" Type="S25FL116K" PageSize="256" SectorSize="4096" NumPages="8192">
<Attribute Name="PORT_SQI_CS" Value="PORT_SQI_CS"/>
<Attribute Name="PORT_SQI_SCLK" Value="PORT_SQI_SCLK"/>
<Attribute Name="PORT_SQI_SIO" Value="PORT_SQI_SIO"/>

View File

@@ -3,7 +3,7 @@ TARGET = xk-audio-216-mc.xn
USED_MODULES = lib_xua \
module_i2c_shared module_i2c_single_port lib_logging
BUILD_FLAGS = -O0 -g -lflash -DXUD_SERIES_SUPPORT=4 -fxscope -save-temps -march=xs2a -DUSB_TILE=tile[1]
BUILD_FLAGS = -O0 -g -lflash -DXUD_SERIES_SUPPORT=4 -DXUD_CORE_CLOCK=600 -fxscope -save-temps -march=xs2a -DUSB_TILE=tile[1]
BUILD_FLAGS_i2s_master_2in_2out_48khz = $(BUILD_FLAGS) \
-D ADAT_RX=0 -D ADAT_TX=0 -D SPDIF_RX=0 -D SPDIF_TX=0 -D MIDI=0 \

View File

@@ -0,0 +1,112 @@
// Copyright 2021 XMOS LIMITED.
// This Software is subject to the terms of the XMOS Public Licence: Version 1.
#ifndef __hid_report_descriptor_h__
#define __hid_report_descriptor_h__
#include "xua_hid_report_descriptor.h"
#if 0
/* Existing static report descriptor kept for reference */
unsigned char hidReportDescriptor[] =
{
0x05, 0x0c, /* Usage Page (Consumer Device) */
0x09, 0x01, /* Usage (Consumer Control) */
0xa1, 0x01, /* Collection (Application) */
0x15, 0x00, /* Logical Minimum (0) */
0x25, 0x01, /* Logical Maximum (1) */
0x09, 0xb0, /* Usage (Play) */
0x09, 0xb5, /* Usage (Scan Next Track) */
0x09, 0xb6, /* Usage (Scan Previous Track) */
0x09, 0xe9, /* Usage (Volume Up) */
0x09, 0xea, /* Usage (Volume Down) */
0x09, 0xe2, /* Usage (Mute) */
0x75, 0x01, /* Report Size (1) */
0x95, 0x06, /* Report Count (6) */
0x81, 0x02, /* Input (Data, Var, Abs) */
0x95, 0x02, /* Report Count (2) */
0x81, 0x01, /* Input (Cnst, Ary, Abs) */
0xc0 /* End collection */
};
#endif
/*
* Define non-configurable items in the HID Report descriptor.
*/
static const USB_HID_Short_Item_t hidCollectionApplication = { .header = 0xA1, .data = { 0x01, 0x00 }, .location = 0x00 };
static const USB_HID_Short_Item_t hidCollectionEnd = { .header = 0xC0, .data = { 0x00, 0x00 }, .location = 0x00 };
static const USB_HID_Short_Item_t hidInputConstArray = { .header = 0x81, .data = { 0x01, 0x00 }, .location = 0x00 };
static const USB_HID_Short_Item_t hidInputDataVar = { .header = 0x81, .data = { 0x02, 0x00 }, .location = 0x00 };
static const USB_HID_Short_Item_t hidLogicalMaximum0 = { .header = 0x25, .data = { 0x00, 0x00 }, .location = 0x00 };
static const USB_HID_Short_Item_t hidLogicalMaximum1 = { .header = 0x25, .data = { 0x01, 0x00 }, .location = 0x00 };
static const USB_HID_Short_Item_t hidLogicalMinimum0 = { .header = 0x15, .data = { 0x00, 0x00 }, .location = 0x00 };
static const USB_HID_Short_Item_t hidReportCount2 = { .header = 0x95, .data = { 0x02, 0x00 }, .location = 0x00 };
static const USB_HID_Short_Item_t hidReportCount6 = { .header = 0x95, .data = { 0x06, 0x00 }, .location = 0x00 };
static const USB_HID_Short_Item_t hidReportSize1 = { .header = 0x75, .data = { 0x01, 0x00 }, .location = 0x00 };
static const USB_HID_Short_Item_t hidUsageConsumerControl = { .header = 0x09, .data = { 0x01, 0x00 }, .location = 0x00 };
static const USB_HID_Short_Item_t hidUsagePageConsumer = { .header = 0x05, .data = { 0x0C, 0x00 }, .location = 0x00 };
/*
* Define configurable items in the HID Report descriptor.
*/
static USB_HID_Short_Item_t hidUsageByte0Bit5 = { .header = 0x09, .data = { 0xE2, 0x00 }, .location = 0x50 }; // Mute
static USB_HID_Short_Item_t hidUsageByte0Bit4 = { .header = 0x09, .data = { 0xEA, 0x00 }, .location = 0x40 }; // Vol-
static USB_HID_Short_Item_t hidUsageByte0Bit3 = { .header = 0x09, .data = { 0xE9, 0x00 }, .location = 0x30 }; // Vol+
static USB_HID_Short_Item_t hidUsageByte0Bit2 = { .header = 0x09, .data = { 0xB6, 0x00 }, .location = 0x20 }; // Scan Prev
static USB_HID_Short_Item_t hidUsageByte0Bit1 = { .header = 0x09, .data = { 0xB5, 0x00 }, .location = 0x10 }; // Scan Next
static USB_HID_Short_Item_t hidUsageByte0Bit0 = { .header = 0x09, .data = { 0xB0, 0x00 }, .location = 0x00 }; // Play
/*
* List the configurable items in the HID Report descriptor.
*/
static USB_HID_Short_Item_t* const hidConfigurableItems[] = {
&hidUsageByte0Bit0,
&hidUsageByte0Bit1,
&hidUsageByte0Bit2,
&hidUsageByte0Bit3,
&hidUsageByte0Bit4,
&hidUsageByte0Bit5
};
/*
* List Usage pages in the HID Report descriptor, one per byte.
*/
static const USB_HID_Short_Item_t* const hidUsagePages[] = {
&hidUsagePageConsumer
};
/*
* List all items in the HID Report descriptor.
*/
static const USB_HID_Short_Item_t* const hidReportDescriptorItems[] = {
&hidUsagePageConsumer,
&hidUsageConsumerControl,
&hidCollectionApplication,
&hidLogicalMinimum0,
&hidLogicalMaximum1,
&hidUsageByte0Bit0,
&hidUsageByte0Bit1,
&hidUsageByte0Bit2,
&hidUsageByte0Bit3,
&hidUsageByte0Bit4,
&hidUsageByte0Bit5,
&hidReportSize1,
&hidReportCount6,
&hidInputDataVar,
&hidLogicalMaximum0,
&hidReportCount2,
&hidInputConstArray,
&hidCollectionEnd
};
/*
* Define the length of the HID Report.
* This value must match the number of Report bytes defined by hidReportDescriptorItems.
*/
#define HID_REPORT_LENGTH ( 1 )
#endif // __hid_report_descriptor_h__

View File

@@ -83,10 +83,12 @@
</Link>
</Links>
<ExternalDevices>
<Device NodeId="0" Tile="0" Class="SQIFlash" Name="bootFlash" Type="S25FL116K">
<Device NodeId="0" Tile="0" Class="SQIFlash" Name="bootFlash" Type="S25FL116K" PageSize="256" SectorSize="4096" NumPages="8192">
<Attribute Name="PORT_SQI_CS" Value="PORT_SQI_CS"/>
<Attribute Name="PORT_SQI_SCLK" Value="PORT_SQI_SCLK"/>
<Attribute Name="PORT_SQI_SIO" Value="PORT_SQI_SIO"/>
<Attribute Name="QE_REGISTER" Value="flash_qe_location_status_reg_0"/>
<Attribute Name="QE_BIT" Value="flash_qe_bit_6"/>
</Device>
</ExternalDevices>
<JTAGChain>

View File

@@ -4,7 +4,7 @@
#define __custom_defines_h__
#define EXCLUDE_USB_AUDIO_MAIN
#define NUM_PDM_MICS 0
#define XUA_NUM_PDM_MICS 0
#define XUD_TILE 1
#define AUDIO_IO_TILE 0
#define MIXER 0

View File

@@ -15,7 +15,10 @@
* \param c_ep0_out Chanend connected to the XUD_Manager() out endpoint array
* \param c_ep0_in Chanend connected to the XUD_Manager() in endpoint array
* \param c_audioCtrl Chanend connected to the decouple thread for control
* audio (sample rate changes etc.)
* audio (sample rate changes etc.). Note when nulled, the
* audio device only supports single sample rate/format and
* DFU is not supported either since this channel is used
* to carry messages about format, rate and DFU state
* \param c_mix_ctl Optional chanend to be connected to the mixer thread if
* present
* \param c_clk_ctl Optional chanend to be connected to the clockgen thread if
@@ -25,7 +28,7 @@
* \param c_EANativeTransport_ctrl Optional chanend to be connected to EA Native
* endpoint manager if present
*/
void XUA_Endpoint0(chanend c_ep0_out, chanend c_ep0_in, chanend c_audioCtrl,
void XUA_Endpoint0(chanend c_ep0_out, chanend c_ep0_in, chanend ?c_audioCtrl,
chanend ?c_mix_ctl,chanend ?c_clk_ctl, chanend ?c_EANativeTransport_ctr, client interface i_dfu ?dfuInterface
VENDOR_REQUESTS_PARAMS_DEC_);

View File

@@ -1,8 +1,8 @@
VERSION = 1.2.0
VERSION = 2.0.0
DEPENDENT_MODULES = lib_logging(>=3.0.0) \
lib_xassert(>=4.0.0) \
lib_xud(>=1.0.0) \
lib_xud(>=2.0.0) \
lib_spdif(>=4.0.0) \
lib_mic_array(>=4.0.0)
@@ -40,7 +40,6 @@ INCLUDE_DIRS = $(EXPORT_INCLUDE_DIRS) \
src/core/pdm_mics \
src/core/ports \
src/core/support \
src/core/support/powersave \
src/core/user \
src/core/user/audiostream \
src/core/user/hid \
@@ -58,7 +57,6 @@ SOURCE_DIRS = src/core \
src/core/pdm_mics \
src/core/ports \
src/core/support \
src/core/support/powersave \
src/core/user/audiostream \
src/core/user/hostactive \
src/core/xuduser \

View File

@@ -21,8 +21,9 @@
#include "testct_byref.h"
#if( 0 < HID_CONTROLS )
#include "xua_hid_report_descriptor.h"
#include "user_hid.h"
unsigned char g_hidData[HID_DATA_BYTES] = {0};
unsigned char g_hidData[HID_MAX_DATA_BYTES] = {0};
#endif
void GetADCCounts(unsigned samFreq, int &min, int &mid, int &max);
@@ -371,7 +372,10 @@ void XUA_Buffer_Ep(register chanend c_aud_out,
#endif
#if( 0 < HID_CONTROLS )
XUD_SetReady_In(ep_hid, g_hidData, 1);
{
int hidDataLength = hidGetReportLength();
XUD_SetReady_In(ep_hid, g_hidData, hidDataLength);
}
#endif
#if (AUDIO_CLASS == 1)
@@ -885,9 +889,9 @@ void XUA_Buffer_Ep(register chanend c_aud_out,
/* HID Report Data */
case XUD_SetData_Select(c_hid, ep_hid, result):
{
g_hidData[0]=0;
int hidDataLength = hidGetReportLength();
UserHIDGetData(g_hidData);
XUD_SetReady_In(ep_hid, g_hidData, 1);
XUD_SetReady_In(ep_hid, g_hidData, hidDataLength);
}
break;
#endif

View File

@@ -7,12 +7,12 @@
#include "vendorrequests.h"
int VendorAudioRequests(XUD_ep ep0_out, XUD_ep ep0_in, unsigned char bRequest, unsigned char cs, unsigned char cn,
unsigned short unitId, unsigned char direction, chanend c_audioControl,
unsigned short unitId, unsigned char direction, NULLABLE_RESOURCE(chanend, c_audioControl),
NULLABLE_RESOURCE(chanend, c_mix_ctl),
NULLABLE_RESOURCE(chanend, c_clk_ctL)) __attribute__ ((weak));
int VendorAudioRequests(XUD_ep ep0_out, XUD_ep ep0_in, unsigned char bRequest, unsigned char cs, unsigned char cn,
unsigned short unitId, unsigned char direction, chanend c_audioControl,
unsigned short unitId, unsigned char direction, NULLABLE_RESOURCE(chanend, c_audioControl),
NULLABLE_RESOURCE(chanend, c_mix_ctl),
NULLABLE_RESOURCE(chanend, c_clk_ctL))
{

View File

@@ -33,7 +33,7 @@
#endif
int VendorAudioRequests(XUD_ep ep0_out, XUD_ep ep0_in, unsigned char bRequest, unsigned char cs, unsigned char cn,
unsigned short unitId, unsigned char direction, chanend c_audioControl,
unsigned short unitId, unsigned char direction, NULLABLE_RESOURCE(chanend, c_audioControl),
NULLABLE_RESOURCE(chanend, c_mix_ctl),
NULLABLE_RESOURCE(chanend, c_clk_ctL));

View File

@@ -10,6 +10,7 @@
#include <stddef.h>
#include <stdint.h>
#include <string.h>
#include <xassert.h>
#include "xua.h"
#if XUA_USB_EN
@@ -23,18 +24,24 @@
#include "vendorrequests.h"
#include "xc_ptr.h"
#include "xua_ep0_uacreqs.h"
#if( 0 < HID_CONTROLS )
#include "hid.h"
#include "xua_hid.h"
#include "xua_hid_report_descriptor.h"
#endif
#if DSD_CHANS_DAC > 0
#include "dsd_support.h"
#endif
#define DEBUG_UNIT XUA_EP0
#ifndef DEBUG_PRINT_ENABLE_XUA_EP0
#define DEBUG_PRINT_ENABLE_XUA_EP0 0
#endif // DEBUG_PRINT_ENABLE_XUA_EP0
#include "debug_print.h"
#include "debug_print.h"
#include "xua_usb_params_funcs.h"
#ifndef __XC__
@@ -51,7 +58,7 @@
#if ((AUDIO_CLASS == 1) || (AUDIO_CLASS_FALLBACK)) && defined(DFU)
#warning DFU will not be enabled in AUDIO 1.0 mode due to Windows requesting driver
#endif
#endif
#endif // FORCE_UAC1_DFU
/* MIDI not supported in Audio 1.0 mode */
#if ((AUDIO_CLASS == 1) || (AUDIO_CLASS_FALLBACK)) && defined(MIDI)
@@ -85,9 +92,6 @@ extern void device_reboot(void);
#endif
#if( 0 < HID_CONTROLS )
#include "xua_hid.h"
#endif
#ifndef MIN
#define MIN(a,b) (((a)<(b))?(a):(b))
#endif
@@ -391,7 +395,7 @@ void XUA_Endpoint0_setBcdDevice(unsigned short bcd) {
#endif // AUDIO_CLASS == 1}
}
void XUA_Endpoint0_init(chanend c_ep0_out, chanend c_ep0_in, chanend c_audioControl,
void XUA_Endpoint0_init(chanend c_ep0_out, chanend c_ep0_in, NULLABLE_RESOURCE(chanend, c_audioControl),
chanend c_mix_ctl, chanend c_clk_ctl, chanend c_EANativeTransport_ctrl, CLIENT_INTERFACE(i_dfu, dfuInterface) VENDOR_REQUESTS_PARAMS_DEC_)
{
ep0_out = XUD_InitEp(c_ep0_out);
@@ -478,6 +482,8 @@ void XUA_Endpoint0_init(chanend c_ep0_out, chanend c_ep0_in, chanend c_audioCont
/* Check if device has started in DFU mode */
if (DFUReportResetState(null))
{
assert((c_audioControl != NULL) && msg("DFU not supported when c_audioControl is null"));
/* Stop audio */
outuint(c_audioControl, SET_SAMPLE_FREQ);
outuint(c_audioControl, AUDIO_STOP_FOR_DFU);
@@ -518,9 +524,25 @@ void XUA_Endpoint0_init(chanend c_ep0_out, chanend c_ep0_in, chanend c_audioCont
#endif
#if( 0 < HID_CONTROLS )
hidPrepareReportDescriptor();
size_t hidReportDescriptorLength = hidGetReportDescriptorLength();
unsigned char hidReportDescriptorLengthLo = hidReportDescriptorLength & 0xFF;
unsigned char hidReportDescriptorLengthHi = (hidReportDescriptorLength & 0xFF00) >> 8;
#if( AUDIO_CLASS == 1 )
cfgDesc_Audio1[USB_HID_DESCRIPTOR_OFFSET + HID_DESCRIPTOR_LENGTH_FIELD_OFFSET ] = hidReportDescriptorLengthLo;
cfgDesc_Audio1[USB_HID_DESCRIPTOR_OFFSET + HID_DESCRIPTOR_LENGTH_FIELD_OFFSET + 1] = hidReportDescriptorLengthHi;
#endif
hidDescriptor[HID_DESCRIPTOR_LENGTH_FIELD_OFFSET ] = hidReportDescriptorLengthLo;
hidDescriptor[HID_DESCRIPTOR_LENGTH_FIELD_OFFSET + 1] = hidReportDescriptorLengthHi;
#endif // 0 < HID_CONTROLS
}
void XUA_Endpoint0_loop(XUD_Result_t result, USB_SetupPacket_t sp, chanend c_ep0_out, chanend c_ep0_in, chanend c_audioControl,
void XUA_Endpoint0_loop(XUD_Result_t result, USB_SetupPacket_t sp, chanend c_ep0_out, chanend c_ep0_in, NULLABLE_RESOURCE(chanend, c_audioControl),
chanend c_mix_ctl, chanend c_clk_ctl, chanend c_EANativeTransport_ctrl, CLIENT_INTERFACE(i_dfu, dfuInterface) VENDOR_REQUESTS_PARAMS_DEC_)
{
if (result == XUD_RES_OKAY)
@@ -547,6 +569,7 @@ void XUA_Endpoint0_loop(XUD_Result_t result, USB_SetupPacket_t sp, chanend c_ep0
/* Only send change if we need to */
if((sp.wValue > 0) && (g_curStreamAlt_Out != sp.wValue))
{
assert((c_audioControl != null) && msg("Format change not supported when c_audioControl is null"));
g_curStreamAlt_Out = sp.wValue;
/* Send format of data onto buffering */
@@ -582,6 +605,7 @@ void XUA_Endpoint0_loop(XUD_Result_t result, USB_SetupPacket_t sp, chanend c_ep0
/* Only send change if we need to */
if((sp.wValue > 0) && (g_curStreamAlt_In != sp.wValue))
{
assert((c_audioControl != null) && msg("Format change not supported when c_audioControl is null"));
g_curStreamAlt_In = sp.wValue;
/* Send format of data onto buffering */
@@ -729,15 +753,22 @@ void XUA_Endpoint0_loop(XUD_Result_t result, USB_SetupPacket_t sp, chanend c_ep0
switch (descriptorType)
{
case HID_HID:
/* Return HID Descriptor */
result = XUD_DoGetRequest(ep0_out, ep0_in, hidDescriptor,
sizeof(hidDescriptor), sp.wLength);
{
/* Return HID Descriptor */
result = XUD_DoGetRequest(ep0_out, ep0_in, hidDescriptor,
sizeof(hidDescriptor), sp.wLength);
}
break;
case HID_REPORT:
/* Return HID report descriptor */
result = XUD_DoGetRequest(ep0_out, ep0_in, hidReportDescriptor,
sizeof(hidReportDescriptor), sp.wLength);
break;
{
/* Return HID report descriptor */
unsigned char* hidReportDescriptorPtr;
hidReportDescriptorPtr = hidGetReportDescriptor();
size_t hidReportDescriptorLength = hidGetReportDescriptorLength();
result = XUD_DoGetRequest(ep0_out, ep0_in, hidReportDescriptorPtr,
hidReportDescriptorLength, sp.wLength);
}
break;
}
}
break;
@@ -819,6 +850,7 @@ void XUA_Endpoint0_loop(XUD_Result_t result, USB_SetupPacket_t sp, chanend c_ep0
if ((DFU_IF == INTERFACE_NUMBER_DFU) && (sp.bRequest != XMOS_DFU_SAVESTATE) &&
(sp.bRequest != XMOS_DFU_RESTORESTATE))
{
assert((c_audioControl != null) && msg("DFU not supported when c_audioControl is null"));
// Stop audio
outuint(c_audioControl, SET_SAMPLE_FREQ);
outuint(c_audioControl, AUDIO_STOP_FOR_DFU);
@@ -1061,7 +1093,7 @@ void XUA_Endpoint0_loop(XUD_Result_t result, USB_SetupPacket_t sp, chanend c_ep0
}
/* Endpoint 0 function. Handles all requests to the device */
void XUA_Endpoint0(chanend c_ep0_out, chanend c_ep0_in, chanend c_audioControl,
void XUA_Endpoint0(chanend c_ep0_out, chanend c_ep0_in, NULLABLE_RESOURCE(chanend, c_audioControl),
chanend c_mix_ctl, chanend c_clk_ctl, chanend c_EANativeTransport_ctrl, CLIENT_INTERFACE(i_dfu, dfuInterface) VENDOR_REQUESTS_PARAMS_DEC_)
{
USB_SetupPacket_t sp;

View File

@@ -15,7 +15,7 @@
#include "usbaudio20.h" /* Defines from the USB Audio 2.0 Specifications */
#include "usbaudiocommon.h"
#include "xud_device.h"
#include "usbaudio20.h" /* Defines from USB Audio 2.0 spec */
#include "xua_hid_descriptor.h"
#ifdef IAP_EA_NATIVE_TRANS
#include "iap2.h" /* Defines iAP EA Native Transport protocol name */
@@ -580,33 +580,6 @@ unsigned char devQualDesc_Null[] =
#define MIXER_LENGTH (0)
#endif
#if( 0 < HID_CONTROLS )
unsigned char hidReportDescriptor[] = /* Voice Command usage as per request #HUTRR45 */
{
0x05, 0x01, /* Usage Page (Generic Desktop) */
0x09, 0x06, /* Usage (Keyboard) */
0xa1, 0x01, /* Collection (Application) */
0x75, 0x01, /* Report Size (1) */
0x95, 0x04, /* Report Count (4) */
0x15, 0x00, /* Logical Minimum (0) */
0x25, 0x00, /* Logical Maximum (0) */
0x81, 0x01, /* Input (Cnst, Ary, Abs, No Wrap, Lin, Pref, No Nul) */
0x95, 0x01, /* Report Count (1) */
0x25, 0x01, /* Logical Maximum (1) */
0x05, 0x0C, /* Usage Page (Consumer) */
0x0a, 0x21, 0x02, /* Usage (AC Search) */
0x81, 0x02, /* Input (Data, Var, Abs, No Wrap, Lin, Pref, No Nul) */
0x0a, 0x26, 0x02, /* Usage (AC Stop) */
0x81, 0x02, /* Input (Data, Var, Abs, No Wrap, Lin, Pref, No Nul) */
0x95, 0x02, /* Report Count (2) */
0x05, 0x07, /* Usage Page (Key Codes) */
0x19, 0x72, /* Usage Minimum (Keyboard F23) */
0x29, 0x73, /* Usage Maximum (Keyboard F24) */
0x81, 0x02, /* Input (Data, Var, Abs, No Wrap, Lin, Pref, No Nul) */
0xc0 /* End collection (Application) */
};
#endif
/* Max packet sizes:
* Samples per channel. e.g (192000+7999/8000) = 24
* Must allow 1 sample extra per chan (24 + 1) = 25
@@ -808,7 +781,7 @@ typedef struct
#if( 0 < HID_CONTROLS )
USB_Descriptor_Interface_t HID_Interface;
unsigned char hidDesc[9]; //TODO ideally we would have a struct for this.
USB_HID_Descriptor_t HID_Descriptor;
USB_Descriptor_Endpoint_t HID_In_Endpoint;
#endif
@@ -1939,7 +1912,7 @@ USB_Config_Descriptor_Audio2_t cfgDesc_Audio2=
.wLockDelay = 0x0008,
},
#endif /* (INPUT_FORMAT_COUNT > 2) */
#endif /* #if(NUM_USB_CHAN_IN > 0) */
#endif /* (NUM_USB_CHAN_IN > 0) */
#ifdef MIDI
/* MIDI Descriptors */
@@ -2204,60 +2177,24 @@ USB_Config_Descriptor_Audio2_t cfgDesc_Audio2=
#endif /* IAP */
#if( 0 < HID_CONTROLS )
.HID_Interface =
{
9, /* 0 bLength : Size of descriptor in Bytes */
4, /* 1 bDescriptorType (Interface: 0x04)*/
INTERFACE_NUMBER_HID, /* 2 bInterfaceNumber : Number of interface */
0, /* 3 bAlternateSetting : Value used alternate interfaces using SetInterface Request */
1, /* 4: bNumEndpoints : Number of endpoitns for this interface (excluding 0) */
3, /* 5: bInterfaceClass */
0, /* 6: bInterfaceSubClass - no boot device */
0, /* 7: bInterfaceProtocol*/
0, /* 8 iInterface */
},
{
9, /* 0 bLength : Size of descriptor in Bytes */
0x21, /* 1 bDescriptorType (HID) */
0x10, /* 2 bcdHID */
0x01, /* 3 bcdHID */
0, /* 4 bCountryCode */
1, /* 5 bNumDescriptors */
0x22, /* 6 bDescriptorType[0] (Report) */
sizeof(hidReportDescriptor) & 0xff,/* 7 wDescriptorLength[0] */
sizeof(hidReportDescriptor) >> 8, /* 8 wDescriptorLength[0] */
},
.HID_In_Endpoint =
{
/* Endpoint descriptor (IN) */
0x7, /* 0 bLength */
5, /* 1 bDescriptorType */
ENDPOINT_ADDRESS_IN_HID, /* 2 bEndpointAddress */
3, /* 3 bmAttributes (INTERRUPT) */
64, /* 4 wMaxPacketSize */
ENDPOINT_INT_INTERVAL_IN_HID, /* 6 bInterval */
}
#include "xua_hid_descriptors.h"
#endif
};
#endif /* (AUDIO_CLASS == 2) */
#if( 0 < HID_CONTROLS )
#if (AUDIO_CLASS ==1 )
unsigned char hidDescriptor[] =
{
0x09, /* 0 bLength : Size of descriptor in Bytes */
0x21, /* 1 bDescriptorType (HID) */
0x10, /* 2 bcdHID */
0x01, /* 3 bcdHID */
0x00, /* 4 bCountryCode */
0x01, /* 5 bNumDescriptors */
0x22, /* 6 bDescriptorType[0] (Report) */
sizeof(hidReportDescriptor) & 0xff, /* 7 wDescriptorLength[0] */
sizeof(hidReportDescriptor) >> 8, /* 8 wDescriptorLength[0] */
#include "xua_hid_descriptor_contents.h"
};
#elif (AUDIO_CLASS == 2)
unsigned char* hidDescriptor = (unsigned char*) &cfgDesc_Audio2.HID_Descriptor;
#else
#error "Unknown Audio Class"
#endif
#endif // 0 < HID_CONTROLS
/* Configuration Descriptor for Null device */
@@ -2362,6 +2299,12 @@ const unsigned num_freqs_a1 = MAX(3, (0
#endif
#if( 0 < HID_CONTROLS )
/*
* The value of HID_INTERFACE_BYTES must match the length of the descriptors defined in
* - xua_hid_descriptor_contents.h
* - xua_hid_endpoint_descriptor_contents.h and
* - xua_hid_interface_descriptor_contents.h
*/
#define HID_INTERFACE_BYTES ( 9 + 9 + 7 )
#define HID_INTERFACES_A1 1
#else
@@ -2403,6 +2346,10 @@ const unsigned num_freqs_a1 = MAX(3, (0
#endif
#if( 0 < HID_CONTROLS )
#define USB_HID_DESCRIPTOR_OFFSET (18 + AC_TOTAL_LENGTH + (INPUT_INTERFACES_A1 * (49 + num_freqs_a1 * 3)) + (OUTPUT_INTERFACES_A1 * (49 + num_freqs_a1 * 3)) + CONTROL_INTERFACE_BYTES + DFU_INTERFACE_BYTES + INTERFACE_DESCRIPTOR_BYTES)
#endif
#define CHARIFY_SR(x) (x & 0xff),((x & 0xff00)>> 8),((x & 0xff0000)>> 16)
#if (MIN_FREQ_FS < 12000) && (MAX_FREQ_FS > 48000)
@@ -2906,36 +2853,7 @@ unsigned char cfgDesc_Audio1[] =
#endif
#if( 0 < HID_CONTROLS )
/* HID interface descriptor */
0x09, /* 0 bLength : Size of descriptor in Bytes */
0x04, /* 1 bDescriptorType (Interface: 0x04)*/
INTERFACE_NUMBER_HID, /* 2 bInterfaceNumber : Number of interface */
0x00, /* 3 bAlternateSetting : Value used alternate interfaces using SetInterface Request */
0x01, /* 4: bNumEndpoints : Number of endpoitns for this interface (excluding 0) */
0x03, /* 5: bInterfaceClass */
0x00, /* 6: bInterfaceSubClass - no boot device */
0x00, /* 7: bInterfaceProtocol*/
0x00, /* 8 iInterface */
/* HID descriptor */
0x09, /* 0 bLength : Size of descriptor in Bytes */
0x21, /* 1 bDescriptorType (HID) */
0x10, /* 2 bcdHID */
0x01, /* 3 bcdHID */
0x00, /* 4 bCountryCode */
0x01, /* 5 bNumDescriptors */
0x22, /* 6 bDescriptorType[0] (Report) */
sizeof(hidReportDescriptor) & 0xff, /* 7 wDescriptorLength[0] */
sizeof(hidReportDescriptor) >> 8, /* 8 wDescriptorLength[0] */
/* HID Endpoint descriptor (IN) */
0x07, /* 0 bLength */
0x05, /* 1 bDescriptorType */
ENDPOINT_ADDRESS_IN_HID, /* 2 bEndpointAddress */
0x03, /* 3 bmAttributes (INTERRUPT) */
0x40, /* 4 wMaxPacketSize */
0x00, /* 5 wMaxPacketSize */
ENDPOINT_INT_INTERVAL_IN_HID, /* 6 bInterval */
#include "xua_hid_descriptors.h"
#endif
};

View File

@@ -1285,4 +1285,4 @@ XUD_Result_t AudioClassRequests_1(XUD_ep ep0_out, XUD_ep ep0_in, USB_SetupPacket
return XUD_RES_ERR;
}
#endif
#endif /* NO_USB */
#endif /* XUA_USB_EN */

View File

@@ -187,20 +187,20 @@ on tile[XUD_TILE] : clock clk_spd_rx = CLKBLK_SPDIF_RX;
#endif
#if (XUA_NUM_PDM_MICS > 0)
in port p_pdm_clk = PORT_PDM_CLK;
in port p_pdm_clk = PORT_PDM_CLK;
in buffered port:32 p_pdm_mics = PORT_PDM_DATA;
in buffered port:32 p_pdm_mics = PORT_PDM_DATA;
#if (PDM_TILE != AUDIO_IO_TILE)
/* If Mics and I2S are not the same tile we need a separate MCLK port */
in port p_pdm_mclk = PORT_PDM_MCLK;
in port p_pdm_mclk = PORT_PDM_MCLK;
#endif
#endif
#if(XUD_SERIES_SUPPORT == XUD_L_SERIES) && (ADAT_RX)
#if (defined(__XS2A__) && (ADAT_RX))
/* Cannot use default clock (CLKBLK_REF) for ADAT RX since it is tied to the
60MHz USB clock on G/L series parts. */
60MHz USB clock on XS2 processors. */
on tile[XUD_TILE] : clock clk_adat_rx = CLKBLK_ADAT_RX;
#endif
@@ -212,15 +212,14 @@ on tile[XUD_TILE] : clock clk_audio_mclk_usb = CLKBLK_MCLK;
on tile[XUD_TILE] : in port p_mclk_in_usb = PORT_MCLK_IN_USB;
#endif
on tile[AUDIO_IO_TILE] : clock clk_audio_bclk = CLKBLK_I2S_BIT; /* Bit clock */
on tile[AUDIO_IO_TILE] : clock clk_audio_bclk = CLKBLK_I2S_BIT; /* Bit clock */
/* L/G Series needs a port to use for USB reset */
#if (XUD_SERIES_SUPPORT != XUD_U_SERIES) && defined(PORT_USB_RESET)
#if ((defined(__XS2A__) || defined (__XS3A__)) && defined(PORT_USB_RESET))
/* This define is checked since it could be on a shift reg or similar */
on tile[XUD_TILE] : out port p_usb_rst = PORT_USB_RESET;
#else
/* Reset port not required for U series due to built in Phy */
#define p_usb_rst null
#endif
@@ -346,8 +345,7 @@ VENDOR_REQUESTS_PARAMS_DEC_
/* USB Interface Core */
XUD_Main(c_xud_out, ENDPOINT_COUNT_OUT, c_xud_in, ENDPOINT_COUNT_IN,
c_sof, epTypeTableOut, epTypeTableIn, p_usb_rst,
null, 0, usbSpeed, XUD_PWR_CFG);
c_sof, epTypeTableOut, epTypeTableIn, usbSpeed, XUD_PWR_CFG);
}
/* USB Packet buffering Core */
@@ -727,8 +725,8 @@ int main()
{
set_thread_fast_mode_on();
#if(XUD_SERIES_SUPPORT == XUD_L_SERIES)
/* Can't use REF clock on L-series as this is usb clock */
#if defined(__XS2A__)
/* Can't use REF clock as this is usb clock */
set_port_clock(p_adat_rx, clk_adat_rx);
start_clock(clk_adat_rx);
#endif

View File

@@ -1,11 +0,0 @@
// Copyright 2013-2021 XMOS LIMITED.
// This Software is subject to the terms of the XMOS Public Licence: Version 1.
#ifndef ARCH_U_POWER_SAVING_
#define ARCH_U_POWER_SAVING_
/* Sets the voltage down by VOLTAGE_REDUCTION_mV (voltage is set to 10 * X + 600 mV),
* and adjusts other features to save power
*/
void archU_powerSaving();
#endif /*ARCH_U_POWER_SAVING_*/

View File

@@ -1,70 +0,0 @@
// Copyright 2013-2021 XMOS LIMITED.
// This Software is subject to the terms of the XMOS Public Licence: Version 1.
#if (XUD_SERIES_SUPPORT==1)
#include "archU_powerSaving.h"
#include <xs1.h>
#include <xs1_l_registers.h>
#include <xs1_su_registers.h>
#include <platform.h>
#if (XCC_MAJOR_VERSION >= 1300)
#include <hwtimer.h>
#else
#define hwtimer_t timer
#endif
#ifndef VOLTAGE_REDUCTION_mV
#define VOLTAGE_REDUCTION_mV 20
#endif
unsigned get_tile_id(tileref t); // Required for use with 12.0 tools. get_tile_id() available in xs1.h with 13.0 tools.
#define ARCH_U_VOLTAGE_FIRST_STEP 39 // First step down from 1V
#define ARCH_U_SSWITCH_PRESCALER 8 // Sswitch down to 1/8 clk freq
void archU_powerSaving()
{
if (get_local_tile_id() == get_tile_id(tile[0]))
{
unsigned writeval[1];
unsigned char writevalc[1];
// Reduce the VDDCORE voltage level
for (unsigned count=0; count < (VOLTAGE_REDUCTION_mV/10); count++)
{
hwtimer_t t;
int time;
writeval[0] = (ARCH_U_VOLTAGE_FIRST_STEP - count);
write_periph_32(usb_tile, XS1_SU_PER_PWR_CHANEND_NUM, XS1_SU_PER_PWR_VOUT1_LVL_NUM, 1, writeval);
t :> time;
time += (1 * PLATFORM_REFERENCE_MHZ); // Wait 1us per step
t when timerafter(time) :> void;
}
// Set switch prescaler down
write_node_config_reg(tile[0], XS1_SSWITCH_CLK_DIVIDER_NUM, (ARCH_U_SSWITCH_PRESCALER - 1)); // PLL clk will be divided by value + 1
// Both DC-DCs in PWM mode, I/O and PLL supply on, Analogue & core on
writeval[0] = XS1_SU_PWR_VOUT1_EN_SET(0, 1);
writeval[0] = XS1_SU_PWR_VOUT2_EN_SET(writeval[0], 1);
writeval[0] = XS1_SU_PWR_VOUT5_EN_SET(writeval[0], 1);
writeval[0] = XS1_SU_PWR_VOUT6_EN_SET(writeval[0], 1);
write_periph_32(usb_tile, XS1_SU_PER_PWR_CHANEND_NUM, XS1_SU_PER_PWR_STATE_AWAKE_NUM, 1, writeval);
// USB suspend off, voltage adjustable, sleep clock 32KHz
writeval[0] = XS1_SU_PWR_USB_PD_EN_SET(0, 1);
writeval[0] = XS1_SU_PWR_RST_VOUT_LVL_SET(writeval[0], 1);
writeval[0] = XS1_SU_PWR_LD_AWAKE_SET(writeval[0], 1);
write_periph_32(usb_tile, XS1_SU_PER_PWR_CHANEND_NUM, XS1_SU_PER_PWR_MISC_CTRL_NUM, 1, writeval);
// Turn off on-chip silicon oscillator (20MHz or 32KHz)
writevalc[0] = XS1_SU_ON_SI_OSC_EN_SET(0, 1);
writevalc[0] = XS1_SU_ON_SI_OSC_SLOW_SET(writevalc[0], 1);
write_periph_8(usb_tile, XS1_SU_PER_OSC_CHANEND_NUM, XS1_SU_PER_OSC_ON_SI_CTRL_NUM, 1, writevalc);
}
}
#endif

View File

@@ -5,18 +5,9 @@
#include <print.h>
#include <xs1_su.h>
#define XS1_SU_PERIPH_USB_ID 0x1
//Normally we would enumerate the XUD_SERIES_SUPPORT possibilities using defines in
//xud.h but we have hard coded them to remove dependancy of sc_xud
#if (XUD_SERIES_SUPPORT == 4)
#include "xs2_su_registers.h"
#define XS2_SU_PERIPH_USB_ID 0x1
#define PLL_MASK 0x3FFFFFFF
#else
#define PLL_MASK 0xFFFFFFFF
#endif
/* Note, this function is prototyped in xs1.h only from 13 tools onwards */
unsigned get_tile_id(tileref);
@@ -38,25 +29,17 @@ static void reset_tile(unsigned const tileId)
*/
void device_reboot(void)
{
#if (XUD_SERIES_SUPPORT == 1)
/* Disconnect from bus */
unsigned data[] = {4};
write_periph_32(usb_tile, XS1_SU_PERIPH_USB_ID, XS1_SU_PER_UIFM_FUNC_CONTROL_NUM, 1, data);
/* Ideally we would reset SU1 here but then we loose power to the xcore and therefore the DFU flag */
/* Disable USB and issue reset to xcore only - not analogue chip */
write_node_config_reg(usb_tile, XS1_SU_CFG_RST_MISC_NUM,0b10);
#else
unsigned int localTileId = get_local_tile_id();
unsigned int tileId;
unsigned int tileArrayLength;
unsigned int localTileNum;
#if (XUD_SERIES_SUPPORT == 4)
#if defined(__XS2A__)
/* Disconnect from bus */
unsigned data[] = {4};
write_periph_32(usb_tile, XS2_SU_PERIPH_USB_ID, XS1_GLX_PER_UIFM_FUNC_CONTROL_NUM, 1, data);
#elif defined(__XS3A__)
#warning Assuming that tile reset also resets USB in XS3 architectures
#endif
tileArrayLength = sizeof(tile)/sizeof(tileref);
@@ -75,24 +58,14 @@ void device_reboot(void)
}
}
#if defined(__XS2A__) || defined(__XS3A__)
/* Reset all even tiles, starting from the remote ones */
for(int tileNum = tileArrayLength-2; tileNum>=0; tileNum-=2)
#else
/* Reset all tiles, starting from the remote ones */
for(int tileNum = tileArrayLength-1; tileNum>=0; tileNum--)
#endif
{
/* Cannot cast tileref to unsigned! */
tileId = get_tile_id(tile[tileNum]);
/* Do not reboot local tile (or tiles residing on the same node) yet */
#if defined(__XS2A__) || defined(__XS3A__)
if((localTileNum | 1) != (tileNum | 1))
#else
if(localTileNum != tileNum)
#endif
{
reset_tile(tileId);
}
@@ -100,7 +73,6 @@ void device_reboot(void)
/* Finally reboot the node this tile resides on */
reset_tile(localTileId);
#endif
while (1);
}

View File

@@ -4,46 +4,14 @@
#ifndef _UAC_HWRESOURCES_H_
#define _UAC_HWRESOURCES_H_
#if XUA_USB_EN
#include "xud.h" /* XMOS USB Device Layer defines and functions */
#endif
#if ((XUD_SERIES_SUPPORT != XUD_U_SERIES) && (XUD_SERIES_SUPPORT != XUD_X200_SERIES))
/* XUD_L_SERIES and XUD_G_SERIES */
#if (AUDIO_IO_TILE == XUD_TILE)
/* Note: L series ref clocked clocked from USB clock when USB enabled - use another clockblock for MIDI
* if MIDI and XUD on same tile. See XUD documentation.
*
* This is a clash with S/PDIF Tx but simultaneous S/PDIF and MIDI not currently supported on single tile device
*
*/
#define CLKBLK_MIDI XS1_CLKBLK_1;
#else
#define CLKBLK_MIDI XS1_CLKBLK_REF;
#endif
#define CLKBLK_SPDIF_TX XS1_CLKBLK_1
#define CLKBLK_SPDIF_RX XS1_CLKBLK_1
#define CLKBLK_MCLK XS1_CLKBLK_2 /* Note, potentially used twice */
#define CLKBLK_ADAT_RX XS1_CLKBLK_3
#define CLKBLK_USB_RST XS1_CLKBLK_4 /* Clock block passed into L/G series XUD */
#define CLKBLK_FLASHLIB XS1_CLKBLK_5 /* Clock block for use by flash lib */
#define CLKBLK_I2S_BIT XS1_CLKBLK_3
#else
/* XUD_U_SERIES, XUD_X200_SERIES */
/* Note, U-series XUD uses clock blocks 4 and 5 - see XUD_Ports.xc */
#define CLKBLK_MIDI XS1_CLKBLK_REF;
#define CLKBLK_SPDIF_TX XS1_CLKBLK_1
#define CLKBLK_SPDIF_RX XS1_CLKBLK_1
#define CLKBLK_MCLK XS1_CLKBLK_2 /* Note, potentially used twice */
#define CLKBLK_MCLK XS1_CLKBLK_4
#define CLKBLK_FLASHLIB XS1_CLKBLK_3 /* Clock block for use by flash lib */
#define CLKBLK_ADAT_RX XS1_CLKBLK_REF /* Use REF for ADAT_RX on U/x200 series */
#define CLKBLK_I2S_BIT XS1_CLKBLK_3
#endif
#define CLKBLK_I2S_BIT XS1_CLKBLK_5
#endif /* _UAC_HWRESOURCES_H_ */

View File

@@ -5,49 +5,19 @@
#define __USER_HID_H__
/**
* \brief HID event identifiers
* \brief HID event
*
* This enumeration defines a constant value for each HID event.
* It defines one value for each of the four GPI pins supported in the standard voice products.
* It defines a further 28 values for generic events.
* This struct identifies the location within the HID Report for an event and
* The value to report for that location.
* It assumes only single bit flags within the HID Report.
*/
typedef enum hidEventId_t {
HID_EVENT_ID_GPI0 = 0,
HID_EVENT_ID_GPI1,
HID_EVENT_ID_GPI2,
HID_EVENT_ID_GPI3,
HID_EVENT_ID_EVT0,
HID_EVENT_ID_EVT1,
HID_EVENT_ID_EVT2,
HID_EVENT_ID_EVT3,
HID_EVENT_ID_EVT4,
HID_EVENT_ID_EVT5,
HID_EVENT_ID_EVT6,
HID_EVENT_ID_EVT7,
HID_EVENT_ID_EVT8,
HID_EVENT_ID_EVT9,
HID_EVENT_ID_EVT10,
HID_EVENT_ID_EVT11,
HID_EVENT_ID_EVT12,
HID_EVENT_ID_EVT13,
HID_EVENT_ID_EVT14,
HID_EVENT_ID_EVT15,
HID_EVENT_ID_EVT16,
HID_EVENT_ID_EVT17,
HID_EVENT_ID_EVT18,
HID_EVENT_ID_EVT19,
HID_EVENT_ID_EVT20,
HID_EVENT_ID_EVT21,
HID_EVENT_ID_EVT22,
HID_EVENT_ID_EVT23,
HID_EVENT_ID_EVT24,
HID_EVENT_ID_EVT25,
HID_EVENT_ID_EVT26,
HID_EVENT_ID_EVT27,
HID_EVENT_ID_INVALID = 0xffffffff,
} hidEventId_t;
typedef struct hidEvent_t {
unsigned bit;
unsigned byte;
unsigned value;
} hidEvent_t;
#define HID_DATA_BYTES 4
#define HID_MAX_DATA_BYTES 4
#if( 0 < HID_CONTROLS )
@@ -60,7 +30,7 @@ typedef enum hidEventId_t {
*
* \param{out} hidData The HID data
*/
void UserHIDGetData( unsigned char hidData[ HID_DATA_BYTES ]);
void UserHIDGetData( unsigned char hidData[ HID_MAX_DATA_BYTES ]);
/**
* \brief Initialize HID processing
@@ -70,17 +40,15 @@ void UserHIDInit( void );
/**
* \brief Record that a HID event has occurred
*
* \param{in} hidEventId The identifier of an event which has occurred
* \param{in} hidEventData A list of data associated with the event
* \param{in} hidEventDataSize The length of the event data list
* \param{in} hidEvent A list of events which have occurred.
* Each element specifies a bit and byte in the HID Report and the value for it.
* \param{in} hidEventCnt The length of the \a hidEvent list.
*
* \note At present, this function only takes a single element of event data, i.e.
* hidEventDataSize must equal 1.
*
* \note At present, this function treats the event data as a Boolean flag.
* Zero means False; all other values mean True.
* \returns A Boolean flag indicating the status of the operation
* \retval False No recording of the event(s) occurred
* \retval True Recording of the event(s) occurred
*/
void UserHIDRecordEvent( const hidEventId_t hidEventId, const int * hidEventData, const unsigned hidEventDataSize );
unsigned UserHIDRecordEvent( const hidEvent_t hidEvent[], const unsigned hidEventCnt );
#endif /* ( 0 < HID_CONTROLS ) */
#endif /* __USER_HID_H__ */

View File

@@ -5,19 +5,17 @@
#include <xs1.h>
#include <platform.h>
#ifndef NO_USB
#if XUA_USB_EN
#include "xud_device.h"
#include "dfu_types.h"
#include "flash_interface.h"
#include "dfu_interface.h"
#if (XUD_SERIES_SUPPORT==4)
/* xCORE-200 */
#if defined(__XS3A__)
#define FLAG_ADDRESS 0xfffcc
#elif defined(__XS2A__)
/* Note range 0x7FFC8 - 0x7FFFF guarenteed to be untouched by tools */
#define FLAG_ADDRESS 0x7ffcc
#else
/* Note range 0x1FFC8 - 0x1FFFF guarenteed to be untouched by tools */
#define FLAG_ADDRESS 0x1ffcc
#endif
/* Store Flag to fixed address */
@@ -581,6 +579,6 @@ int DFUDeviceRequests(XUD_ep ep0_out, XUD_ep &?ep0_in, USB_SetupPacket_t &sp, ch
}
return returnVal;
}
#endif /* NO_USB */
#endif /* XUA_USB_EN */
#endif

View File

@@ -90,9 +90,9 @@ int flash_cmd_enable_ports()
#ifdef DFU_FLASH_DEVICE
#ifdef QUAD_SPI_FLASH
result = fl_connectToDevice(&p_qflash, flash_devices, 1);
result = fl_connectToDevice(&p_qflash, flash_devices, sizeof(flash_devices) / sizeof(fl_QuadDeviceSpec));
#else
result = fl_connectToDevice(&p_flash, flash_devices, 1);
result = fl_connectToDevice(&p_flash, flash_devices, sizeof(flash_devices) / sizeof(fl_DeviceSpec));
#endif
#else
/* Use default flash list */

View File

@@ -0,0 +1,272 @@
// Copyright 2021 XMOS LIMITED.
// This Software is subject to the terms of the XMOS Public Licence: Version 1.
#include <assert.h>
#include <stddef.h>
#include <xs1.h>
#include "xua_hid_report_descriptor.h"
#include "hid_report_descriptor.h"
#include <stdio.h>
#define HID_REPORT_ITEM_LOCATION_SIZE ( 1 )
#define HID_REPORT_DESCRIPTOR_ITEM_COUNT ( sizeof hidReportDescriptorItems / sizeof ( USB_HID_Short_Item_t* ))
#define HID_REPORT_DESCRIPTOR_MAX_LENGTH ( HID_REPORT_DESCRIPTOR_ITEM_COUNT * \
( sizeof ( USB_HID_Short_Item_t ) - HID_REPORT_ITEM_LOCATION_SIZE ))
static unsigned char hidReportDescriptor[ HID_REPORT_DESCRIPTOR_MAX_LENGTH ];
static size_t hidReportDescriptorLength = 0;
static unsigned hidReportDescriptorPrepared = 0;
/**
* @brief Get the bit position from the location of an Item
*
* Parameters:
*
* @param[in] location The \c location field from a \c USB_HID_Short_Item
*
* @return The bit position of the Item
*/
static unsigned hidGetItemBitLocation( const unsigned char header );
/**
* @brief Get the byte position from the location of an Item
*
* Parameters:
*
* @param[in] location The \c location field from a \c USB_HID_Short_Item
*
* @return The byte position of the Item within the HID Report
*/
static unsigned hidGetItemByteLocation( const unsigned char header );
/**
* @brief Get the number of data bytes from the header of an Item
*
* Parameters:
*
* @param[in] header The \c header field from a \c USB_HID_Short_Item
*
* @return The amount of data for the Item
*/
static unsigned hidGetItemSize( const unsigned char header );
/**
* @brief Get the Tag from the header of an Item
*
* Parameters:
*
* @param[in] header The \c header field from a \c USB_HID_Short_Item
*
* @return The Tag of the Item
*/
static unsigned hidGetItemTag( const unsigned char header );
/**
* @brief Get the Type from the header of an Item
*
* Parameters:
*
* @param[in] header The \c header field from a \c USB_HID_Short_Item
*
* @return The Type of the Item
*/
static unsigned hidGetItemType( const unsigned char header );
/**
* @brief Get the Usage Page number for a given byte in the HID Report
*
* Parameters:
*
* @param[in] byte The byte location in the HID Report
*
* @return The USB HID Usage Page code or zero if the \a byte parameter is out-of-range
*/
static unsigned hidGetUsagePage( const unsigned byte );
/**
* @brief Translate an Item from the \c USB_HID_Short_Item format to raw bytes
*
* Parameters:
*
* @param[in] inPtr A pointer to a \c USB_HID_Short_Item
* @param[in,out] outPtrPtr A pointer to a pointer to the next available space in the raw
* byte buffer. Passed as a pointer to a pointer to allow this
* function to return the updated pointer to the raw byte buffer.
*
* @return The number of bytes placed in the raw byte buffer
*/
static size_t hidTranslateItem( const USB_HID_Short_Item_t* inPtr, unsigned char** outPtrPtr );
static unsigned hidGetItemBitLocation( const unsigned char location )
{
unsigned bBit = ( location & HID_REPORT_ITEM_LOC_BIT_MASK ) >> HID_REPORT_ITEM_LOC_BIT_SHIFT;
return bBit;
}
static unsigned hidGetItemByteLocation( const unsigned char location )
{
unsigned bByte = ( location & HID_REPORT_ITEM_LOC_BYTE_MASK ) >> HID_REPORT_ITEM_LOC_BYTE_SHIFT;
return bByte;
}
static unsigned hidGetItemSize( const unsigned char header )
{
unsigned bSize = ( header & HID_REPORT_ITEM_HDR_SIZE_MASK ) >> HID_REPORT_ITEM_HDR_SIZE_SHIFT;
return bSize;
}
static unsigned hidGetItemTag( const unsigned char header )
{
unsigned bTag = ( header & HID_REPORT_ITEM_HDR_TAG_MASK ) >> HID_REPORT_ITEM_HDR_TAG_SHIFT;
return bTag;
}
static unsigned hidGetItemType( const unsigned char header )
{
unsigned bType = ( header & HID_REPORT_ITEM_HDR_TYPE_MASK ) >> HID_REPORT_ITEM_HDR_TYPE_SHIFT;
return bType;
}
unsigned char* hidGetReportDescriptor( void )
{
unsigned char* retVal = NULL;
if( hidReportDescriptorPrepared ) {
retVal = hidReportDescriptor;
}
return retVal;
}
size_t hidGetReportDescriptorLength( void )
{
size_t retVal = ( hidReportDescriptorPrepared ) ? hidReportDescriptorLength : 0;
return retVal;
}
#define HID_CONFIGURABLE_ITEM_COUNT ( sizeof hidConfigurableItems / sizeof ( USB_HID_Short_Item_t* ))
unsigned hidGetReportItem(
const unsigned byte,
const unsigned bit,
unsigned char* const page,
unsigned char* const header,
unsigned char data[]
)
{
unsigned retVal = HID_STATUS_BAD_LOCATION;
for( unsigned itemIdx = 0; itemIdx < HID_CONFIGURABLE_ITEM_COUNT; ++itemIdx ) {
USB_HID_Short_Item_t item = *hidConfigurableItems[ itemIdx ];
unsigned bBit = hidGetItemBitLocation( item.location );
unsigned bByte = hidGetItemByteLocation( item.location );
if(( bit == bBit ) && ( byte == bByte )) {
*page = hidGetUsagePage( byte );
*header = item.header;
for( unsigned dataIdx = 0; dataIdx < HID_REPORT_ITEM_MAX_SIZE; ++data, ++dataIdx ) {
*data = item.data[ dataIdx ];
}
retVal = HID_STATUS_GOOD;
break;
}
}
return retVal;
}
size_t hidGetReportLength( void )
{
size_t retVal = ( hidReportDescriptorPrepared ) ? HID_REPORT_LENGTH : 0;
return retVal;
}
static unsigned hidGetUsagePage( const unsigned byte )
{
unsigned retVal = ( byte < HID_REPORT_LENGTH ) ? hidUsagePages[ byte ]->data[ 0 ] : 0;
return retVal;
}
void hidPrepareReportDescriptor( void )
{
if( !hidReportDescriptorPrepared ) {
hidReportDescriptorLength = 0;
unsigned char* ptr = hidReportDescriptor;
for( unsigned idx = 0; idx < HID_REPORT_DESCRIPTOR_ITEM_COUNT; ++idx ) {
hidReportDescriptorLength += hidTranslateItem( hidReportDescriptorItems[ idx ], &ptr );
}
hidReportDescriptorPrepared = 1;
}
}
void hidResetReportDescriptor( void )
{
hidReportDescriptorPrepared = 0;
}
unsigned hidSetReportItem(
const unsigned byte,
const unsigned bit,
const unsigned char page,
const unsigned char header,
const unsigned char data[]
)
{
unsigned retVal = HID_STATUS_IN_USE;
if( !hidReportDescriptorPrepared ) {
retVal = HID_STATUS_BAD_LOCATION;
unsigned bSize = hidGetItemSize( header );
unsigned bTag = hidGetItemTag ( header );
unsigned bType = hidGetItemType( header );
if(( HID_REPORT_ITEM_MAX_SIZE < bSize ) ||
( HID_REPORT_ITEM_USAGE_TAG != bTag ) ||
( HID_REPORT_ITEM_USAGE_TYPE != bType )) {
retVal = HID_STATUS_BAD_HEADER;
} else {
for( unsigned itemIdx = 0; itemIdx < HID_CONFIGURABLE_ITEM_COUNT; ++itemIdx ) {
USB_HID_Short_Item_t item = *hidConfigurableItems[ itemIdx ];
unsigned bBit = hidGetItemBitLocation( item.location );
unsigned bByte = hidGetItemByteLocation( item.location );
if(( bit == bBit ) && ( byte == bByte )) {
unsigned pg = hidGetUsagePage( byte );
if( page == pg ) {
item.header = header;
for( unsigned dataIdx = 0; dataIdx < bSize; ++dataIdx ) {
item.data[ dataIdx ] = data[ dataIdx ];
}
*hidConfigurableItems[ itemIdx ] = item;
retVal = HID_STATUS_GOOD;
} else {
retVal = HID_STATUS_BAD_PAGE;
}
break;
}
}
}
}
return retVal;
}
static size_t hidTranslateItem( const USB_HID_Short_Item_t* inPtr, unsigned char** outPtrPtr )
{
size_t count = 0;
*(*outPtrPtr)++ = inPtr->header;
++count;
unsigned dataLength = hidGetItemSize( inPtr->header );
for( unsigned idx = 0; idx < dataLength; ++idx ) {
*(*outPtrPtr)++ = inPtr->data[ idx ];
++count;
}
return count;
}

View File

@@ -0,0 +1,28 @@
// Copyright 2021 XMOS LIMITED.
// This Software is subject to the terms of the XMOS Public Licence: Version 1.
/**
* @brief Human Interface Device (HID) descriptor
*
* This file defines the structure of the HID descriptor.
* Document section numbers refer to the HID Device Class Definition, version 1.11.
*/
#ifndef _HID_DESCRIPTOR_
#define _HID_DESCRIPTOR_
#define HID_DESCRIPTOR_LENGTH_FIELD_OFFSET ( 7 )
/* USB HID Descriptor (section 6.2.1) */
typedef struct
{
unsigned char bLength; /* Size of the descriptor (bytes) */
unsigned char bDescriptorType0; /* Descriptor type, a constant, 0x21 (section 7.1) */
unsigned char bcdHID[2]; /* HID class specification release */
unsigned char bCountryCode; /* Country code of localized hardware */
unsigned char bNumDescriptors; /* Number of class descriptors */
unsigned char bDescriptorType1; /* Type of 1st class descriptor (section 7.1) */
unsigned char wDescriptorLength1[2]; /* Length in bytes of the 1st class descriptor */
} __attribute__((packed)) USB_HID_Descriptor_t;
#endif // _HID_DESCRIPTOR_

View File

@@ -0,0 +1,64 @@
// Copyright 2021 XMOS LIMITED.
// This Software is subject to the terms of the XMOS Public Licence: Version 1.
/**
* @brief Human Interface Device (HID) Endpoint descriptors
*
* This file lists the contents of the HID Endpoint descriptor returned during enumeration.
*/
#ifndef _HID_DESCRIPTOR_CONTENTS_
#define _HID_DESCRIPTOR_CONTENTS_
#include "xua_hid_descriptor.h"
#define HID_DESCRIPTOR_LENGTH_0 ( 0x09 ) /* Size of descriptor in Bytes */
#define HID_DESCRIPTOR_TYPE_0 ( 0x21 ) /* HID 0x21 */
#define HID_BCD_VERSION_LO ( 0x10 ) /* HID class specification release */
#define HID_BCD_VERSION_HI ( 0x01 )
#define HID_COUNTRY_CODE ( 0x00 ) /* Country code of localized hardware */
#define HID_NUM_DESCRIPTORS ( 0x01 ) /* Number of class descriptors */
#define HID_DESCRIPTOR_TYPE_1 ( 0x22 ) /* Type of 1st class descriptor, Report 0x22 */
#define HID_DESCRIPTOR_LENGTH_1_LO ( 0x00 ) /* Length of 1st class descriptor, set to zero */
#define HID_DESCRIPTOR_LENGTH_1_HI ( 0x00 ) /* since only pre-processor directives allowed here */
#endif // _HID_DESCRIPTOR_CONTENTS_
#if (AUDIO_CLASS == 1)
/* HID descriptor */
HID_DESCRIPTOR_LENGTH_0, /* 0 bLength */
HID_DESCRIPTOR_TYPE_0, /* 1 bDescriptorType (HID) */
HID_BCD_VERSION_LO, /* 2 bcdHID */
HID_BCD_VERSION_HI, /* 3 bcdHID */
HID_COUNTRY_CODE, /* 4 bCountryCode */
HID_NUM_DESCRIPTORS, /* 5 bNumDescriptors */
HID_DESCRIPTOR_TYPE_1, /* 6 bDescriptorType[0] */
HID_DESCRIPTOR_LENGTH_1_LO, /* 7 wDescriptorLength[0] */
HID_DESCRIPTOR_LENGTH_1_HI, /* 8 wDescriptorLength[0] */
#elif (AUDIO_CLASS == 2)
.HID_Descriptor =
{
/* HID descriptor */
.bLength = sizeof(USB_HID_Descriptor_t),
.bDescriptorType0 = HID_DESCRIPTOR_TYPE_0,
.bcdHID =
{
HID_BCD_VERSION_LO,
HID_BCD_VERSION_HI,
},
.bCountryCode = HID_COUNTRY_CODE,
.bNumDescriptors = HID_NUM_DESCRIPTORS,
.bDescriptorType1 = HID_DESCRIPTOR_TYPE_1,
.wDescriptorLength1 =
{
HID_DESCRIPTOR_LENGTH_1_LO,
HID_DESCRIPTOR_LENGTH_1_HI,
},
},
#else
#error "Unknown Audio Class"
#endif

View File

@@ -0,0 +1,20 @@
// Copyright 2021 XMOS LIMITED.
// This Software is subject to the terms of the XMOS Public Licence: Version 1.
/**
* @brief Human Interface Device (HID) descriptors
*
* This file lists the contents of the HID descriptors returned during enumeration.
* The full definition of the enumerated descriptors appears in xua_ep0_descriptors.h.
* That file should #include the contents of this one at an appropriate point in the
* definition of the cfgDesc_Audio1 and cfgDesc_Audio2 arrays.
*/
#ifndef _HID_DESCRIPTORS_
#define _HID_DESCRIPTORS_
#include "xua_hid_interface_descriptor_contents.h"
#include "xua_hid_descriptor_contents.h"
#include "xua_hid_endpoint_descriptor_contents.h"
#endif // _HID_DESCRIPTORS_

View File

@@ -0,0 +1,49 @@
// Copyright 2021 XMOS LIMITED.
// This Software is subject to the terms of the XMOS Public Licence: Version 1.
/**
* @brief Human Interface Device (HID) Endpoint descriptors
*
* This file lists the contents of the HID Endpoint descriptor returned during enumeration.
*/
#ifndef _HID_ENDPOINT_DESCRIPTOR_CONTENTS_
#define _HID_ENDPOINT_DESCRIPTOR_CONTENTS_
#include "descriptor_defs.h"
#define HID_ENDPOINT_DESCRIPTOR_LENGTH ( 0x07 ) /* Size of descriptor in Bytes */
#define HID_ENDPOINT_DESCRIPTOR_TYPE ( 0x05 ) /* Endpoint 0x05 */
#define HID_ENDPOINT_ATTRIBUTES ( 0x03 ) /* Interrupt */
#define HID_ENDPOINT_DESCRIPTOR_PACKET_SIZE_LO ( 0x40 )
#define HID_ENDPOINT_DESCRIPTOR_PACKET_SIZE_HI ( 0x00 )
#endif // _HID_ENDPOINT_DESCRIPTOR_CONTENTS_
#if (AUDIO_CLASS == 1)
/* HID Endpoint descriptor (IN) */
HID_ENDPOINT_DESCRIPTOR_LENGTH, /* 0 bLength */
HID_ENDPOINT_DESCRIPTOR_TYPE, /* 1 bDescriptorType */
ENDPOINT_ADDRESS_IN_HID, /* 2 bEndpointAddress */
HID_ENDPOINT_ATTRIBUTES, /* 3 bmAttributes (INTERRUPT) */
HID_ENDPOINT_DESCRIPTOR_PACKET_SIZE_LO, /* 4 wMaxPacketSize */
HID_ENDPOINT_DESCRIPTOR_PACKET_SIZE_HI, /* 5 wMaxPacketSize */
ENDPOINT_INT_INTERVAL_IN_HID, /* 6 bInterval */
#elif (AUDIO_CLASS == 2)
.HID_In_Endpoint =
{
/* Endpoint descriptor (IN) */
.bLength = sizeof(USB_Descriptor_Endpoint_t),
.bDescriptorType = HID_ENDPOINT_DESCRIPTOR_TYPE,
.bEndpointAddress = ENDPOINT_ADDRESS_IN_HID,
.bmAttributes = HID_ENDPOINT_ATTRIBUTES,
.wMaxPacketSize = HID_ENDPOINT_DESCRIPTOR_PACKET_SIZE_LO,
.bInterval = ENDPOINT_INT_INTERVAL_IN_HID,
},
#else
#error "Unknown Audio Class"
#endif

View File

@@ -0,0 +1,57 @@
// Copyright 2021 XMOS LIMITED.
// This Software is subject to the terms of the XMOS Public Licence: Version 1.
/**
* @brief Human Interface Device (HID) Interface descriptor
*
* This file lists the contents of the HID Interface descriptor returned during enumeration.
*/
#ifndef _HID_INTERFACE_DESCRIPTOR_CONTENTS_
#define _HID_INTERFACE_DESCRIPTOR_CONTENTS_
#include "descriptor_defs.h"
#define HID_INTERFACE_DESCRIPTOR_LENGTH ( 0x09 ) /* Size of descriptor in Bytes */
#define HID_INTERFACE_DESCRIPTOR_TYPE ( 0x04 ) /* Interface 0x04 */
#define HID_INTERFACE_ALTERNATE_SETTING ( 0x00 ) /* Value used alternate interfaces using SetInterface Request */
#define HID_INTERFACE_NUMBER_OF_ENDPOINTS ( 0x01 ) /* Number of endpoitns for this interface (excluding 0) */
#define HID_INTERFACE_CLASS ( 0x03 )
#define HID_INTERFACE_SUBCLASS ( 0x00 ) /* No boot device */
#define HID_INTERFACE_PROTOCOL ( 0x00 )
#define HID_INTERFACE_STRING_DESCRIPTOR_INDEX ( 0x00 )
#endif // _HID_INTERFACE_DESCRIPTOR_CONTENTS_
#if (AUDIO_CLASS == 1)
/* HID interface descriptor */
HID_INTERFACE_DESCRIPTOR_LENGTH, /* 0 bLength */
HID_INTERFACE_DESCRIPTOR_TYPE, /* 1 bDescriptorType */
INTERFACE_NUMBER_HID, /* 2 bInterfaceNumber : Number of interface */
HID_INTERFACE_ALTERNATE_SETTING, /* 3 bAlternateSetting */
HID_INTERFACE_NUMBER_OF_ENDPOINTS, /* 4: bNumEndpoints */
HID_INTERFACE_CLASS, /* 5: bInterfaceClass */
HID_INTERFACE_SUBCLASS, /* 6: bInterfaceSubClass */
HID_INTERFACE_PROTOCOL, /* 7: bInterfaceProtocol*/
HID_INTERFACE_STRING_DESCRIPTOR_INDEX, /* 8 iInterface */
#elif (AUDIO_CLASS == 2)
.HID_Interface =
{
/* HID interface descriptor */
.bLength = sizeof(USB_Descriptor_Interface_t),
.bDescriptorType = HID_INTERFACE_DESCRIPTOR_TYPE,
.bInterfaceNumber = INTERFACE_NUMBER_HID,
.bAlternateSetting = HID_INTERFACE_ALTERNATE_SETTING,
.bNumEndpoints = HID_INTERFACE_NUMBER_OF_ENDPOINTS,
.bInterfaceClass = HID_INTERFACE_CLASS,
.bInterfaceSubClass = HID_INTERFACE_SUBCLASS,
.bInterfaceProtocol = HID_INTERFACE_PROTOCOL,
.iInterface = HID_INTERFACE_STRING_DESCRIPTOR_INDEX,
},
#else
#error "Unknown Audio Class"
#endif

View File

@@ -0,0 +1,175 @@
// Copyright 2021 XMOS LIMITED.
// This Software is subject to the terms of the XMOS Public Licence: Version 1.
/**
* @brief Human Interface Device (HID) Report descriptor
*
* This file defines the structure of the HID Report descriptor and declares
* functions for manipulating it.
* Because the Report descriptor defines the length of the HID Report, this file
* declares a function for obtaining the Report length as well.
* The using application has the responsibility to define the report descriptor
* structure and default contents in their hid_report_descriptor.h file.
* Document section numbers refer to the HID Device Class Definition, version 1.11.
*/
#ifndef _HID_REPORT_DESCRIPTOR_
#define _HID_REPORT_DESCRIPTOR_
#include <stddef.h>
#define HID_REPORT_ITEM_HDR_SIZE_MASK ( 0x03 )
#define HID_REPORT_ITEM_HDR_SIZE_SHIFT ( 0 )
#define HID_REPORT_ITEM_HDR_TAG_MASK ( 0xF0 )
#define HID_REPORT_ITEM_HDR_TAG_SHIFT ( 4 )
#define HID_REPORT_ITEM_HDR_TYPE_MASK ( 0x0C )
#define HID_REPORT_ITEM_HDR_TYPE_SHIFT ( 2 )
#define HID_REPORT_ITEM_LOC_BIT_MASK ( 0x70 )
#define HID_REPORT_ITEM_LOC_BIT_SHIFT ( 4 )
#define HID_REPORT_ITEM_LOC_BYTE_MASK ( 0x0F )
#define HID_REPORT_ITEM_LOC_BYTE_SHIFT ( 0 )
#define HID_REPORT_ITEM_MAX_SIZE ( 2 )
#define HID_REPORT_ITEM_USAGE_TAG ( 0 )
#define HID_REPORT_ITEM_USAGE_TYPE ( 2 )
#define HID_STATUS_GOOD ( 0 )
#define HID_STATUS_BAD_HEADER ( 1 )
#define HID_STATUS_BAD_LOCATION ( 2 )
#define HID_STATUS_BAD_PAGE ( 3 )
#define HID_STATUS_IN_USE ( 4 )
/**
* @brief USB HID Report Descriptor. Short Item
*
* @note
* To reduce memory use, this type does not support Short Items with 4 data bytes.
* See section 6.2.2.2
*
* Elements:
*
* header - the item prefix containing the size, type and tag fields (see 6.2.2.2)
* Format (bit range): bSize (0:1), bType (2:3), bTag (4:7)
* data - a two byte array for holding the item's data
* The bSize field indicates which data bytes are in use
* location - a non-standard extension locating the item within the HID Report
* Format (bit range): iByte (0:3), iBit (4:6), Reserved (7)
*/
typedef struct
{
unsigned char header;
unsigned char data[ HID_REPORT_ITEM_MAX_SIZE ];
unsigned char location;
} USB_HID_Short_Item_t;
/**
* @brief Get the HID Report descriptor
*
* This function returns a pointer to the USB HID Report descriptor.
* It returns NULL if the Report descriptor has not been prepared,
* i.e., no one has called \c hidPrepareReportDescriptor().
*
* @note An XC-callable version of this function has not been provided.
* XC requires explicit declaration of the kind of pointer returned,
* hence an XC implementation of the function.
*
* @return A pointer to a list of unsigned char containing the Report descriptor
*/
#if !defined(__XC__)
unsigned char* hidGetReportDescriptor( void );
#endif
/**
* @brief Get the length of the HID Report descriptor
*
* This function returns the length of the USB HID Report descriptor.
* It returns zero if the Report descriptor has not been prepared,
* i.e., no one has called \c hidPrepareReportDescriptor().
*
* @return The length of the Report descriptor in bytes
*/
size_t hidGetReportDescriptorLength( void );
/**
* @brief Get a HID Report descriptor item
*
* Parameters:
*
* @param[in] byte The byte position of the control within the HID Report
* @param[in] bit The bit position of the control within the \a byte
* @param[out] page The USB HID Usage Page code for the Item (see 5.5)
* @param[out] header The LSB of the Item containing the bSize, bType and bTag fields (see 6.2.2.2)
* @param[out] data A two element array containing data bytes for the Item
*
* @return A status value
* @retval \c HID_STATUS_GOOD Item successfully returned
* @retval \c HID_STATUS_BAD_LOCATION The \a bit or \a byte arguments specify a location outside
* of the HID Report
*/
#if defined(__XC__)
unsigned hidGetReportItem( const unsigned byte, const unsigned bit, unsigned char* unsafe const page, unsigned char* unsafe const header, unsigned char* unsafe const data);
#else
unsigned hidGetReportItem( const unsigned byte, const unsigned bit, unsigned char* const page, unsigned char* const header, unsigned char data[]);
#endif
/**
* @brief Get the length of the HID Report
*
* This function returns the length of the USB HID Report.
* It returns zero if the Report descriptor has not been prepared,
* i.e., no one has called \c hidPrepareReportDescriptor().
*
* @return The length of the Report in bytes
*/
size_t hidGetReportLength( void );
/**
* @brief Prepare the USB HID Report descriptor
*
* After preparation, \c hidGetReportDescriptor() returns a list suitable for transmission over USB.
* Call this function after altering one or more Report Items using \c hidSetReportItem().
*/
void hidPrepareReportDescriptor( void );
/**
* @brief Reset the USB HID Report descriptor
*
* After reset, \c hidGetReportDescriptor() returns NULL until a subsequent call to
* \c hidPrepareReportDescriptor() occurs.
* Call this function before altering one or more Report Items using \c hidSetReportItem().
*/
void hidResetReportDescriptor( void );
/**
* @brief Modify a HID Report descriptor item
*
* @warning This function does not check that the length of the \a data array matches the value of
* the bSize field in the \a header. For safe operation use a \a data array of at least
* \c HID_REPORT_ITEM_MAX_SIZE bytes in length.
*
* Parameters:
*
* @param[in] byte The byte position of the control within the HID Report
* @param[in] bit The bit position of the control within the \a byte
* @param[in] page The USB HID Usage Page code for the Item (see 5.5)
* @param[in] header The LSB of the Item containing the bSize, bType and bTag fields (see 6.2.2.2)
* @param[in] data An array containing data bytes or NULL for an Item with no data
*
* @return A status value
* @retval \c HID_STATUS_GOOD Item successfully updated
* @retval \c HID_STATUS_BAD_HEADER The Item header specified a data size greater than 2 or
* a Tag or Type inconsistent with a Usage Item
* @retval \c HID_STATUS_BAD_LOCATION The \a bit or \a byte arguments specify a location outside
* of the HID Report
* @retval \c HID_STATUS_BAD_PAGE The \a byte argument specifies a location for controls from
* a Usage Page other than the one given by the \a page parameter
* @retval \c HID_STATUS_IN_USE The Report descriptor is in use
*/
unsigned hidSetReportItem( const unsigned byte, const unsigned bit, const unsigned char page, const unsigned char header, const unsigned char data[]);
#endif // _HID_REPORT_DESCRIPTOR_

View File

@@ -14,6 +14,8 @@ setuptools.setup(
packages=setuptools.find_packages(),
install_requires=[
'flake8~=3.8',
'pytest~=6.0',
'pytest-xdist~=1.34',
],
dependency_links=[
],

View File

@@ -18,6 +18,8 @@
# same modules should appear in the setup.py list as given below.
flake8==3.8.3
pytest==6.0.0
pytest-xdist==1.34.0
# Development dependencies
#

1
tests/.gitignore vendored
View File

@@ -1 +1,2 @@
*/runners/*
test_results.csv

View File

@@ -0,0 +1,104 @@
cmake_minimum_required(VERSION 3.13)
set(XMOS_TOOLS_PATH $ENV{XMOS_TOOL_PATH}/bin)
#**********************
# Setup XMOS toolchain
#**********************
if(NOT DEFINED ENV{XUA_PATH})
message(FATAL_ERROR "XUA_PATH environment variable not defined")
# some more commands
endif()
include("$ENV{XUA_PATH}/cmake_utils/xmos_toolchain.cmake")
#**********************
# Project
#**********************
# 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()
## Define project
project(xua_unit_tests VERSION 0.1.0)
## Enable languages for project
enable_language(CXX XC C ASM)
message(STATUS "CAME HERE")
add_custom_target("runners" ALL)
add_custom_command(
TARGET runners
COMMAND python generate_unity_runners.py
COMMENT "generate unity runners"
)
message(STATUS "CAME HERE 1")
file( GLOB APP_SOURCES src/test*.xc )
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/bin)
foreach( testsourcefile ${APP_SOURCES} )
get_filename_component(ITEM_NAME ${testsourcefile} NAME_WE)
message(STATUS "item_name " ${ITEM_NAME})
add_executable(${ITEM_NAME})
set(APP_COMPILER_FLAGS
"-O2"
"-g"
"-Wall"
"-report"
"-fxscope"
"-target=XCORE-AI-EXPLORER"
"${CMAKE_CURRENT_SOURCE_DIR}/config.xscope"
"-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")
set_target_properties(${ITEM_NAME} PROPERTIES OUTPUT_NAME ${ITEM_NAME}.xe)
target_compile_options(${ITEM_NAME} PRIVATE ${APP_COMPILER_FLAGS})
target_include_directories(${ITEM_NAME}
PRIVATE ${APP_INCLUDES}
PRIVATE ${XUA_INCLUDES_ALL}
)
target_sources(${ITEM_NAME}
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()

View File

@@ -0,0 +1,32 @@
# xua_unit_tests test application
This example builds the xua_unit_tests application for XCORE AI
## Prerequisites for building
[XMOS Toolchain 15.0.3](https://www.xmos.com/software/tools/) or newer.
Install [CMake](https://cmake.org/download/) version 3.13 or newer.
## Building for xCORE
Set environment variable for lib_xua path:
> export XUA_PATH=<path to lib_xua>
cd to lib_xua/tests/xua_unit_tests
Run cmake and build
> cmake .
> make
## Run on hardware
Ensure your XCORE AI EXPLORER board is powered up and connected to the XTAG debugger.
Make sure the input.wav file is copied into the build directory
> pytest -n 1
You should see the tests collected by pytest pass

View File

@@ -0,0 +1,23 @@
<?xml version="1.0" encoding="UTF-8"?>
<!-- ======================================================= -->
<!-- The 'ioMode' attribute on the xSCOPEconfig -->
<!-- element can take the following values: -->
<!-- "none", "basic", "timed" -->
<!-- -->
<!-- The 'type' attribute on Probe -->
<!-- elements can take the following values: -->
<!-- "STARTSTOP", "CONTINUOUS", "DISCRETE", "STATEMACHINE" -->
<!-- -->
<!-- The 'datatype' attribute on Probe -->
<!-- elements can take the following values: -->
<!-- "NONE", "UINT", "INT", "FLOAT" -->
<!-- ======================================================= -->
<xSCOPEconfig ioMode="none" enabled="false">
<!-- For example: -->
<!-- <Probe name="Probe Name" type="CONTINUOUS" datatype="UINT" units="Value" enabled="true"/> -->
<!-- From the target code, call: xscope_int(PROBE_NAME, value); -->
</xSCOPEconfig>

View File

@@ -0,0 +1,115 @@
# Copyright 2021 XMOS LIMITED.
# This Software is subject to the terms of the XMOS Public Licence: Version 1.
from __future__ import print_function
from builtins import str
import os.path
import pytest
import subprocess
target = os.environ.get('TARGET', 'all_possible')
print("target = ", target)
def pytest_collect_file(parent, path):
if(path.ext == ".xe"):
if(target == 'all_possible'):
return UnityTestSource.from_parent(parent, fspath=path)
if(target == 'XCOREAI' and ('xcoreai' in path.basename)):
return UnityTestSource.from_parent(parent, fspath=path)
if(target == 'XCORE200' and ('xcore200' in path.basename)):
return UnityTestSource.from_parent(parent, fspath=path)
class UnityTestSource(pytest.File):
def collect(self):
# Find the binary built from the runner for this test file
#
# Assume the following directory layout:
# unit_tests/ <- Test root directory
# |-- bin/ <- Compiled binaries of the test runners
# |-- conftest.py <- This file
# |-- runners/ <- Auto-generated buildable source of test binaries
# |-- src/ <- Unity test functions
# `-- wscript <- Build system file used to generate/build runners
xe_name = ((os.path.basename(self.name)).split("."))[0] + ".xe"
test_bin_path = os.path.join('bin', xe_name)
yield UnityTestExecutable.from_parent(self, name=self.name)
class UnityTestExecutable(pytest.Item):
def __init__(self, name, parent):
super(UnityTestExecutable, self).__init__(name, parent)
self._nodeid = self.name # Override the naming to suit C better
def runtest(self):
# Run the binary in the simulator
simulator_fail = False
test_output = None
try:
if('xcore200' in self.name):
print("run axe for executable ", self.name)
test_output = subprocess.check_output(['axe', self.name], text=True)
else:
print("run xrun for executable ", self.name)
test_output = subprocess.check_output(['xrun', '--io', '--id', '0', self.name], text=True, stderr=subprocess.STDOUT)
except subprocess.CalledProcessError as e:
# Unity exits non-zero if an assertion fails
simulator_fail = True
test_output = e.output
# Parse the Unity output
unity_pass = False
test_output = test_output.split('\n')
for line in test_output:
if 'test' in line:
test_report = line.split(':')
# Unity output is as follows:
# <test_source>:<line_number>:<test_case>:PASS
# <test_source>:<line_number>:<test_case>:FAIL:<failure_reason>
test_source = test_report[0]
line_number = test_report[1]
test_case = test_report[2]
result = test_report[3]
failure_reason = None
print(('\n {}()'.format(test_case)), end=' ')
if result == 'PASS':
unity_pass = True
continue
if result == 'FAIL':
failure_reason = test_report[4]
print('') # Insert line break after test_case print
raise UnityTestException(self, {'test_source': test_source,
'line_number': line_number,
'test_case': test_case,
'failure_reason':
failure_reason})
if simulator_fail:
raise Exception(self, "Simulation failed.")
if not unity_pass:
raise Exception(self, "Unity test output not found.")
print('') # Insert line break after final test_case which passed
def repr_failure(self, excinfo):
if isinstance(excinfo.value, UnityTestException):
return '\n'.join([str(self.parent).strip('<>'),
'{}:{}:{}()'.format(
excinfo.value[1]['test_source'],
excinfo.value[1]['line_number'],
excinfo.value[1]['test_case']),
'Failure reason:',
excinfo.value[1]['failure_reason']])
else:
return str(excinfo.value)
def reportinfo(self):
# It's not possible to give sensible line number info for an executable
# so we return it as 0.
#
# The source line number will instead be recovered from the Unity print
# statements.
return self.fspath, 0, self.name
class UnityTestException(Exception):
pass

View File

@@ -0,0 +1,120 @@
# Copyright 2021 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()

View File

@@ -0,0 +1,102 @@
// Copyright 2021 XMOS LIMITED.
// This Software is subject to the terms of the XMOS Public Licence: Version 1.
#ifndef __hid_report_descriptor_h__
#define __hid_report_descriptor_h__
#include "xua_hid_report_descriptor.h"
#define MAX_VALID_BIT ( 7 )
#define MAX_VALID_BYTE ( 1 )
#define MIN_VALID_BIT ( 0 )
#define MIN_VALID_BYTE ( 0 )
/*
* Define non-configurable items in the HID Report descriptor.
*/
static const USB_HID_Short_Item_t hidCollectionApplication = { .header = 0xA1, .data = { 0x01, 0x00 }, .location = 0x00 };
static const USB_HID_Short_Item_t hidCollectionEnd = { .header = 0xC0, .data = { 0x00, 0x00 }, .location = 0x00 };
static const USB_HID_Short_Item_t hidCollectionLogical = { .header = 0xA1, .data = { 0x02, 0x00 }, .location = 0x00 };
static const USB_HID_Short_Item_t hidInputConstArray = { .header = 0x81, .data = { 0x01, 0x00 }, .location = 0x00 };
static const USB_HID_Short_Item_t hidInputDataVar = { .header = 0x81, .data = { 0x02, 0x00 }, .location = 0x00 };
static const USB_HID_Short_Item_t hidLogicalMaximum0 = { .header = 0x25, .data = { 0x00, 0x00 }, .location = 0x00 };
static const USB_HID_Short_Item_t hidLogicalMaximum1 = { .header = 0x25, .data = { 0x01, 0x00 }, .location = 0x00 };
static const USB_HID_Short_Item_t hidLogicalMinimum0 = { .header = 0x15, .data = { 0x00, 0x00 }, .location = 0x00 };
static const USB_HID_Short_Item_t hidReportCount1 = { .header = 0x95, .data = { 0x01, 0x00 }, .location = 0x00 };
static const USB_HID_Short_Item_t hidReportCount6 = { .header = 0x95, .data = { 0x06, 0x00 }, .location = 0x00 };
static const USB_HID_Short_Item_t hidReportCount7 = { .header = 0x95, .data = { 0x07, 0x00 }, .location = 0x00 };
static const USB_HID_Short_Item_t hidReportSize1 = { .header = 0x75, .data = { 0x01, 0x00 }, .location = 0x00 };
static const USB_HID_Short_Item_t hidUsageConsumerControl = { .header = 0x09, .data = { 0x01, 0x00 }, .location = 0x00 };
static const USB_HID_Short_Item_t hidUsagePageConsumer = { .header = 0x05, .data = { 0x0C, 0x00 }, .location = 0x00 };
/*
* Define configurable items in the HID Report descriptor.
*/
static USB_HID_Short_Item_t hidUsageByte0Bit0 = { .header = 0x09, .data = { 0xE2, 0x00 }, .location = 0x00 }; // Mute
static USB_HID_Short_Item_t hidUsageByte1Bit7 = { .header = 0x09, .data = { 0xEA, 0x00 }, .location = 0x71 }; // Vol-
static USB_HID_Short_Item_t hidUsageByte1Bit0 = { .header = 0x09, .data = { 0xE9, 0x00 }, .location = 0x01 }; // Vol+
/*
* List the configurable items in the HID Report descriptor.
*/
static USB_HID_Short_Item_t* const hidConfigurableItems[] = {
&hidUsageByte0Bit0,
&hidUsageByte1Bit0,
&hidUsageByte1Bit7
};
/*
* List Usage pages in the HID Report descriptor, one per byte.
*/
static const USB_HID_Short_Item_t* const hidUsagePages[] = {
&hidUsagePageConsumer,
&hidUsagePageConsumer
};
/*
* List all items in the HID Report descriptor.
*/
static const USB_HID_Short_Item_t* const hidReportDescriptorItems[] = {
&hidUsagePageConsumer,
&hidUsageConsumerControl,
&hidCollectionApplication,
&hidReportSize1,
&hidLogicalMinimum0,
&hidCollectionLogical, // Byte 0
&hidLogicalMaximum1,
&hidReportCount1,
&hidUsageByte0Bit0,
&hidInputDataVar,
&hidLogicalMaximum0,
&hidReportCount7,
&hidInputConstArray,
&hidCollectionEnd,
&hidCollectionLogical, // Byte 1
&hidLogicalMaximum1,
&hidReportCount1,
&hidUsageByte1Bit0,
&hidInputDataVar,
&hidLogicalMaximum0,
&hidReportCount6,
&hidInputConstArray,
&hidLogicalMaximum1,
&hidUsageByte1Bit7,
&hidInputDataVar,
&hidCollectionEnd,
&hidCollectionEnd
};
/*
* Define the length of the HID Report.
* This value must match the number of Report bytes defined by hidReportDescriptorItems.
*/
#define HID_REPORT_LENGTH ( 2 )
#endif // __hid_report_descriptor_h__

View File

@@ -0,0 +1,477 @@
// Copyright 2021 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 "xua_hid_report_descriptor.h"
#include "hid_report_descriptor.h"
#define HID_REPORT_ITEM_TYPE_GLOBAL ( 0x01 )
#define HID_REPORT_ITEM_TYPE_LOCAL ( 0x02 )
#define HID_REPORT_ITEM_TYPE_MAIN ( 0x00 )
#define HID_REPORT_ITEM_TYPE_RESERVED ( 0x03 )
#define CONSUMER_CONTROL_PAGE ( 0x0C )
#define LOUDNESS_CONTROL ( 0xE7 )
static unsigned construct_usage_header( unsigned size )
{
unsigned header = 0x00;
header |= ( HID_REPORT_ITEM_USAGE_TAG << HID_REPORT_ITEM_HDR_TAG_SHIFT ) & HID_REPORT_ITEM_HDR_TAG_MASK;
header |= ( HID_REPORT_ITEM_USAGE_TYPE << HID_REPORT_ITEM_HDR_TYPE_SHIFT ) & HID_REPORT_ITEM_HDR_TYPE_MASK;
header |= ( size << HID_REPORT_ITEM_HDR_SIZE_SHIFT ) & HID_REPORT_ITEM_HDR_SIZE_MASK;
return header;
}
void setUp( void )
{
hidResetReportDescriptor();
}
// Basic report descriptor tests
void test_unprepared_hidGetReportDescriptor( void )
{
unsigned char* reportDescPtr = hidGetReportDescriptor();
TEST_ASSERT_NULL( reportDescPtr );
unsigned reportLength = hidGetReportLength();
TEST_ASSERT_EQUAL_UINT( 0, reportLength );
}
void test_prepared_hidGetReportDescriptor( void )
{
hidPrepareReportDescriptor();
unsigned char* reportDescPtr = hidGetReportDescriptor();
TEST_ASSERT_NOT_NULL( reportDescPtr );
unsigned reportLength = hidGetReportLength();
TEST_ASSERT_EQUAL_UINT( HID_REPORT_LENGTH, reportLength );
}
void test_reset_unprepared_hidGetReportDescriptor( void )
{
hidPrepareReportDescriptor();
hidResetReportDescriptor();
unsigned char* reportDescPtr = hidGetReportDescriptor();
TEST_ASSERT_NULL( reportDescPtr );
}
void test_reset_prepared_hidGetReportDescriptor( void )
{
hidPrepareReportDescriptor();
hidResetReportDescriptor();
hidPrepareReportDescriptor();
unsigned char* reportDescPtr = hidGetReportDescriptor();
TEST_ASSERT_NOT_NULL( reportDescPtr );
}
// Basic item tests
void test_max_loc_hidGetReportItem( void )
{
const unsigned bit = MAX_VALID_BIT;
const unsigned byte = MAX_VALID_BYTE;
unsigned char data[ HID_REPORT_ITEM_MAX_SIZE ];
unsigned char header;
unsigned char page;
unsigned retVal = hidGetReportItem( byte, bit, &page, &header, data );
TEST_ASSERT_EQUAL_UINT( HID_STATUS_GOOD, retVal );
TEST_ASSERT_EQUAL_UINT( CONSUMER_CONTROL_PAGE, page );
TEST_ASSERT_EQUAL_UINT( 0x09, header );
TEST_ASSERT_EQUAL_UINT( 0xEA, data[ 0 ]);
TEST_ASSERT_EQUAL_UINT( 0x00, data[ 1 ]);
}
void test_min_loc_hidGetReportItem( void )
{
const unsigned bit = MIN_VALID_BIT;
const unsigned byte = MIN_VALID_BYTE;
unsigned char data[ HID_REPORT_ITEM_MAX_SIZE ];
unsigned char header;
unsigned char page;
unsigned retVal = hidGetReportItem( byte, bit, &page, &header, data );
TEST_ASSERT_EQUAL_UINT( HID_STATUS_GOOD, retVal );
TEST_ASSERT_EQUAL_UINT( CONSUMER_CONTROL_PAGE, page );
TEST_ASSERT_EQUAL_UINT( 0x09, header );
TEST_ASSERT_EQUAL_UINT( 0xE2, data[ 0 ]);
TEST_ASSERT_EQUAL_UINT( 0x00, data[ 1 ]);
}
void test_overflow_bit_hidGetReportItem( void )
{
const unsigned bit = MAX_VALID_BIT + 1;
const unsigned byte = MAX_VALID_BYTE;
unsigned char data[ HID_REPORT_ITEM_MAX_SIZE ] = { 0xBA, 0xD1 };
unsigned char header = 0xAA;
unsigned char page = 0x44;
unsigned retVal = hidGetReportItem( byte, bit, &page, &header, data );
TEST_ASSERT_EQUAL_UINT( HID_STATUS_BAD_LOCATION, retVal );
TEST_ASSERT_EQUAL_UINT( 0x44, page );
TEST_ASSERT_EQUAL_UINT( 0xAA, header );
TEST_ASSERT_EQUAL_UINT( 0xBA, data[ 0 ]);
TEST_ASSERT_EQUAL_UINT( 0xD1, data[ 1 ]);
}
void test_overflow_byte_hidGetReportItem( void )
{
const unsigned bit = MAX_VALID_BIT;
const unsigned byte = MAX_VALID_BYTE + 1;
unsigned char data[ HID_REPORT_ITEM_MAX_SIZE ] = { 0xBA, 0xD1 };
unsigned char header = 0xAA;
unsigned char page = 0x44;
unsigned retVal = hidGetReportItem( byte, bit, &page, &header, data );
TEST_ASSERT_EQUAL_UINT( HID_STATUS_BAD_LOCATION, retVal );
TEST_ASSERT_EQUAL_UINT( 0x44, page );
TEST_ASSERT_EQUAL_UINT( 0xAA, header );
TEST_ASSERT_EQUAL_UINT( 0xBA, data[ 0 ]);
TEST_ASSERT_EQUAL_UINT( 0xD1, data[ 1 ]);
}
void test_underflow_bit_hidGetReportItem( void )
{
const int bit = MIN_VALID_BIT - 1;
const unsigned byte = MIN_VALID_BYTE;
unsigned char data[ HID_REPORT_ITEM_MAX_SIZE ] = { 0xBA, 0xD1 };
unsigned char header = 0xAA;
unsigned char page = 0x44;
unsigned retVal = hidGetReportItem( byte, ( unsigned ) bit, &page, &header, data );
TEST_ASSERT_EQUAL_UINT( HID_STATUS_BAD_LOCATION, retVal );
TEST_ASSERT_EQUAL_UINT( 0x44, page );
TEST_ASSERT_EQUAL_UINT( 0xAA, header );
TEST_ASSERT_EQUAL_UINT( 0xBA, data[ 0 ]);
TEST_ASSERT_EQUAL_UINT( 0xD1, data[ 1 ]);
}
void test_underflow_byte_hidGetReportItem( void )
{
const unsigned bit = MIN_VALID_BIT;
const int byte = MIN_VALID_BYTE - 1;
unsigned char data[ HID_REPORT_ITEM_MAX_SIZE ] = { 0xBA, 0xD1 };
unsigned char header = 0xAA;
unsigned char page = 0x44;
unsigned retVal = hidGetReportItem(( unsigned ) byte, bit, &page, &header, data );
TEST_ASSERT_EQUAL_UINT( HID_STATUS_BAD_LOCATION, retVal );
TEST_ASSERT_EQUAL_UINT( 0x44, page );
TEST_ASSERT_EQUAL_UINT( 0xAA, header );
TEST_ASSERT_EQUAL_UINT( 0xBA, data[ 0 ]);
TEST_ASSERT_EQUAL_UINT( 0xD1, data[ 1 ]);
}
// Configurable and non-configurable item tests
void test_configurable_item_hidSetReportItem( void )
{
const unsigned bit = MIN_VALID_BIT;
const unsigned byte = MIN_VALID_BYTE;
const unsigned char data[ 1 ] = { LOUDNESS_CONTROL };
const unsigned char header = construct_usage_header( sizeof data / sizeof( unsigned char ));
const unsigned char page = CONSUMER_CONTROL_PAGE;
unsigned retVal = hidSetReportItem( byte, bit, page, header, data );
TEST_ASSERT_EQUAL_UINT( HID_STATUS_GOOD, retVal );
}
void test_nonconfigurable_item_hidSetReportItem( void )
{
const unsigned bit = MAX_VALID_BIT; // This bit and byte combination should not appear in the
const unsigned byte = MIN_VALID_BYTE; // hidConfigurableItems list in hid_report_descriptors.c.
const unsigned char data[ 1 ] = { LOUDNESS_CONTROL };
const unsigned char header = construct_usage_header( sizeof data / sizeof( unsigned char ));
const unsigned char page = CONSUMER_CONTROL_PAGE;
unsigned retVal = hidSetReportItem( byte, bit, page, header, data );
TEST_ASSERT_EQUAL_UINT( HID_STATUS_BAD_LOCATION, retVal );
}
// Bit range tests
void test_max_bit_hidSetReportItem( void )
{
const unsigned bit = MAX_VALID_BIT; // Only byte 1 has bit 7 not reserved, See the
const unsigned byte = MAX_VALID_BYTE; // hidConfigurableItems list in hid_report_descriptors.c.
const unsigned char header = construct_usage_header( 0 );
const unsigned char page = CONSUMER_CONTROL_PAGE;
unsigned retVal = hidSetReportItem( byte, bit, page, header, NULL );
TEST_ASSERT_EQUAL_UINT( HID_STATUS_GOOD, retVal );
}
void test_min_bit_hidSetReportItem( void )
{
const unsigned bit = MIN_VALID_BIT;
const unsigned byte = MIN_VALID_BYTE;
const unsigned char header = construct_usage_header( 0 );
const unsigned char page = CONSUMER_CONTROL_PAGE;
unsigned retVal = hidSetReportItem( byte, bit, page, header, NULL );
TEST_ASSERT_EQUAL_UINT( HID_STATUS_GOOD, retVal );
}
void test_overflow_bit_hidSetReportItem( void )
{
const unsigned bit = MAX_VALID_BIT + 1;
const unsigned byte = MIN_VALID_BYTE;
const unsigned char header = construct_usage_header( 0 );
const unsigned char page = CONSUMER_CONTROL_PAGE;
unsigned retVal = hidSetReportItem( byte, bit, page, header, NULL );
TEST_ASSERT_EQUAL_UINT( HID_STATUS_BAD_LOCATION, retVal );
}
void test_underflow_bit_hidSetReportItem( void )
{
const int bit = MIN_VALID_BIT - 1;
const unsigned byte = MIN_VALID_BYTE;
const unsigned char header = construct_usage_header( 0 );
const unsigned char page = CONSUMER_CONTROL_PAGE;
unsigned retVal = hidSetReportItem( byte, ( unsigned ) bit, page, header, NULL );
TEST_ASSERT_EQUAL_UINT( HID_STATUS_BAD_LOCATION, retVal );
}
// Byte range tests
void test_max_byte_hidSetReportItem( void )
{
const unsigned bit = MIN_VALID_BIT;
const unsigned byte = MAX_VALID_BYTE;
const unsigned char header = construct_usage_header( 0 );
const unsigned char page = CONSUMER_CONTROL_PAGE;
unsigned retVal = hidSetReportItem( byte, bit, page, header, NULL );
TEST_ASSERT_EQUAL_UINT( HID_STATUS_GOOD, retVal );
}
void test_min_byte_hidSetReportItem( void )
{
const unsigned bit = MIN_VALID_BIT;
const unsigned byte = MIN_VALID_BYTE;
const unsigned char header = construct_usage_header( 0 );
const unsigned char page = CONSUMER_CONTROL_PAGE;
unsigned retVal = hidSetReportItem( byte, bit, page, header, NULL );
TEST_ASSERT_EQUAL_UINT( HID_STATUS_GOOD, retVal );
}
void test_overflow_byte_hidSetReportItem( void )
{
const unsigned bit = MIN_VALID_BIT;
const unsigned byte = MAX_VALID_BYTE + 1;
const unsigned char header = construct_usage_header( 0 );
const unsigned char page = CONSUMER_CONTROL_PAGE;
unsigned retVal = hidSetReportItem( byte, bit, page, header, NULL );
TEST_ASSERT_EQUAL_UINT( HID_STATUS_BAD_LOCATION, retVal );
}
void test_underflow_byte_hidSetReportItem( void )
{
const unsigned bit = MIN_VALID_BIT;
const int byte = MIN_VALID_BYTE - 1;
const unsigned char header = construct_usage_header( 0 );
const unsigned char page = CONSUMER_CONTROL_PAGE;
unsigned retVal = hidSetReportItem( ( unsigned ) byte, bit, page, header, NULL );
TEST_ASSERT_EQUAL_UINT( HID_STATUS_BAD_LOCATION, retVal );
}
// Size range tests
void test_max_size_hidSetReportItem( void )
{
const unsigned bit = MIN_VALID_BIT;
const unsigned byte = MIN_VALID_BYTE;
const unsigned char data[ HID_REPORT_ITEM_MAX_SIZE ] = { 0x00 };
const unsigned char header = construct_usage_header( HID_REPORT_ITEM_MAX_SIZE );
const unsigned char page = CONSUMER_CONTROL_PAGE;
unsigned retVal = hidSetReportItem( byte, bit, page, header, data );
TEST_ASSERT_EQUAL_UINT( HID_STATUS_GOOD, retVal );
}
void test_min_size_hidSetReportItem( void )
{
const unsigned bit = MIN_VALID_BIT;
const unsigned byte = MIN_VALID_BYTE;
const unsigned char header = construct_usage_header( 0x00 );
const unsigned char page = CONSUMER_CONTROL_PAGE;
unsigned retVal = hidSetReportItem( byte, bit, page, header, NULL );
TEST_ASSERT_EQUAL_UINT( HID_STATUS_GOOD, retVal );
}
void test_unsupported_size_hidSetReportItem( void )
{
const unsigned bit = MIN_VALID_BIT;
const unsigned byte = MIN_VALID_BYTE;
const unsigned char header = construct_usage_header( 0x03 );
const unsigned char page = CONSUMER_CONTROL_PAGE;
unsigned retVal = hidSetReportItem( byte, bit, page, header, NULL );
TEST_ASSERT_EQUAL_UINT( HID_STATUS_BAD_HEADER, retVal );
}
// Header tag and type tests
void test_bad_tag_hidSetReportItem( void )
{
const unsigned bit = MIN_VALID_BIT;
const unsigned byte = MIN_VALID_BYTE;
const unsigned char good_header = construct_usage_header( 0x00 );
const unsigned char page = CONSUMER_CONTROL_PAGE;
for( unsigned tag = 0x01; tag <= 0x0F; ++tag ) {
unsigned char bad_header = good_header | (( 0x0F << HID_REPORT_ITEM_HDR_TAG_SHIFT ) & HID_REPORT_ITEM_HDR_TAG_MASK );
unsigned retVal = hidSetReportItem( byte, bit, page, bad_header, NULL );
TEST_ASSERT_EQUAL_UINT( HID_STATUS_BAD_HEADER, retVal );
}
}
void test_global_type_hidSetReportItem( void )
{
const unsigned bit = MIN_VALID_BIT;
const unsigned byte = MIN_VALID_BYTE;
const unsigned char header = ( construct_usage_header( 0x00 ) & ~HID_REPORT_ITEM_HDR_TYPE_MASK ) |
(( HID_REPORT_ITEM_TYPE_GLOBAL << HID_REPORT_ITEM_HDR_TYPE_SHIFT ) & HID_REPORT_ITEM_HDR_TYPE_MASK );
const unsigned char page = CONSUMER_CONTROL_PAGE;
unsigned retVal = hidSetReportItem( byte, bit, page, header, NULL );
TEST_ASSERT_EQUAL_UINT( HID_STATUS_BAD_HEADER, retVal );
}
void test_local_type_hidSetReportItem( void )
{
const unsigned bit = MIN_VALID_BIT;
const unsigned byte = MIN_VALID_BYTE;
const unsigned char header = ( construct_usage_header( 0x00 ) & ~HID_REPORT_ITEM_HDR_TYPE_MASK ) |
(( HID_REPORT_ITEM_TYPE_LOCAL << HID_REPORT_ITEM_HDR_TYPE_SHIFT ) & HID_REPORT_ITEM_HDR_TYPE_MASK );
const unsigned char page = CONSUMER_CONTROL_PAGE;
unsigned retVal = hidSetReportItem( byte, bit, page, header, NULL );
TEST_ASSERT_EQUAL_UINT( HID_STATUS_GOOD, retVal );
}
void test_main_type_hidSetReportItem( void )
{
const unsigned bit = MIN_VALID_BIT;
const unsigned byte = MIN_VALID_BYTE;
const unsigned char header = ( construct_usage_header( 0x00 ) & ~HID_REPORT_ITEM_HDR_TYPE_MASK ) |
(( HID_REPORT_ITEM_TYPE_MAIN << HID_REPORT_ITEM_HDR_TYPE_SHIFT ) & HID_REPORT_ITEM_HDR_TYPE_MASK );
const unsigned char page = CONSUMER_CONTROL_PAGE;
unsigned retVal = hidSetReportItem( byte, bit, page, header, NULL );
TEST_ASSERT_EQUAL_UINT( HID_STATUS_BAD_HEADER, retVal );
}
void test_reserved_type_hidSetReportItem( void )
{
const unsigned bit = MIN_VALID_BIT;
const unsigned byte = MIN_VALID_BYTE;
const unsigned char header = ( construct_usage_header( 0x00 ) & ~HID_REPORT_ITEM_HDR_TYPE_MASK ) |
(( HID_REPORT_ITEM_TYPE_RESERVED << HID_REPORT_ITEM_HDR_TYPE_SHIFT ) & HID_REPORT_ITEM_HDR_TYPE_MASK );
const unsigned char page = CONSUMER_CONTROL_PAGE;
unsigned retVal = hidSetReportItem( byte, bit, page, header, NULL );
TEST_ASSERT_EQUAL_UINT( HID_STATUS_BAD_HEADER, retVal );
}
// Combined function tests
void test_initial_modification_without_subsequent_preparation( void )
{
const unsigned bit = MIN_VALID_BIT;
const unsigned byte = MIN_VALID_BYTE;
const unsigned char data[ 1 ] = { LOUDNESS_CONTROL };
const unsigned char header = construct_usage_header( sizeof data / sizeof( unsigned char ));
const unsigned char page = CONSUMER_CONTROL_PAGE;
unsigned retVal = hidSetReportItem( byte, bit, page, header, data );
TEST_ASSERT_EQUAL_UINT( HID_STATUS_GOOD, retVal );
unsigned char* reportDescPtr = hidGetReportDescriptor();
TEST_ASSERT_NULL( reportDescPtr );
}
void test_initial_modification_with_subsequent_preparation( void )
{
const unsigned bit = MIN_VALID_BIT;
const unsigned byte = MIN_VALID_BYTE;
const unsigned char data[ 1 ] = { LOUDNESS_CONTROL };
const unsigned char header = construct_usage_header( sizeof data / sizeof( unsigned char ));
const unsigned char page = CONSUMER_CONTROL_PAGE;
unsigned retVal = hidSetReportItem( byte, bit, page, header, data );
TEST_ASSERT_EQUAL_UINT( HID_STATUS_GOOD, retVal );
hidPrepareReportDescriptor();
unsigned char* reportDescPtr = hidGetReportDescriptor();
TEST_ASSERT_NOT_NULL( reportDescPtr );
}
void test_initial_modification_with_subsequent_verification( void )
{
const unsigned bit = MIN_VALID_BIT;
const unsigned byte = MIN_VALID_BYTE;
unsigned char get_data[ HID_REPORT_ITEM_MAX_SIZE ] = { 0xFF, 0xFF };
unsigned char get_header = 0xFF;
unsigned char get_page = 0xFF;
const unsigned char set_data[ 1 ] = { LOUDNESS_CONTROL };
const unsigned char set_header = construct_usage_header( sizeof set_data / sizeof( unsigned char ));
const unsigned char set_page = CONSUMER_CONTROL_PAGE;
unsigned setRetVal = hidSetReportItem( byte, bit, set_page, set_header, set_data );
TEST_ASSERT_EQUAL_UINT( HID_STATUS_GOOD, setRetVal );
unsigned getRetVal = hidGetReportItem( byte, bit, &get_page, &get_header, get_data );
TEST_ASSERT_EQUAL_UINT( HID_STATUS_GOOD, getRetVal );
TEST_ASSERT_EQUAL_UINT( get_page, set_page );
TEST_ASSERT_EQUAL_UINT( get_header, set_header );
TEST_ASSERT_EQUAL_UINT( get_data[ 0 ], set_data[ 0 ]);
TEST_ASSERT_EQUAL_UINT( get_data[ 1 ], set_data[ 1 ]);
}
void test_modification_without_subsequent_preparation( void )
{
hidPrepareReportDescriptor();
unsigned char* reportDescPtr = hidGetReportDescriptor();
TEST_ASSERT_NOT_NULL( reportDescPtr );
const unsigned bit = MIN_VALID_BIT;
const unsigned byte = MIN_VALID_BYTE;
const unsigned char data[ 1 ] = { LOUDNESS_CONTROL };
const unsigned char header = construct_usage_header( sizeof data / sizeof( unsigned char ));
const unsigned char page = CONSUMER_CONTROL_PAGE;
hidResetReportDescriptor();
unsigned retVal = hidSetReportItem( byte, bit, page, header, data );
TEST_ASSERT_EQUAL_UINT( HID_STATUS_GOOD, retVal );
reportDescPtr = hidGetReportDescriptor();
TEST_ASSERT_NULL( reportDescPtr );
}
void test_modification_with_subsequent_preparation( void )
{
hidPrepareReportDescriptor();
unsigned char* reportDescPtr = hidGetReportDescriptor();
TEST_ASSERT_NOT_NULL( reportDescPtr );
const unsigned bit = MIN_VALID_BIT;
const unsigned byte = MIN_VALID_BYTE;
const unsigned char data[ 1 ] = { LOUDNESS_CONTROL };
const unsigned char header = construct_usage_header( sizeof data / sizeof( unsigned char ));
const unsigned char page = CONSUMER_CONTROL_PAGE;
hidResetReportDescriptor();
unsigned retVal = hidSetReportItem( byte, bit, page, header, data );
TEST_ASSERT_EQUAL_UINT( HID_STATUS_GOOD, retVal );
hidPrepareReportDescriptor();
reportDescPtr = hidGetReportDescriptor();
TEST_ASSERT_NOT_NULL( reportDescPtr );
}

View File

@@ -0,0 +1,37 @@
// Copyright 2017-2021 XMOS LIMITED.
// This Software is subject to the terms of the XMOS Public Licence: Version 1.
#define NUM_USB_CHAN_OUT 2
#define NUM_USB_CHAN_IN 2
#define I2S_CHANS_DAC 2
#define I2S_CHANS_ADC 2
#define MCLK_441 (512 * 44100)
#define MCLK_48 (512 * 48000)
#define MIN_FREQ 48000
#define MAX_FREQ 48000
#define EXCLUDE_USB_AUDIO_MAIN
#define XUA_NUM_PDM_MICS 0
#define PDM_TILE 2
#define XUD_TILE 1
#define AUDIO_IO_TILE 1
#define MIXER 0
#define SPDIF_TX_INDEX 0
#define VENDOR_STR "XMOS"
#define VENDOR_ID 0x20B1
#define PRODUCT_STR_A2 "XMOS USB Audio Class"
#define PRODUCT_STR_A1 "XMOS USB Audio Class"
#define PID_AUDIO_1 1
#define PID_AUDIO_2 2
#define AUDIO_CLASS 2
#define AUDIO_CLASS_FALLBACK 0
#define BCD_DEVICE 0x1234
#define XUA_DFU_EN 0
/* TODO */
#define XUA_DFU XUA_DFU_EN
#define FB_USE_REF_CLOCK 1

View File

@@ -0,0 +1,28 @@
// Copyright 2021 XMOS LIMITED.
// This Software is subject to the terms of the XMOS Public Licence: Version 1.
#ifdef __XC__
#include <xs1.h>
#include <platform.h>
#include <xclib.h>
#endif // __XC__
in port p_mclk_in = XS1_PORT_1D;
/* Clock-block declarations */
clock clk_audio_bclk = on tile[0]: XS1_CLKBLK_1; /* Bit clock */
clock clk_audio_mclk = on tile[0]: XS1_CLKBLK_4; /* Master clock */
// Supply missing but unused function
void AudioHwConfig(unsigned samFreq, unsigned mClk, unsigned dsdMode, unsigned sampRes_DAC, unsigned sampRes_ADC)
{
; // nothing
}
// Supply missing but unused function
void AudioHwInit()
{
; // nothing
}

View File

@@ -0,0 +1,9 @@
// Copyright 2021 XMOS LIMITED.
// This Software is subject to the terms of the XMOS Public Licence: Version 1.
#ifndef XUA_UNIT_TESTS_H_
#define XUA_UNIT_TESTS_H_
#include "unity.h"
#include "xua_conf.h"
#endif /* XUA_UNIT_TESTS_H_ */

View File

@@ -0,0 +1,250 @@
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):
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.
"""
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)
return {get_test_name(path): get_file_type(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, test_language in configs.items():
print(f"test_name {test_name}, test_language {test_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 = test_language
target = trgt
runner = test_name
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)
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', 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',
'../../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',
'-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')