From a8ba18094f06d7635f8abb60dce345bd35ea023d Mon Sep 17 00:00:00 2001 From: mbanth Date: Tue, 18 May 2021 16:48:54 +0100 Subject: [PATCH 01/55] Initial implementation, compiles w/o error, not tested --- lib_xua/src/hid/hid_report_descriptor.c | 334 ++++++++++++++++++++ lib_xua/src/hid/xua_hid_report_descriptor.h | 83 +++++ 2 files changed, 417 insertions(+) create mode 100644 lib_xua/src/hid/hid_report_descriptor.c create mode 100644 lib_xua/src/hid/xua_hid_report_descriptor.h diff --git a/lib_xua/src/hid/hid_report_descriptor.c b/lib_xua/src/hid/hid_report_descriptor.c new file mode 100644 index 00000000..76983e89 --- /dev/null +++ b/lib_xua/src/hid/hid_report_descriptor.c @@ -0,0 +1,334 @@ +// Copyright 2021 XMOS LIMITED. +// This Software is subject to the terms of the XMOS Public Licence: Version 1. +#include +#include +#include +#include "xua_hid_report_descriptor.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_USAGE_TAG ( 0 ) +#define HID_REPORT_ITEM_USAGE_TYPE ( 2 ) + +#if 0 +/* Existing static report descriptor kept for reference */ +unsigned char hidReportDescriptor[] = +{ + 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, 0x07, /* Usage Page (Key Codes) */ + 0x19, 0x17, /* Usage Minimum (Keyboard t or T) */ + 0x29, 0x17, /* Usage Maximum (Keyboard t or T) */ + 0x81, 0x02, /* Input (Data, Var, Abs, No Wrap, Lin, Pref, No Nul) */ + 0x05, 0x0C, /* Usage Page (Consumer) */ + 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 + +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 hidReportCount4 = { .header = 0x95, .data = { 0x04, 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 }; +static const USB_HID_Short_Item_t hidUsagePageKeyboard = { .header = 0x05, .data = { 0x07, 0x00 }, .location = 0x00 }; +static const USB_HID_Short_Item_t hidUsagePageTelephony = { .header = 0x05, .data = { 0x0B, 0x00 }, .location = 0x00 }; + +static USB_HID_Short_Item_t hidUsageByte0Bit3 = { .header = 0x09, .data = { 0x73, 0x00 }, .location = 0x30 }; // F24 +static USB_HID_Short_Item_t hidUsageByte0Bit2 = { .header = 0x09, .data = { 0x72, 0x00 }, .location = 0x20 }; // F23 +static USB_HID_Short_Item_t hidUsageByte0Bit0 = { .header = 0x09, .data = { 0x17, 0x00 }, .location = 0x00 }; // 't' + +static USB_HID_Short_Item_t hidUsageByte1Bit7 = { .header = 0x09, .data = { 0xEA, 0x00 }, .location = 0x71 }; // Vol- +static USB_HID_Short_Item_t hidUsageByte1Bit6 = { .header = 0x09, .data = { 0xE9, 0x00 }, .location = 0x61 }; // Vol+ +static USB_HID_Short_Item_t hidUsageByte1Bit4 = { .header = 0x09, .data = { 0x00, 0x00 }, .location = 0x41 }; // Voice Command +static USB_HID_Short_Item_t hidUsageByte1Bit2 = { .header = 0x09, .data = { 0xE2, 0x00 }, .location = 0x21 }; // Mute +static USB_HID_Short_Item_t hidUsageByte1Bit1 = { .header = 0x09, .data = { 0x00, 0x00 }, .location = 0x11 }; // AC Search +static USB_HID_Short_Item_t hidUsageByte1Bit0 = { .header = 0x09, .data = { 0x00, 0x00 }, .location = 0x01 }; // AC Stop + +static USB_HID_Short_Item_t hidUsageByte2Bit1 = { .header = 0x09, .data = { 0x2F, 0x00 }, .location = 0x12 }; // Phone Mute +static USB_HID_Short_Item_t hidUsageByte2Bit0 = { .header = 0x09, .data = { 0x20, 0x00 }, .location = 0x02 }; // Hook Switch + +static USB_HID_Short_Item_t* const hidConfigurableItems[] = { + &hidUsageByte0Bit0, + &hidUsageByte0Bit2, + &hidUsageByte0Bit3, + &hidUsageByte1Bit0, + &hidUsageByte1Bit1, + &hidUsageByte1Bit2, + &hidUsageByte1Bit4, + &hidUsageByte1Bit6, + &hidUsageByte1Bit7, + &hidUsageByte2Bit0, + &hidUsageByte2Bit1 +}; + +static const USB_HID_Short_Item_t* const hidReportDescriptorItems[] = { + &hidUsagePageConsumer, + &hidUsageConsumerControl, + &hidCollectionApplication, + &hidReportSize1, + &hidLogicalMinimum0, + &hidCollectionLogical, // Byte 0 + &hidUsagePageKeyboard, + &hidLogicalMaximum1, + &hidReportCount1, + &hidUsageByte0Bit0, + &hidInputDataVar, + &hidLogicalMaximum0, + &hidInputConstArray, + &hidLogicalMaximum1, + &hidUsageByte0Bit2, + &hidInputDataVar, + &hidUsageByte0Bit3, + &hidInputDataVar, + &hidLogicalMaximum0, + &hidReportCount4, + &hidInputConstArray, + &hidCollectionEnd, + &hidCollectionLogical, // Byte 1 + &hidUsagePageConsumer, + &hidLogicalMaximum1, + &hidReportCount1, + &hidUsageByte1Bit0, + &hidInputDataVar, + &hidUsageByte1Bit1, + &hidInputDataVar, + &hidUsageByte1Bit2, + &hidInputDataVar, + &hidLogicalMaximum0, + &hidInputConstArray, + &hidLogicalMaximum1, + &hidUsageByte1Bit4, + &hidInputDataVar, + &hidLogicalMaximum0, + &hidInputConstArray, + &hidLogicalMaximum1, + &hidUsageByte1Bit6, + &hidInputDataVar, + &hidUsageByte1Bit7, + &hidInputDataVar, + &hidCollectionEnd, + &hidCollectionLogical, // Byte 2 + &hidUsagePageTelephony, + &hidUsageByte2Bit0, + &hidInputDataVar, + &hidUsageByte2Bit1, + &hidLogicalMaximum0, + &hidReportCount6, + &hidInputConstArray, + &hidCollectionEnd, + &hidCollectionEnd +}; + +#define HID_REPORT_ITEM_LOCATION_SIZE ( 1 ) +#define HID_REPORT_DESCRIPTOR_MAX_LENGTH ( sizeof hidReportDescriptorItems / sizeof ( USB_HID_Short_Item_t ) * \ + ( sizeof ( USB_HID_Short_Item_t ) - HID_REPORT_ITEM_LOCATION_SIZE )) + +static unsigned char hidReportDescriptor[ HID_REPORT_DESCRIPTOR_MAX_LENGTH ]; +static unsigned hidReportDescriptorInitialised = 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 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] outPtr A pointer to the next available space in the raw byte buffer + * + * @return The updated \a outPtr + */ +static unsigned char* hidTranslateItem( const USB_HID_Short_Item_t* inPtr, unsigned char* outPtr ); + +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; + assert( bSize <= HID_REPORT_ITEM_MAX_SIZE ); + 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( hidReportDescriptorInitialised ) { + retVal = hidReportDescriptor; + } + + return retVal; +} + +void hidInitReportDescriptor( void ) +{ + unsigned char* ptr = hidReportDescriptor; + for( unsigned idx = 0; idx < sizeof hidReportDescriptorItems / sizeof( USB_HID_Short_Item_t ); ++idx ) { + ptr = hidTranslateItem( hidReportDescriptorItems[ idx ], ptr ); + } + + hidReportDescriptorInitialised = 1; +} + +unsigned hidSetReportItem( const unsigned byte, const unsigned bit, const unsigned char header, const unsigned char data[] ) +{ + unsigned retVal = 2; + 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_TAG == bType )) { + retVal = 1; + } else { + for( unsigned itemIdx = 0; itemIdx < sizeof hidConfigurableItems / sizeof( USB_HID_Short_Item_t ); ++itemIdx ) { + USB_HID_Short_Item_t item = *hidConfigurableItems[ itemIdx ]; + unsigned bBit = hidGetItemBitLocation( item.location ); + unsigned bByte = hidGetItemByteLocation( item.location ); + + if(( bit == bBit ) && ( byte == bByte )) { + item.header = header; + + for( unsigned dataIdx = 0; dataIdx < bSize; ++dataIdx ) { + item.data[ dataIdx ] = data[ dataIdx ]; + } + + *hidConfigurableItems[ itemIdx ] = item; + hidReportDescriptorInitialised = 0; + retVal = 0; + } + } + } + + return retVal; +} + +static unsigned char* hidTranslateItem( const USB_HID_Short_Item_t* inPtr, unsigned char* outPtr ) +{ + *outPtr++ = inPtr->header; + + unsigned dataLength = hidGetItemSize( inPtr->header ); + for( unsigned idx = 0; idx < dataLength; ++idx ) { + *outPtr++ = inPtr->data[ idx ]; + } + + return outPtr; +} diff --git a/lib_xua/src/hid/xua_hid_report_descriptor.h b/lib_xua/src/hid/xua_hid_report_descriptor.h new file mode 100644 index 00000000..2195ddc3 --- /dev/null +++ b/lib_xua/src/hid/xua_hid_report_descriptor.h @@ -0,0 +1,83 @@ +// 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 and default content of the HID Report descriptor. + * Document section numbers refer to the HID Device Class Definition, version 1.11. + */ + +#ifndef _HID_REPORT_DESCRIPTOR_ +#define _HID_REPORT_DESCRIPTOR_ + +#define HID_REPORT_ITEM_MAX_SIZE ( 2 ) + +#define HID_STATUS_GOOD ( 0 ) +#define HID_STATUS_BAD_HEADER ( 1 ) +#define HID_STATUS_BAD_LOCATION ( 2 ) + +/** + * @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 initialised, + * i.e., no one has called \c hidInitReportDescriptor(). + * + * @return A pointer to a list of unsigned char containing the Report descriptor + */ +unsigned char* hidGetReportDescriptor( void ); + +/** + * @brief Modify 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[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 + */ +unsigned hidSetReportItem( const unsigned byte, const unsigned bit, const unsigned char header, const unsigned char data[] ); + +/** + * @brief Initialise the USB HID Report descriptor + * + * After initialisation, \c hidGetReportDescriptor() returns a list suitable + * for transmission over USB. + * + * Call this function after altering one or more Report Items using \c hidSetReportItem(). + */ +void hidInitReportDescriptor( void ); + +#endif // _HID_REPORT_DESCRIPTOR_ From 9b2efd07ad7b99f9a2f00846983d808ae79221c8 Mon Sep 17 00:00:00 2001 From: mbanth Date: Wed, 19 May 2021 16:07:40 +0100 Subject: [PATCH 02/55] Add unit test infrastructure --- Jenkinsfile | 53 +++- tests/xua_unit_tests/config.xscope | 23 ++ tests/xua_unit_tests/conftest.py | 127 ++++++++ tests/xua_unit_tests/src/test_hid/test_hid.xc | 7 + tests/xua_unit_tests/src/xua_unit_tests.h | 25 ++ tests/xua_unit_tests/wscript | 274 ++++++++++++++++++ 6 files changed, 508 insertions(+), 1 deletion(-) create mode 100644 tests/xua_unit_tests/config.xscope create mode 100644 tests/xua_unit_tests/conftest.py create mode 100644 tests/xua_unit_tests/src/test_hid/test_hid.xc create mode 100644 tests/xua_unit_tests/src/xua_unit_tests.h create mode 100644 tests/xua_unit_tests/wscript diff --git a/Jenkinsfile b/Jenkinsfile index ef501285..3ba5bc40 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -27,7 +27,7 @@ pipeline { xcoreLibraryChecks("${REPO}") } } - stage('Tests') { + stage('XS2 Tests') { failFast true parallel { stage('Legacy tests') { @@ -35,6 +35,57 @@ pipeline { runXmostest("${REPO}", 'legacy_tests') } } + stage('Unit tests') { + steps { + dir("${REPO}") { + dir('tests') { + dir('xua_unit_tests') { + viewEnv() { + withVenv { + runWaf('.', "configure clean build --target=xcore200") + runWaf('.', "configure clean build --target=xcoreai") + stash name: 'xua_unit_tests', includes: 'bin/*xcoreai.xe, ' + runPython("TARGET=XCORE200 pytest -n 1") + } + } + } + } + } + } + } + } + } + stage('xcore.ai Verification') { + agent { + label 'xcore.ai-explorer' + } + stages{ + stage('Get View') { + steps { + xcorePrepareSandbox("${VIEW}", "${REPO}") + } + } + stage('Unit tests') { + steps { + dir("${REPO}") { + dir('tests') { + dir('xua_unit_tests') { + viewEnv() { + withVenv { + unstash 'xua_unit_tests' + runPython("TARGET=XCOREAI pytest -n 1 --junitxml pytest_result.xml") + } + } + } + } + } + } + } + } // stages + post { + cleanup { + cleanWs() + } } } stage('xCORE builds') { diff --git a/tests/xua_unit_tests/config.xscope b/tests/xua_unit_tests/config.xscope new file mode 100644 index 00000000..bfdf1f86 --- /dev/null +++ b/tests/xua_unit_tests/config.xscope @@ -0,0 +1,23 @@ + + + + + + + + + + + + + + + + + + + + + + + diff --git a/tests/xua_unit_tests/conftest.py b/tests/xua_unit_tests/conftest.py new file mode 100644 index 00000000..351a61fb --- /dev/null +++ b/tests/xua_unit_tests/conftest.py @@ -0,0 +1,127 @@ +# Copyright 2021 XMOS LIMITED. +# This Software is subject to the terms of the XMOS Public Licence: Version 1. +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 + print("self.name = ",self.name) + #xe_name = ((os.path.basename(self.name)).split("."))[0] + ".xe" + #test_bin_path = os.path.join('bin', xe_name) + # + #test_root_dir_name = os.path.basename(os.path.dirname(__file__)) + #test_src_path = os.path.basename(str(self.fspath)) + #test_src_name = os.path.splitext(test_src_path)[0] + + #test_bin_name_si = os.path.join( + # test_src_name + '_single_issue.xe') + #test_bin_path_si = os.path.join('bin', + # test_bin_name_si) + #yield UnityTestExecutable.from_parent(self, name=test_bin_path_si) + + #test_bin_name_di = os.path.join( + # test_src_name + '_dual_issue.xe') + #test_bin_path_di = os.path.join('bin', + # test_bin_name_di) + 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: + # :::PASS + # :::FAIL: + 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)), + 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 diff --git a/tests/xua_unit_tests/src/test_hid/test_hid.xc b/tests/xua_unit_tests/src/test_hid/test_hid.xc new file mode 100644 index 00000000..d92a7efd --- /dev/null +++ b/tests/xua_unit_tests/src/test_hid/test_hid.xc @@ -0,0 +1,7 @@ +// Copyright 2021 XMOS LIMITED. +// This Software is subject to the terms of the XMOS Public Licence: Version 1. +#include "xua_unit_tests.h" + +void test_null(){ + TEST_ASSERT_MESSAGE(1, "Success!"); +} diff --git a/tests/xua_unit_tests/src/xua_unit_tests.h b/tests/xua_unit_tests/src/xua_unit_tests.h new file mode 100644 index 00000000..bb7275b3 --- /dev/null +++ b/tests/xua_unit_tests/src/xua_unit_tests.h @@ -0,0 +1,25 @@ +// Copyright 2018-2021 XMOS LIMITED. +// This Software is subject to the terms of the XMOS Public Licence: Version 1. +#ifndef VTB_UNIT_TESTS_H_ +#define VTB_UNIT_TESTS_H_ + +#include "unity.h" + +#ifdef __XC__ + +#include +#include +#include + +#include + +#include "audio_test_tools.h" +#include "voice_toolbox.h" +#include "voice_toolbox_fp.h" +#include "vtb_references.h" + +#define TEST_ASM 1 + +#endif // __XC__ + +#endif /* VTB_UNIT_TESTS_H_ */ diff --git a/tests/xua_unit_tests/wscript b/tests/xua_unit_tests/wscript new file mode 100644 index 00000000..961aa216 --- /dev/null +++ b/tests/xua_unit_tests/wscript @@ -0,0 +1,274 @@ +from __future__ import print_function +import glob +import os.path +import subprocess +import sys +from waflib import Options, Errors +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 set_common_build_config(waf_conf, project_root_path, unity_test_path, + unity_runner_build_flags): + """ + Set the common xwaf config variables. + """ + 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 add_single_issue_unity_runner_build_config(waf_conf, project_root_path, + unity_test_path, + unity_runner_build_flags, target): + """ + Add a single issue config to xwaf to build each Unity test runner into an + xCORE executable. + """ + waf_conf.setenv(get_test_name(unity_test_path) + '_single_issue' + '_' + target) + set_common_build_config(waf_conf, project_root_path, unity_test_path, + unity_runner_build_flags + '-mno-dual-issue') + + +def add_dual_issue_unity_runner_build_config(waf_conf, project_root_path, + unity_test_path, + unity_runner_build_flags, target): + """ + Add a dual issue config to xwaf to build each Unity test runner into an + xCORE executable. + """ + waf_conf.setenv(get_test_name(unity_test_path) + '_dual_issue' + '_' + target) + set_common_build_config(waf_conf, project_root_path, unity_test_path, + unity_runner_build_flags + '-mdual-issue') + + +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_single_issue_unity_runner_build_config(waf_conf, project_root_path, + unity_test_path, + runner_build_flags, target) + add_dual_issue_unity_runner_build_config(waf_conf, project_root_path, + unity_test_path, + runner_build_flags, target) + + + +def find_unity_test_paths(unity_test_dir, unity_test_prefix): + """ + Return a list of all file paths with the unity_test_prefix found in the + unity_test_dir. + """ + file_list = [] + for root, dirs, files in os.walk(unity_test_dir): + for f in files: + if f.startswith(unity_test_prefix): + file_list.append(os.path.join(root,f)) + return file_list + +def find_unity_tests(unity_test_dir, unity_test_prefix): + """ + Return a dictionary of all {test names, test language} pairs with the + unity_test_prefix found in the unity_test_dir. + """ + unity_test_paths = find_unity_test_paths(unity_test_dir, unity_test_prefix) + return {get_test_name(path): 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(): + # Single issue test configurations + for ctx in (BuildContext, CleanContext): + raw_context = ctx.__name__.replace('Context', '').lower() + + class si_tmp(ctx): + cmd = raw_context + '_' + test_name + '_single_issue' + '_' + trgt + variant = test_name + '_single_issue' + '_' + trgt + source = test_name + language = test_language + target = trgt + runner = test_name + + # Dual issue test configurations + for ctx in (BuildContext, CleanContext): + raw_context = ctx.__name__.replace('Context', '').lower() + + class di_tmp(ctx): + cmd = raw_context + '_' + test_name + '_dual_issue' + '_' + trgt + variant = test_name + '_dual_issue' + '_' + trgt + source = test_name + language = test_language + target = trgt + runner = test_name + + +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.load('xwaf.xcommon') + opt.add_option('--target', action='store', default='xcore200') + +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: + 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 + print('Adding test runners to build queue') + for name in UNITY_TESTS: + Options.commands.insert(0, 'build_' + name + '_single_issue' + '_' + trgt[0]) + Options.commands.insert(0, 'build_' + name + '_dual_issue' + '_' + trgt[0]) + print('Build queue {}'.format(Options.commands)) + else: + print('Building runner {}'.format(bld.runner)) + if(bld.target == 'xcoreai'): + bld.env.TARGET_ARCH = 'XCORE-AI-EXPLORER' + else: + bld.env.TARGET_ARCH = 'XCORE-200-EXPLORER' + + bld.env.XSCOPE = bld.path.find_resource('config.xscope') + # The issue mode for each build is set during the configure step, + # as the string bld.env.XCC_FLAGS. We append this to the list last to + # ensure it takes precedence over other flags set here. + bld.env.XCC_FLAGS = ['-O2', '-g', '-Wall', '-DUNITY_SUPPORT_64', + '-DUNITY_INCLUDE_DOUBLE', bld.env.XCC_FLAGS] + + depends_on = ['lib_xua', 'Unity'] + include = ['.'] + source = [ + os.path.join(UNITY_TEST_DIR, + '{}.{}'.format(bld.source, bld.language)), + os.path.join(UNITY_RUNNER_DIR, + '{}{}.{}'.format(bld.source, UNITY_RUNNER_SUFFIX, + 'c'))] + makefile_opts = {} + makefile_opts['SOURCE_DIRS'] = [os.path.join('src',bld.runner), 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'] + makefile_opts['XCC_FLAGS'] = ['-O2', '-g', '-Wall', '-DUNITY_SUPPORT_64', '-DUNITY_INCLUDE_DOUBLE'] + makefile_opts['APP_NAME'] = [bld.variant] + makefile_opts['USED_MODULES'] = depends_on + makefile_opts['XCOMMON_MAKEFILE'] = ['Makefile.common'] + bld.do_xcommon(makefile_opts) + +def dist(ctx): + ctx.load('xwaf.xcommon') + +def distcheck(ctx): + ctx.load('xwaf.xcommon') From bd805acf04477e4be709df97334550fa867d96f9 Mon Sep 17 00:00:00 2001 From: mbanth Date: Wed, 19 May 2021 17:06:58 +0100 Subject: [PATCH 03/55] Correct headers --- tests/xua_unit_tests/src/xua_conf.h | 37 +++++++++++++++++++++++ tests/xua_unit_tests/src/xua_unit_tests.h | 18 +++-------- 2 files changed, 42 insertions(+), 13 deletions(-) create mode 100644 tests/xua_unit_tests/src/xua_conf.h diff --git a/tests/xua_unit_tests/src/xua_conf.h b/tests/xua_unit_tests/src/xua_conf.h new file mode 100644 index 00000000..77b3656a --- /dev/null +++ b/tests/xua_unit_tests/src/xua_conf.h @@ -0,0 +1,37 @@ +// Copyright 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 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 diff --git a/tests/xua_unit_tests/src/xua_unit_tests.h b/tests/xua_unit_tests/src/xua_unit_tests.h index bb7275b3..11fd6faf 100644 --- a/tests/xua_unit_tests/src/xua_unit_tests.h +++ b/tests/xua_unit_tests/src/xua_unit_tests.h @@ -1,25 +1,17 @@ -// Copyright 2018-2021 XMOS LIMITED. +// Copyright 2021 XMOS LIMITED. // This Software is subject to the terms of the XMOS Public Licence: Version 1. -#ifndef VTB_UNIT_TESTS_H_ -#define VTB_UNIT_TESTS_H_ +#ifndef XUA_UNIT_TESTS_H_ +#define XUA_UNIT_TESTS_H_ #include "unity.h" #ifdef __XC__ #include -#include -#include - #include -#include "audio_test_tools.h" -#include "voice_toolbox.h" -#include "voice_toolbox_fp.h" -#include "vtb_references.h" - -#define TEST_ASM 1 +#include "xua_conf.h" #endif // __XC__ -#endif /* VTB_UNIT_TESTS_H_ */ +#endif /* XUA_UNIT_TESTS_H_ */ From ae5d36422693d6d978fd8c16d554df708e0136f9 Mon Sep 17 00:00:00 2001 From: mbanth Date: Wed, 19 May 2021 17:11:43 +0100 Subject: [PATCH 04/55] Add XUD to the dependency list --- tests/xua_unit_tests/wscript | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/xua_unit_tests/wscript b/tests/xua_unit_tests/wscript index 961aa216..e82b1d7f 100644 --- a/tests/xua_unit_tests/wscript +++ b/tests/xua_unit_tests/wscript @@ -243,7 +243,7 @@ def build(bld): bld.env.XCC_FLAGS = ['-O2', '-g', '-Wall', '-DUNITY_SUPPORT_64', '-DUNITY_INCLUDE_DOUBLE', bld.env.XCC_FLAGS] - depends_on = ['lib_xua', 'Unity'] + depends_on = ['lib_xua', 'lib_xud', 'Unity'] include = ['.'] source = [ os.path.join(UNITY_TEST_DIR, From cbf2320de6cb887c9c0270dc65c6c339f232766c Mon Sep 17 00:00:00 2001 From: mbanth Date: Wed, 19 May 2021 17:41:53 +0100 Subject: [PATCH 05/55] Change order of dependency list --- tests/xua_unit_tests/wscript | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/xua_unit_tests/wscript b/tests/xua_unit_tests/wscript index e82b1d7f..49cf4828 100644 --- a/tests/xua_unit_tests/wscript +++ b/tests/xua_unit_tests/wscript @@ -243,7 +243,7 @@ def build(bld): bld.env.XCC_FLAGS = ['-O2', '-g', '-Wall', '-DUNITY_SUPPORT_64', '-DUNITY_INCLUDE_DOUBLE', bld.env.XCC_FLAGS] - depends_on = ['lib_xua', 'lib_xud', 'Unity'] + depends_on = ['lib_xud', 'lib_xua', 'Unity'] include = ['.'] source = [ os.path.join(UNITY_TEST_DIR, From 496dd1643134b57f4440dcaadbaf43e7681383d5 Mon Sep 17 00:00:00 2001 From: mbanth Date: Wed, 19 May 2021 17:57:22 +0100 Subject: [PATCH 06/55] Remove dual issue configuration --- tests/xua_unit_tests/wscript | 28 ---------------------------- 1 file changed, 28 deletions(-) diff --git a/tests/xua_unit_tests/wscript b/tests/xua_unit_tests/wscript index 49cf4828..c73beea3 100644 --- a/tests/xua_unit_tests/wscript +++ b/tests/xua_unit_tests/wscript @@ -101,18 +101,6 @@ def add_single_issue_unity_runner_build_config(waf_conf, project_root_path, unity_runner_build_flags + '-mno-dual-issue') -def add_dual_issue_unity_runner_build_config(waf_conf, project_root_path, - unity_test_path, - unity_runner_build_flags, target): - """ - Add a dual issue config to xwaf to build each Unity test runner into an - xCORE executable. - """ - waf_conf.setenv(get_test_name(unity_test_path) + '_dual_issue' + '_' + target) - set_common_build_config(waf_conf, project_root_path, unity_test_path, - unity_runner_build_flags + '-mdual-issue') - - 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, @@ -121,9 +109,6 @@ def prepare_unity_test_for_build(waf_conf, project_root_path, unity_test_path, add_single_issue_unity_runner_build_config(waf_conf, project_root_path, unity_test_path, runner_build_flags, target) - add_dual_issue_unity_runner_build_config(waf_conf, project_root_path, - unity_test_path, - runner_build_flags, target) @@ -181,18 +166,6 @@ def create_waf_contexts(configs): target = trgt runner = test_name - # Dual issue test configurations - for ctx in (BuildContext, CleanContext): - raw_context = ctx.__name__.replace('Context', '').lower() - - class di_tmp(ctx): - cmd = raw_context + '_' + test_name + '_dual_issue' + '_' + trgt - variant = test_name + '_dual_issue' + '_' + trgt - source = test_name - language = test_language - target = trgt - runner = test_name - UNITY_TEST_DIR = 'src' UNITY_TEST_PREFIX = 'test_' @@ -227,7 +200,6 @@ def build(bld): print('Adding test runners to build queue') for name in UNITY_TESTS: Options.commands.insert(0, 'build_' + name + '_single_issue' + '_' + trgt[0]) - Options.commands.insert(0, 'build_' + name + '_dual_issue' + '_' + trgt[0]) print('Build queue {}'.format(Options.commands)) else: print('Building runner {}'.format(bld.runner)) From 0f47ef96be42597fbce6d743d0c314e7c3ab92c9 Mon Sep 17 00:00:00 2001 From: mbanth Date: Wed, 19 May 2021 18:02:05 +0100 Subject: [PATCH 07/55] Reverse dependency order (again) --- tests/xua_unit_tests/wscript | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/xua_unit_tests/wscript b/tests/xua_unit_tests/wscript index c73beea3..d67cce22 100644 --- a/tests/xua_unit_tests/wscript +++ b/tests/xua_unit_tests/wscript @@ -215,7 +215,7 @@ def build(bld): bld.env.XCC_FLAGS = ['-O2', '-g', '-Wall', '-DUNITY_SUPPORT_64', '-DUNITY_INCLUDE_DOUBLE', bld.env.XCC_FLAGS] - depends_on = ['lib_xud', 'lib_xua', 'Unity'] + depends_on = ['lib_xua', 'lib_xud', 'Unity'] include = ['.'] source = [ os.path.join(UNITY_TEST_DIR, From 4ffe3d94c705bafa28665a4aca333d3393a64427 Mon Sep 17 00:00:00 2001 From: mbanth Date: Wed, 19 May 2021 18:08:49 +0100 Subject: [PATCH 08/55] Reverse the dependencies (yet again) and target only xCore-200 --- tests/xua_unit_tests/wscript | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/tests/xua_unit_tests/wscript b/tests/xua_unit_tests/wscript index d67cce22..952519a9 100644 --- a/tests/xua_unit_tests/wscript +++ b/tests/xua_unit_tests/wscript @@ -6,7 +6,8 @@ import sys from waflib import Options, Errors from waflib.Build import BuildContext, CleanContext -TARGETS = ['xcore200', 'xcoreai'] +#TARGETS = ['xcore200', 'xcoreai'] +TARGETS = ['xcore200'] # Target xcore200 only for the time being def get_ruby(): """ @@ -215,7 +216,7 @@ def build(bld): bld.env.XCC_FLAGS = ['-O2', '-g', '-Wall', '-DUNITY_SUPPORT_64', '-DUNITY_INCLUDE_DOUBLE', bld.env.XCC_FLAGS] - depends_on = ['lib_xua', 'lib_xud', 'Unity'] + depends_on = ['lib_xud', 'lib_xua', 'Unity'] include = ['.'] source = [ os.path.join(UNITY_TEST_DIR, From 7836aacf47a38bd83645614a0ccc6c03578b86ab Mon Sep 17 00:00:00 2001 From: mbanth Date: Thu, 20 May 2021 15:14:55 +0100 Subject: [PATCH 09/55] Do not track Unity test runners --- tests/.gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/.gitignore b/tests/.gitignore index f0bcfb69..3bbde6ff 100644 --- a/tests/.gitignore +++ b/tests/.gitignore @@ -1 +1,2 @@ +*/runners/* test_results.csv From ede81bd5f7c9f8f9a683b8b4119915d603e229fb Mon Sep 17 00:00:00 2001 From: mbanth Date: Thu, 20 May 2021 15:29:25 +0100 Subject: [PATCH 10/55] Working infrastructure for xCore200 --- tests/xua_unit_tests/conftest.py | 24 +--- .../xua_unit_tests/generate_unity_runners.py | 120 ++++++++++++++++++ tests/xua_unit_tests/wscript | 109 ++++++++-------- 3 files changed, 178 insertions(+), 75 deletions(-) create mode 100644 tests/xua_unit_tests/generate_unity_runners.py diff --git a/tests/xua_unit_tests/conftest.py b/tests/xua_unit_tests/conftest.py index 351a61fb..e2e1a54a 100644 --- a/tests/xua_unit_tests/conftest.py +++ b/tests/xua_unit_tests/conftest.py @@ -1,11 +1,14 @@ # 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'): @@ -27,24 +30,9 @@ class UnityTestSource(pytest.File): # |-- runners/ <- Auto-generated buildable source of test binaries # |-- src/ <- Unity test functions # `-- wscript <- Build system file used to generate/build runners - print("self.name = ",self.name) - #xe_name = ((os.path.basename(self.name)).split("."))[0] + ".xe" - #test_bin_path = os.path.join('bin', xe_name) - # - #test_root_dir_name = os.path.basename(os.path.dirname(__file__)) - #test_src_path = os.path.basename(str(self.fspath)) - #test_src_name = os.path.splitext(test_src_path)[0] + xe_name = ((os.path.basename(self.name)).split("."))[0] + ".xe" + test_bin_path = os.path.join('bin', xe_name) - #test_bin_name_si = os.path.join( - # test_src_name + '_single_issue.xe') - #test_bin_path_si = os.path.join('bin', - # test_bin_name_si) - #yield UnityTestExecutable.from_parent(self, name=test_bin_path_si) - - #test_bin_name_di = os.path.join( - # test_src_name + '_dual_issue.xe') - #test_bin_path_di = os.path.join('bin', - # test_bin_name_di) yield UnityTestExecutable.from_parent(self, name=self.name) @@ -83,7 +71,7 @@ class UnityTestExecutable(pytest.Item): test_case = test_report[2] result = test_report[3] failure_reason = None - print('\n {}()'.format(test_case)), + print(('\n {}()'.format(test_case)), end=' ') if result == 'PASS': unity_pass = True continue diff --git a/tests/xua_unit_tests/generate_unity_runners.py b/tests/xua_unit_tests/generate_unity_runners.py new file mode 100644 index 00000000..f2fe0f04 --- /dev/null +++ b/tests/xua_unit_tests/generate_unity_runners.py @@ -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() diff --git a/tests/xua_unit_tests/wscript b/tests/xua_unit_tests/wscript index 952519a9..fcae029c 100644 --- a/tests/xua_unit_tests/wscript +++ b/tests/xua_unit_tests/wscript @@ -3,11 +3,10 @@ import glob import os.path import subprocess import sys -from waflib import Options, Errors +from waflib import Options from waflib.Build import BuildContext, CleanContext -#TARGETS = ['xcore200', 'xcoreai'] -TARGETS = ['xcore200'] # Target xcore200 only for the time being +TARGETS = ['xcore200', 'xcoreai'] def get_ruby(): """ @@ -68,6 +67,7 @@ def generate_unity_runner(project_root_path, unity_test_path, unity_runner_dir, 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), @@ -79,38 +79,27 @@ def generate_unity_runner(project_root_path, unity_test_path, unity_runner_dir, exit(1) # TODO: Check this is the correct way to kill xwaf on error -def set_common_build_config(waf_conf, project_root_path, unity_test_path, - unity_runner_build_flags): +def add_unity_runner_build_config(waf_conf, project_root_path, unity_test_path, + unity_runner_build_flags, target): """ - Set the common xwaf config variables. + 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 add_single_issue_unity_runner_build_config(waf_conf, project_root_path, - unity_test_path, - unity_runner_build_flags, target): - """ - Add a single issue config to xwaf to build each Unity test runner into an - xCORE executable. - """ - waf_conf.setenv(get_test_name(unity_test_path) + '_single_issue' + '_' + target) - set_common_build_config(waf_conf, project_root_path, unity_test_path, - unity_runner_build_flags + '-mno-dual-issue') - - 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_single_issue_unity_runner_build_config(waf_conf, project_root_path, - unity_test_path, - runner_build_flags, target) - + 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): @@ -118,12 +107,8 @@ def find_unity_test_paths(unity_test_dir, unity_test_prefix): Return a list of all file paths with the unity_test_prefix found in the unity_test_dir. """ - file_list = [] - for root, dirs, files in os.walk(unity_test_dir): - for f in files: - if f.startswith(unity_test_prefix): - file_list.append(os.path.join(root,f)) - return file_list + return glob.glob(os.path.join(unity_test_dir, unity_test_prefix+'*')) + def find_unity_tests(unity_test_dir, unity_test_prefix): """ @@ -155,17 +140,19 @@ def generate_all_unity_runners(waf_conf, project_root_path, def create_waf_contexts(configs): for trgt in TARGETS: for test_name, test_language in configs.items(): - # Single issue test configurations + print(f"test_name {test_name}, test_language {test_language}") for ctx in (BuildContext, CleanContext): raw_context = ctx.__name__.replace('Context', '').lower() - class si_tmp(ctx): - cmd = raw_context + '_' + test_name + '_single_issue' + '_' + trgt - variant = test_name + '_single_issue' + '_' + trgt - source = test_name + 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' @@ -177,8 +164,8 @@ UNITY_TESTS = find_unity_tests(UNITY_TEST_DIR, UNITY_TEST_PREFIX) create_waf_contexts(UNITY_TESTS) def options(opt): - opt.load('xwaf.xcommon') 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() @@ -191,6 +178,7 @@ def configure(conf): 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 ] @@ -198,34 +186,25 @@ def build(bld): if len(trgt) == 0: bld.fatal('specify a target with --target.\nAvailable targets: {}'.format(', '.join(TARGETS))) return - print('Adding test runners to build queue') + for name in UNITY_TESTS: - Options.commands.insert(0, 'build_' + name + '_single_issue' + '_' + trgt[0]) + 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)) - if(bld.target == 'xcoreai'): - bld.env.TARGET_ARCH = 'XCORE-AI-EXPLORER' - else: - bld.env.TARGET_ARCH = 'XCORE-200-EXPLORER' - bld.env.XSCOPE = bld.path.find_resource('config.xscope') - # The issue mode for each build is set during the configure step, - # as the string bld.env.XCC_FLAGS. We append this to the list last to - # ensure it takes precedence over other flags set here. - bld.env.XCC_FLAGS = ['-O2', '-g', '-Wall', '-DUNITY_SUPPORT_64', - '-DUNITY_INCLUDE_DOUBLE', bld.env.XCC_FLAGS] - depends_on = ['lib_xud', 'lib_xua', 'Unity'] - include = ['.'] - source = [ - os.path.join(UNITY_TEST_DIR, - '{}.{}'.format(bld.source, bld.language)), - os.path.join(UNITY_RUNNER_DIR, - '{}{}.{}'.format(bld.source, UNITY_RUNNER_SUFFIX, - 'c'))] + depends_on = ['lib_xua', + 'lib_xud', + 'lib_spdif', + 'lib_mic_array', + 'lib_logging', + 'lib_xassert', + 'Unity'] + makefile_opts = {} - makefile_opts['SOURCE_DIRS'] = [os.path.join('src',bld.runner), os.path.join('runners',bld.runner)] + makefile_opts['SOURCE_DIRS'] = ['src', os.path.join('runners',bld.runner)] if(bld.target == 'xcoreai'): print('TARGET XCOREAI') makefile_opts['TARGET'] = ['XCORE-AI-EXPLORER'] @@ -233,13 +212,29 @@ def build(bld): print('TARGET XCORE200') makefile_opts['TARGET'] = ['XCORE-200-EXPLORER'] - makefile_opts['INCLUDE_DIRS'] = ['src'] - makefile_opts['XCC_FLAGS'] = ['-O2', '-g', '-Wall', '-DUNITY_SUPPORT_64', '-DUNITY_INCLUDE_DOUBLE'] + makefile_opts['INCLUDE_DIRS'] = ['src', + '../../lib_xua/src/core/pdm_mics', + '../../lib_xua/api', + '../../../lib_xud/lib_xud/src/user/class'] + + makefile_opts['XCC_FLAGS'] = ['-O2', '-g', '-Wall', '-DUNITY_SUPPORT_64', '-DUNITY_INCLUDE_DOUBLE', '-DXUD_CORE_CLOCK=600'] 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') From c0dade0156a855a0cf715a5e3da24e6ef4b12c97 Mon Sep 17 00:00:00 2001 From: mbanth Date: Thu, 20 May 2021 15:47:02 +0100 Subject: [PATCH 11/55] Updated trivial test. Builds for xCore200 with minimal warnings. --- tests/xua_unit_tests/src/test_hid.xc | 25 +++++++++++++++++++ tests/xua_unit_tests/src/test_hid/test_hid.xc | 7 ------ tests/xua_unit_tests/src/xua_unit_tests.h | 1 + 3 files changed, 26 insertions(+), 7 deletions(-) create mode 100644 tests/xua_unit_tests/src/test_hid.xc delete mode 100644 tests/xua_unit_tests/src/test_hid/test_hid.xc diff --git a/tests/xua_unit_tests/src/test_hid.xc b/tests/xua_unit_tests/src/test_hid.xc new file mode 100644 index 00000000..0877f419 --- /dev/null +++ b/tests/xua_unit_tests/src/test_hid.xc @@ -0,0 +1,25 @@ +// Copyright 2021 XMOS LIMITED. +// This Software is subject to the terms of the XMOS Public Licence: Version 1. +#include "xua_unit_tests.h" + +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 +} + +void test_null(){ + TEST_ASSERT_MESSAGE(1, "Success!"); +} diff --git a/tests/xua_unit_tests/src/test_hid/test_hid.xc b/tests/xua_unit_tests/src/test_hid/test_hid.xc deleted file mode 100644 index d92a7efd..00000000 --- a/tests/xua_unit_tests/src/test_hid/test_hid.xc +++ /dev/null @@ -1,7 +0,0 @@ -// Copyright 2021 XMOS LIMITED. -// This Software is subject to the terms of the XMOS Public Licence: Version 1. -#include "xua_unit_tests.h" - -void test_null(){ - TEST_ASSERT_MESSAGE(1, "Success!"); -} diff --git a/tests/xua_unit_tests/src/xua_unit_tests.h b/tests/xua_unit_tests/src/xua_unit_tests.h index 11fd6faf..addefeb9 100644 --- a/tests/xua_unit_tests/src/xua_unit_tests.h +++ b/tests/xua_unit_tests/src/xua_unit_tests.h @@ -8,6 +8,7 @@ #ifdef __XC__ #include +#include #include #include "xua_conf.h" From 0e27c7f2ffd82eb8844ccd606dd6058eaa06619f Mon Sep 17 00:00:00 2001 From: mbanth Date: Thu, 20 May 2021 15:58:30 +0100 Subject: [PATCH 12/55] Align with lib_agc Jenkinsfile regarding unit test operation --- Jenkinsfile | 21 ++++++++++++--------- 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/Jenkinsfile b/Jenkinsfile index 3ba5bc40..23dca52e 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -40,11 +40,11 @@ pipeline { dir("${REPO}") { dir('tests') { dir('xua_unit_tests') { - viewEnv() { - withVenv { - runWaf('.', "configure clean build --target=xcore200") - runWaf('.', "configure clean build --target=xcoreai") - stash name: 'xua_unit_tests', includes: 'bin/*xcoreai.xe, ' + 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") } } @@ -59,6 +59,9 @@ pipeline { agent { label 'xcore.ai-explorer' } + options { + skipDefaultCheckout() + } stages{ stage('Get View') { steps { @@ -70,10 +73,10 @@ pipeline { dir("${REPO}") { dir('tests') { dir('xua_unit_tests') { - viewEnv() { - withVenv { - unstash 'xua_unit_tests' - runPython("TARGET=XCOREAI pytest -n 1 --junitxml pytest_result.xml") + withVenv { + unstash 'xua_unit_tests' + viewEnv() { + runPython("TARGET=XCOREAI pytest -s") } } } From 9cdbe9c62d3d476ca45c097be276498a593b13be Mon Sep 17 00:00:00 2001 From: mbanth Date: Thu, 20 May 2021 16:02:31 +0100 Subject: [PATCH 13/55] Comment out xCore.AI unit test operation until the unit tests build successfully on that platform --- Jenkinsfile | 76 ++++++++++++++++++++++++++--------------------------- 1 file changed, 38 insertions(+), 38 deletions(-) diff --git a/Jenkinsfile b/Jenkinsfile index 23dca52e..905b2301 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -42,8 +42,8 @@ pipeline { 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, ' +// runWaf('.', "configure clean build --target=xcoreai") +// stash name: 'xua_unit_tests', includes: 'bin/*xcoreai.xe, ' viewEnv() { runPython("TARGET=XCORE200 pytest -n 1") } @@ -55,42 +55,42 @@ pipeline { } } } - 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.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}") { From fbef825a3ba9fda8088cd392435d6dc678b62253 Mon Sep 17 00:00:00 2001 From: mbanth Date: Mon, 24 May 2021 15:46:16 +0100 Subject: [PATCH 14/55] Add include path to HID header files --- tests/xua_unit_tests/wscript | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tests/xua_unit_tests/wscript b/tests/xua_unit_tests/wscript index fcae029c..e5cace3b 100644 --- a/tests/xua_unit_tests/wscript +++ b/tests/xua_unit_tests/wscript @@ -213,8 +213,9 @@ def build(bld): makefile_opts['TARGET'] = ['XCORE-200-EXPLORER'] makefile_opts['INCLUDE_DIRS'] = ['src', - '../../lib_xua/src/core/pdm_mics', '../../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'] From eb6d3b0869fe99ed28d4c5a4fbb8c246181238b1 Mon Sep 17 00:00:00 2001 From: mbanth Date: Mon, 24 May 2021 15:47:31 +0100 Subject: [PATCH 15/55] Split functionality into test code in pure C and helper code in XC --- tests/xua_unit_tests/src/test_hid.c | 12 ++++++++++++ .../src/{test_hid.xc => xua_unit_test_helper.xc} | 13 ++++++++----- tests/xua_unit_tests/src/xua_unit_tests.h | 9 --------- 3 files changed, 20 insertions(+), 14 deletions(-) create mode 100644 tests/xua_unit_tests/src/test_hid.c rename tests/xua_unit_tests/src/{test_hid.xc => xua_unit_test_helper.xc} (87%) diff --git a/tests/xua_unit_tests/src/test_hid.c b/tests/xua_unit_tests/src/test_hid.c new file mode 100644 index 00000000..6d7d7465 --- /dev/null +++ b/tests/xua_unit_tests/src/test_hid.c @@ -0,0 +1,12 @@ +// Copyright 2021 XMOS LIMITED. +// This Software is subject to the terms of the XMOS Public Licence: Version 1. +#include + +#include "xua_unit_tests.h" +#include "xua_hid_report_descriptor.h" + +void test_uninitialised_hidGetReportDescriptor() +{ + unsigned char* reportDescPtr = hidGetReportDescriptor(); + TEST_ASSERT_NULL( reportDescPtr ); +} diff --git a/tests/xua_unit_tests/src/test_hid.xc b/tests/xua_unit_tests/src/xua_unit_test_helper.xc similarity index 87% rename from tests/xua_unit_tests/src/test_hid.xc rename to tests/xua_unit_tests/src/xua_unit_test_helper.xc index 0877f419..d4c2911c 100644 --- a/tests/xua_unit_tests/src/test_hid.xc +++ b/tests/xua_unit_tests/src/xua_unit_test_helper.xc @@ -1,6 +1,13 @@ // Copyright 2021 XMOS LIMITED. // This Software is subject to the terms of the XMOS Public Licence: Version 1. -#include "xua_unit_tests.h" +#ifdef __XC__ + +#include +#include +#include + +#endif // __XC__ + in port p_mclk_in = XS1_PORT_1D; @@ -19,7 +26,3 @@ void AudioHwInit() { ; // nothing } - -void test_null(){ - TEST_ASSERT_MESSAGE(1, "Success!"); -} diff --git a/tests/xua_unit_tests/src/xua_unit_tests.h b/tests/xua_unit_tests/src/xua_unit_tests.h index addefeb9..0b1d82d9 100644 --- a/tests/xua_unit_tests/src/xua_unit_tests.h +++ b/tests/xua_unit_tests/src/xua_unit_tests.h @@ -4,15 +4,6 @@ #define XUA_UNIT_TESTS_H_ #include "unity.h" - -#ifdef __XC__ - -#include -#include -#include - #include "xua_conf.h" -#endif // __XC__ - #endif /* XUA_UNIT_TESTS_H_ */ From f1a1ee077f6e7f2eca7ec1ecfd4c232162214759 Mon Sep 17 00:00:00 2001 From: mbanth Date: Mon, 24 May 2021 16:01:54 +0100 Subject: [PATCH 16/55] Add test for returning an initialized Report descriptor --- tests/xua_unit_tests/src/test_hid.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/tests/xua_unit_tests/src/test_hid.c b/tests/xua_unit_tests/src/test_hid.c index 6d7d7465..26ac4fd4 100644 --- a/tests/xua_unit_tests/src/test_hid.c +++ b/tests/xua_unit_tests/src/test_hid.c @@ -10,3 +10,10 @@ void test_uninitialised_hidGetReportDescriptor() unsigned char* reportDescPtr = hidGetReportDescriptor(); TEST_ASSERT_NULL( reportDescPtr ); } + +void test_initialised_hidGetReportDescriptor() +{ + hidInitReportDescriptor(); + unsigned char* reportDescPtr = hidGetReportDescriptor(); + TEST_ASSERT_NOT_NULL( reportDescPtr ); +} From 29ab72e614989438d6422e94a8525847a025e8a5 Mon Sep 17 00:00:00 2001 From: mbanth Date: Mon, 24 May 2021 16:53:13 +0100 Subject: [PATCH 17/55] Move constants needed by callers --- lib_xua/src/hid/hid_report_descriptor.c | 18 +++--------------- lib_xua/src/hid/xua_hid_report_descriptor.h | 20 ++++++++++++++++---- 2 files changed, 19 insertions(+), 19 deletions(-) diff --git a/lib_xua/src/hid/hid_report_descriptor.c b/lib_xua/src/hid/hid_report_descriptor.c index 76983e89..c55ff8f0 100644 --- a/lib_xua/src/hid/hid_report_descriptor.c +++ b/lib_xua/src/hid/hid_report_descriptor.c @@ -5,24 +5,12 @@ #include #include "xua_hid_report_descriptor.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_USAGE_TAG ( 0 ) -#define HID_REPORT_ITEM_USAGE_TYPE ( 2 ) - #if 0 /* Existing static report descriptor kept for reference */ unsigned char hidReportDescriptor[] = @@ -289,7 +277,7 @@ void hidInitReportDescriptor( void ) unsigned hidSetReportItem( const unsigned byte, const unsigned bit, const unsigned char header, const unsigned char data[] ) { - unsigned retVal = 2; + unsigned retVal = HID_STATUS_BAD_LOCATION; unsigned bSize = hidGetItemSize( header ); unsigned bTag = hidGetItemTag ( header ); unsigned bType = hidGetItemType( header ); @@ -297,7 +285,7 @@ unsigned hidSetReportItem( const unsigned byte, const unsigned bit, const unsign if(( HID_REPORT_ITEM_MAX_SIZE < bSize ) && ( HID_REPORT_ITEM_USAGE_TAG == bTag ) && ( HID_REPORT_ITEM_USAGE_TAG == bType )) { - retVal = 1; + retVal = HID_STATUS_BAD_HEADER; } else { for( unsigned itemIdx = 0; itemIdx < sizeof hidConfigurableItems / sizeof( USB_HID_Short_Item_t ); ++itemIdx ) { USB_HID_Short_Item_t item = *hidConfigurableItems[ itemIdx ]; @@ -313,7 +301,7 @@ unsigned hidSetReportItem( const unsigned byte, const unsigned bit, const unsign *hidConfigurableItems[ itemIdx ] = item; hidReportDescriptorInitialised = 0; - retVal = 0; + retVal = HID_STATUS_GOOD; } } } diff --git a/lib_xua/src/hid/xua_hid_report_descriptor.h b/lib_xua/src/hid/xua_hid_report_descriptor.h index 2195ddc3..94e335d8 100644 --- a/lib_xua/src/hid/xua_hid_report_descriptor.h +++ b/lib_xua/src/hid/xua_hid_report_descriptor.h @@ -11,11 +11,23 @@ #ifndef _HID_REPORT_DESCRIPTOR_ #define _HID_REPORT_DESCRIPTOR_ -#define HID_REPORT_ITEM_MAX_SIZE ( 2 ) +#define HID_REPORT_ITEM_HDR_SIZE_MASK ( 0x03 ) +#define HID_REPORT_ITEM_HDR_SIZE_SHIFT ( 0 ) -#define HID_STATUS_GOOD ( 0 ) -#define HID_STATUS_BAD_HEADER ( 1 ) -#define HID_STATUS_BAD_LOCATION ( 2 ) +#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_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 ) /** * @brief USB HID Report Descriptor. Short Item From 728980e7dcb263c0c720b23a009596415d43e692 Mon Sep 17 00:00:00 2001 From: mbanth Date: Mon, 24 May 2021 16:54:01 +0100 Subject: [PATCH 18/55] Add test that specifies a bit out-of-range when modifying a report item --- tests/xua_unit_tests/src/test_hid.c | 26 ++++++++++++++++++++++++-- 1 file changed, 24 insertions(+), 2 deletions(-) diff --git a/tests/xua_unit_tests/src/test_hid.c b/tests/xua_unit_tests/src/test_hid.c index 26ac4fd4..1e45b51d 100644 --- a/tests/xua_unit_tests/src/test_hid.c +++ b/tests/xua_unit_tests/src/test_hid.c @@ -5,15 +5,37 @@ #include "xua_unit_tests.h" #include "xua_hid_report_descriptor.h" -void test_uninitialised_hidGetReportDescriptor() +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 test_uninitialised_hidGetReportDescriptor( void ) { unsigned char* reportDescPtr = hidGetReportDescriptor(); TEST_ASSERT_NULL( reportDescPtr ); } -void test_initialised_hidGetReportDescriptor() +void test_initialised_hidGetReportDescriptor( void ) { hidInitReportDescriptor(); unsigned char* reportDescPtr = hidGetReportDescriptor(); TEST_ASSERT_NOT_NULL( reportDescPtr ); } + +void test_bad_bit_hidSetReportItem( void ) +{ + const unsigned bit = 8; + const unsigned byte = 0; + const unsigned char header = construct_usage_header( 0 ); + + unsigned retVal = hidSetReportItem( byte, bit, header, NULL ); + TEST_ASSERT_EQUAL_UINT( HID_STATUS_BAD_LOCATION, retVal ); +} From 3ae4a4e456ddba6cfab160343f909a3f5313b291 Mon Sep 17 00:00:00 2001 From: mbanth Date: Mon, 24 May 2021 17:12:32 +0100 Subject: [PATCH 19/55] Add tests for max and min valid bit location and one for an underflow --- tests/xua_unit_tests/src/test_hid.c | 34 ++++++++++++++++++++++++++++- 1 file changed, 33 insertions(+), 1 deletion(-) diff --git a/tests/xua_unit_tests/src/test_hid.c b/tests/xua_unit_tests/src/test_hid.c index 1e45b51d..27f9921c 100644 --- a/tests/xua_unit_tests/src/test_hid.c +++ b/tests/xua_unit_tests/src/test_hid.c @@ -17,6 +17,7 @@ static unsigned construct_usage_header( unsigned size ) return header; } +// Basic report descriptor tests void test_uninitialised_hidGetReportDescriptor( void ) { unsigned char* reportDescPtr = hidGetReportDescriptor(); @@ -30,7 +31,28 @@ void test_initialised_hidGetReportDescriptor( void ) TEST_ASSERT_NOT_NULL( reportDescPtr ); } -void test_bad_bit_hidSetReportItem( void ) +// Bit range tests +void test_max_bit_hidSetReportItem( void ) +{ + const unsigned bit = 7; + const unsigned byte = 1; // Only byte 1 has bit 7 not reserved + const unsigned char header = construct_usage_header( 0 ); + + unsigned retVal = hidSetReportItem( byte, bit, header, NULL ); + TEST_ASSERT_EQUAL_UINT( HID_STATUS_GOOD, retVal ); +} + +void test_min_bit_hidSetReportItem( void ) +{ + const unsigned bit = 0; + const unsigned byte = 0; + const unsigned char header = construct_usage_header( 0 ); + + unsigned retVal = hidSetReportItem( byte, bit, header, NULL ); + TEST_ASSERT_EQUAL_UINT( HID_STATUS_GOOD, retVal ); +} + +void test_overflow_bit_hidSetReportItem( void ) { const unsigned bit = 8; const unsigned byte = 0; @@ -39,3 +61,13 @@ void test_bad_bit_hidSetReportItem( void ) unsigned retVal = hidSetReportItem( byte, bit, header, NULL ); TEST_ASSERT_EQUAL_UINT( HID_STATUS_BAD_LOCATION, retVal ); } + +void test_underflow_bit_hidSetReportItem( void ) +{ + const int bit = -1; + const unsigned byte = 0; + const unsigned char header = construct_usage_header( 0 ); + + unsigned retVal = hidSetReportItem( byte, ( unsigned ) bit, header, NULL ); + TEST_ASSERT_EQUAL_UINT( HID_STATUS_BAD_LOCATION, retVal ); +} From b552d605678562d915e1d911fe5042c87d1ba32a Mon Sep 17 00:00:00 2001 From: mbanth Date: Tue, 25 May 2021 08:59:20 +0100 Subject: [PATCH 20/55] Add byte range tests --- tests/xua_unit_tests/src/test_hid.c | 41 +++++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) diff --git a/tests/xua_unit_tests/src/test_hid.c b/tests/xua_unit_tests/src/test_hid.c index 27f9921c..bdac3205 100644 --- a/tests/xua_unit_tests/src/test_hid.c +++ b/tests/xua_unit_tests/src/test_hid.c @@ -71,3 +71,44 @@ void test_underflow_bit_hidSetReportItem( void ) unsigned retVal = hidSetReportItem( byte, ( unsigned ) bit, header, NULL ); TEST_ASSERT_EQUAL_UINT( HID_STATUS_BAD_LOCATION, retVal ); } + +// Byte range tests +void test_max_byte_hidSetReportItem( void ) +{ + const unsigned bit = 0; + const unsigned byte = 2; + const unsigned char header = construct_usage_header( 0 ); + + unsigned retVal = hidSetReportItem( byte, bit, header, NULL ); + TEST_ASSERT_EQUAL_UINT( HID_STATUS_GOOD, retVal ); +} + +void test_min_byte_hidSetReportItem( void ) +{ + const unsigned bit = 0; + const unsigned byte = 0; + const unsigned char header = construct_usage_header( 0 ); + + unsigned retVal = hidSetReportItem( byte, bit, header, NULL ); + TEST_ASSERT_EQUAL_UINT( HID_STATUS_GOOD, retVal ); +} + +void test_overflow_byte_hidSetReportItem( void ) +{ + const unsigned bit = 0; + const unsigned byte = 4; + const unsigned char header = construct_usage_header( 0 ); + + unsigned retVal = hidSetReportItem( byte, bit, header, NULL ); + TEST_ASSERT_EQUAL_UINT( HID_STATUS_BAD_LOCATION, retVal ); +} + +void test_underflow_byte_hidSetReportItem( void ) +{ + const unsigned bit = 0; + const int byte = -1; + const unsigned char header = construct_usage_header( 0 ); + + unsigned retVal = hidSetReportItem( ( unsigned ) byte, bit, header, NULL ); + TEST_ASSERT_EQUAL_UINT( HID_STATUS_BAD_LOCATION, retVal ); +} From 46cac9afb9a05a3a770644f6d638f0f32895b25b Mon Sep 17 00:00:00 2001 From: mbanth Date: Tue, 25 May 2021 10:04:51 +0100 Subject: [PATCH 21/55] Rename function and variable to better reflect its use beyond initialisation --- lib_xua/src/hid/hid_report_descriptor.c | 11 ++++++----- lib_xua/src/hid/xua_hid_report_descriptor.h | 19 +++++++++---------- 2 files changed, 15 insertions(+), 15 deletions(-) diff --git a/lib_xua/src/hid/hid_report_descriptor.c b/lib_xua/src/hid/hid_report_descriptor.c index c55ff8f0..0d43b9fb 100644 --- a/lib_xua/src/hid/hid_report_descriptor.c +++ b/lib_xua/src/hid/hid_report_descriptor.c @@ -154,7 +154,7 @@ static const USB_HID_Short_Item_t* const hidReportDescriptorItems[] = { ( sizeof ( USB_HID_Short_Item_t ) - HID_REPORT_ITEM_LOCATION_SIZE )) static unsigned char hidReportDescriptor[ HID_REPORT_DESCRIPTOR_MAX_LENGTH ]; -static unsigned hidReportDescriptorInitialised = 0; +static unsigned hidReportDescriptorPrepared = 0; /** * @brief Get the bit position from the location of an Item @@ -223,6 +223,7 @@ static unsigned hidGetItemType( const unsigned char header ); */ static unsigned char* hidTranslateItem( const USB_HID_Short_Item_t* inPtr, unsigned char* outPtr ); + static unsigned hidGetItemBitLocation( const unsigned char location ) { unsigned bBit = ( location & HID_REPORT_ITEM_LOC_BIT_MASK ) >> HID_REPORT_ITEM_LOC_BIT_SHIFT; @@ -258,21 +259,21 @@ unsigned char* hidGetReportDescriptor( void ) { unsigned char* retVal = NULL; - if( hidReportDescriptorInitialised ) { + if( hidReportDescriptorPrepared ) { retVal = hidReportDescriptor; } return retVal; } -void hidInitReportDescriptor( void ) +void hidPrerpareReportDescriptor( void ) { unsigned char* ptr = hidReportDescriptor; for( unsigned idx = 0; idx < sizeof hidReportDescriptorItems / sizeof( USB_HID_Short_Item_t ); ++idx ) { ptr = hidTranslateItem( hidReportDescriptorItems[ idx ], ptr ); } - hidReportDescriptorInitialised = 1; + hidReportDescriptorPrepared = 1; } unsigned hidSetReportItem( const unsigned byte, const unsigned bit, const unsigned char header, const unsigned char data[] ) @@ -300,7 +301,7 @@ unsigned hidSetReportItem( const unsigned byte, const unsigned bit, const unsign } *hidConfigurableItems[ itemIdx ] = item; - hidReportDescriptorInitialised = 0; + hidReportDescriptorPrepared = 0; retVal = HID_STATUS_GOOD; } } diff --git a/lib_xua/src/hid/xua_hid_report_descriptor.h b/lib_xua/src/hid/xua_hid_report_descriptor.h index 94e335d8..6198ce16 100644 --- a/lib_xua/src/hid/xua_hid_report_descriptor.h +++ b/lib_xua/src/hid/xua_hid_report_descriptor.h @@ -63,6 +63,15 @@ typedef struct */ unsigned char* hidGetReportDescriptor( void ); +/** + * @brief Prepare the USB HID Report descriptor + * + * After preparation, \c hidGetReportDescriptor() returns a list suitablefor transmission over USB. + * + * Call this function after altering one or more Report Items using \c hidSetReportItem(). + */ +void hidPrepareReportDescriptor( void ); + /** * @brief Modify a HID Report descriptor item * @@ -82,14 +91,4 @@ unsigned char* hidGetReportDescriptor( void ); */ unsigned hidSetReportItem( const unsigned byte, const unsigned bit, const unsigned char header, const unsigned char data[] ); -/** - * @brief Initialise the USB HID Report descriptor - * - * After initialisation, \c hidGetReportDescriptor() returns a list suitable - * for transmission over USB. - * - * Call this function after altering one or more Report Items using \c hidSetReportItem(). - */ -void hidInitReportDescriptor( void ); - #endif // _HID_REPORT_DESCRIPTOR_ From b1f3cc0024f18b86ecb747b76a277eafe17a5b61 Mon Sep 17 00:00:00 2001 From: mbanth Date: Tue, 25 May 2021 11:23:18 +0100 Subject: [PATCH 22/55] Add size range tests. Fix misspelled function name. --- lib_xua/src/hid/hid_report_descriptor.c | 9 +++-- lib_xua/src/hid/xua_hid_report_descriptor.h | 4 +++ tests/xua_unit_tests/src/test_hid.c | 39 +++++++++++++++++++-- 3 files changed, 44 insertions(+), 8 deletions(-) diff --git a/lib_xua/src/hid/hid_report_descriptor.c b/lib_xua/src/hid/hid_report_descriptor.c index 0d43b9fb..2bddc6cc 100644 --- a/lib_xua/src/hid/hid_report_descriptor.c +++ b/lib_xua/src/hid/hid_report_descriptor.c @@ -239,7 +239,6 @@ static unsigned hidGetItemByteLocation( const unsigned char location ) static unsigned hidGetItemSize( const unsigned char header ) { unsigned bSize = ( header & HID_REPORT_ITEM_HDR_SIZE_MASK ) >> HID_REPORT_ITEM_HDR_SIZE_SHIFT; - assert( bSize <= HID_REPORT_ITEM_MAX_SIZE ); return bSize; } @@ -266,7 +265,7 @@ unsigned char* hidGetReportDescriptor( void ) return retVal; } -void hidPrerpareReportDescriptor( void ) +void hidPrepareReportDescriptor( void ) { unsigned char* ptr = hidReportDescriptor; for( unsigned idx = 0; idx < sizeof hidReportDescriptorItems / sizeof( USB_HID_Short_Item_t ); ++idx ) { @@ -283,9 +282,9 @@ unsigned hidSetReportItem( const unsigned byte, const unsigned bit, const unsign 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_TAG == bType )) { + 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 < sizeof hidConfigurableItems / sizeof( USB_HID_Short_Item_t ); ++itemIdx ) { diff --git a/lib_xua/src/hid/xua_hid_report_descriptor.h b/lib_xua/src/hid/xua_hid_report_descriptor.h index 6198ce16..811eb230 100644 --- a/lib_xua/src/hid/xua_hid_report_descriptor.h +++ b/lib_xua/src/hid/xua_hid_report_descriptor.h @@ -75,6 +75,10 @@ void hidPrepareReportDescriptor( 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 diff --git a/tests/xua_unit_tests/src/test_hid.c b/tests/xua_unit_tests/src/test_hid.c index bdac3205..73fa95d3 100644 --- a/tests/xua_unit_tests/src/test_hid.c +++ b/tests/xua_unit_tests/src/test_hid.c @@ -1,6 +1,7 @@ // Copyright 2021 XMOS LIMITED. // This Software is subject to the terms of the XMOS Public Licence: Version 1. #include +#include #include "xua_unit_tests.h" #include "xua_hid_report_descriptor.h" @@ -18,15 +19,15 @@ static unsigned construct_usage_header( unsigned size ) } // Basic report descriptor tests -void test_uninitialised_hidGetReportDescriptor( void ) +void test_unprepared_hidGetReportDescriptor( void ) { unsigned char* reportDescPtr = hidGetReportDescriptor(); TEST_ASSERT_NULL( reportDescPtr ); } -void test_initialised_hidGetReportDescriptor( void ) +void test_prepared_hidGetReportDescriptor( void ) { - hidInitReportDescriptor(); + hidPrepareReportDescriptor(); unsigned char* reportDescPtr = hidGetReportDescriptor(); TEST_ASSERT_NOT_NULL( reportDescPtr ); } @@ -112,3 +113,35 @@ void test_underflow_byte_hidSetReportItem( void ) unsigned retVal = hidSetReportItem( ( unsigned ) byte, bit, header, NULL ); TEST_ASSERT_EQUAL_UINT( HID_STATUS_BAD_LOCATION, retVal ); } + +// Size range tests +void test_max_size_hidSetReportItem( void ) +{ + const unsigned bit = 0; + const unsigned byte = 0; + const unsigned char data[ HID_REPORT_ITEM_MAX_SIZE ] = { 0x00 }; + const unsigned char header = construct_usage_header( HID_REPORT_ITEM_MAX_SIZE ); + + unsigned retVal = hidSetReportItem( byte, bit, header, data ); + TEST_ASSERT_EQUAL_UINT( HID_STATUS_GOOD, retVal ); +} + +void test_min_size_hidSetReportItem( void ) +{ + const unsigned bit = 0; + const unsigned byte = 0; + const unsigned char header = construct_usage_header( 0x00 ); + + unsigned retVal = hidSetReportItem( byte, bit, header, NULL ); + TEST_ASSERT_EQUAL_UINT( HID_STATUS_GOOD, retVal ); +} + +void test_unsupported_size_hidSetReportItem( void ) +{ + const unsigned bit = 0; + const unsigned byte = 0; + const unsigned char header = construct_usage_header( 0x03 ); + + unsigned retVal = hidSetReportItem( byte, bit, header, NULL ); + TEST_ASSERT_EQUAL_UINT( HID_STATUS_BAD_HEADER, retVal ); +} From f3e8a1937f31a6fa8dbf6830e5354814ce75a4a5 Mon Sep 17 00:00:00 2001 From: mbanth Date: Tue, 25 May 2021 12:07:11 +0100 Subject: [PATCH 23/55] Add header tag and type tests --- tests/xua_unit_tests/src/test_hid.c | 62 +++++++++++++++++++++++++++++ 1 file changed, 62 insertions(+) diff --git a/tests/xua_unit_tests/src/test_hid.c b/tests/xua_unit_tests/src/test_hid.c index 73fa95d3..beeef5a9 100644 --- a/tests/xua_unit_tests/src/test_hid.c +++ b/tests/xua_unit_tests/src/test_hid.c @@ -145,3 +145,65 @@ void test_unsupported_size_hidSetReportItem( void ) unsigned retVal = hidSetReportItem( byte, bit, 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 = 0; + const unsigned byte = 0; + const unsigned char good_header = construct_usage_header( 0x00 ); + + 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, bad_header, NULL ); + TEST_ASSERT_EQUAL_UINT( HID_STATUS_BAD_HEADER, retVal ); + } +} + +void test_local_type_hidSetReportItem( void ) +{ + const unsigned bit = 0; + const unsigned byte = 0; + const unsigned char header = ( construct_usage_header( 0x00 ) & + ~HID_REPORT_ITEM_HDR_TYPE_MASK ) | + (( 0x02 << HID_REPORT_ITEM_HDR_TYPE_SHIFT ) & HID_REPORT_ITEM_HDR_TYPE_MASK ); + + unsigned retVal = hidSetReportItem( byte, bit, header, NULL ); + TEST_ASSERT_EQUAL_UINT( HID_STATUS_GOOD, retVal ); +} + +void test_global_type_hidSetReportItem( void ) +{ + const unsigned bit = 0; + const unsigned byte = 0; + const unsigned char header = ( construct_usage_header( 0x00 ) & + ~HID_REPORT_ITEM_HDR_TYPE_MASK ) | + (( 0x01 << HID_REPORT_ITEM_HDR_TYPE_SHIFT ) & HID_REPORT_ITEM_HDR_TYPE_MASK ); + + unsigned retVal = hidSetReportItem( byte, bit, header, NULL ); + TEST_ASSERT_EQUAL_UINT( HID_STATUS_BAD_HEADER, retVal ); +} + +void test_main_type_hidSetReportItem( void ) +{ + const unsigned bit = 0; + const unsigned byte = 0; + const unsigned char header = ( construct_usage_header( 0x00 ) & + ~HID_REPORT_ITEM_HDR_TYPE_MASK ) | + (( 0x00 << HID_REPORT_ITEM_HDR_TYPE_SHIFT ) & HID_REPORT_ITEM_HDR_TYPE_MASK ); + + unsigned retVal = hidSetReportItem( byte, bit, header, NULL ); + TEST_ASSERT_EQUAL_UINT( HID_STATUS_BAD_HEADER, retVal ); +} + +void test_reserved_type_hidSetReportItem( void ) +{ + const unsigned bit = 0; + const unsigned byte = 0; + const unsigned char header = ( construct_usage_header( 0x00 ) & + ~HID_REPORT_ITEM_HDR_TYPE_MASK ) | + (( 0x03 << HID_REPORT_ITEM_HDR_TYPE_SHIFT ) & HID_REPORT_ITEM_HDR_TYPE_MASK ); + + unsigned retVal = hidSetReportItem( byte, bit, header, NULL ); + TEST_ASSERT_EQUAL_UINT( HID_STATUS_BAD_HEADER, retVal ); +} From a9dddfab2fbde7a6a9c76f5350d4c69578085fe6 Mon Sep 17 00:00:00 2001 From: mbanth Date: Tue, 25 May 2021 14:22:09 +0100 Subject: [PATCH 24/55] Add tests: configurable and non-configurable items, and combined functions --- tests/xua_unit_tests/src/test_hid.c | 90 +++++++++++++++++++++++++++++ 1 file changed, 90 insertions(+) diff --git a/tests/xua_unit_tests/src/test_hid.c b/tests/xua_unit_tests/src/test_hid.c index beeef5a9..aadf02f9 100644 --- a/tests/xua_unit_tests/src/test_hid.c +++ b/tests/xua_unit_tests/src/test_hid.c @@ -32,6 +32,29 @@ void test_prepared_hidGetReportDescriptor( void ) TEST_ASSERT_NOT_NULL( reportDescPtr ); } +// Configurable and non-configurable item tests +void test_configurable_item_hidSetReportItem( void ) +{ + const unsigned bit = 0; + const unsigned byte = 0; + const unsigned char data[ 1 ] = { 0x2C }; // Spacebar keycode + const unsigned char header = construct_usage_header( sizeof data / sizeof( unsigned char )); + + unsigned retVal = hidSetReportItem( byte, bit, header, data ); + TEST_ASSERT_EQUAL_UINT( HID_STATUS_GOOD, retVal ); +} + +void test_nonconfigurable_item_hidSetReportItem( void ) +{ + const unsigned bit = 7; // Reserved bit + const unsigned byte = 0; + const unsigned char data[ 1 ] = { 0x2C }; // Spacebar keycode + const unsigned char header = construct_usage_header( sizeof data / sizeof( unsigned char )); + + unsigned retVal = hidSetReportItem( byte, bit, header, data ); + TEST_ASSERT_EQUAL_UINT( HID_STATUS_BAD_LOCATION, retVal ); +} + // Bit range tests void test_max_bit_hidSetReportItem( void ) { @@ -207,3 +230,70 @@ void test_reserved_type_hidSetReportItem( void ) unsigned retVal = hidSetReportItem( byte, bit, 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 = 0; + const unsigned byte = 0; + const unsigned char data[ 1 ] = { 0x2C }; // Spacebar keycode + const unsigned char header = construct_usage_header( sizeof data / sizeof( unsigned char )); + + unsigned retVal = hidSetReportItem( byte, bit, 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 = 0; + const unsigned byte = 0; + const unsigned char data[ 1 ] = { 0x2C }; // Spacebar keycode + const unsigned char header = construct_usage_header( sizeof data / sizeof( unsigned char )); + + unsigned retVal = hidSetReportItem( byte, bit, header, data ); + TEST_ASSERT_EQUAL_UINT( HID_STATUS_GOOD, retVal ); + + hidPrepareReportDescriptor(); + unsigned char* reportDescPtr = hidGetReportDescriptor(); + TEST_ASSERT_NOT_NULL( reportDescPtr ); +} + +void test_modification_without_subsequent_preparation( void ) +{ + hidPrepareReportDescriptor(); + unsigned char* reportDescPtr = hidGetReportDescriptor(); + TEST_ASSERT_NOT_NULL( reportDescPtr ); + + const unsigned bit = 0; + const unsigned byte = 0; + const unsigned char data[ 1 ] = { 0x2C }; // Spacebar keycode + const unsigned char header = construct_usage_header( sizeof data / sizeof( unsigned char )); + + unsigned retVal = hidSetReportItem( byte, bit, 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 = 0; + const unsigned byte = 0; + const unsigned char data[ 1 ] = { 0x2C }; // Spacebar keycode + const unsigned char header = construct_usage_header( sizeof data / sizeof( unsigned char )); + + unsigned retVal = hidSetReportItem( byte, bit, header, data ); + TEST_ASSERT_EQUAL_UINT( HID_STATUS_GOOD, retVal ); + + hidPrepareReportDescriptor(); + reportDescPtr = hidGetReportDescriptor(); + TEST_ASSERT_NOT_NULL( reportDescPtr ); +} From 02596cc5a9a87cc95baf241aa22e6a0971979ba9 Mon Sep 17 00:00:00 2001 From: mbanth Date: Tue, 25 May 2021 15:12:45 +0100 Subject: [PATCH 25/55] Clean-up --- tests/xua_unit_tests/src/test_hid.c | 147 +++++++++++++++------------- 1 file changed, 78 insertions(+), 69 deletions(-) diff --git a/tests/xua_unit_tests/src/test_hid.c b/tests/xua_unit_tests/src/test_hid.c index aadf02f9..05c015fa 100644 --- a/tests/xua_unit_tests/src/test_hid.c +++ b/tests/xua_unit_tests/src/test_hid.c @@ -6,6 +6,19 @@ #include "xua_unit_tests.h" #include "xua_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 MAX_VALID_BIT ( 7 ) +#define MAX_VALID_BYTE ( 2 ) + +#define MIN_VALID_BIT ( 0 ) +#define MIN_VALID_BYTE ( 0 ) + +#define SPACEBAR_KEY_CODE ( 0x2C ) + static unsigned construct_usage_header( unsigned size ) { unsigned header = 0x00; @@ -35,9 +48,9 @@ void test_prepared_hidGetReportDescriptor( void ) // Configurable and non-configurable item tests void test_configurable_item_hidSetReportItem( void ) { - const unsigned bit = 0; - const unsigned byte = 0; - const unsigned char data[ 1 ] = { 0x2C }; // Spacebar keycode + const unsigned bit = MIN_VALID_BIT; + const unsigned byte = MIN_VALID_BYTE; + const unsigned char data[ 1 ] = { SPACEBAR_KEY_CODE }; const unsigned char header = construct_usage_header( sizeof data / sizeof( unsigned char )); unsigned retVal = hidSetReportItem( byte, bit, header, data ); @@ -46,9 +59,9 @@ void test_configurable_item_hidSetReportItem( void ) void test_nonconfigurable_item_hidSetReportItem( void ) { - const unsigned bit = 7; // Reserved bit - const unsigned byte = 0; - const unsigned char data[ 1 ] = { 0x2C }; // Spacebar keycode + const unsigned bit = 7; // This bit and byte combination should not appear in the + const unsigned byte = 0; // hidConfigurableItems list in hid_report_descriptors.c. + const unsigned char data[ 1 ] = { SPACEBAR_KEY_CODE }; const unsigned char header = construct_usage_header( sizeof data / sizeof( unsigned char )); unsigned retVal = hidSetReportItem( byte, bit, header, data ); @@ -58,8 +71,8 @@ void test_nonconfigurable_item_hidSetReportItem( void ) // Bit range tests void test_max_bit_hidSetReportItem( void ) { - const unsigned bit = 7; - const unsigned byte = 1; // Only byte 1 has bit 7 not reserved + const unsigned bit = MAX_VALID_BIT; // Only byte 1 has bit 7 not reserved, See the + const unsigned byte = 1; // hidConfigurableItems list in hid_report_descriptors.c. const unsigned char header = construct_usage_header( 0 ); unsigned retVal = hidSetReportItem( byte, bit, header, NULL ); @@ -68,8 +81,8 @@ void test_max_bit_hidSetReportItem( void ) void test_min_bit_hidSetReportItem( void ) { - const unsigned bit = 0; - const unsigned byte = 0; + const unsigned bit = MIN_VALID_BIT; + const unsigned byte = MIN_VALID_BYTE; const unsigned char header = construct_usage_header( 0 ); unsigned retVal = hidSetReportItem( byte, bit, header, NULL ); @@ -78,8 +91,8 @@ void test_min_bit_hidSetReportItem( void ) void test_overflow_bit_hidSetReportItem( void ) { - const unsigned bit = 8; - const unsigned byte = 0; + const unsigned bit = MAX_VALID_BIT + 1; + const unsigned byte = MIN_VALID_BYTE; const unsigned char header = construct_usage_header( 0 ); unsigned retVal = hidSetReportItem( byte, bit, header, NULL ); @@ -88,8 +101,8 @@ void test_overflow_bit_hidSetReportItem( void ) void test_underflow_bit_hidSetReportItem( void ) { - const int bit = -1; - const unsigned byte = 0; + const int bit = MIN_VALID_BIT - 1; + const unsigned byte = MIN_VALID_BYTE; const unsigned char header = construct_usage_header( 0 ); unsigned retVal = hidSetReportItem( byte, ( unsigned ) bit, header, NULL ); @@ -99,8 +112,8 @@ void test_underflow_bit_hidSetReportItem( void ) // Byte range tests void test_max_byte_hidSetReportItem( void ) { - const unsigned bit = 0; - const unsigned byte = 2; + const unsigned bit = MIN_VALID_BIT; + const unsigned byte = MAX_VALID_BYTE; const unsigned char header = construct_usage_header( 0 ); unsigned retVal = hidSetReportItem( byte, bit, header, NULL ); @@ -109,8 +122,8 @@ void test_max_byte_hidSetReportItem( void ) void test_min_byte_hidSetReportItem( void ) { - const unsigned bit = 0; - const unsigned byte = 0; + const unsigned bit = MIN_VALID_BIT; + const unsigned byte = MIN_VALID_BYTE; const unsigned char header = construct_usage_header( 0 ); unsigned retVal = hidSetReportItem( byte, bit, header, NULL ); @@ -119,8 +132,8 @@ void test_min_byte_hidSetReportItem( void ) void test_overflow_byte_hidSetReportItem( void ) { - const unsigned bit = 0; - const unsigned byte = 4; + const unsigned bit = MIN_VALID_BIT; + const unsigned byte = MAX_VALID_BYTE + 1; const unsigned char header = construct_usage_header( 0 ); unsigned retVal = hidSetReportItem( byte, bit, header, NULL ); @@ -129,8 +142,8 @@ void test_overflow_byte_hidSetReportItem( void ) void test_underflow_byte_hidSetReportItem( void ) { - const unsigned bit = 0; - const int byte = -1; + const unsigned bit = MIN_VALID_BIT; + const int byte = MIN_VALID_BYTE - 1; const unsigned char header = construct_usage_header( 0 ); unsigned retVal = hidSetReportItem( ( unsigned ) byte, bit, header, NULL ); @@ -140,8 +153,8 @@ void test_underflow_byte_hidSetReportItem( void ) // Size range tests void test_max_size_hidSetReportItem( void ) { - const unsigned bit = 0; - const unsigned byte = 0; + 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 ); @@ -151,8 +164,8 @@ void test_max_size_hidSetReportItem( void ) void test_min_size_hidSetReportItem( void ) { - const unsigned bit = 0; - const unsigned byte = 0; + const unsigned bit = MIN_VALID_BIT; + const unsigned byte = MIN_VALID_BYTE; const unsigned char header = construct_usage_header( 0x00 ); unsigned retVal = hidSetReportItem( byte, bit, header, NULL ); @@ -161,8 +174,8 @@ void test_min_size_hidSetReportItem( void ) void test_unsupported_size_hidSetReportItem( void ) { - const unsigned bit = 0; - const unsigned byte = 0; + const unsigned bit = MIN_VALID_BIT; + const unsigned byte = MIN_VALID_BYTE; const unsigned char header = construct_usage_header( 0x03 ); unsigned retVal = hidSetReportItem( byte, bit, header, NULL ); @@ -172,8 +185,8 @@ void test_unsupported_size_hidSetReportItem( void ) // Header tag and type tests void test_bad_tag_hidSetReportItem( void ) { - const unsigned bit = 0; - const unsigned byte = 0; + const unsigned bit = MIN_VALID_BIT; + const unsigned byte = MIN_VALID_BYTE; const unsigned char good_header = construct_usage_header( 0x00 ); for( unsigned tag = 0x01; tag <= 0x0F; ++tag ) { @@ -183,37 +196,34 @@ void test_bad_tag_hidSetReportItem( void ) } } -void test_local_type_hidSetReportItem( void ) -{ - const unsigned bit = 0; - const unsigned byte = 0; - const unsigned char header = ( construct_usage_header( 0x00 ) & - ~HID_REPORT_ITEM_HDR_TYPE_MASK ) | - (( 0x02 << HID_REPORT_ITEM_HDR_TYPE_SHIFT ) & HID_REPORT_ITEM_HDR_TYPE_MASK ); - - unsigned retVal = hidSetReportItem( byte, bit, header, NULL ); - TEST_ASSERT_EQUAL_UINT( HID_STATUS_GOOD, retVal ); -} - void test_global_type_hidSetReportItem( void ) { - const unsigned bit = 0; - const unsigned byte = 0; - const unsigned char header = ( construct_usage_header( 0x00 ) & - ~HID_REPORT_ITEM_HDR_TYPE_MASK ) | - (( 0x01 << HID_REPORT_ITEM_HDR_TYPE_SHIFT ) & HID_REPORT_ITEM_HDR_TYPE_MASK ); + 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 ); unsigned retVal = hidSetReportItem( byte, bit, 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 ); + + unsigned retVal = hidSetReportItem( byte, bit, header, NULL ); + TEST_ASSERT_EQUAL_UINT( HID_STATUS_GOOD, retVal ); +} + void test_main_type_hidSetReportItem( void ) { - const unsigned bit = 0; - const unsigned byte = 0; - const unsigned char header = ( construct_usage_header( 0x00 ) & - ~HID_REPORT_ITEM_HDR_TYPE_MASK ) | - (( 0x00 << HID_REPORT_ITEM_HDR_TYPE_SHIFT ) & HID_REPORT_ITEM_HDR_TYPE_MASK ); + 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 ); unsigned retVal = hidSetReportItem( byte, bit, header, NULL ); TEST_ASSERT_EQUAL_UINT( HID_STATUS_BAD_HEADER, retVal ); @@ -221,11 +231,10 @@ void test_main_type_hidSetReportItem( void ) void test_reserved_type_hidSetReportItem( void ) { - const unsigned bit = 0; - const unsigned byte = 0; - const unsigned char header = ( construct_usage_header( 0x00 ) & - ~HID_REPORT_ITEM_HDR_TYPE_MASK ) | - (( 0x03 << HID_REPORT_ITEM_HDR_TYPE_SHIFT ) & HID_REPORT_ITEM_HDR_TYPE_MASK ); + 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 ); unsigned retVal = hidSetReportItem( byte, bit, header, NULL ); TEST_ASSERT_EQUAL_UINT( HID_STATUS_BAD_HEADER, retVal ); @@ -234,9 +243,9 @@ void test_reserved_type_hidSetReportItem( void ) // Combined function tests void test_initial_modification_without_subsequent_preparation( void ) { - const unsigned bit = 0; - const unsigned byte = 0; - const unsigned char data[ 1 ] = { 0x2C }; // Spacebar keycode + const unsigned bit = MIN_VALID_BIT; + const unsigned byte = MIN_VALID_BYTE; + const unsigned char data[ 1 ] = { SPACEBAR_KEY_CODE }; const unsigned char header = construct_usage_header( sizeof data / sizeof( unsigned char )); unsigned retVal = hidSetReportItem( byte, bit, header, data ); @@ -248,9 +257,9 @@ void test_initial_modification_without_subsequent_preparation( void ) void test_initial_modification_with_subsequent_preparation( void ) { - const unsigned bit = 0; - const unsigned byte = 0; - const unsigned char data[ 1 ] = { 0x2C }; // Spacebar keycode + const unsigned bit = MIN_VALID_BIT; + const unsigned byte = MIN_VALID_BYTE; + const unsigned char data[ 1 ] = { SPACEBAR_KEY_CODE }; const unsigned char header = construct_usage_header( sizeof data / sizeof( unsigned char )); unsigned retVal = hidSetReportItem( byte, bit, header, data ); @@ -267,9 +276,9 @@ void test_modification_without_subsequent_preparation( void ) unsigned char* reportDescPtr = hidGetReportDescriptor(); TEST_ASSERT_NOT_NULL( reportDescPtr ); - const unsigned bit = 0; - const unsigned byte = 0; - const unsigned char data[ 1 ] = { 0x2C }; // Spacebar keycode + const unsigned bit = MIN_VALID_BIT; + const unsigned byte = MIN_VALID_BYTE; + const unsigned char data[ 1 ] = { SPACEBAR_KEY_CODE }; const unsigned char header = construct_usage_header( sizeof data / sizeof( unsigned char )); unsigned retVal = hidSetReportItem( byte, bit, header, data ); @@ -285,9 +294,9 @@ void test_modification_with_subsequent_preparation( void ) unsigned char* reportDescPtr = hidGetReportDescriptor(); TEST_ASSERT_NOT_NULL( reportDescPtr ); - const unsigned bit = 0; - const unsigned byte = 0; - const unsigned char data[ 1 ] = { 0x2C }; // Spacebar keycode + const unsigned bit = MIN_VALID_BIT; + const unsigned byte = MIN_VALID_BYTE; + const unsigned char data[ 1 ] = { SPACEBAR_KEY_CODE }; const unsigned char header = construct_usage_header( sizeof data / sizeof( unsigned char )); unsigned retVal = hidSetReportItem( byte, bit, header, data ); From d1650afd37e430be9c4b983b7b755dfcc3603133 Mon Sep 17 00:00:00 2001 From: mbanth Date: Tue, 25 May 2021 16:00:32 +0100 Subject: [PATCH 26/55] Avoid unnecessary preparation --- lib_xua/src/hid/hid_report_descriptor.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/lib_xua/src/hid/hid_report_descriptor.c b/lib_xua/src/hid/hid_report_descriptor.c index 2bddc6cc..26d03e2e 100644 --- a/lib_xua/src/hid/hid_report_descriptor.c +++ b/lib_xua/src/hid/hid_report_descriptor.c @@ -267,12 +267,14 @@ unsigned char* hidGetReportDescriptor( void ) void hidPrepareReportDescriptor( void ) { - unsigned char* ptr = hidReportDescriptor; - for( unsigned idx = 0; idx < sizeof hidReportDescriptorItems / sizeof( USB_HID_Short_Item_t ); ++idx ) { - ptr = hidTranslateItem( hidReportDescriptorItems[ idx ], ptr ); - } + if( !hidReportDescriptorPrepared ) { + unsigned char* ptr = hidReportDescriptor; + for( unsigned idx = 0; idx < sizeof hidReportDescriptorItems / sizeof( USB_HID_Short_Item_t ); ++idx ) { + ptr = hidTranslateItem( hidReportDescriptorItems[ idx ], ptr ); + } - hidReportDescriptorPrepared = 1; + hidReportDescriptorPrepared = 1; + } } unsigned hidSetReportItem( const unsigned byte, const unsigned bit, const unsigned char header, const unsigned char data[] ) From fcee74d9127c1da2690acaf3a4659e75d65d8866 Mon Sep 17 00:00:00 2001 From: mbanth Date: Tue, 25 May 2021 16:51:54 +0100 Subject: [PATCH 27/55] Add Report descriptor length function. Change the internal Translate function to return the length of each item added to the raw buffer. Fix some out-of-date comments. --- lib_xua/src/hid/hid_report_descriptor.c | 29 ++++++++++++++------- lib_xua/src/hid/xua_hid_report_descriptor.h | 15 +++++++++-- 2 files changed, 33 insertions(+), 11 deletions(-) diff --git a/lib_xua/src/hid/hid_report_descriptor.c b/lib_xua/src/hid/hid_report_descriptor.c index 26d03e2e..3d6e0e6f 100644 --- a/lib_xua/src/hid/hid_report_descriptor.c +++ b/lib_xua/src/hid/hid_report_descriptor.c @@ -154,6 +154,7 @@ static const USB_HID_Short_Item_t* const hidReportDescriptorItems[] = { ( 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; /** @@ -216,12 +217,14 @@ static unsigned hidGetItemType( const unsigned char header ); * * Parameters: * - * @param[in] inPtr A pointer to a \c USB_HID_Short_Item - * @param[in,out] outPtr A pointer to the next available space in the raw byte buffer + * @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 updated \a outPtr + * @return The number of bytes placed in the raw byte buffer */ -static unsigned char* hidTranslateItem( const USB_HID_Short_Item_t* inPtr, unsigned char* outPtr ); +static size_t hidTranslateItem( const USB_HID_Short_Item_t* inPtr, unsigned char** outPtrPtr ); static unsigned hidGetItemBitLocation( const unsigned char location ) @@ -265,12 +268,18 @@ unsigned char* hidGetReportDescriptor( void ) return retVal; } +size_t hidGetReportDescriptorLength( void ) +{ + return ( hidReportDescriptorPrepared ) ? hidReportDescriptorLength : 0; +} + void hidPrepareReportDescriptor( void ) { if( !hidReportDescriptorPrepared ) { + hidReportDescriptorLength = 0; unsigned char* ptr = hidReportDescriptor; for( unsigned idx = 0; idx < sizeof hidReportDescriptorItems / sizeof( USB_HID_Short_Item_t ); ++idx ) { - ptr = hidTranslateItem( hidReportDescriptorItems[ idx ], ptr ); + hidReportDescriptorLength += hidTranslateItem( hidReportDescriptorItems[ idx ], &ptr ); } hidReportDescriptorPrepared = 1; @@ -311,14 +320,16 @@ unsigned hidSetReportItem( const unsigned byte, const unsigned bit, const unsign return retVal; } -static unsigned char* hidTranslateItem( const USB_HID_Short_Item_t* inPtr, unsigned char* outPtr ) +static size_t hidTranslateItem( const USB_HID_Short_Item_t* inPtr, unsigned char** outPtrPtr ) { - *outPtr++ = inPtr->header; + size_t count = 0; + *(*outPtrPtr)++ = inPtr->header; unsigned dataLength = hidGetItemSize( inPtr->header ); for( unsigned idx = 0; idx < dataLength; ++idx ) { - *outPtr++ = inPtr->data[ idx ]; + *(*outPtrPtr)++ = inPtr->data[ idx ]; + ++count; } - return outPtr; + return count; } diff --git a/lib_xua/src/hid/xua_hid_report_descriptor.h b/lib_xua/src/hid/xua_hid_report_descriptor.h index 811eb230..fb812f25 100644 --- a/lib_xua/src/hid/xua_hid_report_descriptor.h +++ b/lib_xua/src/hid/xua_hid_report_descriptor.h @@ -56,13 +56,24 @@ typedef struct * @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 initialised, - * i.e., no one has called \c hidInitReportDescriptor(). + * It returns NULL if the Report descriptor has not been prepared, + * i.e., no one has called \c hidPrepareReportDescriptor(). * * @return A pointer to a list of unsigned char containing the Report descriptor */ unsigned char* hidGetReportDescriptor( void ); +/** + * @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 Prepare the USB HID Report descriptor * From b81d096a5a5428cece300c4d35edd67a3dda27d4 Mon Sep 17 00:00:00 2001 From: mbanth Date: Wed, 26 May 2021 12:17:38 +0100 Subject: [PATCH 28/55] Add XS1-specific XUD symbol to allow building with the current develop branch of lib_xud --- tests/xua_unit_tests/wscript | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/tests/xua_unit_tests/wscript b/tests/xua_unit_tests/wscript index e5cace3b..0f162c19 100644 --- a/tests/xua_unit_tests/wscript +++ b/tests/xua_unit_tests/wscript @@ -218,7 +218,14 @@ def build(bld): '../../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'] + 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'] From 7b433a40fcea1c6ada70ea5d3fd39b9e21d01397 Mon Sep 17 00:00:00 2001 From: mbanth Date: Wed, 26 May 2021 12:18:11 +0100 Subject: [PATCH 29/55] Assign an unused clock block to MCLK --- tests/xua_unit_tests/src/xua_unit_test_helper.xc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/xua_unit_tests/src/xua_unit_test_helper.xc b/tests/xua_unit_tests/src/xua_unit_test_helper.xc index d4c2911c..ccb35260 100644 --- a/tests/xua_unit_tests/src/xua_unit_test_helper.xc +++ b/tests/xua_unit_tests/src/xua_unit_test_helper.xc @@ -13,7 +13,7 @@ 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 */ +clock clk_audio_mclk = on tile[0]: XS1_CLKBLK_3; /* Master clock */ // Supply missing but unused function void AudioHwConfig(unsigned samFreq, unsigned mClk, unsigned dsdMode, unsigned sampRes_DAC, unsigned sampRes_ADC) From 33fcac9c47fdb2c35fbe85aa7cbb7a6ca8f97a79 Mon Sep 17 00:00:00 2001 From: mbanth Date: Wed, 26 May 2021 13:21:58 +0100 Subject: [PATCH 30/55] Add pytest and pytest-xdist to the requirements, needed for unit tests --- python/setup.py | 2 ++ requirements.txt | 2 ++ 2 files changed, 4 insertions(+) diff --git a/python/setup.py b/python/setup.py index 98d3d6a5..d3a7c32c 100644 --- a/python/setup.py +++ b/python/setup.py @@ -14,6 +14,8 @@ setuptools.setup( packages=setuptools.find_packages(), install_requires=[ 'flake8~=3.8', + 'pytest~=6.0', + 'pytest-xdist~=1.34', ], dependency_links=[ ], diff --git a/requirements.txt b/requirements.txt index 99e7dd7b..a9ebc4e9 100644 --- a/requirements.txt +++ b/requirements.txt @@ -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 # From 6adc94642a63baa8ac6c00253c1fa22f774f7099 Mon Sep 17 00:00:00 2001 From: mbanth Date: Wed, 26 May 2021 14:07:06 +0100 Subject: [PATCH 31/55] Attempt to correct the copyright date range --- tests/xua_unit_tests/src/xua_conf.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/xua_unit_tests/src/xua_conf.h b/tests/xua_unit_tests/src/xua_conf.h index 77b3656a..b5a0dbf3 100644 --- a/tests/xua_unit_tests/src/xua_conf.h +++ b/tests/xua_unit_tests/src/xua_conf.h @@ -1,4 +1,4 @@ -// Copyright 2021 XMOS LIMITED. +// 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 From a9e97b33b9b81790e5b969f75bda3dddfd22e139 Mon Sep 17 00:00:00 2001 From: mbanth Date: Wed, 26 May 2021 16:39:03 +0100 Subject: [PATCH 32/55] Add constant offset to the field in the HID descriptor that provides the length of the HID Report descriptor --- lib_xua/src/core/endpoint0/xua_ep0_descriptors.h | 4 ++++ lib_xua/src/hid/xua_hid_descriptor.h | 2 ++ 2 files changed, 6 insertions(+) diff --git a/lib_xua/src/core/endpoint0/xua_ep0_descriptors.h b/lib_xua/src/core/endpoint0/xua_ep0_descriptors.h index 47991bf9..5c154b08 100644 --- a/lib_xua/src/core/endpoint0/xua_ep0_descriptors.h +++ b/lib_xua/src/core/endpoint0/xua_ep0_descriptors.h @@ -2373,6 +2373,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) diff --git a/lib_xua/src/hid/xua_hid_descriptor.h b/lib_xua/src/hid/xua_hid_descriptor.h index 4fed07a2..4dd44007 100644 --- a/lib_xua/src/hid/xua_hid_descriptor.h +++ b/lib_xua/src/hid/xua_hid_descriptor.h @@ -11,6 +11,8 @@ #ifndef _HID_DESCRIPTOR_ #define _HID_DESCRIPTOR_ +#define HID_DESCRIPTOR_LENGTH_FIELD_OFFSET ( 7 ) + /* USB HID Descriptor (section 6.2.1) */ typedef struct { From dd7a8f423eb8678a94f45dcb82d0dd796bb5cccd Mon Sep 17 00:00:00 2001 From: mbanth Date: Thu, 27 May 2021 11:36:36 +0100 Subject: [PATCH 33/55] Move HID Report descriptor to application --- lib_xua/src/hid/hid_report_descriptor.c | 145 +------------------- lib_xua/src/hid/xua_hid_report_descriptor.h | 6 + 2 files changed, 7 insertions(+), 144 deletions(-) diff --git a/lib_xua/src/hid/hid_report_descriptor.c b/lib_xua/src/hid/hid_report_descriptor.c index 3d6e0e6f..d4d1fb28 100644 --- a/lib_xua/src/hid/hid_report_descriptor.c +++ b/lib_xua/src/hid/hid_report_descriptor.c @@ -4,150 +4,7 @@ #include #include #include "xua_hid_report_descriptor.h" - -#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 ) - -#if 0 -/* Existing static report descriptor kept for reference */ -unsigned char hidReportDescriptor[] = -{ - 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, 0x07, /* Usage Page (Key Codes) */ - 0x19, 0x17, /* Usage Minimum (Keyboard t or T) */ - 0x29, 0x17, /* Usage Maximum (Keyboard t or T) */ - 0x81, 0x02, /* Input (Data, Var, Abs, No Wrap, Lin, Pref, No Nul) */ - 0x05, 0x0C, /* Usage Page (Consumer) */ - 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 - -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 hidReportCount4 = { .header = 0x95, .data = { 0x04, 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 }; -static const USB_HID_Short_Item_t hidUsagePageKeyboard = { .header = 0x05, .data = { 0x07, 0x00 }, .location = 0x00 }; -static const USB_HID_Short_Item_t hidUsagePageTelephony = { .header = 0x05, .data = { 0x0B, 0x00 }, .location = 0x00 }; - -static USB_HID_Short_Item_t hidUsageByte0Bit3 = { .header = 0x09, .data = { 0x73, 0x00 }, .location = 0x30 }; // F24 -static USB_HID_Short_Item_t hidUsageByte0Bit2 = { .header = 0x09, .data = { 0x72, 0x00 }, .location = 0x20 }; // F23 -static USB_HID_Short_Item_t hidUsageByte0Bit0 = { .header = 0x09, .data = { 0x17, 0x00 }, .location = 0x00 }; // 't' - -static USB_HID_Short_Item_t hidUsageByte1Bit7 = { .header = 0x09, .data = { 0xEA, 0x00 }, .location = 0x71 }; // Vol- -static USB_HID_Short_Item_t hidUsageByte1Bit6 = { .header = 0x09, .data = { 0xE9, 0x00 }, .location = 0x61 }; // Vol+ -static USB_HID_Short_Item_t hidUsageByte1Bit4 = { .header = 0x09, .data = { 0x00, 0x00 }, .location = 0x41 }; // Voice Command -static USB_HID_Short_Item_t hidUsageByte1Bit2 = { .header = 0x09, .data = { 0xE2, 0x00 }, .location = 0x21 }; // Mute -static USB_HID_Short_Item_t hidUsageByte1Bit1 = { .header = 0x09, .data = { 0x00, 0x00 }, .location = 0x11 }; // AC Search -static USB_HID_Short_Item_t hidUsageByte1Bit0 = { .header = 0x09, .data = { 0x00, 0x00 }, .location = 0x01 }; // AC Stop - -static USB_HID_Short_Item_t hidUsageByte2Bit1 = { .header = 0x09, .data = { 0x2F, 0x00 }, .location = 0x12 }; // Phone Mute -static USB_HID_Short_Item_t hidUsageByte2Bit0 = { .header = 0x09, .data = { 0x20, 0x00 }, .location = 0x02 }; // Hook Switch - -static USB_HID_Short_Item_t* const hidConfigurableItems[] = { - &hidUsageByte0Bit0, - &hidUsageByte0Bit2, - &hidUsageByte0Bit3, - &hidUsageByte1Bit0, - &hidUsageByte1Bit1, - &hidUsageByte1Bit2, - &hidUsageByte1Bit4, - &hidUsageByte1Bit6, - &hidUsageByte1Bit7, - &hidUsageByte2Bit0, - &hidUsageByte2Bit1 -}; - -static const USB_HID_Short_Item_t* const hidReportDescriptorItems[] = { - &hidUsagePageConsumer, - &hidUsageConsumerControl, - &hidCollectionApplication, - &hidReportSize1, - &hidLogicalMinimum0, - &hidCollectionLogical, // Byte 0 - &hidUsagePageKeyboard, - &hidLogicalMaximum1, - &hidReportCount1, - &hidUsageByte0Bit0, - &hidInputDataVar, - &hidLogicalMaximum0, - &hidInputConstArray, - &hidLogicalMaximum1, - &hidUsageByte0Bit2, - &hidInputDataVar, - &hidUsageByte0Bit3, - &hidInputDataVar, - &hidLogicalMaximum0, - &hidReportCount4, - &hidInputConstArray, - &hidCollectionEnd, - &hidCollectionLogical, // Byte 1 - &hidUsagePageConsumer, - &hidLogicalMaximum1, - &hidReportCount1, - &hidUsageByte1Bit0, - &hidInputDataVar, - &hidUsageByte1Bit1, - &hidInputDataVar, - &hidUsageByte1Bit2, - &hidInputDataVar, - &hidLogicalMaximum0, - &hidInputConstArray, - &hidLogicalMaximum1, - &hidUsageByte1Bit4, - &hidInputDataVar, - &hidLogicalMaximum0, - &hidInputConstArray, - &hidLogicalMaximum1, - &hidUsageByte1Bit6, - &hidInputDataVar, - &hidUsageByte1Bit7, - &hidInputDataVar, - &hidCollectionEnd, - &hidCollectionLogical, // Byte 2 - &hidUsagePageTelephony, - &hidUsageByte2Bit0, - &hidInputDataVar, - &hidUsageByte2Bit1, - &hidLogicalMaximum0, - &hidReportCount6, - &hidInputConstArray, - &hidCollectionEnd, - &hidCollectionEnd -}; +#include "hid_report_descriptor.h" #define HID_REPORT_ITEM_LOCATION_SIZE ( 1 ) #define HID_REPORT_DESCRIPTOR_MAX_LENGTH ( sizeof hidReportDescriptorItems / sizeof ( USB_HID_Short_Item_t ) * \ diff --git a/lib_xua/src/hid/xua_hid_report_descriptor.h b/lib_xua/src/hid/xua_hid_report_descriptor.h index fb812f25..7e1c41ac 100644 --- a/lib_xua/src/hid/xua_hid_report_descriptor.h +++ b/lib_xua/src/hid/xua_hid_report_descriptor.h @@ -20,6 +20,12 @@ #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 ) From 3c129ab5216c04ad56f20eddd44c9c64a8a1c2cd Mon Sep 17 00:00:00 2001 From: mbanth Date: Thu, 27 May 2021 11:37:25 +0100 Subject: [PATCH 34/55] Update unit tests to align with Report descriptor defined in application --- .../src/hid_report_descriptor.h | 106 ++++++++++++++++++ tests/xua_unit_tests/src/test_hid.c | 29 ++--- 2 files changed, 118 insertions(+), 17 deletions(-) create mode 100644 tests/xua_unit_tests/src/hid_report_descriptor.h diff --git a/tests/xua_unit_tests/src/hid_report_descriptor.h b/tests/xua_unit_tests/src/hid_report_descriptor.h new file mode 100644 index 00000000..2037dfda --- /dev/null +++ b/tests/xua_unit_tests/src/hid_report_descriptor.h @@ -0,0 +1,106 @@ +// 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 ) + +#if 0 +/* Existing static report descriptor kept for reference */ +unsigned char hidReportDescriptor[] = +{ + 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, 0x07, /* Usage Page (Key Codes) */ + 0x19, 0x17, /* Usage Minimum (Keyboard t or T) */ + 0x29, 0x17, /* Usage Maximum (Keyboard t or T) */ + 0x81, 0x02, /* Input (Data, Var, Abs, No Wrap, Lin, Pref, No Nul) */ + 0x05, 0x0C, /* Usage Page (Consumer) */ + 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 + +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 }; + +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+ + +static USB_HID_Short_Item_t* const hidConfigurableItems[] = { + &hidUsageByte0Bit0, + &hidUsageByte1Bit0, + &hidUsageByte1Bit7 +}; + +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 +}; + +#endif // __hid_report_descriptor_h__ diff --git a/tests/xua_unit_tests/src/test_hid.c b/tests/xua_unit_tests/src/test_hid.c index 05c015fa..7dee6fcf 100644 --- a/tests/xua_unit_tests/src/test_hid.c +++ b/tests/xua_unit_tests/src/test_hid.c @@ -5,19 +5,14 @@ #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 MAX_VALID_BIT ( 7 ) -#define MAX_VALID_BYTE ( 2 ) - -#define MIN_VALID_BIT ( 0 ) -#define MIN_VALID_BYTE ( 0 ) - -#define SPACEBAR_KEY_CODE ( 0x2C ) +#define LOUDNESS_CONTROL ( 0xE7 ) static unsigned construct_usage_header( unsigned size ) { @@ -50,7 +45,7 @@ void test_configurable_item_hidSetReportItem( void ) { const unsigned bit = MIN_VALID_BIT; const unsigned byte = MIN_VALID_BYTE; - const unsigned char data[ 1 ] = { SPACEBAR_KEY_CODE }; + const unsigned char data[ 1 ] = { LOUDNESS_CONTROL }; const unsigned char header = construct_usage_header( sizeof data / sizeof( unsigned char )); unsigned retVal = hidSetReportItem( byte, bit, header, data ); @@ -59,9 +54,9 @@ void test_configurable_item_hidSetReportItem( void ) void test_nonconfigurable_item_hidSetReportItem( void ) { - const unsigned bit = 7; // This bit and byte combination should not appear in the - const unsigned byte = 0; // hidConfigurableItems list in hid_report_descriptors.c. - const unsigned char data[ 1 ] = { SPACEBAR_KEY_CODE }; + 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 )); unsigned retVal = hidSetReportItem( byte, bit, header, data ); @@ -71,8 +66,8 @@ void test_nonconfigurable_item_hidSetReportItem( void ) // 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 = 1; // hidConfigurableItems list in hid_report_descriptors.c. + 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 ); unsigned retVal = hidSetReportItem( byte, bit, header, NULL ); @@ -245,7 +240,7 @@ 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 ] = { SPACEBAR_KEY_CODE }; + const unsigned char data[ 1 ] = { LOUDNESS_CONTROL }; const unsigned char header = construct_usage_header( sizeof data / sizeof( unsigned char )); unsigned retVal = hidSetReportItem( byte, bit, header, data ); @@ -259,7 +254,7 @@ 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 ] = { SPACEBAR_KEY_CODE }; + const unsigned char data[ 1 ] = { LOUDNESS_CONTROL }; const unsigned char header = construct_usage_header( sizeof data / sizeof( unsigned char )); unsigned retVal = hidSetReportItem( byte, bit, header, data ); @@ -278,7 +273,7 @@ void test_modification_without_subsequent_preparation( void ) const unsigned bit = MIN_VALID_BIT; const unsigned byte = MIN_VALID_BYTE; - const unsigned char data[ 1 ] = { SPACEBAR_KEY_CODE }; + const unsigned char data[ 1 ] = { LOUDNESS_CONTROL }; const unsigned char header = construct_usage_header( sizeof data / sizeof( unsigned char )); unsigned retVal = hidSetReportItem( byte, bit, header, data ); @@ -296,7 +291,7 @@ void test_modification_with_subsequent_preparation( void ) const unsigned bit = MIN_VALID_BIT; const unsigned byte = MIN_VALID_BYTE; - const unsigned char data[ 1 ] = { SPACEBAR_KEY_CODE }; + const unsigned char data[ 1 ] = { LOUDNESS_CONTROL }; const unsigned char header = construct_usage_header( sizeof data / sizeof( unsigned char )); unsigned retVal = hidSetReportItem( byte, bit, header, data ); From 8a9d8cdd3ec2722feb81388b971adde8449d41d2 Mon Sep 17 00:00:00 2001 From: mbanth Date: Thu, 27 May 2021 11:54:31 +0100 Subject: [PATCH 35/55] Add explicit reset --- lib_xua/src/hid/hid_report_descriptor.c | 50 ++++++++++++--------- lib_xua/src/hid/xua_hid_report_descriptor.h | 15 ++++++- 2 files changed, 42 insertions(+), 23 deletions(-) diff --git a/lib_xua/src/hid/hid_report_descriptor.c b/lib_xua/src/hid/hid_report_descriptor.c index d4d1fb28..14cfd0a4 100644 --- a/lib_xua/src/hid/hid_report_descriptor.c +++ b/lib_xua/src/hid/hid_report_descriptor.c @@ -143,33 +143,41 @@ void hidPrepareReportDescriptor( void ) } } +void hidResetReportDescriptor( void ) +{ + hidReportDescriptorPrepared = 0; +} + unsigned hidSetReportItem( const unsigned byte, const unsigned bit, const unsigned char header, const unsigned char data[] ) { - unsigned retVal = HID_STATUS_BAD_LOCATION; - unsigned bSize = hidGetItemSize( header ); - unsigned bTag = hidGetItemTag ( header ); - unsigned bType = hidGetItemType( header ); + unsigned retVal = HID_STATUS_IN_USE; - 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 < sizeof hidConfigurableItems / sizeof( USB_HID_Short_Item_t ); ++itemIdx ) { - USB_HID_Short_Item_t item = *hidConfigurableItems[ itemIdx ]; - unsigned bBit = hidGetItemBitLocation( item.location ); - unsigned bByte = hidGetItemByteLocation( item.location ); + if( !hidReportDescriptorPrepared ) { + retVal = HID_STATUS_BAD_LOCATION; + unsigned bSize = hidGetItemSize( header ); + unsigned bTag = hidGetItemTag ( header ); + unsigned bType = hidGetItemType( header ); - if(( bit == bBit ) && ( byte == bByte )) { - item.header = 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 < sizeof hidConfigurableItems / sizeof( USB_HID_Short_Item_t ); ++itemIdx ) { + USB_HID_Short_Item_t item = *hidConfigurableItems[ itemIdx ]; + unsigned bBit = hidGetItemBitLocation( item.location ); + unsigned bByte = hidGetItemByteLocation( item.location ); - for( unsigned dataIdx = 0; dataIdx < bSize; ++dataIdx ) { - item.data[ dataIdx ] = data[ dataIdx ]; + if(( bit == bBit ) && ( byte == bByte )) { + item.header = header; + + for( unsigned dataIdx = 0; dataIdx < bSize; ++dataIdx ) { + item.data[ dataIdx ] = data[ dataIdx ]; + } + + *hidConfigurableItems[ itemIdx ] = item; + retVal = HID_STATUS_GOOD; } - - *hidConfigurableItems[ itemIdx ] = item; - hidReportDescriptorPrepared = 0; - retVal = HID_STATUS_GOOD; } } } diff --git a/lib_xua/src/hid/xua_hid_report_descriptor.h b/lib_xua/src/hid/xua_hid_report_descriptor.h index 7e1c41ac..91d01e41 100644 --- a/lib_xua/src/hid/xua_hid_report_descriptor.h +++ b/lib_xua/src/hid/xua_hid_report_descriptor.h @@ -4,7 +4,8 @@ /** * @brief Human Interface Device (HID) Report descriptor * - * This file defines the structure and default content of the HID Report descriptor. + * This file defines the structure of the HID Report descriptor and decalres + * functions for manipulating it. * Document section numbers refer to the HID Device Class Definition, version 1.11. */ @@ -34,6 +35,7 @@ #define HID_STATUS_GOOD ( 0 ) #define HID_STATUS_BAD_HEADER ( 1 ) #define HID_STATUS_BAD_LOCATION ( 2 ) +#define HID_STATUS_IN_USE ( 3 ) /** * @brief USB HID Report Descriptor. Short Item @@ -84,11 +86,19 @@ size_t hidGetReportDescriptorLength( void ); * @brief Prepare the USB HID Report descriptor * * After preparation, \c hidGetReportDescriptor() returns a list suitablefor 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 * @@ -109,6 +119,7 @@ void hidPrepareReportDescriptor( void ); * 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_IN_USE The Report descriptor is in use */ unsigned hidSetReportItem( const unsigned byte, const unsigned bit, const unsigned char header, const unsigned char data[] ); From 13abe0e9e171e400d759ae1279d5d6170c9ef816 Mon Sep 17 00:00:00 2001 From: mbanth Date: Thu, 27 May 2021 12:26:57 +0100 Subject: [PATCH 36/55] Update unit tests for explicit reset --- tests/xua_unit_tests/src/test_hid.c | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/tests/xua_unit_tests/src/test_hid.c b/tests/xua_unit_tests/src/test_hid.c index 7dee6fcf..d528462f 100644 --- a/tests/xua_unit_tests/src/test_hid.c +++ b/tests/xua_unit_tests/src/test_hid.c @@ -26,6 +26,11 @@ static unsigned construct_usage_header( unsigned size ) return header; } +void setUp( void ) +{ + hidResetReportDescriptor(); +} + // Basic report descriptor tests void test_unprepared_hidGetReportDescriptor( void ) { @@ -40,6 +45,23 @@ void test_prepared_hidGetReportDescriptor( void ) TEST_ASSERT_NOT_NULL( reportDescPtr ); } +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 ); +} + // Configurable and non-configurable item tests void test_configurable_item_hidSetReportItem( void ) { @@ -276,6 +298,7 @@ void test_modification_without_subsequent_preparation( void ) const unsigned char data[ 1 ] = { LOUDNESS_CONTROL }; const unsigned char header = construct_usage_header( sizeof data / sizeof( unsigned char )); + hidResetReportDescriptor(); unsigned retVal = hidSetReportItem( byte, bit, header, data ); TEST_ASSERT_EQUAL_UINT( HID_STATUS_GOOD, retVal ); @@ -294,6 +317,7 @@ void test_modification_with_subsequent_preparation( void ) const unsigned char data[ 1 ] = { LOUDNESS_CONTROL }; const unsigned char header = construct_usage_header( sizeof data / sizeof( unsigned char )); + hidResetReportDescriptor(); unsigned retVal = hidSetReportItem( byte, bit, header, data ); TEST_ASSERT_EQUAL_UINT( HID_STATUS_GOOD, retVal ); From cafdd8c93da83f6f4c0bb987ec9764b112ce7293 Mon Sep 17 00:00:00 2001 From: mbanth Date: Thu, 27 May 2021 16:07:10 +0100 Subject: [PATCH 37/55] Provide a HID Report descriptor definition for legacy tests --- .../hid_report_descriptor.h | 22 +++++++++++++++++++ 1 file changed, 22 insertions(+) create mode 100644 legacy_tests/app_test_i2s_loopback/hid_report_descriptor.h diff --git a/legacy_tests/app_test_i2s_loopback/hid_report_descriptor.h b/legacy_tests/app_test_i2s_loopback/hid_report_descriptor.h new file mode 100644 index 00000000..75a77f06 --- /dev/null +++ b/legacy_tests/app_test_i2s_loopback/hid_report_descriptor.h @@ -0,0 +1,22 @@ +// Copyright 2021 XMOS LIMITED. +// This Software is subject to the terms of the XMOS Public Licence: Version 1. +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 */ +}; From d0b2c7717725b7b86ddc17e6dc4e921f885fa36f Mon Sep 17 00:00:00 2001 From: mbanth Date: Thu, 27 May 2021 16:31:07 +0100 Subject: [PATCH 38/55] Update HID Report descriptor items --- .../hid_report_descriptor.h | 68 +++++++++++++++++++ 1 file changed, 68 insertions(+) diff --git a/legacy_tests/app_test_i2s_loopback/hid_report_descriptor.h b/legacy_tests/app_test_i2s_loopback/hid_report_descriptor.h index 75a77f06..f06ec0a0 100644 --- a/legacy_tests/app_test_i2s_loopback/hid_report_descriptor.h +++ b/legacy_tests/app_test_i2s_loopback/hid_report_descriptor.h @@ -1,5 +1,15 @@ // 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" + +// Copyright 2021 XMOS LIMITED. +// This Software is subject to the terms of the XMOS Public Licence: Version 1. + +#if 0 +/* Existing static report descriptor kept for reference */ unsigned char hidReportDescriptor[] = { 0x05, 0x0c, /* Usage Page (Consumer Device) */ @@ -20,3 +30,61 @@ unsigned char hidReportDescriptor[] = 0x81, 0x01, /* Input (Cnst, Ary, Abs) */ 0xc0 /* End collection */ }; +#endif + +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 }; + +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 + +static USB_HID_Short_Item_t* const hidConfigurableItems[] = { + &hidUsageByte0Bit0, + &hidUsageByte0Bit1, + &hidUsageByte0Bit2, + &hidUsageByte0Bit3, + &hidUsageByte0Bit4, + &hidUsageByte0Bit5 +}; + +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 +}; + +#endif // __hid_report_descriptor_h__ From f2b09522b811ab5bd6ca8b85a3a7563ae412d796 Mon Sep 17 00:00:00 2001 From: mbanth Date: Thu, 27 May 2021 16:49:21 +0100 Subject: [PATCH 39/55] Remove dead code --- .../src/hid_report_descriptor.h | 30 ------------------- 1 file changed, 30 deletions(-) diff --git a/tests/xua_unit_tests/src/hid_report_descriptor.h b/tests/xua_unit_tests/src/hid_report_descriptor.h index 2037dfda..7830ca8d 100644 --- a/tests/xua_unit_tests/src/hid_report_descriptor.h +++ b/tests/xua_unit_tests/src/hid_report_descriptor.h @@ -12,36 +12,6 @@ #define MIN_VALID_BIT ( 0 ) #define MIN_VALID_BYTE ( 0 ) -#if 0 -/* Existing static report descriptor kept for reference */ -unsigned char hidReportDescriptor[] = -{ - 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, 0x07, /* Usage Page (Key Codes) */ - 0x19, 0x17, /* Usage Minimum (Keyboard t or T) */ - 0x29, 0x17, /* Usage Maximum (Keyboard t or T) */ - 0x81, 0x02, /* Input (Data, Var, Abs, No Wrap, Lin, Pref, No Nul) */ - 0x05, 0x0C, /* Usage Page (Consumer) */ - 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 - 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 }; From 0b9d970f75b3923e873562fc9fca7580e2f77a35 Mon Sep 17 00:00:00 2001 From: mbanth Date: Thu, 27 May 2021 16:53:06 +0100 Subject: [PATCH 40/55] Add HID Report descriptor definition to each App Note --- .../src/hid_report_descriptor.h | 90 +++++++++++++++++++ .../src/hid_report_descriptor.h | 90 +++++++++++++++++++ .../src/hid_report_descriptor.h | 90 +++++++++++++++++++ 3 files changed, 270 insertions(+) create mode 100644 examples/AN00246_xua_example/src/hid_report_descriptor.h create mode 100644 examples/AN00247_xua_example_spdif_tx/src/hid_report_descriptor.h create mode 100644 examples/AN00248_xua_example_pdm_mics/src/hid_report_descriptor.h diff --git a/examples/AN00246_xua_example/src/hid_report_descriptor.h b/examples/AN00246_xua_example/src/hid_report_descriptor.h new file mode 100644 index 00000000..f06ec0a0 --- /dev/null +++ b/examples/AN00246_xua_example/src/hid_report_descriptor.h @@ -0,0 +1,90 @@ +// 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" + +// Copyright 2021 XMOS LIMITED. +// This Software is subject to the terms of the XMOS Public Licence: Version 1. + +#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 + +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 }; + +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 + +static USB_HID_Short_Item_t* const hidConfigurableItems[] = { + &hidUsageByte0Bit0, + &hidUsageByte0Bit1, + &hidUsageByte0Bit2, + &hidUsageByte0Bit3, + &hidUsageByte0Bit4, + &hidUsageByte0Bit5 +}; + +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 +}; + +#endif // __hid_report_descriptor_h__ diff --git a/examples/AN00247_xua_example_spdif_tx/src/hid_report_descriptor.h b/examples/AN00247_xua_example_spdif_tx/src/hid_report_descriptor.h new file mode 100644 index 00000000..f06ec0a0 --- /dev/null +++ b/examples/AN00247_xua_example_spdif_tx/src/hid_report_descriptor.h @@ -0,0 +1,90 @@ +// 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" + +// Copyright 2021 XMOS LIMITED. +// This Software is subject to the terms of the XMOS Public Licence: Version 1. + +#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 + +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 }; + +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 + +static USB_HID_Short_Item_t* const hidConfigurableItems[] = { + &hidUsageByte0Bit0, + &hidUsageByte0Bit1, + &hidUsageByte0Bit2, + &hidUsageByte0Bit3, + &hidUsageByte0Bit4, + &hidUsageByte0Bit5 +}; + +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 +}; + +#endif // __hid_report_descriptor_h__ diff --git a/examples/AN00248_xua_example_pdm_mics/src/hid_report_descriptor.h b/examples/AN00248_xua_example_pdm_mics/src/hid_report_descriptor.h new file mode 100644 index 00000000..f06ec0a0 --- /dev/null +++ b/examples/AN00248_xua_example_pdm_mics/src/hid_report_descriptor.h @@ -0,0 +1,90 @@ +// 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" + +// Copyright 2021 XMOS LIMITED. +// This Software is subject to the terms of the XMOS Public Licence: Version 1. + +#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 + +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 }; + +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 + +static USB_HID_Short_Item_t* const hidConfigurableItems[] = { + &hidUsageByte0Bit0, + &hidUsageByte0Bit1, + &hidUsageByte0Bit2, + &hidUsageByte0Bit3, + &hidUsageByte0Bit4, + &hidUsageByte0Bit5 +}; + +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 +}; + +#endif // __hid_report_descriptor_h__ From 7b43785816d614f96c212aaa4cc2f133e0289c93 Mon Sep 17 00:00:00 2001 From: mbanth Date: Thu, 27 May 2021 17:56:26 +0100 Subject: [PATCH 41/55] Makes each #define value a primary expression. Set the class length field in the HID descriptor to zero. --- lib_xua/src/hid/xua_hid_descriptor_contents.h | 18 +++++++++--------- .../hid/xua_hid_endpoint_descriptor_contents.h | 10 +++++----- .../xua_hid_interface_descriptor_contents.h | 16 ++++++++-------- 3 files changed, 22 insertions(+), 22 deletions(-) diff --git a/lib_xua/src/hid/xua_hid_descriptor_contents.h b/lib_xua/src/hid/xua_hid_descriptor_contents.h index d91e7b15..766c323e 100644 --- a/lib_xua/src/hid/xua_hid_descriptor_contents.h +++ b/lib_xua/src/hid/xua_hid_descriptor_contents.h @@ -12,15 +12,15 @@ #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 sizeof(hidReportDescriptor) & 0xff -#define HID_DESCRIPTOR_LENGTH_1_HI sizeof(hidReportDescriptor) >> 8 +#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_ diff --git a/lib_xua/src/hid/xua_hid_endpoint_descriptor_contents.h b/lib_xua/src/hid/xua_hid_endpoint_descriptor_contents.h index bba85c72..d6bcc6b3 100644 --- a/lib_xua/src/hid/xua_hid_endpoint_descriptor_contents.h +++ b/lib_xua/src/hid/xua_hid_endpoint_descriptor_contents.h @@ -12,11 +12,11 @@ #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 +#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_ diff --git a/lib_xua/src/hid/xua_hid_interface_descriptor_contents.h b/lib_xua/src/hid/xua_hid_interface_descriptor_contents.h index 20df1815..83d69fbd 100644 --- a/lib_xua/src/hid/xua_hid_interface_descriptor_contents.h +++ b/lib_xua/src/hid/xua_hid_interface_descriptor_contents.h @@ -12,14 +12,14 @@ #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 +#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_ From 3106ccefcfb8e70a21574e395981e33dde5d5e82 Mon Sep 17 00:00:00 2001 From: mbanth Date: Thu, 27 May 2021 17:56:51 +0100 Subject: [PATCH 42/55] Remove the redundant HID Report descriptor --- .../src/core/endpoint0/xua_ep0_descriptors.h | 27 ------------------- 1 file changed, 27 deletions(-) diff --git a/lib_xua/src/core/endpoint0/xua_ep0_descriptors.h b/lib_xua/src/core/endpoint0/xua_ep0_descriptors.h index 5c154b08..d8513888 100644 --- a/lib_xua/src/core/endpoint0/xua_ep0_descriptors.h +++ b/lib_xua/src/core/endpoint0/xua_ep0_descriptors.h @@ -580,33 +580,6 @@ unsigned char devQualDesc_Null[] = #define MIXER_LENGTH (0) #endif -#if( 0 < HID_CONTROLS ) -unsigned char hidReportDescriptor[] = -{ - 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 From aec5bb8daa9669d6fdef297f08b1fa7aa6472a9c Mon Sep 17 00:00:00 2001 From: mbanth Date: Thu, 27 May 2021 18:05:56 +0100 Subject: [PATCH 43/55] Remove duplicate copyright and license reference comments --- examples/AN00246_xua_example/src/hid_report_descriptor.h | 3 --- .../AN00247_xua_example_spdif_tx/src/hid_report_descriptor.h | 3 --- .../AN00248_xua_example_pdm_mics/src/hid_report_descriptor.h | 3 --- legacy_tests/app_test_i2s_loopback/hid_report_descriptor.h | 3 --- 4 files changed, 12 deletions(-) diff --git a/examples/AN00246_xua_example/src/hid_report_descriptor.h b/examples/AN00246_xua_example/src/hid_report_descriptor.h index f06ec0a0..7bedc6a2 100644 --- a/examples/AN00246_xua_example/src/hid_report_descriptor.h +++ b/examples/AN00246_xua_example/src/hid_report_descriptor.h @@ -5,9 +5,6 @@ #include "xua_hid_report_descriptor.h" -// Copyright 2021 XMOS LIMITED. -// This Software is subject to the terms of the XMOS Public Licence: Version 1. - #if 0 /* Existing static report descriptor kept for reference */ unsigned char hidReportDescriptor[] = diff --git a/examples/AN00247_xua_example_spdif_tx/src/hid_report_descriptor.h b/examples/AN00247_xua_example_spdif_tx/src/hid_report_descriptor.h index f06ec0a0..7bedc6a2 100644 --- a/examples/AN00247_xua_example_spdif_tx/src/hid_report_descriptor.h +++ b/examples/AN00247_xua_example_spdif_tx/src/hid_report_descriptor.h @@ -5,9 +5,6 @@ #include "xua_hid_report_descriptor.h" -// Copyright 2021 XMOS LIMITED. -// This Software is subject to the terms of the XMOS Public Licence: Version 1. - #if 0 /* Existing static report descriptor kept for reference */ unsigned char hidReportDescriptor[] = diff --git a/examples/AN00248_xua_example_pdm_mics/src/hid_report_descriptor.h b/examples/AN00248_xua_example_pdm_mics/src/hid_report_descriptor.h index f06ec0a0..7bedc6a2 100644 --- a/examples/AN00248_xua_example_pdm_mics/src/hid_report_descriptor.h +++ b/examples/AN00248_xua_example_pdm_mics/src/hid_report_descriptor.h @@ -5,9 +5,6 @@ #include "xua_hid_report_descriptor.h" -// Copyright 2021 XMOS LIMITED. -// This Software is subject to the terms of the XMOS Public Licence: Version 1. - #if 0 /* Existing static report descriptor kept for reference */ unsigned char hidReportDescriptor[] = diff --git a/legacy_tests/app_test_i2s_loopback/hid_report_descriptor.h b/legacy_tests/app_test_i2s_loopback/hid_report_descriptor.h index f06ec0a0..7bedc6a2 100644 --- a/legacy_tests/app_test_i2s_loopback/hid_report_descriptor.h +++ b/legacy_tests/app_test_i2s_loopback/hid_report_descriptor.h @@ -5,9 +5,6 @@ #include "xua_hid_report_descriptor.h" -// Copyright 2021 XMOS LIMITED. -// This Software is subject to the terms of the XMOS Public Licence: Version 1. - #if 0 /* Existing static report descriptor kept for reference */ unsigned char hidReportDescriptor[] = From 4c9130166ce93eb4a332a6e186609d1ebf3418bb Mon Sep 17 00:00:00 2001 From: mbanth Date: Tue, 1 Jun 2021 14:41:15 +0100 Subject: [PATCH 44/55] Rename a constant to match the expected name --- legacy_tests/app_test_i2s_loopback/xua_conf.h | 2 +- tests/xua_unit_tests/src/xua_conf.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/legacy_tests/app_test_i2s_loopback/xua_conf.h b/legacy_tests/app_test_i2s_loopback/xua_conf.h index bec236b1..a1120f49 100644 --- a/legacy_tests/app_test_i2s_loopback/xua_conf.h +++ b/legacy_tests/app_test_i2s_loopback/xua_conf.h @@ -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 diff --git a/tests/xua_unit_tests/src/xua_conf.h b/tests/xua_unit_tests/src/xua_conf.h index b5a0dbf3..798c5e43 100644 --- a/tests/xua_unit_tests/src/xua_conf.h +++ b/tests/xua_unit_tests/src/xua_conf.h @@ -11,7 +11,7 @@ #define MAX_FREQ 48000 #define EXCLUDE_USB_AUDIO_MAIN -#define NUM_PDM_MICS 0 +#define XUA_NUM_PDM_MICS 0 #define PDM_TILE 2 #define XUD_TILE 1 From 64805d203edbb6ea77f73ca31400e76676693893 Mon Sep 17 00:00:00 2001 From: mbanth Date: Thu, 3 Jun 2021 15:28:58 +0100 Subject: [PATCH 45/55] Remove deprecated and ineffective compiler option --- examples/AN00246_xua_example/Makefile | 2 +- examples/AN00247_xua_example_spdif_tx/Makefile | 2 +- examples/AN00248_xua_example_pdm_mics/Makefile | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/examples/AN00246_xua_example/Makefile b/examples/AN00246_xua_example/Makefile index 9bdea14b..699e31b2 100644 --- a/examples/AN00246_xua_example/Makefile +++ b/examples/AN00246_xua_example/Makefile @@ -3,7 +3,7 @@ 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 \ +XCC_FLAGS = -fcomment-asm -Xmapper --map -Xmapper MAPFILE -O3 -report -save-temps \ -g -Wno-unused-function -Wno-timing -DXUD_SERIES_SUPPORT=XUD_X200_SERIES -DUSB_TILE=tile[1] -fxscope #-DSDA_HIGH=2 -DSCL_HIGH=1 -fxscope diff --git a/examples/AN00247_xua_example_spdif_tx/Makefile b/examples/AN00247_xua_example_spdif_tx/Makefile index cedcb1c7..2003fdd8 100644 --- a/examples/AN00247_xua_example_spdif_tx/Makefile +++ b/examples/AN00247_xua_example_spdif_tx/Makefile @@ -3,7 +3,7 @@ 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 \ +XCC_FLAGS = -fcomment-asm -Xmapper --map -Xmapper MAPFILE -O3 -report -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 diff --git a/examples/AN00248_xua_example_pdm_mics/Makefile b/examples/AN00248_xua_example_pdm_mics/Makefile index 8681d0b5..9eefd8bc 100644 --- a/examples/AN00248_xua_example_pdm_mics/Makefile +++ b/examples/AN00248_xua_example_pdm_mics/Makefile @@ -3,7 +3,7 @@ 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 \ +XCC_FLAGS = -fcomment-asm -Xmapper --map -Xmapper MAPFILE -O3 -report -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 From dab84e56dfe094b78bc462cebb63627fbf7bfcd4 Mon Sep 17 00:00:00 2001 From: mbanth Date: Thu, 3 Jun 2021 15:30:12 +0100 Subject: [PATCH 46/55] Add missing Flash programming parameters --- examples/AN00246_xua_example/src/xk-audio-216-mc.xn | 2 +- examples/AN00247_xua_example_spdif_tx/src/xk-audio-216-mc.xn | 2 +- examples/AN00248_xua_example_pdm_mics/src/mic_array_ref.xn | 2 +- legacy_tests/app_test_i2s_loopback/xk_216_mc/xk-audio-216-mc.xn | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/examples/AN00246_xua_example/src/xk-audio-216-mc.xn b/examples/AN00246_xua_example/src/xk-audio-216-mc.xn index c2e90f16..88e6d699 100644 --- a/examples/AN00246_xua_example/src/xk-audio-216-mc.xn +++ b/examples/AN00246_xua_example/src/xk-audio-216-mc.xn @@ -75,7 +75,7 @@ - + diff --git a/examples/AN00247_xua_example_spdif_tx/src/xk-audio-216-mc.xn b/examples/AN00247_xua_example_spdif_tx/src/xk-audio-216-mc.xn index c2e90f16..88e6d699 100644 --- a/examples/AN00247_xua_example_spdif_tx/src/xk-audio-216-mc.xn +++ b/examples/AN00247_xua_example_spdif_tx/src/xk-audio-216-mc.xn @@ -75,7 +75,7 @@ - + diff --git a/examples/AN00248_xua_example_pdm_mics/src/mic_array_ref.xn b/examples/AN00248_xua_example_pdm_mics/src/mic_array_ref.xn index 66caa132..a9e1b9b4 100644 --- a/examples/AN00248_xua_example_pdm_mics/src/mic_array_ref.xn +++ b/examples/AN00248_xua_example_pdm_mics/src/mic_array_ref.xn @@ -81,7 +81,7 @@ - + diff --git a/legacy_tests/app_test_i2s_loopback/xk_216_mc/xk-audio-216-mc.xn b/legacy_tests/app_test_i2s_loopback/xk_216_mc/xk-audio-216-mc.xn index a9f765b0..7c15cf0a 100644 --- a/legacy_tests/app_test_i2s_loopback/xk_216_mc/xk-audio-216-mc.xn +++ b/legacy_tests/app_test_i2s_loopback/xk_216_mc/xk-audio-216-mc.xn @@ -83,7 +83,7 @@ - + From fd45908ff6f83425404bfd5f3253ec4bfc13fb0d Mon Sep 17 00:00:00 2001 From: mbanth Date: Thu, 3 Jun 2021 15:53:50 +0100 Subject: [PATCH 47/55] Add function to return the length of the HID Report --- CHANGELOG.rst | 3 ++- .../src/hid_report_descriptor.h | 18 ++++++++++++++++++ .../src/hid_report_descriptor.h | 18 ++++++++++++++++++ .../src/hid_report_descriptor.h | 18 ++++++++++++++++++ .../hid_report_descriptor.h | 18 ++++++++++++++++++ lib_xua/src/hid/hid_report_descriptor.c | 5 +++++ lib_xua/src/hid/xua_hid_report_descriptor.h | 15 +++++++++++++++ .../xua_unit_tests/src/hid_report_descriptor.h | 18 ++++++++++++++++++ tests/xua_unit_tests/src/test_hid.c | 6 ++++++ 9 files changed, 118 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.rst b/CHANGELOG.rst index 23ac34cf..dd6f39cc 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -7,6 +7,8 @@ lib_xua Change Log * 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 1.2.0 ----- @@ -19,7 +21,6 @@ lib_xua Change Log * FIXED: Runtime error when using mic array interface * CHANGED: Use XMOS Public Licence Version 1 * FIXED: Automate HID Report Descriptor length in AC1 HID Descriptor - * CHANGED: Move HID descriptors to ease maintenance 1.1.1 ----- diff --git a/examples/AN00246_xua_example/src/hid_report_descriptor.h b/examples/AN00246_xua_example/src/hid_report_descriptor.h index 7bedc6a2..b183beda 100644 --- a/examples/AN00246_xua_example/src/hid_report_descriptor.h +++ b/examples/AN00246_xua_example/src/hid_report_descriptor.h @@ -29,6 +29,9 @@ unsigned char hidReportDescriptor[] = }; #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 }; @@ -47,6 +50,9 @@ static const USB_HID_Short_Item_t hidUsageConsumerControl = { .header = 0x09, 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+ @@ -54,6 +60,9 @@ static USB_HID_Short_Item_t hidUsageByte0Bit2 = { .header = 0x09, .data = { 0x 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, @@ -63,6 +72,9 @@ static USB_HID_Short_Item_t* const hidConfigurableItems[] = { &hidUsageByte0Bit5 }; +/* + * List all items in the HID Report descriptor. + */ static const USB_HID_Short_Item_t* const hidReportDescriptorItems[] = { &hidUsagePageConsumer, &hidUsageConsumerControl, @@ -84,4 +96,10 @@ static const USB_HID_Short_Item_t* const hidReportDescriptorItems[] = { &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__ diff --git a/examples/AN00247_xua_example_spdif_tx/src/hid_report_descriptor.h b/examples/AN00247_xua_example_spdif_tx/src/hid_report_descriptor.h index 7bedc6a2..b183beda 100644 --- a/examples/AN00247_xua_example_spdif_tx/src/hid_report_descriptor.h +++ b/examples/AN00247_xua_example_spdif_tx/src/hid_report_descriptor.h @@ -29,6 +29,9 @@ unsigned char hidReportDescriptor[] = }; #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 }; @@ -47,6 +50,9 @@ static const USB_HID_Short_Item_t hidUsageConsumerControl = { .header = 0x09, 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+ @@ -54,6 +60,9 @@ static USB_HID_Short_Item_t hidUsageByte0Bit2 = { .header = 0x09, .data = { 0x 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, @@ -63,6 +72,9 @@ static USB_HID_Short_Item_t* const hidConfigurableItems[] = { &hidUsageByte0Bit5 }; +/* + * List all items in the HID Report descriptor. + */ static const USB_HID_Short_Item_t* const hidReportDescriptorItems[] = { &hidUsagePageConsumer, &hidUsageConsumerControl, @@ -84,4 +96,10 @@ static const USB_HID_Short_Item_t* const hidReportDescriptorItems[] = { &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__ diff --git a/examples/AN00248_xua_example_pdm_mics/src/hid_report_descriptor.h b/examples/AN00248_xua_example_pdm_mics/src/hid_report_descriptor.h index 7bedc6a2..b183beda 100644 --- a/examples/AN00248_xua_example_pdm_mics/src/hid_report_descriptor.h +++ b/examples/AN00248_xua_example_pdm_mics/src/hid_report_descriptor.h @@ -29,6 +29,9 @@ unsigned char hidReportDescriptor[] = }; #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 }; @@ -47,6 +50,9 @@ static const USB_HID_Short_Item_t hidUsageConsumerControl = { .header = 0x09, 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+ @@ -54,6 +60,9 @@ static USB_HID_Short_Item_t hidUsageByte0Bit2 = { .header = 0x09, .data = { 0x 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, @@ -63,6 +72,9 @@ static USB_HID_Short_Item_t* const hidConfigurableItems[] = { &hidUsageByte0Bit5 }; +/* + * List all items in the HID Report descriptor. + */ static const USB_HID_Short_Item_t* const hidReportDescriptorItems[] = { &hidUsagePageConsumer, &hidUsageConsumerControl, @@ -84,4 +96,10 @@ static const USB_HID_Short_Item_t* const hidReportDescriptorItems[] = { &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__ diff --git a/legacy_tests/app_test_i2s_loopback/hid_report_descriptor.h b/legacy_tests/app_test_i2s_loopback/hid_report_descriptor.h index 7bedc6a2..b183beda 100644 --- a/legacy_tests/app_test_i2s_loopback/hid_report_descriptor.h +++ b/legacy_tests/app_test_i2s_loopback/hid_report_descriptor.h @@ -29,6 +29,9 @@ unsigned char hidReportDescriptor[] = }; #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 }; @@ -47,6 +50,9 @@ static const USB_HID_Short_Item_t hidUsageConsumerControl = { .header = 0x09, 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+ @@ -54,6 +60,9 @@ static USB_HID_Short_Item_t hidUsageByte0Bit2 = { .header = 0x09, .data = { 0x 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, @@ -63,6 +72,9 @@ static USB_HID_Short_Item_t* const hidConfigurableItems[] = { &hidUsageByte0Bit5 }; +/* + * List all items in the HID Report descriptor. + */ static const USB_HID_Short_Item_t* const hidReportDescriptorItems[] = { &hidUsagePageConsumer, &hidUsageConsumerControl, @@ -84,4 +96,10 @@ static const USB_HID_Short_Item_t* const hidReportDescriptorItems[] = { &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__ diff --git a/lib_xua/src/hid/hid_report_descriptor.c b/lib_xua/src/hid/hid_report_descriptor.c index 14cfd0a4..42565265 100644 --- a/lib_xua/src/hid/hid_report_descriptor.c +++ b/lib_xua/src/hid/hid_report_descriptor.c @@ -130,6 +130,11 @@ size_t hidGetReportDescriptorLength( void ) return ( hidReportDescriptorPrepared ) ? hidReportDescriptorLength : 0; } +size_t hidGetReportLength( void ) +{ + return ( hidReportDescriptorPrepared ) ? HID_REPORT_LENGTH : 0; +} + void hidPrepareReportDescriptor( void ) { if( !hidReportDescriptorPrepared ) { diff --git a/lib_xua/src/hid/xua_hid_report_descriptor.h b/lib_xua/src/hid/xua_hid_report_descriptor.h index 91d01e41..e917a483 100644 --- a/lib_xua/src/hid/xua_hid_report_descriptor.h +++ b/lib_xua/src/hid/xua_hid_report_descriptor.h @@ -6,6 +6,10 @@ * * This file defines the structure of the HID Report descriptor and decalres * 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. */ @@ -82,6 +86,17 @@ unsigned char* hidGetReportDescriptor( void ); */ size_t hidGetReportDescriptorLength( void ); +/** + * @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 * diff --git a/tests/xua_unit_tests/src/hid_report_descriptor.h b/tests/xua_unit_tests/src/hid_report_descriptor.h index 7830ca8d..faf3e7f7 100644 --- a/tests/xua_unit_tests/src/hid_report_descriptor.h +++ b/tests/xua_unit_tests/src/hid_report_descriptor.h @@ -12,6 +12,9 @@ #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 }; @@ -32,17 +35,26 @@ static const USB_HID_Short_Item_t hidUsageConsumerControl = { .header = 0x09, 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 all items in the HID Report descriptor. + */ static const USB_HID_Short_Item_t* const hidReportDescriptorItems[] = { &hidUsagePageConsumer, &hidUsageConsumerControl, @@ -73,4 +85,10 @@ static const USB_HID_Short_Item_t* const hidReportDescriptorItems[] = { &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__ diff --git a/tests/xua_unit_tests/src/test_hid.c b/tests/xua_unit_tests/src/test_hid.c index d528462f..7c014a2c 100644 --- a/tests/xua_unit_tests/src/test_hid.c +++ b/tests/xua_unit_tests/src/test_hid.c @@ -36,6 +36,9 @@ 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 ) @@ -43,6 +46,9 @@ 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 ) From b871b4c046f64d13746826d21b5361bf7b4281af Mon Sep 17 00:00:00 2001 From: mbanth Date: Thu, 3 Jun 2021 16:01:45 +0100 Subject: [PATCH 48/55] Change interface to UserHIDRecordEvent function to support only binary event states --- lib_xua/src/core/buffer/ep/ep_buffer.xc | 2 +- lib_xua/src/core/user/hid/user_hid.h | 22 ++++++++++------------ 2 files changed, 11 insertions(+), 13 deletions(-) diff --git a/lib_xua/src/core/buffer/ep/ep_buffer.xc b/lib_xua/src/core/buffer/ep/ep_buffer.xc index 50f475bd..dea02295 100644 --- a/lib_xua/src/core/buffer/ep/ep_buffer.xc +++ b/lib_xua/src/core/buffer/ep/ep_buffer.xc @@ -22,7 +22,7 @@ #if( 0 < HID_CONTROLS ) #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); diff --git a/lib_xua/src/core/user/hid/user_hid.h b/lib_xua/src/core/user/hid/user_hid.h index 7eced6ca..1e5ade42 100644 --- a/lib_xua/src/core/user/hid/user_hid.h +++ b/lib_xua/src/core/user/hid/user_hid.h @@ -47,7 +47,7 @@ typedef enum hidEventId_t { HID_EVENT_ID_INVALID = 0xffffffff, } hidEventId_t; -#define HID_DATA_BYTES 4 +#define HID_MAX_DATA_BYTES 4 #if( 0 < HID_CONTROLS ) @@ -60,7 +60,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 +70,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 - * - * \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. + * \param{in} hidEventId The identifier of an event which has occurred. + * Each event corresponds to bit in the HID Report: + * Events 0- 7 to bits 0-7 of byte 0, + * Events 8-15 to bits 0-7 of byte 1, etc. + * \param{in} hidEventData A Boolean indicating the state of the event: + * Zero = deasserted, + * Any other value = asserted. */ -void UserHIDRecordEvent( const hidEventId_t hidEventId, const int * hidEventData, const unsigned hidEventDataSize ); +void UserHIDRecordEvent( const hidEventId_t hidEventId, const unsigned hidEventData ); #endif /* ( 0 < HID_CONTROLS ) */ #endif /* __USER_HID_H__ */ From 4446ab89c0f5fad4e4bd55adf3c67ecf3d39d9f5 Mon Sep 17 00:00:00 2001 From: mbanth Date: Fri, 4 Jun 2021 15:15:05 +0100 Subject: [PATCH 49/55] Limit the usage of hidGetReportDescriptor() to C only --- lib_xua/src/hid/xua_hid_report_descriptor.h | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/lib_xua/src/hid/xua_hid_report_descriptor.h b/lib_xua/src/hid/xua_hid_report_descriptor.h index e917a483..bc9a81b0 100644 --- a/lib_xua/src/hid/xua_hid_report_descriptor.h +++ b/lib_xua/src/hid/xua_hid_report_descriptor.h @@ -71,9 +71,15 @@ typedef struct * 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 From 382b1a8754213e75ea48755f6b761275e86d3709 Mon Sep 17 00:00:00 2001 From: mbanth Date: Fri, 4 Jun 2021 15:17:28 +0100 Subject: [PATCH 50/55] Add support for boot-time creation of the HID Report descriptor --- lib_xua/src/core/endpoint0/xua_endpoint0.c | 50 ++++++++++++++++------ 1 file changed, 38 insertions(+), 12 deletions(-) diff --git a/lib_xua/src/core/endpoint0/xua_endpoint0.c b/lib_xua/src/core/endpoint0/xua_endpoint0.c index 40064918..9af03eb2 100755 --- a/lib_xua/src/core/endpoint0/xua_endpoint0.c +++ b/lib_xua/src/core/endpoint0/xua_endpoint0.c @@ -23,18 +23,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 +57,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 +91,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 @@ -518,6 +521,22 @@ 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, @@ -729,15 +748,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; From 567e5cc0e0040f57eb44e01b0867a67f3d344f6e Mon Sep 17 00:00:00 2001 From: mbanth Date: Fri, 4 Jun 2021 15:18:51 +0100 Subject: [PATCH 51/55] Fix bugs that prevented correct operation of HID Report descriptor. Add descriptive constants. --- lib_xua/src/hid/hid_report_descriptor.c | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/lib_xua/src/hid/hid_report_descriptor.c b/lib_xua/src/hid/hid_report_descriptor.c index 42565265..e233d187 100644 --- a/lib_xua/src/hid/hid_report_descriptor.c +++ b/lib_xua/src/hid/hid_report_descriptor.c @@ -6,8 +6,11 @@ #include "xua_hid_report_descriptor.h" #include "hid_report_descriptor.h" +#include + #define HID_REPORT_ITEM_LOCATION_SIZE ( 1 ) -#define HID_REPORT_DESCRIPTOR_MAX_LENGTH ( sizeof hidReportDescriptorItems / sizeof ( USB_HID_Short_Item_t ) * \ +#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 ]; @@ -127,12 +130,15 @@ unsigned char* hidGetReportDescriptor( void ) size_t hidGetReportDescriptorLength( void ) { - return ( hidReportDescriptorPrepared ) ? hidReportDescriptorLength : 0; + size_t retVal = ( hidReportDescriptorPrepared ) ? hidReportDescriptorLength : 0; + return retVal; } size_t hidGetReportLength( void ) { - return ( hidReportDescriptorPrepared ) ? HID_REPORT_LENGTH : 0; + size_t retVal = ( hidReportDescriptorPrepared ) ? HID_REPORT_LENGTH : 0; + printf( "hidGetReportLength: %d\n", retVal ); + return retVal; } void hidPrepareReportDescriptor( void ) @@ -140,7 +146,7 @@ void hidPrepareReportDescriptor( void ) if( !hidReportDescriptorPrepared ) { hidReportDescriptorLength = 0; unsigned char* ptr = hidReportDescriptor; - for( unsigned idx = 0; idx < sizeof hidReportDescriptorItems / sizeof( USB_HID_Short_Item_t ); ++idx ) { + for( unsigned idx = 0; idx < HID_REPORT_DESCRIPTOR_ITEM_COUNT; ++idx ) { hidReportDescriptorLength += hidTranslateItem( hidReportDescriptorItems[ idx ], &ptr ); } @@ -153,6 +159,7 @@ void hidResetReportDescriptor( void ) hidReportDescriptorPrepared = 0; } +#define HID_CONFIGURABLE_ITEM_COUNT ( sizeof hidConfigurableItems / sizeof ( USB_HID_Short_Item_t* )) unsigned hidSetReportItem( const unsigned byte, const unsigned bit, const unsigned char header, const unsigned char data[] ) { unsigned retVal = HID_STATUS_IN_USE; @@ -168,7 +175,7 @@ unsigned hidSetReportItem( const unsigned byte, const unsigned bit, const unsign ( HID_REPORT_ITEM_USAGE_TYPE != bType )) { retVal = HID_STATUS_BAD_HEADER; } else { - for( unsigned itemIdx = 0; itemIdx < sizeof hidConfigurableItems / sizeof( USB_HID_Short_Item_t ); ++itemIdx ) { + 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 ); @@ -194,6 +201,7 @@ static size_t hidTranslateItem( const USB_HID_Short_Item_t* inPtr, unsigned char { size_t count = 0; *(*outPtrPtr)++ = inPtr->header; + ++count; unsigned dataLength = hidGetItemSize( inPtr->header ); for( unsigned idx = 0; idx < dataLength; ++idx ) { From b47a30a04ced1c312dfd1afc19ceb1373988322a Mon Sep 17 00:00:00 2001 From: mbanth Date: Fri, 4 Jun 2021 16:27:17 +0100 Subject: [PATCH 52/55] Remove debugging printf() --- lib_xua/src/hid/hid_report_descriptor.c | 1 - 1 file changed, 1 deletion(-) diff --git a/lib_xua/src/hid/hid_report_descriptor.c b/lib_xua/src/hid/hid_report_descriptor.c index e233d187..022085ed 100644 --- a/lib_xua/src/hid/hid_report_descriptor.c +++ b/lib_xua/src/hid/hid_report_descriptor.c @@ -137,7 +137,6 @@ size_t hidGetReportDescriptorLength( void ) size_t hidGetReportLength( void ) { size_t retVal = ( hidReportDescriptorPrepared ) ? HID_REPORT_LENGTH : 0; - printf( "hidGetReportLength: %d\n", retVal ); return retVal; } From 6636e2f505c968e4e67dd7c8c5fb09f4e8d13d60 Mon Sep 17 00:00:00 2001 From: mbanth Date: Fri, 4 Jun 2021 16:27:54 +0100 Subject: [PATCH 53/55] Add support for multi-byte HID Report --- lib_xua/src/core/buffer/ep/ep_buffer.xc | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/lib_xua/src/core/buffer/ep/ep_buffer.xc b/lib_xua/src/core/buffer/ep/ep_buffer.xc index dea02295..eb6b373a 100644 --- a/lib_xua/src/core/buffer/ep/ep_buffer.xc +++ b/lib_xua/src/core/buffer/ep/ep_buffer.xc @@ -21,6 +21,7 @@ #include "testct_byref.h" #if( 0 < HID_CONTROLS ) +#include "xua_hid_report_descriptor.h" #include "user_hid.h" unsigned char g_hidData[HID_MAX_DATA_BYTES] = {0}; #endif @@ -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 From 008508c8ae114853104cf3b03d685b74ca14e7b4 Mon Sep 17 00:00:00 2001 From: mbanth Date: Fri, 4 Jun 2021 17:04:20 +0100 Subject: [PATCH 54/55] Added change log entry --- CHANGELOG.rst | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.rst b/CHANGELOG.rst index dd6f39cc..74f0cf97 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -9,6 +9,7 @@ lib_xua Change Log * 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 1.2.0 ----- From 05bf241ab8a3d1acb12aca669f4a19962fc343ce Mon Sep 17 00:00:00 2001 From: mbanth Date: Tue, 8 Jun 2021 09:52:25 +0100 Subject: [PATCH 55/55] Fix comment typos --- lib_xua/src/hid/xua_hid_report_descriptor.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib_xua/src/hid/xua_hid_report_descriptor.h b/lib_xua/src/hid/xua_hid_report_descriptor.h index bc9a81b0..9d936c2b 100644 --- a/lib_xua/src/hid/xua_hid_report_descriptor.h +++ b/lib_xua/src/hid/xua_hid_report_descriptor.h @@ -4,7 +4,7 @@ /** * @brief Human Interface Device (HID) Report descriptor * - * This file defines the structure of the HID Report descriptor and decalres + * 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. @@ -106,7 +106,7 @@ size_t hidGetReportLength( void ); /** * @brief Prepare the USB HID Report descriptor * - * After preparation, \c hidGetReportDescriptor() returns a list suitablefor transmission over USB. + * 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 );