forked from PAWPAW-Mirror/lib_xua
Merge pull request #226 from CiaranWoodward/feature/multiple_hid_reports
Support multiple HID Reports & update examples for new API
This commit is contained in:
2
.gitignore
vendored
2
.gitignore
vendored
@@ -20,6 +20,8 @@
|
||||
test_results.csv
|
||||
_build*
|
||||
**/.venv/**
|
||||
**/.vscode/**
|
||||
**.egg-info
|
||||
|
||||
# waf build files
|
||||
.lock-waf_*
|
||||
|
||||
@@ -1,6 +1,15 @@
|
||||
lib_xua Change Log
|
||||
==================
|
||||
|
||||
3.0.0
|
||||
-----
|
||||
|
||||
* ADDED: Support for HID Report IDs
|
||||
* REMOVED: Support for HID Reports containing controls from mixed Usage
|
||||
pages
|
||||
* CHANGED: Renamed the HID API file xua_hid_report_descriptor.h to
|
||||
xua_hid_report.h
|
||||
|
||||
2.1.1
|
||||
-----
|
||||
|
||||
|
||||
2
Jenkinsfile
vendored
2
Jenkinsfile
vendored
@@ -45,7 +45,7 @@ pipeline {
|
||||
// runWaf('.', "configure clean build --target=xcoreai")
|
||||
// stash name: 'xua_unit_tests', includes: 'bin/*xcoreai.xe, '
|
||||
viewEnv() {
|
||||
runPython("TARGET=XCORE200 pytest -n 1")
|
||||
runPython("TARGET=XCORE200 pytest -s")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
#ifndef __hid_report_descriptor_h__
|
||||
#define __hid_report_descriptor_h__
|
||||
|
||||
#include "xua_hid_report_descriptor.h"
|
||||
#include "xua_hid_report.h"
|
||||
|
||||
#if 0
|
||||
/* Existing static report descriptor kept for reference */
|
||||
@@ -32,38 +32,92 @@ unsigned char hidReportDescriptor[] =
|
||||
/*
|
||||
* 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 hidCollectionApplication = {
|
||||
.header = HID_REPORT_SET_HEADER(1, HID_REPORT_ITEM_TYPE_MAIN, HID_REPORT_ITEM_TAG_COLLECTION),
|
||||
.data = { 0x01, 0x00 } };
|
||||
static const USB_HID_Short_Item_t hidCollectionEnd = {
|
||||
.header = HID_REPORT_SET_HEADER(0, HID_REPORT_ITEM_TYPE_MAIN, HID_REPORT_ITEM_TAG_END_COLLECTION),
|
||||
.data = { 0x00, 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 hidInputConstArray = {
|
||||
.header = HID_REPORT_SET_HEADER(1, HID_REPORT_ITEM_TYPE_MAIN, HID_REPORT_ITEM_TAG_INPUT),
|
||||
.data = { 0x01, 0x00 } };
|
||||
static const USB_HID_Short_Item_t hidInputDataVar = {
|
||||
.header = HID_REPORT_SET_HEADER(1, HID_REPORT_ITEM_TYPE_MAIN, HID_REPORT_ITEM_TAG_INPUT),
|
||||
.data = { 0x02, 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 hidLogicalMaximum0 = {
|
||||
.header = HID_REPORT_SET_HEADER(1, HID_REPORT_ITEM_TYPE_GLOBAL, HID_REPORT_ITEM_TAG_LOGICAL_MAXIMUM),
|
||||
.data = { 0x00, 0x00 } };
|
||||
static const USB_HID_Short_Item_t hidLogicalMaximum1 = {
|
||||
.header = HID_REPORT_SET_HEADER(1, HID_REPORT_ITEM_TYPE_GLOBAL, HID_REPORT_ITEM_TAG_LOGICAL_MAXIMUM),
|
||||
.data = { 0x01, 0x00 } };
|
||||
static const USB_HID_Short_Item_t hidLogicalMinimum0 = {
|
||||
.header = HID_REPORT_SET_HEADER(1, HID_REPORT_ITEM_TYPE_GLOBAL, HID_REPORT_ITEM_TAG_LOGICAL_MINIMUM),
|
||||
.data = { 0x00, 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 hidReportCount2 = {
|
||||
.header = HID_REPORT_SET_HEADER(1, HID_REPORT_ITEM_TYPE_GLOBAL, HID_REPORT_ITEM_TAG_REPORT_COUNT),
|
||||
.data = { 0x02, 0x00 } };
|
||||
static const USB_HID_Short_Item_t hidReportCount6 = {
|
||||
.header = HID_REPORT_SET_HEADER(1, HID_REPORT_ITEM_TYPE_GLOBAL, HID_REPORT_ITEM_TAG_REPORT_COUNT),
|
||||
.data = { 0x06, 0x00 } };
|
||||
static const USB_HID_Short_Item_t hidReportSize1 = {
|
||||
.header = HID_REPORT_SET_HEADER(1, HID_REPORT_ITEM_TYPE_GLOBAL, HID_REPORT_ITEM_TAG_REPORT_SIZE),
|
||||
.data = { 0x01, 0x00 } };
|
||||
|
||||
static const USB_HID_Short_Item_t hidUsageConsumerControl = { .header = 0x09, .data = { 0x01, 0x00 }, .location = 0x00 };
|
||||
static const USB_HID_Short_Item_t hidUsageConsumerControl = {
|
||||
.header = HID_REPORT_SET_HEADER(1, HID_REPORT_ITEM_TYPE_LOCAL, HID_REPORT_ITEM_TAG_USAGE),
|
||||
.data = { 0x01, 0x00 } };
|
||||
|
||||
static const USB_HID_Short_Item_t hidUsagePageConsumer = { .header = 0x05, .data = { 0x0C, 0x00 }, .location = 0x00 };
|
||||
/*
|
||||
* Define the HID Report Descriptor Item, Usage Page, Report ID and length for each HID Report
|
||||
* For internal purposes, a report element with ID of 0 must be included if report IDs are not being used.
|
||||
*/
|
||||
static const USB_HID_Report_Element_t hidReportPageConsumer = {
|
||||
.item.header = HID_REPORT_SET_HEADER(1, HID_REPORT_ITEM_TYPE_GLOBAL, HID_REPORT_ITEM_TAG_USAGE_PAGE),
|
||||
.item.data = { USB_HID_USAGE_PAGE_ID_CONSUMER, 0x00 },
|
||||
.location = HID_REPORT_SET_LOC( 0, 2, 0, 0 )
|
||||
};
|
||||
|
||||
/*
|
||||
* Define configurable items in the HID Report descriptor.
|
||||
*/
|
||||
static USB_HID_Short_Item_t hidUsageByte0Bit5 = { .header = 0x09, .data = { 0xE2, 0x00 }, .location = 0x50 }; // Mute
|
||||
static USB_HID_Short_Item_t hidUsageByte0Bit4 = { .header = 0x09, .data = { 0xEA, 0x00 }, .location = 0x40 }; // Vol-
|
||||
static USB_HID_Short_Item_t hidUsageByte0Bit3 = { .header = 0x09, .data = { 0xE9, 0x00 }, .location = 0x30 }; // Vol+
|
||||
static USB_HID_Short_Item_t hidUsageByte0Bit2 = { .header = 0x09, .data = { 0xB6, 0x00 }, .location = 0x20 }; // Scan Prev
|
||||
static USB_HID_Short_Item_t hidUsageByte0Bit1 = { .header = 0x09, .data = { 0xB5, 0x00 }, .location = 0x10 }; // Scan Next
|
||||
static USB_HID_Short_Item_t hidUsageByte0Bit0 = { .header = 0x09, .data = { 0xB0, 0x00 }, .location = 0x00 }; // Play
|
||||
static USB_HID_Report_Element_t hidUsageByte0Bit5 = {
|
||||
.item.header = HID_REPORT_SET_HEADER(1, HID_REPORT_ITEM_TYPE_LOCAL, HID_REPORT_ITEM_TAG_USAGE),
|
||||
.item.data = { 0xE2, 0x00 },
|
||||
.location = HID_REPORT_SET_LOC(0, 0, 0, 5)
|
||||
}; // Mute
|
||||
static USB_HID_Report_Element_t hidUsageByte0Bit4 = {
|
||||
.item.header = HID_REPORT_SET_HEADER(1, HID_REPORT_ITEM_TYPE_LOCAL, HID_REPORT_ITEM_TAG_USAGE),
|
||||
.item.data = { 0xEA, 0x00 },
|
||||
.location = HID_REPORT_SET_LOC(0, 0, 0, 4)
|
||||
}; // Vol-
|
||||
static USB_HID_Report_Element_t hidUsageByte0Bit3 = {
|
||||
.item.header = HID_REPORT_SET_HEADER(1, HID_REPORT_ITEM_TYPE_LOCAL, HID_REPORT_ITEM_TAG_USAGE),
|
||||
.item.data = { 0xE9, 0x00 },
|
||||
.location = HID_REPORT_SET_LOC(0, 0, 0, 3)
|
||||
}; // Vol+
|
||||
static USB_HID_Report_Element_t hidUsageByte0Bit2 = {
|
||||
.item.header = HID_REPORT_SET_HEADER(1, HID_REPORT_ITEM_TYPE_LOCAL, HID_REPORT_ITEM_TAG_USAGE),
|
||||
.item.data = { 0xB6, 0x00 },
|
||||
.location = HID_REPORT_SET_LOC(0, 0, 0, 2)
|
||||
}; // Scan Prev
|
||||
static USB_HID_Report_Element_t hidUsageByte0Bit1 = {
|
||||
.item.header = HID_REPORT_SET_HEADER(1, HID_REPORT_ITEM_TYPE_LOCAL, HID_REPORT_ITEM_TAG_USAGE),
|
||||
.item.data = { 0xB5, 0x00 },
|
||||
.location = HID_REPORT_SET_LOC(0, 0, 0, 1)
|
||||
}; // Scan Next
|
||||
static USB_HID_Report_Element_t hidUsageByte0Bit0 = {
|
||||
.item.header = HID_REPORT_SET_HEADER(1, HID_REPORT_ITEM_TYPE_LOCAL, HID_REPORT_ITEM_TAG_USAGE),
|
||||
.item.data = { 0xB0, 0x00 },
|
||||
.location = HID_REPORT_SET_LOC(0, 0, 0, 0)
|
||||
}; // Play
|
||||
|
||||
/*
|
||||
* List the configurable items in the HID Report descriptor.
|
||||
* List the configurable elements in the HID Report descriptor.
|
||||
*/
|
||||
static USB_HID_Short_Item_t* const hidConfigurableItems[] = {
|
||||
static USB_HID_Report_Element_t* const hidConfigurableElements[] = {
|
||||
&hidUsageByte0Bit0,
|
||||
&hidUsageByte0Bit1,
|
||||
&hidUsageByte0Bit2,
|
||||
@@ -73,27 +127,28 @@ static USB_HID_Short_Item_t* const hidConfigurableItems[] = {
|
||||
};
|
||||
|
||||
/*
|
||||
* List Usage pages in the HID Report descriptor, one per byte.
|
||||
* List HID Reports, one per Report ID. This should be a usage page item with the relevant
|
||||
* If not using report IDs - still have one with report ID 0
|
||||
*/
|
||||
static const USB_HID_Short_Item_t* const hidUsagePages[] = {
|
||||
&hidUsagePageConsumer
|
||||
static const USB_HID_Report_Element_t* const hidReports[] = {
|
||||
&hidReportPageConsumer
|
||||
};
|
||||
|
||||
/*
|
||||
* List all items in the HID Report descriptor.
|
||||
*/
|
||||
static const USB_HID_Short_Item_t* const hidReportDescriptorItems[] = {
|
||||
&hidUsagePageConsumer,
|
||||
&(hidReportPageConsumer.item),
|
||||
&hidUsageConsumerControl,
|
||||
&hidCollectionApplication,
|
||||
&hidLogicalMinimum0,
|
||||
&hidLogicalMaximum1,
|
||||
&hidUsageByte0Bit0,
|
||||
&hidUsageByte0Bit1,
|
||||
&hidUsageByte0Bit2,
|
||||
&hidUsageByte0Bit3,
|
||||
&hidUsageByte0Bit4,
|
||||
&hidUsageByte0Bit5,
|
||||
&(hidUsageByte0Bit0.item),
|
||||
&(hidUsageByte0Bit1.item),
|
||||
&(hidUsageByte0Bit2.item),
|
||||
&(hidUsageByte0Bit3.item),
|
||||
&(hidUsageByte0Bit4.item),
|
||||
&(hidUsageByte0Bit5.item),
|
||||
&hidReportSize1,
|
||||
&hidReportCount6,
|
||||
&hidInputDataVar,
|
||||
@@ -104,9 +159,10 @@ static const USB_HID_Short_Item_t* const hidReportDescriptorItems[] = {
|
||||
};
|
||||
|
||||
/*
|
||||
* Define the length of the HID Report.
|
||||
* This value must match the number of Report bytes defined by hidReportDescriptorItems.
|
||||
* Define the number of HID Reports
|
||||
* Due to XC not supporting designated initializers, this constant has a hard-coded value.
|
||||
* It must equal ( sizeof hidReports / sizeof ( USB_HID_Report_Element_t* ))
|
||||
*/
|
||||
#define HID_REPORT_LENGTH ( 1 )
|
||||
#define HID_REPORT_COUNT ( 1 )
|
||||
|
||||
#endif // __hid_report_descriptor_h__
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
#ifndef __hid_report_descriptor_h__
|
||||
#define __hid_report_descriptor_h__
|
||||
|
||||
#include "xua_hid_report_descriptor.h"
|
||||
#include "xua_hid_report.h"
|
||||
|
||||
#if 0
|
||||
/* Existing static report descriptor kept for reference */
|
||||
@@ -32,38 +32,92 @@ unsigned char hidReportDescriptor[] =
|
||||
/*
|
||||
* 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 hidCollectionApplication = {
|
||||
.header = HID_REPORT_SET_HEADER(1, HID_REPORT_ITEM_TYPE_MAIN, HID_REPORT_ITEM_TAG_COLLECTION),
|
||||
.data = { 0x01, 0x00 } };
|
||||
static const USB_HID_Short_Item_t hidCollectionEnd = {
|
||||
.header = HID_REPORT_SET_HEADER(0, HID_REPORT_ITEM_TYPE_MAIN, HID_REPORT_ITEM_TAG_END_COLLECTION),
|
||||
.data = { 0x00, 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 hidInputConstArray = {
|
||||
.header = HID_REPORT_SET_HEADER(1, HID_REPORT_ITEM_TYPE_MAIN, HID_REPORT_ITEM_TAG_INPUT),
|
||||
.data = { 0x01, 0x00 } };
|
||||
static const USB_HID_Short_Item_t hidInputDataVar = {
|
||||
.header = HID_REPORT_SET_HEADER(1, HID_REPORT_ITEM_TYPE_MAIN, HID_REPORT_ITEM_TAG_INPUT),
|
||||
.data = { 0x02, 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 hidLogicalMaximum0 = {
|
||||
.header = HID_REPORT_SET_HEADER(1, HID_REPORT_ITEM_TYPE_GLOBAL, HID_REPORT_ITEM_TAG_LOGICAL_MAXIMUM),
|
||||
.data = { 0x00, 0x00 } };
|
||||
static const USB_HID_Short_Item_t hidLogicalMaximum1 = {
|
||||
.header = HID_REPORT_SET_HEADER(1, HID_REPORT_ITEM_TYPE_GLOBAL, HID_REPORT_ITEM_TAG_LOGICAL_MAXIMUM),
|
||||
.data = { 0x01, 0x00 } };
|
||||
static const USB_HID_Short_Item_t hidLogicalMinimum0 = {
|
||||
.header = HID_REPORT_SET_HEADER(1, HID_REPORT_ITEM_TYPE_GLOBAL, HID_REPORT_ITEM_TAG_LOGICAL_MINIMUM),
|
||||
.data = { 0x00, 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 hidReportCount2 = {
|
||||
.header = HID_REPORT_SET_HEADER(1, HID_REPORT_ITEM_TYPE_GLOBAL, HID_REPORT_ITEM_TAG_REPORT_COUNT),
|
||||
.data = { 0x02, 0x00 } };
|
||||
static const USB_HID_Short_Item_t hidReportCount6 = {
|
||||
.header = HID_REPORT_SET_HEADER(1, HID_REPORT_ITEM_TYPE_GLOBAL, HID_REPORT_ITEM_TAG_REPORT_COUNT),
|
||||
.data = { 0x06, 0x00 } };
|
||||
static const USB_HID_Short_Item_t hidReportSize1 = {
|
||||
.header = HID_REPORT_SET_HEADER(1, HID_REPORT_ITEM_TYPE_GLOBAL, HID_REPORT_ITEM_TAG_REPORT_SIZE),
|
||||
.data = { 0x01, 0x00 } };
|
||||
|
||||
static const USB_HID_Short_Item_t hidUsageConsumerControl = { .header = 0x09, .data = { 0x01, 0x00 }, .location = 0x00 };
|
||||
static const USB_HID_Short_Item_t hidUsageConsumerControl = {
|
||||
.header = HID_REPORT_SET_HEADER(1, HID_REPORT_ITEM_TYPE_LOCAL, HID_REPORT_ITEM_TAG_USAGE),
|
||||
.data = { 0x01, 0x00 } };
|
||||
|
||||
static const USB_HID_Short_Item_t hidUsagePageConsumer = { .header = 0x05, .data = { 0x0C, 0x00 }, .location = 0x00 };
|
||||
/*
|
||||
* Define the HID Report Descriptor Item, Usage Page, Report ID and length for each HID Report
|
||||
* For internal purposes, a report element with ID of 0 must be included if report IDs are not being used.
|
||||
*/
|
||||
static const USB_HID_Report_Element_t hidReportPageConsumer = {
|
||||
.item.header = HID_REPORT_SET_HEADER(1, HID_REPORT_ITEM_TYPE_GLOBAL, HID_REPORT_ITEM_TAG_USAGE_PAGE),
|
||||
.item.data = { USB_HID_USAGE_PAGE_ID_CONSUMER, 0x00 },
|
||||
.location = HID_REPORT_SET_LOC( 0, 2, 0, 0 )
|
||||
};
|
||||
|
||||
/*
|
||||
* Define configurable items in the HID Report descriptor.
|
||||
*/
|
||||
static USB_HID_Short_Item_t hidUsageByte0Bit5 = { .header = 0x09, .data = { 0xE2, 0x00 }, .location = 0x50 }; // Mute
|
||||
static USB_HID_Short_Item_t hidUsageByte0Bit4 = { .header = 0x09, .data = { 0xEA, 0x00 }, .location = 0x40 }; // Vol-
|
||||
static USB_HID_Short_Item_t hidUsageByte0Bit3 = { .header = 0x09, .data = { 0xE9, 0x00 }, .location = 0x30 }; // Vol+
|
||||
static USB_HID_Short_Item_t hidUsageByte0Bit2 = { .header = 0x09, .data = { 0xB6, 0x00 }, .location = 0x20 }; // Scan Prev
|
||||
static USB_HID_Short_Item_t hidUsageByte0Bit1 = { .header = 0x09, .data = { 0xB5, 0x00 }, .location = 0x10 }; // Scan Next
|
||||
static USB_HID_Short_Item_t hidUsageByte0Bit0 = { .header = 0x09, .data = { 0xB0, 0x00 }, .location = 0x00 }; // Play
|
||||
static USB_HID_Report_Element_t hidUsageByte0Bit5 = {
|
||||
.item.header = HID_REPORT_SET_HEADER(1, HID_REPORT_ITEM_TYPE_LOCAL, HID_REPORT_ITEM_TAG_USAGE),
|
||||
.item.data = { 0xE2, 0x00 },
|
||||
.location = HID_REPORT_SET_LOC(0, 0, 0, 5)
|
||||
}; // Mute
|
||||
static USB_HID_Report_Element_t hidUsageByte0Bit4 = {
|
||||
.item.header = HID_REPORT_SET_HEADER(1, HID_REPORT_ITEM_TYPE_LOCAL, HID_REPORT_ITEM_TAG_USAGE),
|
||||
.item.data = { 0xEA, 0x00 },
|
||||
.location = HID_REPORT_SET_LOC(0, 0, 0, 4)
|
||||
}; // Vol-
|
||||
static USB_HID_Report_Element_t hidUsageByte0Bit3 = {
|
||||
.item.header = HID_REPORT_SET_HEADER(1, HID_REPORT_ITEM_TYPE_LOCAL, HID_REPORT_ITEM_TAG_USAGE),
|
||||
.item.data = { 0xE9, 0x00 },
|
||||
.location = HID_REPORT_SET_LOC(0, 0, 0, 3)
|
||||
}; // Vol+
|
||||
static USB_HID_Report_Element_t hidUsageByte0Bit2 = {
|
||||
.item.header = HID_REPORT_SET_HEADER(1, HID_REPORT_ITEM_TYPE_LOCAL, HID_REPORT_ITEM_TAG_USAGE),
|
||||
.item.data = { 0xB6, 0x00 },
|
||||
.location = HID_REPORT_SET_LOC(0, 0, 0, 2)
|
||||
}; // Scan Prev
|
||||
static USB_HID_Report_Element_t hidUsageByte0Bit1 = {
|
||||
.item.header = HID_REPORT_SET_HEADER(1, HID_REPORT_ITEM_TYPE_LOCAL, HID_REPORT_ITEM_TAG_USAGE),
|
||||
.item.data = { 0xB5, 0x00 },
|
||||
.location = HID_REPORT_SET_LOC(0, 0, 0, 1)
|
||||
}; // Scan Next
|
||||
static USB_HID_Report_Element_t hidUsageByte0Bit0 = {
|
||||
.item.header = HID_REPORT_SET_HEADER(1, HID_REPORT_ITEM_TYPE_LOCAL, HID_REPORT_ITEM_TAG_USAGE),
|
||||
.item.data = { 0xB0, 0x00 },
|
||||
.location = HID_REPORT_SET_LOC(0, 0, 0, 0)
|
||||
}; // Play
|
||||
|
||||
/*
|
||||
* List the configurable items in the HID Report descriptor.
|
||||
* List the configurable elements in the HID Report descriptor.
|
||||
*/
|
||||
static USB_HID_Short_Item_t* const hidConfigurableItems[] = {
|
||||
static USB_HID_Report_Element_t* const hidConfigurableElements[] = {
|
||||
&hidUsageByte0Bit0,
|
||||
&hidUsageByte0Bit1,
|
||||
&hidUsageByte0Bit2,
|
||||
@@ -73,27 +127,28 @@ static USB_HID_Short_Item_t* const hidConfigurableItems[] = {
|
||||
};
|
||||
|
||||
/*
|
||||
* List Usage pages in the HID Report descriptor, one per byte.
|
||||
* List HID Reports, one per Report ID. This should be a usage page item with the relevant
|
||||
* If not using report IDs - still have one with report ID 0
|
||||
*/
|
||||
static const USB_HID_Short_Item_t* const hidUsagePages[] = {
|
||||
&hidUsagePageConsumer
|
||||
static const USB_HID_Report_Element_t* const hidReports[] = {
|
||||
&hidReportPageConsumer
|
||||
};
|
||||
|
||||
/*
|
||||
* List all items in the HID Report descriptor.
|
||||
*/
|
||||
static const USB_HID_Short_Item_t* const hidReportDescriptorItems[] = {
|
||||
&hidUsagePageConsumer,
|
||||
&(hidReportPageConsumer.item),
|
||||
&hidUsageConsumerControl,
|
||||
&hidCollectionApplication,
|
||||
&hidLogicalMinimum0,
|
||||
&hidLogicalMaximum1,
|
||||
&hidUsageByte0Bit0,
|
||||
&hidUsageByte0Bit1,
|
||||
&hidUsageByte0Bit2,
|
||||
&hidUsageByte0Bit3,
|
||||
&hidUsageByte0Bit4,
|
||||
&hidUsageByte0Bit5,
|
||||
&(hidUsageByte0Bit0.item),
|
||||
&(hidUsageByte0Bit1.item),
|
||||
&(hidUsageByte0Bit2.item),
|
||||
&(hidUsageByte0Bit3.item),
|
||||
&(hidUsageByte0Bit4.item),
|
||||
&(hidUsageByte0Bit5.item),
|
||||
&hidReportSize1,
|
||||
&hidReportCount6,
|
||||
&hidInputDataVar,
|
||||
@@ -104,9 +159,10 @@ static const USB_HID_Short_Item_t* const hidReportDescriptorItems[] = {
|
||||
};
|
||||
|
||||
/*
|
||||
* Define the length of the HID Report.
|
||||
* This value must match the number of Report bytes defined by hidReportDescriptorItems.
|
||||
* Define the number of HID Reports
|
||||
* Due to XC not supporting designated initializers, this constant has a hard-coded value.
|
||||
* It must equal ( sizeof hidReports / sizeof ( USB_HID_Report_Element_t* ))
|
||||
*/
|
||||
#define HID_REPORT_LENGTH ( 1 )
|
||||
#define HID_REPORT_COUNT ( 1 )
|
||||
|
||||
#endif // __hid_report_descriptor_h__
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
#ifndef __hid_report_descriptor_h__
|
||||
#define __hid_report_descriptor_h__
|
||||
|
||||
#include "xua_hid_report_descriptor.h"
|
||||
#include "xua_hid_report.h"
|
||||
|
||||
#if 0
|
||||
/* Existing static report descriptor kept for reference */
|
||||
@@ -32,38 +32,92 @@ unsigned char hidReportDescriptor[] =
|
||||
/*
|
||||
* 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 hidCollectionApplication = {
|
||||
.header = HID_REPORT_SET_HEADER(1, HID_REPORT_ITEM_TYPE_MAIN, HID_REPORT_ITEM_TAG_COLLECTION),
|
||||
.data = { 0x01, 0x00 } };
|
||||
static const USB_HID_Short_Item_t hidCollectionEnd = {
|
||||
.header = HID_REPORT_SET_HEADER(0, HID_REPORT_ITEM_TYPE_MAIN, HID_REPORT_ITEM_TAG_END_COLLECTION),
|
||||
.data = { 0x00, 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 hidInputConstArray = {
|
||||
.header = HID_REPORT_SET_HEADER(1, HID_REPORT_ITEM_TYPE_MAIN, HID_REPORT_ITEM_TAG_INPUT),
|
||||
.data = { 0x01, 0x00 } };
|
||||
static const USB_HID_Short_Item_t hidInputDataVar = {
|
||||
.header = HID_REPORT_SET_HEADER(1, HID_REPORT_ITEM_TYPE_MAIN, HID_REPORT_ITEM_TAG_INPUT),
|
||||
.data = { 0x02, 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 hidLogicalMaximum0 = {
|
||||
.header = HID_REPORT_SET_HEADER(1, HID_REPORT_ITEM_TYPE_GLOBAL, HID_REPORT_ITEM_TAG_LOGICAL_MAXIMUM),
|
||||
.data = { 0x00, 0x00 } };
|
||||
static const USB_HID_Short_Item_t hidLogicalMaximum1 = {
|
||||
.header = HID_REPORT_SET_HEADER(1, HID_REPORT_ITEM_TYPE_GLOBAL, HID_REPORT_ITEM_TAG_LOGICAL_MAXIMUM),
|
||||
.data = { 0x01, 0x00 } };
|
||||
static const USB_HID_Short_Item_t hidLogicalMinimum0 = {
|
||||
.header = HID_REPORT_SET_HEADER(1, HID_REPORT_ITEM_TYPE_GLOBAL, HID_REPORT_ITEM_TAG_LOGICAL_MINIMUM),
|
||||
.data = { 0x00, 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 hidReportCount2 = {
|
||||
.header = HID_REPORT_SET_HEADER(1, HID_REPORT_ITEM_TYPE_GLOBAL, HID_REPORT_ITEM_TAG_REPORT_COUNT),
|
||||
.data = { 0x02, 0x00 } };
|
||||
static const USB_HID_Short_Item_t hidReportCount6 = {
|
||||
.header = HID_REPORT_SET_HEADER(1, HID_REPORT_ITEM_TYPE_GLOBAL, HID_REPORT_ITEM_TAG_REPORT_COUNT),
|
||||
.data = { 0x06, 0x00 } };
|
||||
static const USB_HID_Short_Item_t hidReportSize1 = {
|
||||
.header = HID_REPORT_SET_HEADER(1, HID_REPORT_ITEM_TYPE_GLOBAL, HID_REPORT_ITEM_TAG_REPORT_SIZE),
|
||||
.data = { 0x01, 0x00 } };
|
||||
|
||||
static const USB_HID_Short_Item_t hidUsageConsumerControl = { .header = 0x09, .data = { 0x01, 0x00 }, .location = 0x00 };
|
||||
static const USB_HID_Short_Item_t hidUsageConsumerControl = {
|
||||
.header = HID_REPORT_SET_HEADER(1, HID_REPORT_ITEM_TYPE_LOCAL, HID_REPORT_ITEM_TAG_USAGE),
|
||||
.data = { 0x01, 0x00 } };
|
||||
|
||||
static const USB_HID_Short_Item_t hidUsagePageConsumer = { .header = 0x05, .data = { 0x0C, 0x00 }, .location = 0x00 };
|
||||
/*
|
||||
* Define the HID Report Descriptor Item, Usage Page, Report ID and length for each HID Report
|
||||
* For internal purposes, a report element with ID of 0 must be included if report IDs are not being used.
|
||||
*/
|
||||
static const USB_HID_Report_Element_t hidReportPageConsumer = {
|
||||
.item.header = HID_REPORT_SET_HEADER(1, HID_REPORT_ITEM_TYPE_GLOBAL, HID_REPORT_ITEM_TAG_USAGE_PAGE),
|
||||
.item.data = { USB_HID_USAGE_PAGE_ID_CONSUMER, 0x00 },
|
||||
.location = HID_REPORT_SET_LOC( 0, 2, 0, 0 )
|
||||
};
|
||||
|
||||
/*
|
||||
* Define configurable items in the HID Report descriptor.
|
||||
*/
|
||||
static USB_HID_Short_Item_t hidUsageByte0Bit5 = { .header = 0x09, .data = { 0xE2, 0x00 }, .location = 0x50 }; // Mute
|
||||
static USB_HID_Short_Item_t hidUsageByte0Bit4 = { .header = 0x09, .data = { 0xEA, 0x00 }, .location = 0x40 }; // Vol-
|
||||
static USB_HID_Short_Item_t hidUsageByte0Bit3 = { .header = 0x09, .data = { 0xE9, 0x00 }, .location = 0x30 }; // Vol+
|
||||
static USB_HID_Short_Item_t hidUsageByte0Bit2 = { .header = 0x09, .data = { 0xB6, 0x00 }, .location = 0x20 }; // Scan Prev
|
||||
static USB_HID_Short_Item_t hidUsageByte0Bit1 = { .header = 0x09, .data = { 0xB5, 0x00 }, .location = 0x10 }; // Scan Next
|
||||
static USB_HID_Short_Item_t hidUsageByte0Bit0 = { .header = 0x09, .data = { 0xB0, 0x00 }, .location = 0x00 }; // Play
|
||||
static USB_HID_Report_Element_t hidUsageByte0Bit5 = {
|
||||
.item.header = HID_REPORT_SET_HEADER(1, HID_REPORT_ITEM_TYPE_LOCAL, HID_REPORT_ITEM_TAG_USAGE),
|
||||
.item.data = { 0xE2, 0x00 },
|
||||
.location = HID_REPORT_SET_LOC(0, 0, 0, 5)
|
||||
}; // Mute
|
||||
static USB_HID_Report_Element_t hidUsageByte0Bit4 = {
|
||||
.item.header = HID_REPORT_SET_HEADER(1, HID_REPORT_ITEM_TYPE_LOCAL, HID_REPORT_ITEM_TAG_USAGE),
|
||||
.item.data = { 0xEA, 0x00 },
|
||||
.location = HID_REPORT_SET_LOC(0, 0, 0, 4)
|
||||
}; // Vol-
|
||||
static USB_HID_Report_Element_t hidUsageByte0Bit3 = {
|
||||
.item.header = HID_REPORT_SET_HEADER(1, HID_REPORT_ITEM_TYPE_LOCAL, HID_REPORT_ITEM_TAG_USAGE),
|
||||
.item.data = { 0xE9, 0x00 },
|
||||
.location = HID_REPORT_SET_LOC(0, 0, 0, 3)
|
||||
}; // Vol+
|
||||
static USB_HID_Report_Element_t hidUsageByte0Bit2 = {
|
||||
.item.header = HID_REPORT_SET_HEADER(1, HID_REPORT_ITEM_TYPE_LOCAL, HID_REPORT_ITEM_TAG_USAGE),
|
||||
.item.data = { 0xB6, 0x00 },
|
||||
.location = HID_REPORT_SET_LOC(0, 0, 0, 2)
|
||||
}; // Scan Prev
|
||||
static USB_HID_Report_Element_t hidUsageByte0Bit1 = {
|
||||
.item.header = HID_REPORT_SET_HEADER(1, HID_REPORT_ITEM_TYPE_LOCAL, HID_REPORT_ITEM_TAG_USAGE),
|
||||
.item.data = { 0xB5, 0x00 },
|
||||
.location = HID_REPORT_SET_LOC(0, 0, 0, 1)
|
||||
}; // Scan Next
|
||||
static USB_HID_Report_Element_t hidUsageByte0Bit0 = {
|
||||
.item.header = HID_REPORT_SET_HEADER(1, HID_REPORT_ITEM_TYPE_LOCAL, HID_REPORT_ITEM_TAG_USAGE),
|
||||
.item.data = { 0xB0, 0x00 },
|
||||
.location = HID_REPORT_SET_LOC(0, 0, 0, 0)
|
||||
}; // Play
|
||||
|
||||
/*
|
||||
* List the configurable items in the HID Report descriptor.
|
||||
* List the configurable elements in the HID Report descriptor.
|
||||
*/
|
||||
static USB_HID_Short_Item_t* const hidConfigurableItems[] = {
|
||||
static USB_HID_Report_Element_t* const hidConfigurableElements[] = {
|
||||
&hidUsageByte0Bit0,
|
||||
&hidUsageByte0Bit1,
|
||||
&hidUsageByte0Bit2,
|
||||
@@ -73,27 +127,28 @@ static USB_HID_Short_Item_t* const hidConfigurableItems[] = {
|
||||
};
|
||||
|
||||
/*
|
||||
* List Usage pages in the HID Report descriptor, one per byte.
|
||||
* List HID Reports, one per Report ID. This should be a usage page item with the relevant
|
||||
* If not using report IDs - still have one with report ID 0
|
||||
*/
|
||||
static const USB_HID_Short_Item_t* const hidUsagePages[] = {
|
||||
&hidUsagePageConsumer
|
||||
static const USB_HID_Report_Element_t* const hidReports[] = {
|
||||
&hidReportPageConsumer
|
||||
};
|
||||
|
||||
/*
|
||||
* List all items in the HID Report descriptor.
|
||||
*/
|
||||
static const USB_HID_Short_Item_t* const hidReportDescriptorItems[] = {
|
||||
&hidUsagePageConsumer,
|
||||
&(hidReportPageConsumer.item),
|
||||
&hidUsageConsumerControl,
|
||||
&hidCollectionApplication,
|
||||
&hidLogicalMinimum0,
|
||||
&hidLogicalMaximum1,
|
||||
&hidUsageByte0Bit0,
|
||||
&hidUsageByte0Bit1,
|
||||
&hidUsageByte0Bit2,
|
||||
&hidUsageByte0Bit3,
|
||||
&hidUsageByte0Bit4,
|
||||
&hidUsageByte0Bit5,
|
||||
&(hidUsageByte0Bit0.item),
|
||||
&(hidUsageByte0Bit1.item),
|
||||
&(hidUsageByte0Bit2.item),
|
||||
&(hidUsageByte0Bit3.item),
|
||||
&(hidUsageByte0Bit4.item),
|
||||
&(hidUsageByte0Bit5.item),
|
||||
&hidReportSize1,
|
||||
&hidReportCount6,
|
||||
&hidInputDataVar,
|
||||
@@ -104,9 +159,10 @@ static const USB_HID_Short_Item_t* const hidReportDescriptorItems[] = {
|
||||
};
|
||||
|
||||
/*
|
||||
* Define the length of the HID Report.
|
||||
* This value must match the number of Report bytes defined by hidReportDescriptorItems.
|
||||
* Define the number of HID Reports
|
||||
* Due to XC not supporting designated initializers, this constant has a hard-coded value.
|
||||
* It must equal ( sizeof hidReports / sizeof ( USB_HID_Report_Element_t* ))
|
||||
*/
|
||||
#define HID_REPORT_LENGTH ( 1 )
|
||||
#define HID_REPORT_COUNT ( 1 )
|
||||
|
||||
#endif // __hid_report_descriptor_h__
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
#ifndef __hid_report_descriptor_h__
|
||||
#define __hid_report_descriptor_h__
|
||||
|
||||
#include "xua_hid_report_descriptor.h"
|
||||
#include "xua_hid_report.h"
|
||||
|
||||
#if 0
|
||||
/* Existing static report descriptor kept for reference */
|
||||
@@ -32,38 +32,91 @@ unsigned char hidReportDescriptor[] =
|
||||
/*
|
||||
* 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 hidCollectionApplication = {
|
||||
.header = HID_REPORT_SET_HEADER(1, HID_REPORT_ITEM_TYPE_MAIN, HID_REPORT_ITEM_TAG_COLLECTION),
|
||||
.data = { 0x01, 0x00 } };
|
||||
static const USB_HID_Short_Item_t hidCollectionEnd = {
|
||||
.header = HID_REPORT_SET_HEADER(0, HID_REPORT_ITEM_TYPE_MAIN, HID_REPORT_ITEM_TAG_END_COLLECTION),
|
||||
.data = { 0x00, 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 hidInputConstArray = {
|
||||
.header = HID_REPORT_SET_HEADER(1, HID_REPORT_ITEM_TYPE_MAIN, HID_REPORT_ITEM_TAG_INPUT),
|
||||
.data = { 0x01, 0x00 } };
|
||||
static const USB_HID_Short_Item_t hidInputDataVar = {
|
||||
.header = HID_REPORT_SET_HEADER(1, HID_REPORT_ITEM_TYPE_MAIN, HID_REPORT_ITEM_TAG_INPUT),
|
||||
.data = { 0x02, 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 hidLogicalMaximum0 = {
|
||||
.header = HID_REPORT_SET_HEADER(1, HID_REPORT_ITEM_TYPE_GLOBAL, HID_REPORT_ITEM_TAG_LOGICAL_MAXIMUM),
|
||||
.data = { 0x00, 0x00 } };
|
||||
static const USB_HID_Short_Item_t hidLogicalMaximum1 = {
|
||||
.header = HID_REPORT_SET_HEADER(1, HID_REPORT_ITEM_TYPE_GLOBAL, HID_REPORT_ITEM_TAG_LOGICAL_MAXIMUM),
|
||||
.data = { 0x01, 0x00 } };
|
||||
static const USB_HID_Short_Item_t hidLogicalMinimum0 = {
|
||||
.header = HID_REPORT_SET_HEADER(1, HID_REPORT_ITEM_TYPE_GLOBAL, HID_REPORT_ITEM_TAG_LOGICAL_MINIMUM),
|
||||
.data = { 0x00, 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 hidReportCount2 = {
|
||||
.header = HID_REPORT_SET_HEADER(1, HID_REPORT_ITEM_TYPE_GLOBAL, HID_REPORT_ITEM_TAG_REPORT_COUNT),
|
||||
.data = { 0x02, 0x00 } };
|
||||
static const USB_HID_Short_Item_t hidReportCount6 = {
|
||||
.header = HID_REPORT_SET_HEADER(1, HID_REPORT_ITEM_TYPE_GLOBAL, HID_REPORT_ITEM_TAG_REPORT_COUNT),
|
||||
.data = { 0x06, 0x00 } };
|
||||
static const USB_HID_Short_Item_t hidReportSize1 = {
|
||||
.header = HID_REPORT_SET_HEADER(1, HID_REPORT_ITEM_TYPE_GLOBAL, HID_REPORT_ITEM_TAG_REPORT_SIZE),
|
||||
.data = { 0x01, 0x00 } };
|
||||
|
||||
static const USB_HID_Short_Item_t hidUsageConsumerControl = { .header = 0x09, .data = { 0x01, 0x00 }, .location = 0x00 };
|
||||
static const USB_HID_Short_Item_t hidUsageConsumerControl = {
|
||||
.header = HID_REPORT_SET_HEADER(1, HID_REPORT_ITEM_TYPE_LOCAL, HID_REPORT_ITEM_TAG_USAGE),
|
||||
.data = { 0x01, 0x00 } };
|
||||
|
||||
static const USB_HID_Short_Item_t hidUsagePageConsumer = { .header = 0x05, .data = { 0x0C, 0x00 }, .location = 0x00 };
|
||||
/*
|
||||
* Define the HID Report Descriptor Item, Usage Page, Report ID and length for each HID Report
|
||||
* For internal purposes, a report element with ID of 0 must be included if report IDs are not being used.
|
||||
*/
|
||||
static const USB_HID_Report_Element_t hidReportPageConsumer = {
|
||||
.item.header = HID_REPORT_SET_HEADER(1, HID_REPORT_ITEM_TYPE_GLOBAL, HID_REPORT_ITEM_TAG_USAGE_PAGE),
|
||||
.item.data = { USB_HID_USAGE_PAGE_ID_CONSUMER, 0x00 },
|
||||
.location = HID_REPORT_SET_LOC( 0, 1, 0, 0 ) };
|
||||
|
||||
/*
|
||||
* Define configurable items in the HID Report descriptor.
|
||||
*/
|
||||
static USB_HID_Short_Item_t hidUsageByte0Bit5 = { .header = 0x09, .data = { 0xE2, 0x00 }, .location = 0x50 }; // Mute
|
||||
static USB_HID_Short_Item_t hidUsageByte0Bit4 = { .header = 0x09, .data = { 0xEA, 0x00 }, .location = 0x40 }; // Vol-
|
||||
static USB_HID_Short_Item_t hidUsageByte0Bit3 = { .header = 0x09, .data = { 0xE9, 0x00 }, .location = 0x30 }; // Vol+
|
||||
static USB_HID_Short_Item_t hidUsageByte0Bit2 = { .header = 0x09, .data = { 0xB6, 0x00 }, .location = 0x20 }; // Scan Prev
|
||||
static USB_HID_Short_Item_t hidUsageByte0Bit1 = { .header = 0x09, .data = { 0xB5, 0x00 }, .location = 0x10 }; // Scan Next
|
||||
static USB_HID_Short_Item_t hidUsageByte0Bit0 = { .header = 0x09, .data = { 0xB0, 0x00 }, .location = 0x00 }; // Play
|
||||
static USB_HID_Report_Element_t hidUsageByte0Bit5 = {
|
||||
.item.header = HID_REPORT_SET_HEADER(1, HID_REPORT_ITEM_TYPE_LOCAL, HID_REPORT_ITEM_TAG_USAGE),
|
||||
.item.data = { 0xE2, 0x00 },
|
||||
.location = HID_REPORT_SET_LOC( 0, 0, 0, 5 )
|
||||
}; // Mute
|
||||
static USB_HID_Report_Element_t hidUsageByte0Bit4 = {
|
||||
.item.header = HID_REPORT_SET_HEADER(1, HID_REPORT_ITEM_TYPE_LOCAL, HID_REPORT_ITEM_TAG_USAGE),
|
||||
.item.data = { 0xEA, 0x00 },
|
||||
.location = HID_REPORT_SET_LOC( 0, 0, 0, 4 )
|
||||
}; // Vol-
|
||||
static USB_HID_Report_Element_t hidUsageByte0Bit3 = {
|
||||
.item.header = HID_REPORT_SET_HEADER(1, HID_REPORT_ITEM_TYPE_LOCAL, HID_REPORT_ITEM_TAG_USAGE),
|
||||
.item.data = { 0xE9, 0x00 },
|
||||
.location = HID_REPORT_SET_LOC( 0, 0, 0, 3 )
|
||||
}; // Vol+
|
||||
static USB_HID_Report_Element_t hidUsageByte0Bit2 = {
|
||||
.item.header = HID_REPORT_SET_HEADER(1, HID_REPORT_ITEM_TYPE_LOCAL, HID_REPORT_ITEM_TAG_USAGE),
|
||||
.item.data = { 0xB6, 0x00 },
|
||||
.location = HID_REPORT_SET_LOC( 0, 0, 0, 2 )
|
||||
}; // Scan Prev
|
||||
static USB_HID_Report_Element_t hidUsageByte0Bit1 = {
|
||||
.item.header = HID_REPORT_SET_HEADER(1, HID_REPORT_ITEM_TYPE_LOCAL, HID_REPORT_ITEM_TAG_USAGE),
|
||||
.item.data = { 0xB5, 0x00 },
|
||||
.location = HID_REPORT_SET_LOC( 0, 0, 0, 1 )
|
||||
}; // Scan Next
|
||||
static USB_HID_Report_Element_t hidUsageByte0Bit0 = {
|
||||
.item.header = HID_REPORT_SET_HEADER(1, HID_REPORT_ITEM_TYPE_LOCAL, HID_REPORT_ITEM_TAG_USAGE),
|
||||
.item.data = { 0xB0, 0x00 },
|
||||
.location = HID_REPORT_SET_LOC( 0, 0, 0, 0 )
|
||||
}; // Play
|
||||
|
||||
/*
|
||||
* List the configurable items in the HID Report descriptor.
|
||||
*/
|
||||
static USB_HID_Short_Item_t* const hidConfigurableItems[] = {
|
||||
static USB_HID_Report_Element_t* const hidConfigurableElements[] = {
|
||||
&hidUsageByte0Bit0,
|
||||
&hidUsageByte0Bit1,
|
||||
&hidUsageByte0Bit2,
|
||||
@@ -73,27 +126,28 @@ static USB_HID_Short_Item_t* const hidConfigurableItems[] = {
|
||||
};
|
||||
|
||||
/*
|
||||
* List Usage pages in the HID Report descriptor, one per byte.
|
||||
* List HID Reports, one per Report ID. This should be a usage page item with the relevant
|
||||
* If not using report IDs - still have one with report ID 0
|
||||
*/
|
||||
static const USB_HID_Short_Item_t* const hidUsagePages[] = {
|
||||
&hidUsagePageConsumer
|
||||
static const USB_HID_Report_Element_t* const hidReports[] = {
|
||||
&hidReportPageConsumer
|
||||
};
|
||||
|
||||
/*
|
||||
* List all items in the HID Report descriptor.
|
||||
*/
|
||||
static const USB_HID_Short_Item_t* const hidReportDescriptorItems[] = {
|
||||
&hidUsagePageConsumer,
|
||||
static const USB_HID_Short_Item_t * const hidReportDescriptorItems[] = {
|
||||
&(hidReportPageConsumer.item),
|
||||
&hidUsageConsumerControl,
|
||||
&hidCollectionApplication,
|
||||
&hidLogicalMinimum0,
|
||||
&hidLogicalMaximum1,
|
||||
&hidUsageByte0Bit0,
|
||||
&hidUsageByte0Bit1,
|
||||
&hidUsageByte0Bit2,
|
||||
&hidUsageByte0Bit3,
|
||||
&hidUsageByte0Bit4,
|
||||
&hidUsageByte0Bit5,
|
||||
&(hidUsageByte0Bit0.item),
|
||||
&(hidUsageByte0Bit1.item),
|
||||
&(hidUsageByte0Bit2.item),
|
||||
&(hidUsageByte0Bit3.item),
|
||||
&(hidUsageByte0Bit4.item),
|
||||
&(hidUsageByte0Bit5.item),
|
||||
&hidReportSize1,
|
||||
&hidReportCount6,
|
||||
&hidInputDataVar,
|
||||
@@ -104,9 +158,10 @@ static const USB_HID_Short_Item_t* const hidReportDescriptorItems[] = {
|
||||
};
|
||||
|
||||
/*
|
||||
* Define the length of the HID Report.
|
||||
* This value must match the number of Report bytes defined by hidReportDescriptorItems.
|
||||
* Define the number of HID Reports
|
||||
* Due to XC not supporting designated initializers, this constant has a hard-coded value.
|
||||
* It must equal ( sizeof hidReports / sizeof ( USB_HID_Report_Element_t* ))
|
||||
*/
|
||||
#define HID_REPORT_LENGTH ( 1 )
|
||||
#define HID_REPORT_COUNT ( 1 )
|
||||
|
||||
#endif // __hid_report_descriptor_h__
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
VERSION = 2.1.1
|
||||
VERSION = 3.0.0
|
||||
|
||||
DEPENDENT_MODULES = lib_logging(>=3.0.0) \
|
||||
lib_xassert(>=4.0.0) \
|
||||
|
||||
@@ -21,8 +21,9 @@
|
||||
#include "testct_byref.h"
|
||||
|
||||
#if( 0 < HID_CONTROLS )
|
||||
#include "xua_hid_report_descriptor.h"
|
||||
#include "xua_hid_report.h"
|
||||
#include "user_hid.h"
|
||||
#include "xua_hid.h"
|
||||
unsigned char g_hidData[HID_MAX_DATA_BYTES] = {0};
|
||||
#endif
|
||||
|
||||
@@ -372,9 +373,15 @@ void XUA_Buffer_Ep(register chanend c_aud_out,
|
||||
#endif
|
||||
|
||||
#if( 0 < HID_CONTROLS )
|
||||
UserHIDInit();
|
||||
{
|
||||
int hidDataLength = hidGetReportLength();
|
||||
XUD_SetReady_In(ep_hid, g_hidData, hidDataLength);
|
||||
while (!hidIsReportDescriptorPrepared())
|
||||
;
|
||||
|
||||
/* Get the last report - we don't really care which it is, so long as there's some data we can grab. */
|
||||
int hidReportLength = (int) UserHIDGetData(hidGetReportIdLimit() - 1, g_hidData);
|
||||
|
||||
XUD_SetReady_In(ep_hid, g_hidData, hidReportLength);
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -887,11 +894,22 @@ void XUA_Buffer_Ep(register chanend c_aud_out,
|
||||
|
||||
#if( 0 < HID_CONTROLS )
|
||||
/* HID Report Data */
|
||||
case XUD_SetData_Select(c_hid, ep_hid, result):
|
||||
case hidIsChangePending(0U) || !HidIsSetIdleSilenced(0U) => XUD_SetData_Select(c_hid, ep_hid, result):
|
||||
{
|
||||
int hidDataLength = hidGetReportLength();
|
||||
UserHIDGetData(g_hidData);
|
||||
XUD_SetReady_In(ep_hid, g_hidData, hidDataLength);
|
||||
timer tmr;
|
||||
unsigned reportTime;
|
||||
tmr :> reportTime;
|
||||
|
||||
for(unsigned id = 0U; id < hidGetReportIdLimit(); ++id) {
|
||||
if(0U == id || (hidIsChangePending(id) || !HidIsSetIdleSilenced(id))) {
|
||||
hidCaptureReportTime(id, reportTime);
|
||||
int hidDataLength = (int) UserHIDGetData(id, g_hidData);
|
||||
XUD_SetReady_In(ep_hid, g_hidData, hidDataLength);
|
||||
hidCalcNextReportTime(id);
|
||||
hidClearChangePending(id);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
|
||||
@@ -66,7 +66,7 @@ enum USBInterfaceNumber
|
||||
INTERFACE_COUNT /* End marker */
|
||||
};
|
||||
|
||||
#if( 0 < HID_CONTROLS )
|
||||
#ifndef ENDPOINT_INT_INTERVAL_IN_HID
|
||||
#define ENDPOINT_INT_INTERVAL_IN_HID 0x08
|
||||
#endif
|
||||
|
||||
|
||||
@@ -28,7 +28,7 @@
|
||||
#if( 0 < HID_CONTROLS )
|
||||
#include "hid.h"
|
||||
#include "xua_hid.h"
|
||||
#include "xua_hid_report_descriptor.h"
|
||||
#include "xua_hid_report.h"
|
||||
#endif
|
||||
|
||||
#if DSD_CHANS_DAC > 0
|
||||
@@ -525,6 +525,7 @@ void XUA_Endpoint0_init(chanend c_ep0_out, chanend c_ep0_in, NULLABLE_RESOURCE(c
|
||||
#endif
|
||||
|
||||
#if( 0 < HID_CONTROLS )
|
||||
hidReportInit();
|
||||
hidPrepareReportDescriptor();
|
||||
|
||||
size_t hidReportDescriptorLength = hidGetReportDescriptorLength();
|
||||
|
||||
@@ -1,36 +1,60 @@
|
||||
// Copyright 2013-2021 XMOS LIMITED.
|
||||
// This Software is subject to the terms of the XMOS Public Licence: Version 1.
|
||||
|
||||
/**
|
||||
* @brief Human Interface Device (HID) API
|
||||
*
|
||||
* This file defines the Application Programming Interface (API) used to record HID
|
||||
* events and retrieve a HID Report for sending to a host.
|
||||
* The using application has the responsibility to fulfill this API.
|
||||
* Document section numbers refer to the HID Device Class Definition, version 1.11.
|
||||
*/
|
||||
|
||||
#ifndef __USER_HID_H__
|
||||
#define __USER_HID_H__
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
/**
|
||||
* \brief HID event
|
||||
*
|
||||
* This struct identifies the location within the HID Report for an event and
|
||||
* The value to report for that location.
|
||||
* This struct identifies:
|
||||
* - the HID Report that reports an event, i.e., the ID,
|
||||
* - the location within the HID Report for the event, i.e., the byte and bit, and
|
||||
* - the value to report for that location (typically interpreted as a Boolean).
|
||||
* It assumes only single bit flags within the HID Report.
|
||||
*/
|
||||
typedef struct hidEvent_t {
|
||||
unsigned bit;
|
||||
unsigned byte;
|
||||
unsigned id;
|
||||
unsigned value;
|
||||
} hidEvent_t;
|
||||
|
||||
#define HID_MAX_DATA_BYTES 4
|
||||
#define HID_MAX_DATA_BYTES ( 4 )
|
||||
#define HID_EVENT_INVALID_ID ( 0x100 )
|
||||
|
||||
#if( 0 < HID_CONTROLS )
|
||||
|
||||
/**
|
||||
* \brief Get the data for the next HID report
|
||||
* \brief Get the data for the next HID Report
|
||||
*
|
||||
* \note This function returns the HID data as a list of unsigned char because the
|
||||
* \c XUD_SetReady_In() accepts data for transmission to the USB Host using
|
||||
* this type.
|
||||
*
|
||||
* \param{out} hidData The HID data
|
||||
* \param[in] id The HID Report ID (see 5.6, 6.2.2.7, 8.1 and 8.2)
|
||||
* Set to zero if the application provides only one HID Report
|
||||
* which does not include a Report ID
|
||||
* \param[out] hidData The HID data
|
||||
* If using Report IDs, this function places the Report ID in
|
||||
* the first element; otherwise the first element holds the
|
||||
* first byte of HID event data.
|
||||
*
|
||||
* \returns The length of the HID Report in the \a hidData argument
|
||||
* \retval Zero means no new HID event data has been recorded for the given \a id
|
||||
*/
|
||||
void UserHIDGetData( unsigned char hidData[ HID_MAX_DATA_BYTES ]);
|
||||
size_t UserHIDGetData( const unsigned id, unsigned char hidData[ HID_MAX_DATA_BYTES ]);
|
||||
|
||||
/**
|
||||
* \brief Initialize HID processing
|
||||
@@ -40,15 +64,18 @@ void UserHIDInit( void );
|
||||
/**
|
||||
* \brief Record that a HID event has occurred
|
||||
*
|
||||
* \param{in} hidEvent A list of events which have occurred.
|
||||
* Each element specifies a bit and byte in the HID Report and the value for it.
|
||||
* \param{in} hidEventCnt The length of the \a hidEvent list.
|
||||
* \param[in] hidEvent A list of events which have occurred.
|
||||
* Each element specifies a HID Report ID, a bit and byte
|
||||
* within the HID Report and the value for it.
|
||||
* Set the Report ID to zero if not using Report IDs
|
||||
* (see 5.6, 6.2.2.7, 8.1 and 8.2).
|
||||
* \param[in] hidEventCnt The length of the \a hidEvent list.
|
||||
*
|
||||
* \returns A Boolean flag indicating the status of the operation
|
||||
* \retval False No recording of the event(s) occurred
|
||||
* \retval True Recording of the event(s) occurred
|
||||
* \returns The index of the first unrecorded event in \a hidEvent
|
||||
* \retval Zero indicates no events were recorded
|
||||
* \retval \a hidEventCnt indicates all events were recorded
|
||||
*/
|
||||
unsigned UserHIDRecordEvent( const hidEvent_t hidEvent[], const unsigned hidEventCnt );
|
||||
size_t UserHIDRecordEvent( const hidEvent_t hidEvent[], const size_t hidEventCnt );
|
||||
|
||||
#endif /* ( 0 < HID_CONTROLS ) */
|
||||
#endif /* __USER_HID_H__ */
|
||||
|
||||
@@ -7,38 +7,15 @@
|
||||
#include "xud.h"
|
||||
#include "xud_std_requests.h"
|
||||
#include "xua_hid.h"
|
||||
#include "xua_hid_report.h"
|
||||
|
||||
#if( 0 < HID_CONTROLS )
|
||||
#define MS_IN_TICKS 100000U
|
||||
|
||||
static unsigned s_hidChangePending = 0U;
|
||||
static unsigned s_hidCurrentPeriod = ENDPOINT_INT_INTERVAL_IN_HID * MS_IN_TICKS;
|
||||
static unsigned s_hidIdleActive = 0U;
|
||||
static unsigned s_hidIndefiniteDuration = 0U;
|
||||
static unsigned s_hidNextReportTime = 0U;
|
||||
static unsigned s_hidReportTime = 0U;
|
||||
|
||||
unsafe {
|
||||
volatile unsigned * unsafe s_hidChangePendingPtr = &s_hidChangePending;
|
||||
}
|
||||
|
||||
static unsigned HidCalcNewReportTime( const unsigned currentPeriod, const unsigned reportTime, const unsigned reportToSetIdleInterval, const unsigned newPeriod );
|
||||
static unsigned HidCalcReportToSetIdleInterval( const unsigned reportTime );
|
||||
static unsigned HidFindSetIdleActivationPoint( const unsigned currentPeriod, const unsigned timeWithinPeriod );
|
||||
static XUD_Result_t HidProcessSetIdleRequest( XUD_ep c_ep0_out, XUD_ep c_ep0_in, USB_SetupPacket_t &sp );
|
||||
static unsigned HidTimeDiff( const unsigned earlierTime, const unsigned laterTime );
|
||||
|
||||
void HidCalcNextReportTime( void )
|
||||
{
|
||||
s_hidNextReportTime = s_hidReportTime + s_hidCurrentPeriod;
|
||||
}
|
||||
|
||||
void HidCaptureReportTime( void )
|
||||
{
|
||||
timer tmr;
|
||||
tmr :> s_hidReportTime;
|
||||
}
|
||||
|
||||
XUD_Result_t HidInterfaceClassRequests(
|
||||
XUD_ep c_ep0_out,
|
||||
XUD_ep c_ep0_in,
|
||||
@@ -58,41 +35,22 @@ XUD_Result_t HidInterfaceClassRequests(
|
||||
return result;
|
||||
}
|
||||
|
||||
void HidClearChangePending( void )
|
||||
unsigned HidIsSetIdleSilenced( const unsigned id )
|
||||
{
|
||||
unsafe {
|
||||
*s_hidChangePendingPtr = 0U;
|
||||
}
|
||||
}
|
||||
unsigned isSilenced = hidIsIdleActive( id );
|
||||
|
||||
unsigned HidIsChangePending( void )
|
||||
{
|
||||
return( s_hidChangePending != 0 );
|
||||
}
|
||||
|
||||
unsigned HidIsSetIdleSilenced( void )
|
||||
{
|
||||
unsigned isSilenced = s_hidIdleActive;
|
||||
|
||||
if( s_hidIdleActive ) {
|
||||
if( !isSilenced ) {
|
||||
unsigned currentTime;
|
||||
// Use inline assembly to access the time without creating a side-effect.
|
||||
// The mapper complains if the time comes from an XC timer because this function is called in the guard of a select case.
|
||||
// Appearently the use of a timer creates a side-effect that prohibits the operation of the select functionality.
|
||||
asm volatile( "gettime %0" : "=r" ( currentTime ));
|
||||
isSilenced = ( s_hidIndefiniteDuration || ( timeafter( s_hidNextReportTime, currentTime )));
|
||||
isSilenced = ( 0U == hidGetReportPeriod( id ) || ( timeafter( hidGetNextReportTime( id ), currentTime )));
|
||||
}
|
||||
|
||||
return isSilenced;
|
||||
}
|
||||
|
||||
void HidSetChangePending( void )
|
||||
{
|
||||
unsafe {
|
||||
*s_hidChangePendingPtr = 1;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Calculate the timer value for sending the next HID Report.
|
||||
*
|
||||
@@ -112,7 +70,7 @@ void HidSetChangePending( void )
|
||||
*/
|
||||
static unsigned HidCalcNewReportTime( const unsigned currentPeriod, const unsigned reportTime, const unsigned reportToSetIdleInterval, const unsigned newPeriod )
|
||||
{
|
||||
unsigned nextReportTime = 0;
|
||||
unsigned nextReportTime = 0U;
|
||||
|
||||
if( HidFindSetIdleActivationPoint( currentPeriod, reportToSetIdleInterval )) {
|
||||
/* Activate immediately after sending the next HID Report */
|
||||
@@ -209,18 +167,20 @@ static XUD_Result_t HidProcessSetIdleRequest( XUD_ep c_ep0_out, XUD_ep c_ep0_in,
|
||||
Any Interface value other than INTERFACE_NUMBER_HID indicates an error by the USB Host.
|
||||
*/
|
||||
if(( 0U == reportId ) && ( INTERFACE_NUMBER_HID == interfaceNum )) {
|
||||
s_hidIdleActive = (( 0U == duration ) || ( ENDPOINT_INT_INTERVAL_IN_HID < duration ));
|
||||
hidSetIdle( reportId, ( 0U == duration ) || ( ENDPOINT_INT_INTERVAL_IN_HID < duration ));
|
||||
|
||||
if( s_hidIdleActive ) {
|
||||
unsigned reportToSetIdleInterval = HidCalcReportToSetIdleInterval( s_hidReportTime );
|
||||
s_hidNextReportTime = HidCalcNewReportTime( s_hidCurrentPeriod, s_hidReportTime, reportToSetIdleInterval, duration * MS_IN_TICKS );
|
||||
s_hidCurrentPeriod = duration * MS_IN_TICKS;
|
||||
s_hidIndefiniteDuration = ( 0U == duration );
|
||||
unsigned currentPeriod = hidGetReportPeriod( reportId );
|
||||
if( hidIsIdleActive( reportId )) {
|
||||
unsigned reportTime = hidGetReportTime( reportId );
|
||||
unsigned reportToSetIdleInterval = HidCalcReportToSetIdleInterval( reportTime );
|
||||
unsigned nextReportTime = HidCalcNewReportTime( currentPeriod, reportTime, reportToSetIdleInterval, duration * MS_IN_TICKS );
|
||||
hidSetNextReportTime( reportId, nextReportTime );
|
||||
currentPeriod = duration * MS_IN_TICKS;
|
||||
} else {
|
||||
s_hidCurrentPeriod = ENDPOINT_INT_INTERVAL_IN_HID * MS_IN_TICKS;
|
||||
s_hidIndefiniteDuration = 0U;
|
||||
currentPeriod = ENDPOINT_INT_INTERVAL_IN_HID * MS_IN_TICKS;
|
||||
}
|
||||
|
||||
hidSetReportPeriod( reportId, currentPeriod );
|
||||
result = XUD_DoSetRequestStatus( c_ep0_in );
|
||||
}
|
||||
|
||||
|
||||
785
lib_xua/src/hid/hid_report.c
Normal file
785
lib_xua/src/hid/hid_report.c
Normal file
@@ -0,0 +1,785 @@
|
||||
// Copyright 2021 XMOS LIMITED.
|
||||
// This Software is subject to the terms of the XMOS Public Licence: Version 1.
|
||||
#include <assert.h>
|
||||
#include <stddef.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <xs1.h>
|
||||
|
||||
#include "descriptor_defs.h"
|
||||
#include "xua_hid_report.h"
|
||||
#include "hid_report_descriptor.h"
|
||||
|
||||
|
||||
#define HID_REPORT_ITEM_LOCATION_SIZE ( 1 )
|
||||
#define HID_REPORT_DESCRIPTOR_ITEM_COUNT ( sizeof hidReportDescriptorItems / sizeof ( USB_HID_Short_Item_t* ))
|
||||
#define HID_REPORT_DESCRIPTOR_MAX_LENGTH ( HID_REPORT_DESCRIPTOR_ITEM_COUNT * \
|
||||
( sizeof ( USB_HID_Short_Item_t ) - HID_REPORT_ITEM_LOCATION_SIZE ))
|
||||
/*
|
||||
* Each element in s_hidChangePending corresponds to an element in hidReports.
|
||||
*/
|
||||
static unsigned s_hidChangePending[ HID_REPORT_COUNT ];
|
||||
static unsigned char s_hidReportDescriptor[ HID_REPORT_DESCRIPTOR_MAX_LENGTH ];
|
||||
static size_t s_hidReportDescriptorLength;
|
||||
static unsigned s_hidReportDescriptorPrepared;
|
||||
|
||||
static unsigned s_hidCurrentPeriod[ HID_REPORT_COUNT ];
|
||||
static unsigned s_hidIdleActive[ HID_REPORT_COUNT ];
|
||||
static unsigned s_hidNextReportTime[ HID_REPORT_COUNT ];
|
||||
static unsigned s_hidReportTime[ HID_REPORT_COUNT ];
|
||||
|
||||
/**
|
||||
* @brief Get the bit position from the location of a report element
|
||||
*
|
||||
* Parameters:
|
||||
*
|
||||
* @param[in] location The \c location field from a \c USB_HID_Report_Element_t
|
||||
*
|
||||
* @return The bit position of the report element
|
||||
*/
|
||||
static unsigned hidGetElementBitLocation( const unsigned short location );
|
||||
|
||||
/**
|
||||
* @brief Get the byte position from the location of a report element
|
||||
*
|
||||
* Parameters:
|
||||
*
|
||||
* @param[in] location The \c location field from a \c USB_HID_Report_Element_t
|
||||
*
|
||||
* @return The byte position of the report element within the HID report
|
||||
*/
|
||||
static unsigned hidGetElementByteLocation( const unsigned short location );
|
||||
|
||||
/**
|
||||
* @brief Get the report identifier from the location of a report element
|
||||
*
|
||||
* Parameters:
|
||||
*
|
||||
* @param[in] location The \c location field from a \c USB_HID_Report_Element_t
|
||||
*
|
||||
* @return The report id of the report element within the HID report
|
||||
*/
|
||||
static unsigned hidGetElementReportId( const unsigned short location );
|
||||
|
||||
/**
|
||||
* @brief Get the report length from the location of a report element
|
||||
*
|
||||
* Parameters:
|
||||
*
|
||||
* @param[in] location The \c location field from a \c USB_HID_Report_Element_t
|
||||
*
|
||||
* @return The length of the HID report
|
||||
*/
|
||||
static size_t hidGetElementReportLength( const unsigned short location );
|
||||
|
||||
/**
|
||||
* @brief Get the number of data bytes from the header of an Item
|
||||
*
|
||||
* Parameters:
|
||||
*
|
||||
* @param[in] header The \c header field from a \c USB_HID_Short_Item
|
||||
*
|
||||
* @return The amount of data for the Item
|
||||
*/
|
||||
static unsigned hidGetItemSize( const unsigned char header );
|
||||
|
||||
/**
|
||||
* @brief Get the Tag from the header of an Item
|
||||
*
|
||||
* Parameters:
|
||||
*
|
||||
* @param[in] header The \c header field from a \c USB_HID_Short_Item
|
||||
*
|
||||
* @return The Tag of the Item
|
||||
*/
|
||||
static unsigned hidGetItemTag( const unsigned char header );
|
||||
|
||||
/**
|
||||
* @brief Get the Type from the header of an Item
|
||||
*
|
||||
* Parameters:
|
||||
*
|
||||
* @param[in] header The \c header field from a \c USB_HID_Short_Item
|
||||
*
|
||||
* @return The Type of the Item
|
||||
*/
|
||||
static unsigned hidGetItemType( const unsigned char header );
|
||||
|
||||
/**
|
||||
* @brief Get the Usage Page number for a given byte in the HID Report
|
||||
*
|
||||
* Parameters:
|
||||
*
|
||||
* @param[in] id The HID Report ID for the Usage Page.
|
||||
* A value of zero means the application does not use Report IDs.
|
||||
*
|
||||
* @return The USB HID Usage Page code or zero if the \a id parameter is out-of-range
|
||||
*/
|
||||
static unsigned hidGetUsagePage( const unsigned id );
|
||||
|
||||
/**
|
||||
* @brief Translate an Item from the \c USB_HID_Short_Item format to raw bytes
|
||||
*
|
||||
* Parameters:
|
||||
*
|
||||
* @param[in] inPtr A pointer to a \c USB_HID_Short_Item
|
||||
* @param[in,out] outPtrPtr A pointer to a pointer to the next available space in the raw
|
||||
* byte buffer. Passed as a pointer to a pointer to allow this
|
||||
* function to return the updated pointer to the raw byte buffer.
|
||||
*
|
||||
* @return The number of bytes placed in the raw byte buffer
|
||||
*/
|
||||
static size_t hidTranslateItem( const USB_HID_Short_Item_t* inPtr, unsigned char** outPtrPtr );
|
||||
|
||||
|
||||
void hidCalcNextReportTime( const unsigned id )
|
||||
{
|
||||
for( size_t idx = 0U; idx < HID_REPORT_COUNT; ++idx ) {
|
||||
if( id == hidGetElementReportId( hidReports[ idx ]->location )) {
|
||||
s_hidNextReportTime[ idx ] = s_hidReportTime[ idx ] + s_hidCurrentPeriod[ idx ];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void hidCaptureReportTime( const unsigned id, const unsigned time )
|
||||
{
|
||||
for( size_t idx = 0U; idx < HID_REPORT_COUNT; ++idx ) {
|
||||
if( id == hidGetElementReportId( hidReports[ idx ]->location )) {
|
||||
s_hidReportTime[ idx ] = time;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void hidClearChangePending( const unsigned id )
|
||||
{
|
||||
for( size_t idx = 0U; idx < HID_REPORT_COUNT; ++idx) {
|
||||
if(( id == 0U ) || ( id == hidGetElementReportId( hidReports[ idx ]->location ))) {
|
||||
s_hidChangePending[ idx ] = 0U;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static unsigned hidGetElementBitLocation( const unsigned short location )
|
||||
{
|
||||
unsigned bBit = ( location & HID_REPORT_ELEMENT_LOC_BIT_MASK ) >> HID_REPORT_ELEMENT_LOC_BIT_SHIFT;
|
||||
return bBit;
|
||||
}
|
||||
|
||||
static unsigned hidGetElementByteLocation( const unsigned short location )
|
||||
{
|
||||
unsigned bByte = ( location & HID_REPORT_ELEMENT_LOC_BYTE_MASK ) >> HID_REPORT_ELEMENT_LOC_BYTE_SHIFT;
|
||||
return bByte;
|
||||
}
|
||||
|
||||
static unsigned hidGetElementReportId( const unsigned short location )
|
||||
{
|
||||
unsigned bReportId = ( location & HID_REPORT_ELEMENT_LOC_ID_MASK ) >> HID_REPORT_ELEMENT_LOC_ID_SHIFT;
|
||||
return bReportId;
|
||||
}
|
||||
|
||||
static size_t hidGetElementReportLength( const unsigned short location )
|
||||
{
|
||||
size_t bReportLen = (size_t)( location & HID_REPORT_ELEMENT_LOC_LEN_MASK ) >> HID_REPORT_ELEMENT_LOC_LEN_SHIFT;
|
||||
return bReportLen;
|
||||
}
|
||||
|
||||
static unsigned hidGetItemSize( const unsigned char header )
|
||||
{
|
||||
unsigned bSize = ( header & HID_REPORT_ITEM_HDR_SIZE_MASK ) >> HID_REPORT_ITEM_HDR_SIZE_SHIFT;
|
||||
return bSize;
|
||||
}
|
||||
|
||||
static unsigned hidGetItemTag( const unsigned char header )
|
||||
{
|
||||
unsigned bTag = ( header & HID_REPORT_ITEM_HDR_TAG_MASK ) >> HID_REPORT_ITEM_HDR_TAG_SHIFT;
|
||||
return bTag;
|
||||
}
|
||||
|
||||
static unsigned hidGetItemType( const unsigned char header )
|
||||
{
|
||||
unsigned bType = ( header & HID_REPORT_ITEM_HDR_TYPE_MASK ) >> HID_REPORT_ITEM_HDR_TYPE_SHIFT;
|
||||
return bType;
|
||||
}
|
||||
|
||||
unsigned hidGetNextReportTime( const unsigned id ) {
|
||||
unsigned retVal = 0U;
|
||||
|
||||
for( size_t idx = 0U; idx < HID_REPORT_COUNT; ++idx ) {
|
||||
if( id == hidGetElementReportId( hidReports[ idx ]->location )) {
|
||||
retVal = s_hidNextReportTime[ idx ];
|
||||
}
|
||||
}
|
||||
return retVal;
|
||||
}
|
||||
|
||||
unsigned hidIsReportDescriptorPrepared( void )
|
||||
{
|
||||
return s_hidReportDescriptorPrepared;
|
||||
}
|
||||
|
||||
unsigned char* hidGetReportDescriptor( void )
|
||||
{
|
||||
unsigned char* retVal = NULL;
|
||||
|
||||
if( s_hidReportDescriptorPrepared ) {
|
||||
retVal = s_hidReportDescriptor;
|
||||
}
|
||||
|
||||
return retVal;
|
||||
}
|
||||
|
||||
size_t hidGetReportDescriptorLength( void )
|
||||
{
|
||||
size_t retVal = ( s_hidReportDescriptorPrepared ) ? s_hidReportDescriptorLength : 0U;
|
||||
return retVal;
|
||||
}
|
||||
|
||||
unsigned hidGetReportIdLimit ( void ) {
|
||||
unsigned retVal = 0U;
|
||||
|
||||
for( size_t idx = 0U; idx < HID_REPORT_COUNT; ++idx ) {
|
||||
unsigned reportId = hidGetElementReportId( hidReports[ idx ]->location );
|
||||
if( reportId >= retVal ) {
|
||||
retVal = reportId + 1;
|
||||
}
|
||||
}
|
||||
return retVal;
|
||||
}
|
||||
|
||||
unsigned hidIsReportIdInUse ( void ) {
|
||||
if ( hidGetElementReportId( hidReports[ 0 ]->location ) ) {
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
unsigned hidGetNextValidReportId ( unsigned idPrev ) {
|
||||
size_t retIndex = 0;
|
||||
|
||||
for( size_t idx = 0U; idx < HID_REPORT_COUNT; ++idx ) {
|
||||
unsigned reportId = hidGetElementReportId( hidReports[ idx ]->location );
|
||||
if( reportId == idPrev ) {
|
||||
retIndex = (idx + 1) % HID_REPORT_COUNT;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return hidGetElementReportId( hidReports[ retIndex ]->location );
|
||||
}
|
||||
|
||||
#define HID_CONFIGURABLE_ELEMENT_COUNT ( sizeof hidConfigurableElements / sizeof ( USB_HID_Report_Element_t* ))
|
||||
unsigned hidGetReportItem(
|
||||
const unsigned id,
|
||||
const unsigned byte,
|
||||
const unsigned bit,
|
||||
unsigned char* const page,
|
||||
unsigned char* const header,
|
||||
unsigned char data[]
|
||||
)
|
||||
{
|
||||
unsigned retVal = HID_STATUS_BAD_ID;
|
||||
for( size_t elementIdx = 0U; elementIdx < HID_CONFIGURABLE_ELEMENT_COUNT; ++elementIdx ) {
|
||||
USB_HID_Report_Element_t element = *hidConfigurableElements[ elementIdx ];
|
||||
unsigned bBit = hidGetElementBitLocation( element.location );
|
||||
unsigned bByte = hidGetElementByteLocation( element.location );
|
||||
unsigned bId = hidGetElementReportId( element.location );
|
||||
|
||||
if( id == bId ) {
|
||||
retVal = HID_STATUS_BAD_LOCATION;
|
||||
|
||||
if(( bit == bBit ) && ( byte == bByte )) {
|
||||
*page = hidGetUsagePage( id );
|
||||
*header = element.item.header;
|
||||
|
||||
for( size_t dataIdx = 0U; dataIdx < HID_REPORT_ITEM_MAX_SIZE; ++data, ++dataIdx ) {
|
||||
*data = element.item.data[ dataIdx ];
|
||||
}
|
||||
|
||||
retVal = HID_STATUS_GOOD;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return retVal;
|
||||
}
|
||||
|
||||
size_t hidGetReportLength( const unsigned id )
|
||||
{
|
||||
size_t retVal = 0U;
|
||||
if( s_hidReportDescriptorPrepared ) {
|
||||
for( size_t idx = 0U; idx < HID_REPORT_COUNT; ++idx ) {
|
||||
if( id == hidGetElementReportId( hidReports[ idx ]->location )) {
|
||||
retVal = hidGetElementReportLength( hidReports[ idx ]->location );
|
||||
}
|
||||
}
|
||||
}
|
||||
return retVal;
|
||||
}
|
||||
|
||||
unsigned hidGetReportPeriod( const unsigned id )
|
||||
{
|
||||
unsigned retVal = 0U;
|
||||
for( size_t idx = 0U; idx < HID_REPORT_COUNT; ++idx) {
|
||||
if( id == hidGetElementReportId( hidReports[ idx ]->location )) {
|
||||
retVal = s_hidCurrentPeriod[ idx ];
|
||||
break;
|
||||
}
|
||||
}
|
||||
return retVal;
|
||||
}
|
||||
|
||||
unsigned hidGetReportTime( const unsigned id ) {
|
||||
unsigned retVal = 0U;
|
||||
|
||||
for( size_t idx = 0U; idx < HID_REPORT_COUNT; ++idx ) {
|
||||
if( id == hidGetElementReportId( hidReports[ idx ]->location )) {
|
||||
retVal = s_hidReportTime[ idx ];
|
||||
}
|
||||
}
|
||||
return retVal;
|
||||
}
|
||||
|
||||
static unsigned hidGetUsagePage( const unsigned id )
|
||||
{
|
||||
unsigned retVal = 0U;
|
||||
for( size_t idx = 0U; idx < HID_REPORT_COUNT; ++idx) {
|
||||
if( id == hidGetElementReportId( hidReports[ idx ]->location )) {
|
||||
retVal = hidReports[ idx ]->item.data[ 0 ];
|
||||
break;
|
||||
}
|
||||
}
|
||||
return retVal;
|
||||
}
|
||||
|
||||
unsigned hidIsChangePending( const unsigned id )
|
||||
{
|
||||
unsigned retVal = 0U;
|
||||
for( size_t idx = 0U; idx < HID_REPORT_COUNT; ++idx) {
|
||||
if( id == 0U && s_hidChangePending[ idx ] != 0U ) {
|
||||
retVal = 1;
|
||||
} else if( id == hidGetElementReportId( hidReports[ idx ]->location )) {
|
||||
retVal = ( s_hidChangePending[ idx ] != 0U );
|
||||
break;
|
||||
}
|
||||
}
|
||||
return retVal;
|
||||
}
|
||||
|
||||
unsigned hidIsIdleActive( const unsigned id )
|
||||
{
|
||||
unsigned retVal = 0U;
|
||||
if( 0U == id ) {
|
||||
retVal = 1U;
|
||||
}
|
||||
|
||||
for( size_t idx = 0U; idx < HID_REPORT_COUNT; ++idx) {
|
||||
if( id == 0U ) {
|
||||
retVal &= ( s_hidIdleActive[ idx ] != 0U );
|
||||
} else if( id == hidGetElementReportId( hidReports[ idx ]->location )) {
|
||||
retVal = ( s_hidIdleActive[ idx ] != 0U );
|
||||
break;
|
||||
}
|
||||
}
|
||||
return retVal;
|
||||
}
|
||||
|
||||
void hidPrepareReportDescriptor( void )
|
||||
{
|
||||
if( !s_hidReportDescriptorPrepared ) {
|
||||
s_hidReportDescriptorLength = 0U;
|
||||
unsigned char* ptr = s_hidReportDescriptor;
|
||||
|
||||
for( size_t idx = 0U; idx < HID_REPORT_DESCRIPTOR_ITEM_COUNT; ++idx ) {
|
||||
s_hidReportDescriptorLength += hidTranslateItem( hidReportDescriptorItems[ idx ], &ptr );
|
||||
}
|
||||
|
||||
s_hidReportDescriptorPrepared = 1U;
|
||||
}
|
||||
}
|
||||
|
||||
void hidReportInit( void )
|
||||
{
|
||||
for( unsigned idx = 0U; idx < HID_REPORT_COUNT; ++idx ) {
|
||||
s_hidCurrentPeriod[ idx ] = ENDPOINT_INT_INTERVAL_IN_HID * MS_IN_TICKS;
|
||||
}
|
||||
memset( s_hidIdleActive, 0, sizeof( s_hidIdleActive ) );
|
||||
memset( s_hidChangePending, 0, sizeof( s_hidChangePending ) );
|
||||
}
|
||||
|
||||
void hidResetReportDescriptor( void )
|
||||
{
|
||||
s_hidReportDescriptorPrepared = 0U;
|
||||
}
|
||||
|
||||
void hidSetChangePending( const unsigned id )
|
||||
{
|
||||
for( size_t idx = 0U; idx < HID_REPORT_COUNT; ++idx) {
|
||||
if( id == hidGetElementReportId( hidReports[ idx ]->location )) {
|
||||
s_hidChangePending[ idx ] = 1U;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void hidSetIdle( const unsigned id, const unsigned state )
|
||||
{
|
||||
for( size_t idx = 0U; idx < HID_REPORT_COUNT; ++idx) {
|
||||
if( id == hidGetElementReportId( hidReports[ idx ]->location )) {
|
||||
s_hidIdleActive[ idx ] = ( state != 0U );
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void hidSetNextReportTime( const unsigned id, const unsigned time )
|
||||
{
|
||||
for( size_t idx = 0U; idx < HID_REPORT_COUNT; ++idx ) {
|
||||
if( id == hidGetElementReportId( hidReports[ idx ]->location )) {
|
||||
s_hidNextReportTime[ idx ] = time;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
unsigned hidSetReportItem(
|
||||
const unsigned id,
|
||||
const unsigned byte,
|
||||
const unsigned bit,
|
||||
const unsigned char page,
|
||||
const unsigned char header,
|
||||
const unsigned char data[]
|
||||
)
|
||||
{
|
||||
unsigned retVal = HID_STATUS_IN_USE;
|
||||
|
||||
if( !s_hidReportDescriptorPrepared ) {
|
||||
retVal = HID_STATUS_BAD_ID;
|
||||
unsigned bSize = hidGetItemSize( header );
|
||||
unsigned bTag = hidGetItemTag ( header );
|
||||
unsigned bType = hidGetItemType( header );
|
||||
|
||||
if(( HID_REPORT_ITEM_MAX_SIZE < bSize ) ||
|
||||
( HID_REPORT_ITEM_USAGE_TAG != bTag ) ||
|
||||
( HID_REPORT_ITEM_USAGE_TYPE != bType )) {
|
||||
retVal = HID_STATUS_BAD_HEADER;
|
||||
} else {
|
||||
for( size_t elementIdx = 0U; elementIdx < HID_CONFIGURABLE_ELEMENT_COUNT; ++elementIdx ) {
|
||||
USB_HID_Report_Element_t element = *hidConfigurableElements[ elementIdx ];
|
||||
unsigned bBit = hidGetElementBitLocation( element.location );
|
||||
unsigned bByte = hidGetElementByteLocation( element.location );
|
||||
unsigned bId = hidGetElementReportId( element.location );
|
||||
|
||||
if( id == bId ) {
|
||||
retVal = HID_STATUS_BAD_PAGE;
|
||||
unsigned pg = hidGetUsagePage( id );
|
||||
|
||||
if( page == pg ) {
|
||||
retVal = HID_STATUS_BAD_LOCATION;
|
||||
|
||||
if(( bit == bBit ) && ( byte == bByte )) {
|
||||
element.item.header = header;
|
||||
|
||||
for( size_t dataIdx = 0U; dataIdx < bSize; ++dataIdx ) {
|
||||
element.item.data[ dataIdx ] = data[ dataIdx ];
|
||||
}
|
||||
|
||||
for( size_t dataIdx = bSize; dataIdx < HID_REPORT_ITEM_MAX_SIZE; ++dataIdx ) {
|
||||
element.item.data[ dataIdx ] = 0U;
|
||||
}
|
||||
|
||||
*hidConfigurableElements[ elementIdx ] = element;
|
||||
retVal = HID_STATUS_GOOD;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return retVal;
|
||||
}
|
||||
|
||||
void hidSetReportPeriod( const unsigned id, const unsigned period )
|
||||
{
|
||||
for( size_t idx = 0U; idx < HID_REPORT_COUNT; ++idx) {
|
||||
if( id == hidGetElementReportId( hidReports[ idx ]->location )) {
|
||||
s_hidCurrentPeriod[ idx ] = period;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static size_t hidTranslateItem( const USB_HID_Short_Item_t* inPtr, unsigned char** outPtrPtr )
|
||||
{
|
||||
size_t count = 0U;
|
||||
*(*outPtrPtr)++ = inPtr->header;
|
||||
++count;
|
||||
|
||||
unsigned dataLength = hidGetItemSize( inPtr->header );
|
||||
for( size_t idx = 0U; idx < dataLength; ++idx ) {
|
||||
*(*outPtrPtr)++ = inPtr->data[ idx ];
|
||||
++count;
|
||||
}
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
// hid_report_descriptor.h validation functions for development purposes
|
||||
|
||||
/**
|
||||
* @brief Internal HID Report Descriptor validation state
|
||||
*/
|
||||
struct HID_validation_info {
|
||||
int collectionOpenedCount; //!< Current count of open collections (to track that they are all closed)
|
||||
int reportCount; //!< Current count of defined reports (to count them)
|
||||
|
||||
int currentReportIdx; //!< Index of current report in hidReports array
|
||||
int currentConfigurableElementIdx; //!< Index of current configurable element in hidConfigurableElements array
|
||||
|
||||
unsigned char reportIds[HID_REPORT_COUNT]; // Array of report IDs (for general validation & duplication detection)
|
||||
unsigned reportUsagePage[HID_REPORT_COUNT]; // Array of the usage page for each report (for general validation)
|
||||
|
||||
unsigned current_bit_size; // State tracker for the current set report bit width (todo: should technically be a stack)
|
||||
unsigned current_bit_count; // State tracker for the current set report count (todo: should technically be a stack)
|
||||
unsigned current_bit_offset; // Current bit offset into this report (for location validation)
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Validation step for hidReportValidate, checking the info struct to ensure correctness of Report IDs
|
||||
*
|
||||
* @param info The info struct that has been built by hidReportValidate to check
|
||||
* @return unsigned HID_STATUS value
|
||||
*/
|
||||
static unsigned hidReportValidateInfoStructReportIDs( struct HID_validation_info *info ) {
|
||||
if ( info->reportCount != HID_REPORT_COUNT) {
|
||||
if ( !( info->reportCount == 0 && HID_REPORT_COUNT == 1 ) ) {
|
||||
// (Only if report IDs are being used)
|
||||
printf("Error: The number of actual reports does not match HID_REPORT_COUNT.\n");
|
||||
return HID_STATUS_BAD_REPORT_DESCRIPTOR;
|
||||
}
|
||||
}
|
||||
for ( size_t idx1 = 0; idx1 < HID_REPORT_COUNT; ++idx1 ) {
|
||||
for ( size_t idx2 = idx1 + 1; idx2 < HID_REPORT_COUNT; ++idx2 ) {
|
||||
if ( info->reportIds[idx1] == info->reportIds[idx2] ) {
|
||||
printf("Error: Duplicate report ID 0x%02x.\n", info->reportIds[idx1]);
|
||||
return HID_STATUS_BAD_REPORT_DESCRIPTOR;
|
||||
}
|
||||
}
|
||||
}
|
||||
for ( size_t idx = 0; idx < HID_REPORT_COUNT; ++idx ) {
|
||||
if ( info->reportIds[idx] != hidGetElementReportId( hidReports[idx]->location ) ) {
|
||||
printf("Error: Report ID in descriptor does not match report ID in hidReports.\n");
|
||||
return HID_STATUS_BAD_REPORT_DESCRIPTOR;
|
||||
}
|
||||
if ( info->reportCount && info->reportIds[idx] == 0 ) {
|
||||
printf("Error: Report ID 0 is invalid.\n");
|
||||
return HID_STATUS_BAD_REPORT_DESCRIPTOR;
|
||||
}
|
||||
}
|
||||
return HID_STATUS_GOOD;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Validation step for hidReportValidate, checking reports are the correct length specified in their location field
|
||||
*
|
||||
* @param info The info struct that has been built by hidReportValidate to check
|
||||
* @return unsigned HID_STATUS value
|
||||
*/
|
||||
static unsigned hidReportValidateInfoStructReportLength( struct HID_validation_info *info ) {
|
||||
if ( info->current_bit_offset % 8 ) {
|
||||
printf("Error: HID Report not byte aligned (%d bits).\n", info->current_bit_offset);
|
||||
return HID_STATUS_BAD_REPORT_DESCRIPTOR;
|
||||
}
|
||||
if ( ( info->current_bit_offset / 8 ) != hidGetElementReportLength( hidReports[info->currentReportIdx]->location ) ) {
|
||||
printf("Error: Actual report length does not match value in location field %d != %d.\n",
|
||||
( info->current_bit_offset / 8 ),
|
||||
hidGetElementReportLength( hidReports[info->currentReportIdx]->location ));
|
||||
return HID_STATUS_BAD_REPORT_DESCRIPTOR;
|
||||
}
|
||||
return HID_STATUS_GOOD;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Validation step for hidReportValidate, collections are correctly opened and closed
|
||||
*
|
||||
* @param info The info struct that has been built by hidReportValidate to check
|
||||
* @return unsigned HID_STATUS value
|
||||
*/
|
||||
static unsigned hidReportValidateInfoStructCollections( struct HID_validation_info *info ) {
|
||||
if ( info->collectionOpenedCount ) {
|
||||
printf("Error: Collections not equally opened and closed.\n");
|
||||
return HID_STATUS_BAD_REPORT_DESCRIPTOR;
|
||||
}
|
||||
return HID_STATUS_GOOD;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Validation step for hidReportValidate, High level - Checks the summarised information in the info struct by calling
|
||||
* the subroutines for checking.
|
||||
*
|
||||
* @param info The info struct that has been built by hidReportValidate to check
|
||||
* @return unsigned HID_STATUS value
|
||||
*/
|
||||
static unsigned hidReportValidateInfoStruct( struct HID_validation_info *info ) {
|
||||
unsigned status = hidReportValidateInfoStructCollections( info );
|
||||
if( status == HID_STATUS_GOOD ) {
|
||||
status = hidReportValidateInfoStructReportIDs( info );
|
||||
}
|
||||
if( status == HID_STATUS_GOOD ) {
|
||||
status = hidReportValidateInfoStructReportLength( info );
|
||||
}
|
||||
return status;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Preparation step for hidReportValidate, Adds a report ID field into the information struct for validation
|
||||
*
|
||||
* @param info The info struct being built by hidReportValidate
|
||||
* @param item The ReportId item being added
|
||||
* @return unsigned HID_STATUS value
|
||||
*/
|
||||
static unsigned hidReportValidateAddReportId( struct HID_validation_info *info, const USB_HID_Short_Item_t *item ) {
|
||||
if ( info->reportCount == 0 ) {
|
||||
if ( info->current_bit_offset ) {
|
||||
printf("Error: Some elements not associated with report ID.\n");
|
||||
return HID_STATUS_BAD_REPORT_DESCRIPTOR;
|
||||
}
|
||||
info->reportUsagePage[0] = 0;
|
||||
} else {
|
||||
unsigned status = hidReportValidateInfoStructReportLength( info );
|
||||
if ( status ) {
|
||||
return status;
|
||||
}
|
||||
}
|
||||
|
||||
if ( hidGetItemSize(item->header) != 1 ) {
|
||||
printf("Error: ReportId field has invalid length %d (expected 1)\n", hidGetItemSize(item->header));
|
||||
return HID_STATUS_BAD_REPORT_DESCRIPTOR;
|
||||
}
|
||||
|
||||
info->reportIds[info->reportCount] = item->data[0];
|
||||
info->currentReportIdx = info->reportCount;
|
||||
info->reportCount += 1;
|
||||
info->current_bit_offset = 0;
|
||||
if ( info->reportCount > HID_REPORT_COUNT ) {
|
||||
printf("Error: HID_REPORT_COUNT does not match number of report IDs in descriptor.\n");
|
||||
return HID_STATUS_BAD_REPORT_DESCRIPTOR;
|
||||
}
|
||||
|
||||
return HID_STATUS_GOOD;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Preparation step for hidReportValidate, Adds a Usage Page field into the information struct for validation
|
||||
*
|
||||
* @param info The info struct being built by hidReportValidate
|
||||
* @param item The UsagePage item being added
|
||||
* @return unsigned HID_STATUS value
|
||||
*/
|
||||
static unsigned hidReportValidateAddUsagePageItem( struct HID_validation_info *info, const USB_HID_Short_Item_t *item ) {
|
||||
|
||||
if ( info->collectionOpenedCount == 0 ) {
|
||||
return HID_STATUS_GOOD;
|
||||
}
|
||||
if ( info->reportUsagePage[info->currentReportIdx] ) {
|
||||
printf("Error: Multiple usage pages per report ID not supported by this implementation.\n");
|
||||
return HID_STATUS_BAD_REPORT_DESCRIPTOR;
|
||||
}
|
||||
|
||||
switch (hidGetItemSize(item->header)){
|
||||
case 1:
|
||||
info->reportUsagePage[info->currentReportIdx] = item->data[0];
|
||||
break;
|
||||
case 2:
|
||||
info->reportUsagePage[info->currentReportIdx] = ((unsigned) item->data[1] << 8) + item->data[0];
|
||||
break;
|
||||
default:
|
||||
printf("Error: Invalid size for UsagePage report descriptor item.\n");
|
||||
return HID_STATUS_BAD_REPORT_DESCRIPTOR;
|
||||
}
|
||||
|
||||
return HID_STATUS_GOOD;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Preparation step for hidReportValidate, Adds a Usage field into the information struct for validation
|
||||
*
|
||||
* @param info The info struct being built by hidReportValidate
|
||||
* @param item The Usage item being added
|
||||
* @return unsigned HID_STATUS value
|
||||
*/
|
||||
static unsigned hidReportValidateAddUsageItem( struct HID_validation_info *info, const USB_HID_Short_Item_t *item) {
|
||||
if ( ( info->currentConfigurableElementIdx < HID_CONFIGURABLE_ELEMENT_COUNT ) &&
|
||||
( &(hidConfigurableElements[info->currentConfigurableElementIdx]->item) == item ) ) {
|
||||
|
||||
USB_HID_Report_Element_t *element = hidConfigurableElements[info->currentConfigurableElementIdx];
|
||||
unsigned bBit = hidGetElementBitLocation( element->location );
|
||||
unsigned bByte = hidGetElementByteLocation( element->location );
|
||||
unsigned bReportId = hidGetElementReportId( element->location );
|
||||
|
||||
if ( bBit != ( info->current_bit_offset % 8 ) || bByte != ( info->current_bit_offset / 8 ) ) {
|
||||
printf("Error: Locator bit/byte setting incorrect for configurable element index %d.\n", info->currentConfigurableElementIdx);
|
||||
return HID_STATUS_BAD_REPORT_DESCRIPTOR;
|
||||
}
|
||||
if ( bReportId != info->reportIds[info->currentReportIdx] ) {
|
||||
printf("Error: Locator report ID setting incorrect for configurable element index %d.\n", info->currentConfigurableElementIdx);
|
||||
return HID_STATUS_BAD_REPORT_DESCRIPTOR;
|
||||
}
|
||||
|
||||
info->currentConfigurableElementIdx += 1;
|
||||
}
|
||||
return HID_STATUS_GOOD;
|
||||
}
|
||||
|
||||
unsigned hidReportValidate( void )
|
||||
{
|
||||
struct HID_validation_info info = {};
|
||||
unsigned status = HID_STATUS_GOOD;
|
||||
|
||||
// Fill in the validation info struct by iterating through the hid report items
|
||||
for ( size_t idx = 0; idx < HID_REPORT_DESCRIPTOR_ITEM_COUNT; ++idx ) {
|
||||
const USB_HID_Short_Item_t *item = hidReportDescriptorItems[idx];
|
||||
unsigned bTag = hidGetItemTag ( item->header );
|
||||
unsigned bType = hidGetItemType( item->header );
|
||||
|
||||
if ( bTag == HID_REPORT_ITEM_TAG_COLLECTION && bType == HID_REPORT_ITEM_TYPE_MAIN ) {
|
||||
info.collectionOpenedCount += 1;
|
||||
}
|
||||
else if ( bTag == HID_REPORT_ITEM_TAG_END_COLLECTION && bType == HID_REPORT_ITEM_TYPE_MAIN ) {
|
||||
info.collectionOpenedCount -= 1;
|
||||
if ( info.collectionOpenedCount < 0 ) {
|
||||
printf("Error: Collection closed while there is no collection open.\n");
|
||||
status = HID_STATUS_BAD_REPORT_DESCRIPTOR;
|
||||
}
|
||||
}
|
||||
else if ( bTag == HID_REPORT_ITEM_TAG_INPUT && bType == HID_REPORT_ITEM_TYPE_MAIN ) {
|
||||
info.current_bit_offset += (info.current_bit_size * info.current_bit_count);
|
||||
}
|
||||
else if ( bTag == HID_REPORT_ITEM_TAG_REPORT_SIZE && bType == HID_REPORT_ITEM_TYPE_GLOBAL ) {
|
||||
info.current_bit_size = item->data[0];
|
||||
}
|
||||
else if ( bTag == HID_REPORT_ITEM_TAG_REPORT_COUNT && bType == HID_REPORT_ITEM_TYPE_GLOBAL ) {
|
||||
info.current_bit_count = item->data[0];
|
||||
}
|
||||
else if ( bTag == HID_REPORT_ITEM_TAG_REPORT_ID && bType == HID_REPORT_ITEM_TYPE_GLOBAL ) {
|
||||
status = hidReportValidateAddReportId( &info, item );
|
||||
}
|
||||
else if ( bTag == HID_REPORT_ITEM_TAG_USAGE_PAGE && bType == HID_REPORT_ITEM_TYPE_GLOBAL ) {
|
||||
status = hidReportValidateAddUsagePageItem( &info, item );
|
||||
}
|
||||
else if ( bTag == HID_REPORT_ITEM_TAG_USAGE && bType == HID_REPORT_ITEM_TYPE_LOCAL ) {
|
||||
status = hidReportValidateAddUsageItem( &info, item );
|
||||
}
|
||||
|
||||
if ( status ) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if(status) {
|
||||
return status;
|
||||
} else {
|
||||
return hidReportValidateInfoStruct( &info );
|
||||
}
|
||||
}
|
||||
@@ -1,276 +0,0 @@
|
||||
// Copyright 2021 XMOS LIMITED.
|
||||
// This Software is subject to the terms of the XMOS Public Licence: Version 1.
|
||||
#include <assert.h>
|
||||
#include <stddef.h>
|
||||
#include <xs1.h>
|
||||
#include "xua_hid_report_descriptor.h"
|
||||
#include "hid_report_descriptor.h"
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#define HID_REPORT_ITEM_LOCATION_SIZE ( 1 )
|
||||
#define HID_REPORT_DESCRIPTOR_ITEM_COUNT ( sizeof hidReportDescriptorItems / sizeof ( USB_HID_Short_Item_t* ))
|
||||
#define HID_REPORT_DESCRIPTOR_MAX_LENGTH ( HID_REPORT_DESCRIPTOR_ITEM_COUNT * \
|
||||
( sizeof ( USB_HID_Short_Item_t ) - HID_REPORT_ITEM_LOCATION_SIZE ))
|
||||
|
||||
static unsigned char hidReportDescriptor[ HID_REPORT_DESCRIPTOR_MAX_LENGTH ];
|
||||
static size_t hidReportDescriptorLength = 0;
|
||||
static unsigned hidReportDescriptorPrepared = 0;
|
||||
|
||||
/**
|
||||
* @brief Get the bit position from the location of an Item
|
||||
*
|
||||
* Parameters:
|
||||
*
|
||||
* @param[in] location The \c location field from a \c USB_HID_Short_Item
|
||||
*
|
||||
* @return The bit position of the Item
|
||||
*/
|
||||
static unsigned hidGetItemBitLocation( const unsigned char header );
|
||||
|
||||
/**
|
||||
* @brief Get the byte position from the location of an Item
|
||||
*
|
||||
* Parameters:
|
||||
*
|
||||
* @param[in] location The \c location field from a \c USB_HID_Short_Item
|
||||
*
|
||||
* @return The byte position of the Item within the HID Report
|
||||
*/
|
||||
static unsigned hidGetItemByteLocation( const unsigned char header );
|
||||
|
||||
/**
|
||||
* @brief Get the number of data bytes from the header of an Item
|
||||
*
|
||||
* Parameters:
|
||||
*
|
||||
* @param[in] header The \c header field from a \c USB_HID_Short_Item
|
||||
*
|
||||
* @return The amount of data for the Item
|
||||
*/
|
||||
static unsigned hidGetItemSize( const unsigned char header );
|
||||
|
||||
/**
|
||||
* @brief Get the Tag from the header of an Item
|
||||
*
|
||||
* Parameters:
|
||||
*
|
||||
* @param[in] header The \c header field from a \c USB_HID_Short_Item
|
||||
*
|
||||
* @return The Tag of the Item
|
||||
*/
|
||||
static unsigned hidGetItemTag( const unsigned char header );
|
||||
|
||||
/**
|
||||
* @brief Get the Type from the header of an Item
|
||||
*
|
||||
* Parameters:
|
||||
*
|
||||
* @param[in] header The \c header field from a \c USB_HID_Short_Item
|
||||
*
|
||||
* @return The Type of the Item
|
||||
*/
|
||||
static unsigned hidGetItemType( const unsigned char header );
|
||||
|
||||
/**
|
||||
* @brief Get the Usage Page number for a given byte in the HID Report
|
||||
*
|
||||
* Parameters:
|
||||
*
|
||||
* @param[in] byte The byte location in the HID Report
|
||||
*
|
||||
* @return The USB HID Usage Page code or zero if the \a byte parameter is out-of-range
|
||||
*/
|
||||
static unsigned hidGetUsagePage( const unsigned byte );
|
||||
|
||||
/**
|
||||
* @brief Translate an Item from the \c USB_HID_Short_Item format to raw bytes
|
||||
*
|
||||
* Parameters:
|
||||
*
|
||||
* @param[in] inPtr A pointer to a \c USB_HID_Short_Item
|
||||
* @param[in,out] outPtrPtr A pointer to a pointer to the next available space in the raw
|
||||
* byte buffer. Passed as a pointer to a pointer to allow this
|
||||
* function to return the updated pointer to the raw byte buffer.
|
||||
*
|
||||
* @return The number of bytes placed in the raw byte buffer
|
||||
*/
|
||||
static size_t hidTranslateItem( const USB_HID_Short_Item_t* inPtr, unsigned char** outPtrPtr );
|
||||
|
||||
|
||||
static unsigned hidGetItemBitLocation( const unsigned char location )
|
||||
{
|
||||
unsigned bBit = ( location & HID_REPORT_ITEM_LOC_BIT_MASK ) >> HID_REPORT_ITEM_LOC_BIT_SHIFT;
|
||||
return bBit;
|
||||
}
|
||||
|
||||
static unsigned hidGetItemByteLocation( const unsigned char location )
|
||||
{
|
||||
unsigned bByte = ( location & HID_REPORT_ITEM_LOC_BYTE_MASK ) >> HID_REPORT_ITEM_LOC_BYTE_SHIFT;
|
||||
return bByte;
|
||||
}
|
||||
|
||||
static unsigned hidGetItemSize( const unsigned char header )
|
||||
{
|
||||
unsigned bSize = ( header & HID_REPORT_ITEM_HDR_SIZE_MASK ) >> HID_REPORT_ITEM_HDR_SIZE_SHIFT;
|
||||
return bSize;
|
||||
}
|
||||
|
||||
static unsigned hidGetItemTag( const unsigned char header )
|
||||
{
|
||||
unsigned bTag = ( header & HID_REPORT_ITEM_HDR_TAG_MASK ) >> HID_REPORT_ITEM_HDR_TAG_SHIFT;
|
||||
return bTag;
|
||||
}
|
||||
|
||||
static unsigned hidGetItemType( const unsigned char header )
|
||||
{
|
||||
unsigned bType = ( header & HID_REPORT_ITEM_HDR_TYPE_MASK ) >> HID_REPORT_ITEM_HDR_TYPE_SHIFT;
|
||||
return bType;
|
||||
}
|
||||
|
||||
unsigned char* hidGetReportDescriptor( void )
|
||||
{
|
||||
unsigned char* retVal = NULL;
|
||||
|
||||
if( hidReportDescriptorPrepared ) {
|
||||
retVal = hidReportDescriptor;
|
||||
}
|
||||
|
||||
return retVal;
|
||||
}
|
||||
|
||||
size_t hidGetReportDescriptorLength( void )
|
||||
{
|
||||
size_t retVal = ( hidReportDescriptorPrepared ) ? hidReportDescriptorLength : 0;
|
||||
return retVal;
|
||||
}
|
||||
|
||||
#define HID_CONFIGURABLE_ITEM_COUNT ( sizeof hidConfigurableItems / sizeof ( USB_HID_Short_Item_t* ))
|
||||
unsigned hidGetReportItem(
|
||||
const unsigned byte,
|
||||
const unsigned bit,
|
||||
unsigned char* const page,
|
||||
unsigned char* const header,
|
||||
unsigned char data[]
|
||||
)
|
||||
{
|
||||
unsigned retVal = HID_STATUS_BAD_LOCATION;
|
||||
for( unsigned itemIdx = 0; itemIdx < HID_CONFIGURABLE_ITEM_COUNT; ++itemIdx ) {
|
||||
USB_HID_Short_Item_t item = *hidConfigurableItems[ itemIdx ];
|
||||
unsigned bBit = hidGetItemBitLocation( item.location );
|
||||
unsigned bByte = hidGetItemByteLocation( item.location );
|
||||
|
||||
if(( bit == bBit ) && ( byte == bByte )) {
|
||||
*page = hidGetUsagePage( byte );
|
||||
*header = item.header;
|
||||
|
||||
for( unsigned dataIdx = 0; dataIdx < HID_REPORT_ITEM_MAX_SIZE; ++data, ++dataIdx ) {
|
||||
*data = item.data[ dataIdx ];
|
||||
}
|
||||
|
||||
retVal = HID_STATUS_GOOD;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return retVal;
|
||||
}
|
||||
|
||||
size_t hidGetReportLength( void )
|
||||
{
|
||||
size_t retVal = ( hidReportDescriptorPrepared ) ? HID_REPORT_LENGTH : 0;
|
||||
return retVal;
|
||||
}
|
||||
|
||||
static unsigned hidGetUsagePage( const unsigned byte )
|
||||
{
|
||||
unsigned retVal = ( byte < HID_REPORT_LENGTH ) ? hidUsagePages[ byte ]->data[ 0 ] : 0;
|
||||
return retVal;
|
||||
}
|
||||
|
||||
void hidPrepareReportDescriptor( void )
|
||||
{
|
||||
if( !hidReportDescriptorPrepared ) {
|
||||
hidReportDescriptorLength = 0;
|
||||
unsigned char* ptr = hidReportDescriptor;
|
||||
for( unsigned idx = 0; idx < HID_REPORT_DESCRIPTOR_ITEM_COUNT; ++idx ) {
|
||||
hidReportDescriptorLength += hidTranslateItem( hidReportDescriptorItems[ idx ], &ptr );
|
||||
}
|
||||
|
||||
hidReportDescriptorPrepared = 1;
|
||||
}
|
||||
}
|
||||
|
||||
void hidResetReportDescriptor( void )
|
||||
{
|
||||
hidReportDescriptorPrepared = 0;
|
||||
}
|
||||
|
||||
unsigned hidSetReportItem(
|
||||
const unsigned byte,
|
||||
const unsigned bit,
|
||||
const unsigned char page,
|
||||
const unsigned char header,
|
||||
const unsigned char data[]
|
||||
)
|
||||
{
|
||||
unsigned retVal = HID_STATUS_IN_USE;
|
||||
|
||||
if( !hidReportDescriptorPrepared ) {
|
||||
retVal = HID_STATUS_BAD_LOCATION;
|
||||
unsigned bSize = hidGetItemSize( header );
|
||||
unsigned bTag = hidGetItemTag ( header );
|
||||
unsigned bType = hidGetItemType( header );
|
||||
|
||||
if(( HID_REPORT_ITEM_MAX_SIZE < bSize ) ||
|
||||
( HID_REPORT_ITEM_USAGE_TAG != bTag ) ||
|
||||
( HID_REPORT_ITEM_USAGE_TYPE != bType )) {
|
||||
retVal = HID_STATUS_BAD_HEADER;
|
||||
} else {
|
||||
for( unsigned itemIdx = 0; itemIdx < HID_CONFIGURABLE_ITEM_COUNT; ++itemIdx ) {
|
||||
USB_HID_Short_Item_t item = *hidConfigurableItems[ itemIdx ];
|
||||
unsigned bBit = hidGetItemBitLocation( item.location );
|
||||
unsigned bByte = hidGetItemByteLocation( item.location );
|
||||
|
||||
if(( bit == bBit ) && ( byte == bByte )) {
|
||||
unsigned pg = hidGetUsagePage( byte );
|
||||
|
||||
if( page == pg ) {
|
||||
item.header = header;
|
||||
|
||||
for( unsigned dataIdx = 0; dataIdx < bSize; ++dataIdx ) {
|
||||
item.data[ dataIdx ] = data[ dataIdx ];
|
||||
}
|
||||
|
||||
for( unsigned dataIdx = bSize; dataIdx < HID_REPORT_ITEM_MAX_SIZE; ++dataIdx ) {
|
||||
item.data[ dataIdx ] = 0;
|
||||
}
|
||||
|
||||
*hidConfigurableItems[ itemIdx ] = item;
|
||||
retVal = HID_STATUS_GOOD;
|
||||
} else {
|
||||
retVal = HID_STATUS_BAD_PAGE;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return retVal;
|
||||
}
|
||||
|
||||
static size_t hidTranslateItem( const USB_HID_Short_Item_t* inPtr, unsigned char** outPtrPtr )
|
||||
{
|
||||
size_t count = 0;
|
||||
*(*outPtrPtr)++ = inPtr->header;
|
||||
++count;
|
||||
|
||||
unsigned dataLength = hidGetItemSize( inPtr->header );
|
||||
for( unsigned idx = 0; idx < dataLength; ++idx ) {
|
||||
*(*outPtrPtr)++ = inPtr->data[ idx ];
|
||||
++count;
|
||||
}
|
||||
|
||||
return count;
|
||||
}
|
||||
@@ -1,6 +1,12 @@
|
||||
// Copyright 2019-2021 XMOS LIMITED.
|
||||
// This Software is subject to the terms of the XMOS Public Licence: Version 1.
|
||||
|
||||
/**
|
||||
* @brief Human Interface Device (HID) Class Request functions
|
||||
*
|
||||
* Document section numbers refer to the HID Device Class Definition, version 1.11.
|
||||
*/
|
||||
|
||||
#ifndef __XUA_HID_H__
|
||||
#define __XUA_HID_H__
|
||||
|
||||
@@ -9,49 +15,11 @@
|
||||
#include "xud.h"
|
||||
#include "xud_std_requests.h"
|
||||
|
||||
/**
|
||||
* \brief Calculate the next time to respond with a HID Report.
|
||||
*
|
||||
* If the USB Host has previously sent a valid HID Set_Idle request with
|
||||
* a duration of zero or greater than the default reporting interval,
|
||||
* the device sends HID Reports periodically or when the value of the
|
||||
* payload has changed.
|
||||
*
|
||||
* This function calculates the time for sending the next periodic
|
||||
* HID Report.
|
||||
*/
|
||||
void HidCalcNextReportTime( void );
|
||||
|
||||
/**
|
||||
* \brief Capture the time of sending the current HID Report.
|
||||
*
|
||||
* If the USB Host has previously sent a valid HID Set_Idle request with
|
||||
* a duration of zero or greater than the default reporting interval,
|
||||
* the device sends HID Reports periodically or when the value of the
|
||||
* payload has changed.
|
||||
*
|
||||
* This function captures the time when the HID Report was sent so that
|
||||
* a subsequent call to HidCalNextReportTime() can calculate the time
|
||||
* to send the next periodic HID Report.
|
||||
*/
|
||||
void HidCaptureReportTime( void );
|
||||
|
||||
XUD_Result_t HidInterfaceClassRequests(
|
||||
XUD_ep c_ep0_out,
|
||||
XUD_ep c_ep0_in,
|
||||
REFERENCE_PARAM( USB_SetupPacket_t, sp ));
|
||||
|
||||
/**
|
||||
* \brief Register that previously changed HID Report data has reported
|
||||
* to the USB Host.
|
||||
*/
|
||||
void HidClearChangePending( void );
|
||||
|
||||
/**
|
||||
* \brief Indicate if a change to the HID Report data has been received.
|
||||
*/
|
||||
unsigned HidIsChangePending( void );
|
||||
|
||||
/**
|
||||
* \brief Indicate whether to send a HID Report based on elapsed time.
|
||||
*
|
||||
@@ -64,15 +32,15 @@ unsigned HidIsChangePending( void );
|
||||
* whether or not the time to send the next periodic HID Report has
|
||||
* elapsed.
|
||||
*
|
||||
* Parameters:
|
||||
*
|
||||
* @param[in] id The identifier for the HID Report (see 5.6, 6.2.2.7, 8.1 and 8.2)
|
||||
* A value of zero means the application does not use Report IDs.
|
||||
*
|
||||
* \return A Boolean value indicating whether or not to send the HID Report.
|
||||
* \retval 1 -- Do not send the HID Report
|
||||
* \retval 0 -- Send the HID Report
|
||||
*/
|
||||
unsigned HidIsSetIdleSilenced( void );
|
||||
|
||||
/**
|
||||
* \brief Register that a change to the HID Report data has been received.
|
||||
*/
|
||||
void HidSetChangePending( void );
|
||||
unsigned HidIsSetIdleSilenced( const unsigned id );
|
||||
|
||||
#endif // __XUA_HID_H__
|
||||
|
||||
542
lib_xua/src/hid/xua_hid_report.h
Normal file
542
lib_xua/src/hid/xua_hid_report.h
Normal file
@@ -0,0 +1,542 @@
|
||||
// Copyright 2021 XMOS LIMITED.
|
||||
// This Software is subject to the terms of the XMOS Public Licence: Version 1.
|
||||
|
||||
/**
|
||||
* @brief Human Interface Device (HID) Report descriptor
|
||||
*
|
||||
* This file defines the structure of the HID Report descriptor and declares
|
||||
* functions for manipulating it.
|
||||
* Because the Report descriptor defines the length of the HID Report, this file
|
||||
* declares a function for obtaining the Report length as well.
|
||||
* The using application has the responsibility to define the report descriptor
|
||||
* structure and default contents in their hid_report_descriptor.h file.
|
||||
* Document section numbers refer to the HID Device Class Definition, version 1.11.
|
||||
*/
|
||||
|
||||
#ifndef _XUA_HID_REPORT_
|
||||
#define _XUA_HID_REPORT_
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
#include "xua_hid_report_descriptor_constants.h"
|
||||
|
||||
#define HID_REPORT_ITEM_HDR_SIZE_MASK ( 0x03 )
|
||||
#define HID_REPORT_ITEM_HDR_SIZE_SHIFT ( 0U )
|
||||
|
||||
#define HID_REPORT_ITEM_HDR_TAG_MASK ( 0xF0 )
|
||||
#define HID_REPORT_ITEM_HDR_TAG_SHIFT ( 4U )
|
||||
|
||||
#define HID_REPORT_ITEM_HDR_TYPE_MASK ( 0x0C )
|
||||
#define HID_REPORT_ITEM_HDR_TYPE_SHIFT ( 2U )
|
||||
|
||||
#define HID_REPORT_ELEMENT_LOC_BIT_MASK ( 0x0070 )
|
||||
#define HID_REPORT_ELEMENT_LOC_BIT_SHIFT ( 4U )
|
||||
|
||||
#define HID_REPORT_ELEMENT_LOC_BYTE_MASK ( 0x000F )
|
||||
#define HID_REPORT_ELEMENT_LOC_BYTE_SHIFT ( 0U )
|
||||
|
||||
#define HID_REPORT_ELEMENT_LOC_ID_MASK ( 0xF000 )
|
||||
#define HID_REPORT_ELEMENT_LOC_ID_SHIFT ( 12U )
|
||||
|
||||
#define HID_REPORT_ELEMENT_LOC_LEN_MASK ( 0x0F00 )
|
||||
#define HID_REPORT_ELEMENT_LOC_LEN_SHIFT ( 8U )
|
||||
|
||||
#define HID_REPORT_ITEM_MAX_SIZE ( 2U )
|
||||
|
||||
#define HID_REPORT_ITEM_USAGE_TAG ( 0U )
|
||||
#define HID_REPORT_ITEM_USAGE_TYPE ( 2U )
|
||||
|
||||
/**
|
||||
* @brief Helper macro to configure the location field of USB_HID_Report_Element_t.
|
||||
*
|
||||
* @param id The report ID that this element is within.
|
||||
* @param len (only relevant for the usage_page elements in hidReports) The length
|
||||
* of the report under this report ID.
|
||||
* @param byte The byte location of this element in the report.
|
||||
* @param bit The bit location (within the byte) of this element in the report.
|
||||
*/
|
||||
#define HID_REPORT_SET_LOC(id, len, byte, bit) (\
|
||||
(( id << HID_REPORT_ELEMENT_LOC_ID_SHIFT ) & HID_REPORT_ELEMENT_LOC_ID_MASK ) | \
|
||||
(( len << HID_REPORT_ELEMENT_LOC_LEN_SHIFT ) & HID_REPORT_ELEMENT_LOC_LEN_MASK ) | \
|
||||
(( byte << HID_REPORT_ELEMENT_LOC_BYTE_SHIFT ) & HID_REPORT_ELEMENT_LOC_BYTE_MASK ) | \
|
||||
(( bit << HID_REPORT_ELEMENT_LOC_BIT_SHIFT ) & HID_REPORT_ELEMENT_LOC_BIT_MASK ))
|
||||
|
||||
/**
|
||||
* @brief Helper macro to configure the header field of USB_HID_Short_Item_t
|
||||
*
|
||||
* @param size The size of the report descriptor item (valid values: 0, 1, 2)
|
||||
* @param type The type of the report descriptor item
|
||||
* @param tag The tag
|
||||
*/
|
||||
#define HID_REPORT_SET_HEADER(size, type, tag) (\
|
||||
(( size << HID_REPORT_ITEM_HDR_SIZE_SHIFT) & HID_REPORT_ITEM_HDR_SIZE_MASK ) |\
|
||||
(( type << HID_REPORT_ITEM_HDR_TYPE_SHIFT) & HID_REPORT_ITEM_HDR_TYPE_MASK ) |\
|
||||
(( tag << HID_REPORT_ITEM_HDR_TAG_SHIFT ) & HID_REPORT_ITEM_HDR_TAG_MASK ) )
|
||||
|
||||
#define HID_STATUS_GOOD ( 0U )
|
||||
#define HID_STATUS_BAD_HEADER ( 1U )
|
||||
#define HID_STATUS_BAD_ID ( 2U )
|
||||
#define HID_STATUS_BAD_LOCATION ( 3U )
|
||||
#define HID_STATUS_BAD_PAGE ( 4U )
|
||||
#define HID_STATUS_IN_USE ( 5U )
|
||||
#define HID_STATUS_BAD_REPORT_DESCRIPTOR ( 6U )
|
||||
|
||||
#define MS_IN_TICKS 100000U
|
||||
|
||||
/**
|
||||
* @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
|
||||
* id - a non-standard extension identifying the HID Report ID associated with
|
||||
* the item (see 5.6, 6.2.2.7, 8.1 and 8.2)
|
||||
* 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 ];
|
||||
} USB_HID_Short_Item_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
USB_HID_Short_Item_t item;
|
||||
unsigned short location;
|
||||
} USB_HID_Report_Element_t;
|
||||
|
||||
/**
|
||||
* \brief Register that a previously changed HID Report data has been sent
|
||||
* to the USB Host.
|
||||
*
|
||||
* HID processing maintains a list of HID Reports with changed data not yet
|
||||
* reported to the USB Host.
|
||||
*
|
||||
* Applications that have only one HID Report may or may not use a Report ID.
|
||||
* Applications that have more than one HID Report must use Report IDs.
|
||||
*
|
||||
* For applications that do not use Report IDs, the list contains one element.
|
||||
* That element tracks whether or not an unreported change has occurred in the
|
||||
* HID data.
|
||||
* For applications that use Report IDs, the list contains one element per
|
||||
* Report ID.
|
||||
* Each element tracks unreported changes for the corresponding Report ID.
|
||||
*
|
||||
* Calling this function for a given Report ID indicates that the changed
|
||||
* HID data has been reported to the USB Host.
|
||||
*
|
||||
* \warning This function will fail silently if given an id that is not
|
||||
* either the value zero, or a Report ID that is in use.
|
||||
*
|
||||
* \param[in] id A HID Report ID.
|
||||
* Zero clears the pending status of all Report IDs.
|
||||
* Use zero if the application does not use Report IDs.
|
||||
*/
|
||||
void hidClearChangePending( const unsigned id );
|
||||
|
||||
/**
|
||||
* @brief Indicate if the HID Report descriptor has been prepared
|
||||
*
|
||||
* \returns A Boolean indicating whether the HID Report descriptor has been prepared.
|
||||
* \retval True The HID Report descriptor has been prepared.
|
||||
* \retval False The HID Report descriptor has not been prepared.
|
||||
*/
|
||||
unsigned hidIsReportDescriptorPrepared( void );
|
||||
|
||||
/**
|
||||
* @brief Get the HID Report descriptor
|
||||
*
|
||||
* This function returns a pointer to the USB HID Report descriptor.
|
||||
* It returns NULL if the Report descriptor has not been prepared,
|
||||
* i.e., no one has called \c hidPrepareReportDescriptor().
|
||||
*
|
||||
* @note An XC-callable version of this function has not been provided.
|
||||
* XC requires explicit declaration of the kind of pointer returned,
|
||||
* hence an XC implementation of the function.
|
||||
*
|
||||
* @return A pointer to a list of unsigned char containing the Report descriptor
|
||||
*/
|
||||
#if !defined(__XC__)
|
||||
unsigned char* hidGetReportDescriptor( void );
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Get the length of the HID Report descriptor
|
||||
*
|
||||
* This function returns the length of the USB HID Report descriptor.
|
||||
* It returns zero if the Report descriptor has not been prepared,
|
||||
* i.e., no one has called \c hidPrepareReportDescriptor().
|
||||
*
|
||||
* @return The length of the Report descriptor in bytes
|
||||
*/
|
||||
size_t hidGetReportDescriptorLength( void );
|
||||
|
||||
/**
|
||||
* \brief Get the upper limit of HID Report identifiers
|
||||
*
|
||||
* This function returns the upper limit of the HID Report identifiers.
|
||||
* The upper limit has a value one greater than the maximum HID Report identifier.
|
||||
* In the case that HID Report identifiers are not in use, this function returns the value 1.
|
||||
*
|
||||
* \returns The upper limit of HID Report identifiers
|
||||
*/
|
||||
unsigned hidGetReportIdLimit ( void );
|
||||
|
||||
/**
|
||||
* @brief Does the application use Report IDs?
|
||||
*
|
||||
* If the application is not using Report IDs, then the id value that is passed around
|
||||
* everywhere can just be zero. Otherwise zero is an invalid ID that has a special meaning
|
||||
* in some cases (read the documentation for each function).
|
||||
*
|
||||
* @return Boolean
|
||||
* @retval 1 Report IDs are in use
|
||||
* @retval 0 Report IDs are not in use
|
||||
*/
|
||||
unsigned hidIsReportIdInUse ( void );
|
||||
|
||||
/**
|
||||
* @brief Get the next valid report ID - iterator style.
|
||||
*
|
||||
* This function will loop around and start returning the first report ID again once it has
|
||||
* returned all valid report IDs.
|
||||
*
|
||||
* @param idPrev The previous returned id, or 0 if this is the first call
|
||||
* @return unsigned The next valid report ID.
|
||||
*/
|
||||
unsigned hidGetNextValidReportId ( unsigned idPrev );
|
||||
|
||||
/**
|
||||
* @brief Get a HID Report descriptor item
|
||||
*
|
||||
* Parameters:
|
||||
*
|
||||
* @param[in] id The identifier for the HID Report (see 5.6, 6.2.2.7, 8.1 and 8.2).
|
||||
* A value of zero means the application does not use Report IDs.
|
||||
* @param[in] byte The byte position of the control within the HID Report
|
||||
* @param[in] bit The bit position of the control within the \a byte
|
||||
* @param[out] page The USB HID Usage Page code for the Item (see 5.5)
|
||||
* @param[out] header The LSB of the Item containing the bSize, bType and bTag fields (see 6.2.2.2)
|
||||
* @param[out] data A two element array containing data bytes for the Item
|
||||
*
|
||||
* @return A status value
|
||||
* @retval \c HID_STATUS_GOOD Item successfully returned
|
||||
* @retval \c HID_STATUS_BAD_ID The \a id argument specifies a non-existant HID Report
|
||||
* @retval \c HID_STATUS_BAD_LOCATION The \a bit or \a byte arguments specify a location outside
|
||||
* of the HID Report
|
||||
*/
|
||||
#if defined(__XC__)
|
||||
unsigned hidGetReportItem(
|
||||
const unsigned id,
|
||||
const unsigned byte,
|
||||
const unsigned bit,
|
||||
unsigned char* unsafe const page,
|
||||
unsigned char* unsafe const header,
|
||||
unsigned char* unsafe const data);
|
||||
#else
|
||||
unsigned hidGetReportItem(
|
||||
const unsigned id,
|
||||
const unsigned byte,
|
||||
const unsigned bit,
|
||||
unsigned char* const page,
|
||||
unsigned char* const header,
|
||||
unsigned char data[]);
|
||||
#endif
|
||||
|
||||
/**
|
||||
* \brief Calculate the next time to respond with a HID Report.
|
||||
*
|
||||
* If the USB Host has previously sent a valid HID Set_Idle request with
|
||||
* a duration of zero or greater than the default reporting interval,
|
||||
* the device sends HID Reports periodically or when the value of the
|
||||
* payload has changed.
|
||||
*
|
||||
* This function calculates the time for sending the next periodic
|
||||
* HID Report.
|
||||
*
|
||||
* Parameters:
|
||||
*
|
||||
* @param[in] id The identifier for the HID Report (see 5.6, 6.2.2.7, 8.1 and 8.2)
|
||||
* A value of zero means the application does not use Report IDs.
|
||||
*/
|
||||
void hidCalcNextReportTime( const unsigned id );
|
||||
|
||||
/**
|
||||
* \brief Capture the time of sending the current HID Report.
|
||||
*
|
||||
* If the USB Host has previously sent a valid HID Set_Idle request with
|
||||
* a duration of zero or greater than the default reporting interval,
|
||||
* the device sends HID Reports periodically or when the value of the
|
||||
* payload has changed.
|
||||
*
|
||||
* This function captures the time when the HID Report was sent so that
|
||||
* a subsequent call to HidCalNextReportTime() can calculate the time
|
||||
* to send the next periodic HID Report.
|
||||
*
|
||||
* Parameters:
|
||||
*
|
||||
* @param[in] id The identifier for the HID Report (see 5.6, 6.2.2.7, 8.1 and 8.2)
|
||||
* A value of zero means the application does not use Report IDs.
|
||||
*
|
||||
* @param[in] time The time when the HID Report for the given \a id was sent.
|
||||
*/
|
||||
void hidCaptureReportTime( const unsigned id, const unsigned time );
|
||||
|
||||
/**
|
||||
* @brief Get the time to send the next HID Report for the given \a id
|
||||
*
|
||||
* Parameters:
|
||||
*
|
||||
* @param[in] id The identifier for the HID Report (see 5.6, 6.2.2.7, 8.1 and 8.2)
|
||||
* A value of zero means the application does not use Report IDs.
|
||||
*
|
||||
* @returns The time at which to send the next HID Report for the given \a id
|
||||
*/
|
||||
unsigned hidGetNextReportTime( const unsigned id );
|
||||
|
||||
/**
|
||||
* @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(),
|
||||
* or if the \a id argument specifies a non-existent HID Report
|
||||
*
|
||||
* Parameters:
|
||||
*
|
||||
* @param[in] id The identifier for the HID Report (see 5.6, 6.2.2.7, 8.1 and 8.2)
|
||||
* A value of zero means the application does not use Report IDs.
|
||||
*
|
||||
* @return The length of the Report in bytes
|
||||
*/
|
||||
size_t hidGetReportLength( const unsigned id );
|
||||
|
||||
/**
|
||||
* @brief Get the HID Report period for the given \a id
|
||||
*
|
||||
* Parameters:
|
||||
*
|
||||
* @param[in] id The identifier for the HID Report (see 5.6, 6.2.2.7, 8.1 and 8.2)
|
||||
* A value of zero means the application does not use Report IDs.
|
||||
*
|
||||
* @returns The period for the given HID Report \a id in units of ms.
|
||||
* The value zero means the period is indefinite.
|
||||
*/
|
||||
unsigned hidGetReportPeriod( const unsigned id );
|
||||
|
||||
/**
|
||||
* @brief Get the HID Report time for the given \a id
|
||||
*
|
||||
* Parameters:
|
||||
*
|
||||
* @param[in] id The identifier for the HID Report (see 5.6, 6.2.2.7, 8.1 and 8.2)
|
||||
* A value of zero means the application does not use Report IDs.
|
||||
*
|
||||
* @returns The time of the last call to \c hidCaptureReportTime()
|
||||
*/
|
||||
unsigned hidGetReportTime( const unsigned id );
|
||||
|
||||
/**
|
||||
* \brief Indicate if a change to the HID Report data has been received.
|
||||
*
|
||||
* HID processing maintains a list of HID Reports with changed data not yet
|
||||
* reported to the USB Host.
|
||||
*
|
||||
* Applications that have only one HID Report may or may not use a Report ID.
|
||||
* Applications that have more than one HID Report must use Report IDs.
|
||||
*
|
||||
* For applications that do not use Report IDs, the list contains one element.
|
||||
* That element tracks whether or not an unreported change has occurred in the
|
||||
* HID data.
|
||||
* For applications that use Report IDs, the list contains one element per
|
||||
* Report ID.
|
||||
* Each element tracks unreported changes for the corresponding Report ID.
|
||||
*
|
||||
* Calling this function with a given Report ID returns an indication of
|
||||
* whether unreported HID data exists for that Report ID.
|
||||
*
|
||||
* \warning This function will return zero if given an id that is not
|
||||
* either the value zero, or a Report ID that is in use.
|
||||
*
|
||||
* \param[in] id A HID Report ID.
|
||||
* Zero reports the pending status of all Report IDs.
|
||||
* Use zero if the application does not use Report IDs.
|
||||
*
|
||||
* \returns A Boolean indicating whether the given \a id has a changed
|
||||
* HID Report not yet sent to the USB Host.
|
||||
* \retval True The given \a id has changed HID Report data.
|
||||
* For an \a id of zero, some HID Report has changed data.
|
||||
* \retval False The given \a id does not have changed HID Report data.
|
||||
* For an \a id of zero, no HID Report has changed data.
|
||||
*/
|
||||
unsigned hidIsChangePending( const unsigned id );
|
||||
|
||||
/**
|
||||
* @brief Indicate if the HID report for the given \a id is idle
|
||||
*
|
||||
* Parameters:
|
||||
*
|
||||
* @param[in] id The identifier for the HID Report (see 5.6, 6.2.2.7, 8.1 and 8.2)
|
||||
* A value of zero returns the collective Idle state.
|
||||
*
|
||||
* \returns A Boolean indicating whether the HID Report for the given \a id is idle.
|
||||
* \retval True The HID Report is idle.
|
||||
* For an \a id of zero, all HID Reports are idle.
|
||||
* \retval False The HID Report is not idle.
|
||||
* For an \a id of zero, at least one HID Report is not idle.
|
||||
*/
|
||||
unsigned hidIsIdleActive( const unsigned id );
|
||||
|
||||
/**
|
||||
* @brief Prepare the USB HID Report descriptor
|
||||
*
|
||||
* After preparation, \c hidGetReportDescriptor() returns a list suitable for transmission over USB.
|
||||
* Call this function after altering one or more Report Items using \c hidSetReportItem().
|
||||
*/
|
||||
void hidPrepareReportDescriptor( void );
|
||||
|
||||
/**
|
||||
* @brief Initialise the USB HID Report functionality
|
||||
*
|
||||
* Call this function before using any other functions in this API.
|
||||
*/
|
||||
void hidReportInit( 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 Register that a change to the HID Report data has been received.
|
||||
*
|
||||
* HID processing maintains a list of HID Reports with changed data not yet
|
||||
* reported to the USB Host.
|
||||
*
|
||||
* Applications that have only one HID Report may or may not use a Report ID.
|
||||
* Applications that have more than one HID Report must use Report IDs.
|
||||
*
|
||||
* For applications that do not use Report IDs, the list contains one element.
|
||||
* That element tracks whether or not an unreported change has occurred in the
|
||||
* HID data.
|
||||
* For applications that use Report IDs, the list contains one element per
|
||||
* Report ID.
|
||||
* Each element tracks unreported changes for the corresponding Report ID.
|
||||
*
|
||||
* Calling this function with a given Report ID indicates that the HID data
|
||||
* for that Report ID has changed and has not yet been reported to the USB
|
||||
* Host.
|
||||
*
|
||||
* \warning This function will fail silently if given an id that is not
|
||||
* either the value zero, or a Report ID that is in use.
|
||||
*
|
||||
* \param[in] id A HID Report ID.
|
||||
* Use zero if the application does not use Report IDs.
|
||||
*/
|
||||
void hidSetChangePending( const unsigned id );
|
||||
|
||||
/**
|
||||
* @brief Set the HID Report Idle state for the given \a id
|
||||
*
|
||||
* Parameters:
|
||||
*
|
||||
* @param[in] id The identifier for the HID Report (see 5.6, 6.2.2.7, 8.1 and 8.2)
|
||||
* A value of zero means the application does not use Report IDs.
|
||||
*
|
||||
* @param[in] state A Boolean indicating the Idle state
|
||||
* If true, the HID Report for the given \a id is Idle, otherwise it
|
||||
* is not Idle.
|
||||
*/
|
||||
void hidSetIdle( const unsigned id, const unsigned state );
|
||||
|
||||
/**
|
||||
* @brief Set the time to send the HID Report for the given \a id
|
||||
*
|
||||
* Parameters:
|
||||
*
|
||||
* @param[in] id The identifier for the HID Report (see 5.6, 6.2.2.7, 8.1 and 8.2)
|
||||
* A value of zero means the application does not use Report IDs.
|
||||
*
|
||||
* @param[in] time The time to send the HID Report for the given \a id.
|
||||
*/
|
||||
void hidSetNextReportTime( const unsigned id, const unsigned time );
|
||||
|
||||
/**
|
||||
* @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] id The identifier for the HID Report (see 5.6, 6.2.2.7, 8.1 and 8.2)
|
||||
* A value of zero means the application does not use Report IDs.
|
||||
* @param[in] byte The byte position of the control within the HID Report
|
||||
* @param[in] bit The bit position of the control within the \a byte
|
||||
* @param[in] page The USB HID Usage Page code for the Item (see 5.5)
|
||||
* @param[in] header The LSB of the Item containing the bSize, bType and bTag fields (see 6.2.2.2)
|
||||
* @param[in] data An array containing data bytes or NULL for an Item with no data
|
||||
*
|
||||
* @return A status value
|
||||
* @retval \c HID_STATUS_GOOD Item successfully updated
|
||||
* @retval \c HID_STATUS_BAD_HEADER The Item header specified a data size greater than 2 or
|
||||
* a Tag or Type inconsistent with a Usage Item
|
||||
* @retval \c HID_STATUS_BAD_ID The \a id argument specifies a non-existent HID Report
|
||||
* @retval \c HID_STATUS_BAD_LOCATION The \a bit or \a byte arguments specify a location outside
|
||||
* of the HID Report
|
||||
* @retval \c HID_STATUS_BAD_PAGE The \a byte argument specifies a location for controls from
|
||||
* a Usage Page other than the one given by the \a page parameter
|
||||
* @retval \c HID_STATUS_IN_USE The Report descriptor is in use
|
||||
*/
|
||||
unsigned hidSetReportItem(
|
||||
const unsigned id,
|
||||
const unsigned byte,
|
||||
const unsigned bit,
|
||||
const unsigned char page,
|
||||
const unsigned char header,
|
||||
const unsigned char data[]);
|
||||
|
||||
/**
|
||||
* @brief Set the HID Report period for the given \a id
|
||||
*
|
||||
* Parameters:
|
||||
*
|
||||
* @param[in] id The identifier for the HID Report (see 5.6, 6.2.2.7, 8.1 and 8.2)
|
||||
* A value of zero means the application does not use Report IDs.
|
||||
*
|
||||
* @param[in] period The period for sending the HID Report in units of ms.
|
||||
* This period must be a multiple of 4 ms.
|
||||
* Use zero to indicate an indefinite period.
|
||||
*/
|
||||
void hidSetReportPeriod( const unsigned id, const unsigned period );
|
||||
|
||||
/**
|
||||
* @brief Development function: Validate the contents of hid_report_descriptor.h for common errors, printing
|
||||
* error messages if any issues were found.
|
||||
*
|
||||
* This function is intended for use when developing the contents of hid_report_descriptor.h, which is static,
|
||||
* so shouldn't be required for use in a production application.
|
||||
*
|
||||
* @return Validation result
|
||||
* @retval HID_STATUS_GOOD The validation found no issues with the data structures defined
|
||||
* in hid_report_descriptor.h
|
||||
* @retval HID_STATUS_BAD_REPORT_DESCRIPTOR The validation encountered an issue with the data structures
|
||||
* defined in hid_report_descriptor.h . More information is
|
||||
* provided in the printed messages.
|
||||
*/
|
||||
unsigned hidReportValidate( void );
|
||||
|
||||
#endif // _XUA_HID_REPORT_
|
||||
@@ -1,175 +0,0 @@
|
||||
// Copyright 2021 XMOS LIMITED.
|
||||
// This Software is subject to the terms of the XMOS Public Licence: Version 1.
|
||||
|
||||
/**
|
||||
* @brief Human Interface Device (HID) Report descriptor
|
||||
*
|
||||
* This file defines the structure of the HID Report descriptor and declares
|
||||
* functions for manipulating it.
|
||||
* Because the Report descriptor defines the length of the HID Report, this file
|
||||
* declares a function for obtaining the Report length as well.
|
||||
* The using application has the responsibility to define the report descriptor
|
||||
* structure and default contents in their hid_report_descriptor.h file.
|
||||
* Document section numbers refer to the HID Device Class Definition, version 1.11.
|
||||
*/
|
||||
|
||||
#ifndef _HID_REPORT_DESCRIPTOR_
|
||||
#define _HID_REPORT_DESCRIPTOR_
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
#define HID_REPORT_ITEM_HDR_SIZE_MASK ( 0x03 )
|
||||
#define HID_REPORT_ITEM_HDR_SIZE_SHIFT ( 0 )
|
||||
|
||||
#define HID_REPORT_ITEM_HDR_TAG_MASK ( 0xF0 )
|
||||
#define HID_REPORT_ITEM_HDR_TAG_SHIFT ( 4 )
|
||||
|
||||
#define HID_REPORT_ITEM_HDR_TYPE_MASK ( 0x0C )
|
||||
#define HID_REPORT_ITEM_HDR_TYPE_SHIFT ( 2 )
|
||||
|
||||
#define HID_REPORT_ITEM_LOC_BIT_MASK ( 0x70 )
|
||||
#define HID_REPORT_ITEM_LOC_BIT_SHIFT ( 4 )
|
||||
|
||||
#define HID_REPORT_ITEM_LOC_BYTE_MASK ( 0x0F )
|
||||
#define HID_REPORT_ITEM_LOC_BYTE_SHIFT ( 0 )
|
||||
|
||||
#define HID_REPORT_ITEM_MAX_SIZE ( 2 )
|
||||
|
||||
#define HID_REPORT_ITEM_USAGE_TAG ( 0 )
|
||||
#define HID_REPORT_ITEM_USAGE_TYPE ( 2 )
|
||||
|
||||
#define HID_STATUS_GOOD ( 0 )
|
||||
#define HID_STATUS_BAD_HEADER ( 1 )
|
||||
#define HID_STATUS_BAD_LOCATION ( 2 )
|
||||
#define HID_STATUS_BAD_PAGE ( 3 )
|
||||
#define HID_STATUS_IN_USE ( 4 )
|
||||
|
||||
/**
|
||||
* @brief USB HID Report Descriptor. Short Item
|
||||
*
|
||||
* @note
|
||||
* To reduce memory use, this type does not support Short Items with 4 data bytes.
|
||||
* See section 6.2.2.2
|
||||
*
|
||||
* Elements:
|
||||
*
|
||||
* header - the item prefix containing the size, type and tag fields (see 6.2.2.2)
|
||||
* Format (bit range): bSize (0:1), bType (2:3), bTag (4:7)
|
||||
* data - a two byte array for holding the item's data
|
||||
* The bSize field indicates which data bytes are in use
|
||||
* location - a non-standard extension locating the item within the HID Report
|
||||
* Format (bit range): iByte (0:3), iBit (4:6), Reserved (7)
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
unsigned char header;
|
||||
unsigned char data[ HID_REPORT_ITEM_MAX_SIZE ];
|
||||
unsigned char location;
|
||||
} USB_HID_Short_Item_t;
|
||||
|
||||
/**
|
||||
* @brief Get the HID Report descriptor
|
||||
*
|
||||
* This function returns a pointer to the USB HID Report descriptor.
|
||||
* It returns NULL if the Report descriptor has not been prepared,
|
||||
* i.e., no one has called \c hidPrepareReportDescriptor().
|
||||
*
|
||||
* @note An XC-callable version of this function has not been provided.
|
||||
* XC requires explicit declaration of the kind of pointer returned,
|
||||
* hence an XC implementation of the function.
|
||||
*
|
||||
* @return A pointer to a list of unsigned char containing the Report descriptor
|
||||
*/
|
||||
#if !defined(__XC__)
|
||||
unsigned char* hidGetReportDescriptor( void );
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Get the length of the HID Report descriptor
|
||||
*
|
||||
* This function returns the length of the USB HID Report descriptor.
|
||||
* It returns zero if the Report descriptor has not been prepared,
|
||||
* i.e., no one has called \c hidPrepareReportDescriptor().
|
||||
*
|
||||
* @return The length of the Report descriptor in bytes
|
||||
*/
|
||||
size_t hidGetReportDescriptorLength( void );
|
||||
|
||||
/**
|
||||
* @brief Get a HID Report descriptor item
|
||||
*
|
||||
* Parameters:
|
||||
*
|
||||
* @param[in] byte The byte position of the control within the HID Report
|
||||
* @param[in] bit The bit position of the control within the \a byte
|
||||
* @param[out] page The USB HID Usage Page code for the Item (see 5.5)
|
||||
* @param[out] header The LSB of the Item containing the bSize, bType and bTag fields (see 6.2.2.2)
|
||||
* @param[out] data A two element array containing data bytes for the Item
|
||||
*
|
||||
* @return A status value
|
||||
* @retval \c HID_STATUS_GOOD Item successfully returned
|
||||
* @retval \c HID_STATUS_BAD_LOCATION The \a bit or \a byte arguments specify a location outside
|
||||
* of the HID Report
|
||||
*/
|
||||
#if defined(__XC__)
|
||||
unsigned hidGetReportItem( const unsigned byte, const unsigned bit, unsigned char* unsafe const page, unsigned char* unsafe const header, unsigned char* unsafe const data);
|
||||
#else
|
||||
unsigned hidGetReportItem( const unsigned byte, const unsigned bit, unsigned char* const page, unsigned char* const header, unsigned char data[]);
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Get the length of the HID Report
|
||||
*
|
||||
* This function returns the length of the USB HID Report.
|
||||
* It returns zero if the Report descriptor has not been prepared,
|
||||
* i.e., no one has called \c hidPrepareReportDescriptor().
|
||||
*
|
||||
* @return The length of the Report in bytes
|
||||
*/
|
||||
size_t hidGetReportLength( void );
|
||||
|
||||
/**
|
||||
* @brief Prepare the USB HID Report descriptor
|
||||
*
|
||||
* After preparation, \c hidGetReportDescriptor() returns a list suitable for transmission over USB.
|
||||
* Call this function after altering one or more Report Items using \c hidSetReportItem().
|
||||
*/
|
||||
void hidPrepareReportDescriptor( void );
|
||||
|
||||
/**
|
||||
* @brief Reset the USB HID Report descriptor
|
||||
*
|
||||
* After reset, \c hidGetReportDescriptor() returns NULL until a subsequent call to
|
||||
* \c hidPrepareReportDescriptor() occurs.
|
||||
* Call this function before altering one or more Report Items using \c hidSetReportItem().
|
||||
*/
|
||||
void hidResetReportDescriptor( void );
|
||||
|
||||
/**
|
||||
* @brief Modify a HID Report descriptor item
|
||||
*
|
||||
* @warning This function does not check that the length of the \a data array matches the value of
|
||||
* the bSize field in the \a header. For safe operation use a \a data array of at least
|
||||
* \c HID_REPORT_ITEM_MAX_SIZE bytes in length.
|
||||
*
|
||||
* Parameters:
|
||||
*
|
||||
* @param[in] byte The byte position of the control within the HID Report
|
||||
* @param[in] bit The bit position of the control within the \a byte
|
||||
* @param[in] page The USB HID Usage Page code for the Item (see 5.5)
|
||||
* @param[in] header The LSB of the Item containing the bSize, bType and bTag fields (see 6.2.2.2)
|
||||
* @param[in] data An array containing data bytes or NULL for an Item with no data
|
||||
*
|
||||
* @return A status value
|
||||
* @retval \c HID_STATUS_GOOD Item successfully updated
|
||||
* @retval \c HID_STATUS_BAD_HEADER The Item header specified a data size greater than 2 or
|
||||
* a Tag or Type inconsistent with a Usage Item
|
||||
* @retval \c HID_STATUS_BAD_LOCATION The \a bit or \a byte arguments specify a location outside
|
||||
* of the HID Report
|
||||
* @retval \c HID_STATUS_BAD_PAGE The \a byte argument specifies a location for controls from
|
||||
* a Usage Page other than the one given by the \a page parameter
|
||||
* @retval \c HID_STATUS_IN_USE The Report descriptor is in use
|
||||
*/
|
||||
unsigned hidSetReportItem( const unsigned byte, const unsigned bit, const unsigned char page, const unsigned char header, const unsigned char data[]);
|
||||
|
||||
#endif // _HID_REPORT_DESCRIPTOR_
|
||||
66
lib_xua/src/hid/xua_hid_report_descriptor_constants.h
Normal file
66
lib_xua/src/hid/xua_hid_report_descriptor_constants.h
Normal file
@@ -0,0 +1,66 @@
|
||||
// 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 constants
|
||||
*
|
||||
* This file defines a collection of constants from the USB HID documents.
|
||||
* This includes constants from:
|
||||
* - Device Class Definition for Human Interface Devices, version 1.11
|
||||
* - HID Usage Tables for Universal Serial Bus, version 1.22
|
||||
*
|
||||
* This file is incomplete, but can be expanded with new constants as necessary.
|
||||
*/
|
||||
|
||||
#ifndef _XUA_HID_REPORT_DESCRIPTOR_CONSTANTS_
|
||||
#define _XUA_HID_REPORT_DESCRIPTOR_CONSTANTS_
|
||||
|
||||
|
||||
// Constants from the USB Device Class Definition for HID for type
|
||||
#define HID_REPORT_ITEM_TYPE_MAIN ( 0x00 )
|
||||
#define HID_REPORT_ITEM_TYPE_GLOBAL ( 0x01 )
|
||||
#define HID_REPORT_ITEM_TYPE_LOCAL ( 0x02 )
|
||||
#define HID_REPORT_ITEM_TYPE_RESERVED ( 0x03 )
|
||||
|
||||
// Constants from the USB Device Class Definition for HID for tag
|
||||
// Main items
|
||||
#define HID_REPORT_ITEM_TAG_INPUT ( 0x08 )
|
||||
#define HID_REPORT_ITEM_TAG_OUTPUT ( 0x09 )
|
||||
#define HID_REPORT_ITEM_TAG_FEATURE ( 0x0B )
|
||||
#define HID_REPORT_ITEM_TAG_COLLECTION ( 0x0A )
|
||||
#define HID_REPORT_ITEM_TAG_END_COLLECTION ( 0x0C )
|
||||
|
||||
// Global items
|
||||
#define HID_REPORT_ITEM_TAG_USAGE_PAGE ( 0x00 )
|
||||
#define HID_REPORT_ITEM_TAG_LOGICAL_MINIMUM ( 0x01 )
|
||||
#define HID_REPORT_ITEM_TAG_LOGICAL_MAXIMUM ( 0x02 )
|
||||
#define HID_REPORT_ITEM_TAG_PHYSICAL_MINIMUM ( 0x03 )
|
||||
#define HID_REPORT_ITEM_TAG_PHYSICAL_MAXIMUM ( 0x04 )
|
||||
#define HID_REPORT_ITEM_TAG_UNIT_EXPONENT ( 0x05 )
|
||||
#define HID_REPORT_ITEM_TAG_UNIT ( 0x06 )
|
||||
#define HID_REPORT_ITEM_TAG_REPORT_SIZE ( 0x07 )
|
||||
#define HID_REPORT_ITEM_TAG_REPORT_ID ( 0x08 )
|
||||
#define HID_REPORT_ITEM_TAG_REPORT_COUNT ( 0x09 )
|
||||
#define HID_REPORT_ITEM_TAG_PUSH ( 0x0A )
|
||||
#define HID_REPORT_ITEM_TAG_POP ( 0x0B )
|
||||
|
||||
// Local items
|
||||
#define HID_REPORT_ITEM_TAG_USAGE ( 0x00 )
|
||||
#define HID_REPORT_ITEM_TAG_USAGE_MINIMUM ( 0x01 )
|
||||
#define HID_REPORT_ITEM_TAG_USAGE_MAXIMUM ( 0x02 )
|
||||
#define HID_REPORT_ITEM_TAG_DESIGNATOR_INDEX ( 0x03 )
|
||||
#define HID_REPORT_ITEM_TAG_DESIGNATOR_MINIMUM ( 0x04 )
|
||||
#define HID_REPORT_ITEM_TAG_DESIGNATOR_MAXIMUM ( 0x05 )
|
||||
#define HID_REPORT_ITEM_TAG_STRING_INDEX ( 0x07 )
|
||||
#define HID_REPORT_ITEM_TAG_STRING_MINIMUM ( 0x08 )
|
||||
#define HID_REPORT_ITEM_TAG_STRING_MAXIMUM ( 0x09 )
|
||||
#define HID_REPORT_ITEM_TAG_DELIMITER ( 0x0A )
|
||||
|
||||
// Constants from HID Usage Tables
|
||||
// Usage page IDs (incomplete)
|
||||
#define USB_HID_USAGE_PAGE_ID_GENERIC_DESKTOP ( 0x01 )
|
||||
#define USB_HID_USAGE_PAGE_ID_KEYBOARD ( 0x07 )
|
||||
#define USB_HID_USAGE_PAGE_ID_TELEPHONY_DEVICE ( 0x0B )
|
||||
#define USB_HID_USAGE_PAGE_ID_CONSUMER ( 0x0C )
|
||||
|
||||
#endif // _XUA_HID_REPORT_DESCRIPTOR_CONSTANTS_
|
||||
@@ -79,12 +79,10 @@ foreach( testsourcefile ${APP_SOURCES} )
|
||||
set_target_properties(${ITEM_NAME} PROPERTIES OUTPUT_NAME ${ITEM_NAME}.xe)
|
||||
target_compile_options(${ITEM_NAME} PRIVATE ${APP_COMPILER_FLAGS})
|
||||
|
||||
|
||||
|
||||
target_include_directories(${ITEM_NAME}
|
||||
PRIVATE ${APP_INCLUDES}
|
||||
PRIVATE ${XUA_INCLUDES_ALL}
|
||||
)
|
||||
target_include_directories(${ITEM_NAME}
|
||||
PRIVATE ${APP_INCLUDES}
|
||||
PRIVATE ${XUA_INCLUDES_ALL}
|
||||
)
|
||||
|
||||
target_sources(${ITEM_NAME}
|
||||
PRIVATE ${APP_SRCS}
|
||||
|
||||
@@ -1,102 +0,0 @@
|
||||
// Copyright 2021 XMOS LIMITED.
|
||||
// This Software is subject to the terms of the XMOS Public Licence: Version 1.
|
||||
|
||||
#ifndef __hid_report_descriptor_h__
|
||||
#define __hid_report_descriptor_h__
|
||||
|
||||
#include "xua_hid_report_descriptor.h"
|
||||
|
||||
#define MAX_VALID_BIT ( 7 )
|
||||
#define MAX_VALID_BYTE ( 1 )
|
||||
|
||||
#define MIN_VALID_BIT ( 0 )
|
||||
#define MIN_VALID_BYTE ( 0 )
|
||||
|
||||
/*
|
||||
* Define non-configurable items in the HID Report descriptor.
|
||||
*/
|
||||
static const USB_HID_Short_Item_t hidCollectionApplication = { .header = 0xA1, .data = { 0x01, 0x00 }, .location = 0x00 };
|
||||
static const USB_HID_Short_Item_t hidCollectionEnd = { .header = 0xC0, .data = { 0x00, 0x00 }, .location = 0x00 };
|
||||
static const USB_HID_Short_Item_t hidCollectionLogical = { .header = 0xA1, .data = { 0x02, 0x00 }, .location = 0x00 };
|
||||
|
||||
static const USB_HID_Short_Item_t hidInputConstArray = { .header = 0x81, .data = { 0x01, 0x00 }, .location = 0x00 };
|
||||
static const USB_HID_Short_Item_t hidInputDataVar = { .header = 0x81, .data = { 0x02, 0x00 }, .location = 0x00 };
|
||||
|
||||
static const USB_HID_Short_Item_t hidLogicalMaximum0 = { .header = 0x25, .data = { 0x00, 0x00 }, .location = 0x00 };
|
||||
static const USB_HID_Short_Item_t hidLogicalMaximum1 = { .header = 0x25, .data = { 0x01, 0x00 }, .location = 0x00 };
|
||||
static const USB_HID_Short_Item_t hidLogicalMinimum0 = { .header = 0x15, .data = { 0x00, 0x00 }, .location = 0x00 };
|
||||
|
||||
static const USB_HID_Short_Item_t hidReportCount1 = { .header = 0x95, .data = { 0x01, 0x00 }, .location = 0x00 };
|
||||
static const USB_HID_Short_Item_t hidReportCount6 = { .header = 0x95, .data = { 0x06, 0x00 }, .location = 0x00 };
|
||||
static const USB_HID_Short_Item_t hidReportCount7 = { .header = 0x95, .data = { 0x07, 0x00 }, .location = 0x00 };
|
||||
static const USB_HID_Short_Item_t hidReportSize1 = { .header = 0x75, .data = { 0x01, 0x00 }, .location = 0x00 };
|
||||
|
||||
static const USB_HID_Short_Item_t hidUsageConsumerControl = { .header = 0x09, .data = { 0x01, 0x00 }, .location = 0x00 };
|
||||
|
||||
static const USB_HID_Short_Item_t hidUsagePageConsumer = { .header = 0x05, .data = { 0x0C, 0x00 }, .location = 0x00 };
|
||||
|
||||
/*
|
||||
* Define configurable items in the HID Report descriptor.
|
||||
*/
|
||||
static USB_HID_Short_Item_t hidUsageByte0Bit0 = { .header = 0x09, .data = { 0xE2, 0x00 }, .location = 0x00 }; // Mute
|
||||
|
||||
static USB_HID_Short_Item_t hidUsageByte1Bit7 = { .header = 0x09, .data = { 0xEA, 0x00 }, .location = 0x71 }; // Vol-
|
||||
static USB_HID_Short_Item_t hidUsageByte1Bit0 = { .header = 0x09, .data = { 0xE9, 0x00 }, .location = 0x01 }; // Vol+
|
||||
|
||||
/*
|
||||
* List the configurable items in the HID Report descriptor.
|
||||
*/
|
||||
static USB_HID_Short_Item_t* const hidConfigurableItems[] = {
|
||||
&hidUsageByte0Bit0,
|
||||
&hidUsageByte1Bit0,
|
||||
&hidUsageByte1Bit7
|
||||
};
|
||||
|
||||
/*
|
||||
* List Usage pages in the HID Report descriptor, one per byte.
|
||||
*/
|
||||
static const USB_HID_Short_Item_t* const hidUsagePages[] = {
|
||||
&hidUsagePageConsumer,
|
||||
&hidUsagePageConsumer
|
||||
};
|
||||
|
||||
/*
|
||||
* List all items in the HID Report descriptor.
|
||||
*/
|
||||
static const USB_HID_Short_Item_t* const hidReportDescriptorItems[] = {
|
||||
&hidUsagePageConsumer,
|
||||
&hidUsageConsumerControl,
|
||||
&hidCollectionApplication,
|
||||
&hidReportSize1,
|
||||
&hidLogicalMinimum0,
|
||||
&hidCollectionLogical, // Byte 0
|
||||
&hidLogicalMaximum1,
|
||||
&hidReportCount1,
|
||||
&hidUsageByte0Bit0,
|
||||
&hidInputDataVar,
|
||||
&hidLogicalMaximum0,
|
||||
&hidReportCount7,
|
||||
&hidInputConstArray,
|
||||
&hidCollectionEnd,
|
||||
&hidCollectionLogical, // Byte 1
|
||||
&hidLogicalMaximum1,
|
||||
&hidReportCount1,
|
||||
&hidUsageByte1Bit0,
|
||||
&hidInputDataVar,
|
||||
&hidLogicalMaximum0,
|
||||
&hidReportCount6,
|
||||
&hidInputConstArray,
|
||||
&hidLogicalMaximum1,
|
||||
&hidUsageByte1Bit7,
|
||||
&hidInputDataVar,
|
||||
&hidCollectionEnd,
|
||||
&hidCollectionEnd
|
||||
};
|
||||
|
||||
/*
|
||||
* Define the length of the HID Report.
|
||||
* This value must match the number of Report bytes defined by hidReportDescriptorItems.
|
||||
*/
|
||||
#define HID_REPORT_LENGTH ( 2 )
|
||||
|
||||
#endif // __hid_report_descriptor_h__
|
||||
@@ -0,0 +1,277 @@
|
||||
// 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.h"
|
||||
|
||||
#define USB_HID_REPORT_ID_KEYBOARD ( 0x01 )
|
||||
#define USB_HID_REPORT_ID_CONSUMER ( 0x02 )
|
||||
#define USB_HID_REPORT_ID_TELEPHONY ( 0x03 )
|
||||
|
||||
/*
|
||||
* Define non-configurable items in the HID Report descriptor.
|
||||
* (These are short items as the location field isn't relevant for them)
|
||||
*/
|
||||
static const USB_HID_Short_Item_t hidCollectionApplication = {
|
||||
.header = HID_REPORT_SET_HEADER(1, HID_REPORT_ITEM_TYPE_MAIN, HID_REPORT_ITEM_TAG_COLLECTION),
|
||||
.data = { 0x01, 0x00 } };
|
||||
static const USB_HID_Short_Item_t hidCollectionEnd = {
|
||||
.header = HID_REPORT_SET_HEADER(0, HID_REPORT_ITEM_TYPE_MAIN, HID_REPORT_ITEM_TAG_END_COLLECTION),
|
||||
.data = { 0x00, 0x00 } };
|
||||
static const USB_HID_Short_Item_t hidCollectionLogical = {
|
||||
.header = HID_REPORT_SET_HEADER(1, HID_REPORT_ITEM_TYPE_MAIN, HID_REPORT_ITEM_TAG_COLLECTION),
|
||||
.data = { 0x02, 0x00 } };
|
||||
|
||||
static const USB_HID_Short_Item_t hidInputConstArray = {
|
||||
.header = HID_REPORT_SET_HEADER(1, HID_REPORT_ITEM_TYPE_MAIN, HID_REPORT_ITEM_TAG_INPUT),
|
||||
.data = { 0x01, 0x00 } };
|
||||
static const USB_HID_Short_Item_t hidInputDataVar = {
|
||||
.header = HID_REPORT_SET_HEADER(1, HID_REPORT_ITEM_TYPE_MAIN, HID_REPORT_ITEM_TAG_INPUT),
|
||||
.data = { 0x02, 0x00 } };
|
||||
|
||||
static const USB_HID_Short_Item_t hidLogicalMaximum0 = {
|
||||
.header = HID_REPORT_SET_HEADER(1, HID_REPORT_ITEM_TYPE_GLOBAL, HID_REPORT_ITEM_TAG_LOGICAL_MAXIMUM),
|
||||
.data = { 0x00, 0x00 } };
|
||||
static const USB_HID_Short_Item_t hidLogicalMaximum1 = {
|
||||
.header = HID_REPORT_SET_HEADER(1, HID_REPORT_ITEM_TYPE_GLOBAL, HID_REPORT_ITEM_TAG_LOGICAL_MAXIMUM),
|
||||
.data = { 0x01, 0x00 } };
|
||||
static const USB_HID_Short_Item_t hidLogicalMinimum0 = {
|
||||
.header = HID_REPORT_SET_HEADER(1, HID_REPORT_ITEM_TYPE_GLOBAL, HID_REPORT_ITEM_TAG_LOGICAL_MINIMUM),
|
||||
.data = { 0x00, 0x00 } };
|
||||
|
||||
static const USB_HID_Short_Item_t hidReportCount1 = {
|
||||
.header = HID_REPORT_SET_HEADER(1, HID_REPORT_ITEM_TYPE_GLOBAL, HID_REPORT_ITEM_TAG_REPORT_COUNT),
|
||||
.data = { 0x01, 0x00 } };
|
||||
static const USB_HID_Short_Item_t hidReportCount4 = {
|
||||
.header = HID_REPORT_SET_HEADER(1, HID_REPORT_ITEM_TYPE_GLOBAL, HID_REPORT_ITEM_TAG_REPORT_COUNT),
|
||||
.data = { 0x04, 0x00 } };
|
||||
static const USB_HID_Short_Item_t hidReportCount6 = {
|
||||
.header = HID_REPORT_SET_HEADER(1, HID_REPORT_ITEM_TYPE_GLOBAL, HID_REPORT_ITEM_TAG_REPORT_COUNT),
|
||||
.data = { 0x06, 0x00 } };
|
||||
static const USB_HID_Short_Item_t hidReportCount7 = {
|
||||
.header = HID_REPORT_SET_HEADER(1, HID_REPORT_ITEM_TYPE_GLOBAL, HID_REPORT_ITEM_TAG_REPORT_COUNT),
|
||||
.data = { 0x07, 0x00 } };
|
||||
static const USB_HID_Short_Item_t hidReportSize1 = {
|
||||
.header = HID_REPORT_SET_HEADER(1, HID_REPORT_ITEM_TYPE_GLOBAL, HID_REPORT_ITEM_TAG_REPORT_SIZE),
|
||||
.data = { 0x01, 0x00 } };
|
||||
|
||||
static const USB_HID_Short_Item_t hidUsageConsumerControl = {
|
||||
.header = HID_REPORT_SET_HEADER(1, HID_REPORT_ITEM_TYPE_LOCAL, HID_REPORT_ITEM_TAG_USAGE),
|
||||
.data = { 0x01, 0x00 } };
|
||||
|
||||
/*
|
||||
* Define the HID Report Descriptor Item, Usage Page, Report ID and length for each HID Report
|
||||
* For internal purposes, a report element with ID of 0 must be included if report IDs are not being used.
|
||||
*/
|
||||
static const USB_HID_Short_Item_t hidReportId1 = {
|
||||
.header = HID_REPORT_SET_HEADER(1, HID_REPORT_ITEM_TYPE_GLOBAL, HID_REPORT_ITEM_TAG_REPORT_ID),
|
||||
.data = { USB_HID_REPORT_ID_KEYBOARD, 0x00 } };
|
||||
static const USB_HID_Short_Item_t hidReportId2 = {
|
||||
.header = HID_REPORT_SET_HEADER(1, HID_REPORT_ITEM_TYPE_GLOBAL, HID_REPORT_ITEM_TAG_REPORT_ID),
|
||||
.data = { USB_HID_REPORT_ID_CONSUMER, 0x00 } };
|
||||
static const USB_HID_Short_Item_t hidReportId3 = {
|
||||
.header = HID_REPORT_SET_HEADER(1, HID_REPORT_ITEM_TYPE_GLOBAL, HID_REPORT_ITEM_TAG_REPORT_ID),
|
||||
.data = { USB_HID_REPORT_ID_TELEPHONY, 0x00 } };
|
||||
|
||||
static const USB_HID_Report_Element_t hidReportKeyboard = {
|
||||
.item.header = HID_REPORT_SET_HEADER(1, HID_REPORT_ITEM_TYPE_GLOBAL, HID_REPORT_ITEM_TAG_USAGE_PAGE),
|
||||
.item.data = { USB_HID_USAGE_PAGE_ID_KEYBOARD, 0x00 },
|
||||
.location = HID_REPORT_SET_LOC( USB_HID_REPORT_ID_KEYBOARD, 1, 0, 0 )
|
||||
};
|
||||
|
||||
static const USB_HID_Report_Element_t hidReportConsumer = {
|
||||
.item.header = HID_REPORT_SET_HEADER(1, HID_REPORT_ITEM_TYPE_GLOBAL, HID_REPORT_ITEM_TAG_USAGE_PAGE),
|
||||
.item.data = { USB_HID_USAGE_PAGE_ID_CONSUMER, 0x00 },
|
||||
.location = HID_REPORT_SET_LOC( USB_HID_REPORT_ID_CONSUMER, 2, 0, 0 )
|
||||
};
|
||||
|
||||
static const USB_HID_Report_Element_t hidReportTelephony = {
|
||||
.item.header = HID_REPORT_SET_HEADER(1, HID_REPORT_ITEM_TYPE_GLOBAL, HID_REPORT_ITEM_TAG_USAGE_PAGE),
|
||||
.item.data = { USB_HID_USAGE_PAGE_ID_TELEPHONY_DEVICE, 0x00 },
|
||||
.location = HID_REPORT_SET_LOC( USB_HID_REPORT_ID_TELEPHONY, 1, 0, 0 )
|
||||
};
|
||||
|
||||
static USB_HID_Report_Element_t hidUsageReport1Byte0Bit0 = {
|
||||
.item.header = HID_REPORT_SET_HEADER(1, HID_REPORT_ITEM_TYPE_LOCAL, HID_REPORT_ITEM_TAG_USAGE),
|
||||
.item.data = { 0x17, 0x00 },
|
||||
.location = HID_REPORT_SET_LOC( USB_HID_REPORT_ID_KEYBOARD, 0, 0, 0 )
|
||||
}; // 't'
|
||||
|
||||
static USB_HID_Report_Element_t hidUsageReport1Byte0Bit2 = {
|
||||
.item.header = HID_REPORT_SET_HEADER(1, HID_REPORT_ITEM_TYPE_LOCAL, HID_REPORT_ITEM_TAG_USAGE),
|
||||
.item.data = { 0x72, 0x00 },
|
||||
.location = HID_REPORT_SET_LOC( USB_HID_REPORT_ID_KEYBOARD, 0, 0, 2 )
|
||||
}; // F23
|
||||
|
||||
static USB_HID_Report_Element_t hidUsageReport1Byte0Bit3 = {
|
||||
.item.header = HID_REPORT_SET_HEADER(1, HID_REPORT_ITEM_TYPE_LOCAL, HID_REPORT_ITEM_TAG_USAGE),
|
||||
.item.data = { 0x73, 0x00 },
|
||||
.location = HID_REPORT_SET_LOC( USB_HID_REPORT_ID_KEYBOARD, 0, 0, 3 )
|
||||
}; // F24
|
||||
|
||||
static USB_HID_Report_Element_t hidUsageReport2Byte0Bit0 = {
|
||||
.item.header = HID_REPORT_SET_HEADER(2, HID_REPORT_ITEM_TYPE_LOCAL, HID_REPORT_ITEM_TAG_USAGE),
|
||||
.item.data = { 0x26, 0x02 },
|
||||
.location = HID_REPORT_SET_LOC( USB_HID_REPORT_ID_CONSUMER, 0, 0, 0 )
|
||||
}; // AC Stop
|
||||
|
||||
static USB_HID_Report_Element_t hidUsageReport2Byte0Bit1 = {
|
||||
.item.header = HID_REPORT_SET_HEADER(2, HID_REPORT_ITEM_TYPE_LOCAL, HID_REPORT_ITEM_TAG_USAGE),
|
||||
.item.data = { 0x21, 0x02 },
|
||||
.location = HID_REPORT_SET_LOC( USB_HID_REPORT_ID_CONSUMER, 0, 0, 1 )
|
||||
}; // AC Search
|
||||
|
||||
static USB_HID_Report_Element_t hidUsageReport2Byte0Bit2 = {
|
||||
.item.header = HID_REPORT_SET_HEADER(1, HID_REPORT_ITEM_TYPE_LOCAL, HID_REPORT_ITEM_TAG_USAGE),
|
||||
.item.data = { 0xE2, 0x00 },
|
||||
.location = HID_REPORT_SET_LOC( USB_HID_REPORT_ID_CONSUMER, 0, 0, 2 )
|
||||
}; // Mute
|
||||
|
||||
static USB_HID_Report_Element_t hidUsageReport2Byte0Bit4 = {
|
||||
.item.header = HID_REPORT_SET_HEADER(1, HID_REPORT_ITEM_TYPE_LOCAL, HID_REPORT_ITEM_TAG_USAGE),
|
||||
.item.data = { 0xCF, 0x00 },
|
||||
.location = HID_REPORT_SET_LOC( USB_HID_REPORT_ID_CONSUMER, 0, 0, 4 )
|
||||
}; // Voice Command
|
||||
|
||||
static USB_HID_Report_Element_t hidUsageReport2Byte0Bit6 = {
|
||||
.item.header = HID_REPORT_SET_HEADER(1, HID_REPORT_ITEM_TYPE_LOCAL, HID_REPORT_ITEM_TAG_USAGE),
|
||||
.item.data = { 0xE9, 0x00 },
|
||||
.location = HID_REPORT_SET_LOC( USB_HID_REPORT_ID_CONSUMER, 0, 0, 6 )
|
||||
}; // Vol+
|
||||
|
||||
static USB_HID_Report_Element_t hidUsageReport2Byte0Bit7 = {
|
||||
.item.header = HID_REPORT_SET_HEADER(1, HID_REPORT_ITEM_TYPE_LOCAL, HID_REPORT_ITEM_TAG_USAGE),
|
||||
.item.data = { 0xEA, 0x00 },
|
||||
.location = HID_REPORT_SET_LOC( USB_HID_REPORT_ID_CONSUMER, 0, 0, 7 )
|
||||
}; // Vol-
|
||||
|
||||
static USB_HID_Report_Element_t hidUsageReport2Byte1Bit7 = {
|
||||
.item.header = HID_REPORT_SET_HEADER(1, HID_REPORT_ITEM_TYPE_LOCAL, HID_REPORT_ITEM_TAG_USAGE),
|
||||
.item.data = { 0xE5, 0x00 },
|
||||
.location = HID_REPORT_SET_LOC( USB_HID_REPORT_ID_CONSUMER, 0, 1, 7 )
|
||||
}; // Bass boost
|
||||
|
||||
static USB_HID_Report_Element_t hidUsageReport3Byte0Bit0 = {
|
||||
.item.header = HID_REPORT_SET_HEADER(1, HID_REPORT_ITEM_TYPE_LOCAL, HID_REPORT_ITEM_TAG_USAGE),
|
||||
.item.data = { 0x20, 0x00 },
|
||||
.location = HID_REPORT_SET_LOC( USB_HID_REPORT_ID_TELEPHONY, 0, 0, 0 )
|
||||
}; // Hook Switch
|
||||
|
||||
static USB_HID_Report_Element_t hidUsageReport3Byte0Bit1 = {
|
||||
.item.header = HID_REPORT_SET_HEADER(1, HID_REPORT_ITEM_TYPE_LOCAL, HID_REPORT_ITEM_TAG_USAGE),
|
||||
.item.data = { 0x2F, 0x00 },
|
||||
.location = HID_REPORT_SET_LOC( USB_HID_REPORT_ID_TELEPHONY, 0, 0, 1 )
|
||||
}; // Phone Mute
|
||||
|
||||
/*
|
||||
* List the configurable elements in the HID Report.
|
||||
*/
|
||||
static USB_HID_Report_Element_t* const hidConfigurableElements[] = {
|
||||
&hidUsageReport1Byte0Bit0,
|
||||
&hidUsageReport1Byte0Bit2,
|
||||
&hidUsageReport1Byte0Bit3,
|
||||
|
||||
&hidUsageReport2Byte0Bit0,
|
||||
&hidUsageReport2Byte0Bit1,
|
||||
&hidUsageReport2Byte0Bit2,
|
||||
&hidUsageReport2Byte0Bit4,
|
||||
&hidUsageReport2Byte0Bit6,
|
||||
&hidUsageReport2Byte0Bit7,
|
||||
&hidUsageReport2Byte1Bit7,
|
||||
|
||||
&hidUsageReport3Byte0Bit0,
|
||||
&hidUsageReport3Byte0Bit1
|
||||
};
|
||||
|
||||
/*
|
||||
* List HID Reports, one per Report ID. This should be a usage page item with the locator filled out with ID and size
|
||||
* If not using report IDs - still have one with report ID 0
|
||||
*/
|
||||
static const USB_HID_Report_Element_t* const hidReports[] = {
|
||||
&hidReportKeyboard,
|
||||
&hidReportConsumer,
|
||||
&hidReportTelephony
|
||||
};
|
||||
|
||||
/*
|
||||
* List all items in the HID Report descriptor.
|
||||
*/
|
||||
static const USB_HID_Short_Item_t* const hidReportDescriptorItems[] = {
|
||||
&(hidReportConsumer.item),
|
||||
&hidUsageConsumerControl,
|
||||
&hidCollectionApplication,
|
||||
&hidReportSize1,
|
||||
&hidLogicalMinimum0,
|
||||
&hidCollectionLogical, // Report 1
|
||||
&hidReportId1,
|
||||
&(hidReportKeyboard.item),
|
||||
&hidLogicalMaximum1,
|
||||
&hidReportCount1,
|
||||
&(hidUsageReport1Byte0Bit0.item),
|
||||
&hidInputDataVar,
|
||||
&hidLogicalMaximum0,
|
||||
&hidInputConstArray,
|
||||
&hidLogicalMaximum1,
|
||||
&(hidUsageReport1Byte0Bit2.item),
|
||||
&hidInputDataVar,
|
||||
&(hidUsageReport1Byte0Bit3.item),
|
||||
&hidInputDataVar,
|
||||
&hidLogicalMaximum0,
|
||||
&hidReportCount4,
|
||||
&hidInputConstArray,
|
||||
&hidCollectionEnd,
|
||||
&hidCollectionLogical, // Report 2
|
||||
&hidReportId2,
|
||||
&(hidReportConsumer.item),
|
||||
&hidLogicalMaximum1,
|
||||
&hidReportCount1,
|
||||
&(hidUsageReport2Byte0Bit0.item),
|
||||
&hidInputDataVar,
|
||||
&(hidUsageReport2Byte0Bit1.item),
|
||||
&hidInputDataVar,
|
||||
&(hidUsageReport2Byte0Bit2.item),
|
||||
&hidInputDataVar,
|
||||
&hidLogicalMaximum0,
|
||||
&hidInputConstArray,
|
||||
&hidLogicalMaximum1,
|
||||
&(hidUsageReport2Byte0Bit4.item),
|
||||
&hidInputDataVar,
|
||||
&hidLogicalMaximum0,
|
||||
&hidInputConstArray,
|
||||
&hidLogicalMaximum1,
|
||||
&(hidUsageReport2Byte0Bit6.item),
|
||||
&hidInputDataVar,
|
||||
&(hidUsageReport2Byte0Bit7.item),
|
||||
&hidInputDataVar,
|
||||
&hidLogicalMaximum0,
|
||||
&hidReportCount7,
|
||||
&hidInputConstArray,
|
||||
&hidLogicalMaximum1,
|
||||
&hidReportCount1,
|
||||
&(hidUsageReport2Byte1Bit7.item),
|
||||
&hidInputDataVar,
|
||||
&hidCollectionEnd,
|
||||
&hidCollectionLogical, // Report 3
|
||||
&hidReportId3,
|
||||
&(hidReportTelephony.item),
|
||||
&(hidUsageReport3Byte0Bit0.item),
|
||||
&hidInputDataVar,
|
||||
&(hidUsageReport3Byte0Bit1.item),
|
||||
&hidInputDataVar,
|
||||
&hidLogicalMaximum0,
|
||||
&hidReportCount6,
|
||||
&hidInputConstArray,
|
||||
&hidCollectionEnd,
|
||||
&hidCollectionEnd
|
||||
};
|
||||
|
||||
/*
|
||||
* Define the number of HID Reports
|
||||
* Due to XC not supporting designated initializers, this constant has a hard-coded value.
|
||||
* It must equal ( sizeof hidReports / sizeof ( USB_HID_Report_Element_t* ))
|
||||
*/
|
||||
#define HID_REPORT_COUNT ( 3 )
|
||||
|
||||
#endif // __hid_report_descriptor_h__
|
||||
@@ -0,0 +1,891 @@
|
||||
// Copyright 2021 XMOS LIMITED.
|
||||
// This Software is subject to the terms of the XMOS Public Licence: Version 1.
|
||||
#include <stddef.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include "xua_unit_tests.h"
|
||||
#include "xua_hid_report.h"
|
||||
|
||||
// Test constants related to the report descriptor defined in hid_report_descriptor.h
|
||||
#define REPORT1_MAX_VALID_BIT ( 3 )
|
||||
#define REPORT1_MAX_VALID_BYTE ( 0 )
|
||||
#define REPORT1_MIN_VALID_BIT ( 0 )
|
||||
#define REPORT1_MIN_VALID_BYTE ( 0 )
|
||||
|
||||
#define REPORT2_MAX_VALID_BIT ( 7 )
|
||||
#define REPORT2_MAX_VALID_BYTE ( 1 )
|
||||
#define REPORT2_MIN_VALID_BIT ( 0 )
|
||||
#define REPORT2_MIN_VALID_BYTE ( 0 )
|
||||
|
||||
#define REPORT3_MAX_VALID_BIT ( 1 )
|
||||
#define REPORT3_MAX_VALID_BYTE ( 0 )
|
||||
#define REPORT3_MIN_VALID_BIT ( 0 )
|
||||
#define REPORT3_MIN_VALID_BYTE ( 0 )
|
||||
|
||||
#define HID_REPORT_LENGTH ( 3 )
|
||||
#define HID_REPORT_COUNT ( 3 )
|
||||
#define HID_REPORTID_LIMIT ( 4 )
|
||||
|
||||
// Constants from USB HID Usage Tables
|
||||
#define KEYBOARD_PAGE ( 0x07 )
|
||||
#define CONSUMER_PAGE ( 0x0C )
|
||||
#define TELEPHONY_DEVICE_PAGE ( 0x0B )
|
||||
#define LOUDNESS_CONTROL ( 0xE7 )
|
||||
#define PHONE_KEY_9 ( 0xB9 )
|
||||
#define KEYBOARD_X ( 0x1B )
|
||||
#define PHONE_HOST_HOLD ( 0x010A )
|
||||
|
||||
static unsigned construct_usage_header( unsigned size )
|
||||
{
|
||||
unsigned header = 0x00;
|
||||
|
||||
header |= ( HID_REPORT_ITEM_USAGE_TAG << HID_REPORT_ITEM_HDR_TAG_SHIFT ) & HID_REPORT_ITEM_HDR_TAG_MASK;
|
||||
header |= ( HID_REPORT_ITEM_USAGE_TYPE << HID_REPORT_ITEM_HDR_TYPE_SHIFT ) & HID_REPORT_ITEM_HDR_TYPE_MASK;
|
||||
|
||||
header |= ( size << HID_REPORT_ITEM_HDR_SIZE_SHIFT ) & HID_REPORT_ITEM_HDR_SIZE_MASK;
|
||||
|
||||
return header;
|
||||
}
|
||||
|
||||
void setUp( void )
|
||||
{
|
||||
hidReportInit();
|
||||
hidResetReportDescriptor();
|
||||
}
|
||||
|
||||
void test_validate_report( void ) {
|
||||
unsigned retVal = hidReportValidate();
|
||||
TEST_ASSERT_EQUAL_UINT( HID_STATUS_GOOD, retVal );
|
||||
}
|
||||
|
||||
void test_reportid_in_use( void ) {
|
||||
unsigned reportIdInUse = hidIsReportIdInUse();
|
||||
TEST_ASSERT_EQUAL_UINT( 1, reportIdInUse );
|
||||
}
|
||||
|
||||
void test_get_next_valid_report_id( void ) {
|
||||
unsigned reportId = 0U;
|
||||
|
||||
reportId = hidGetNextValidReportId(reportId);
|
||||
TEST_ASSERT_EQUAL_UINT( 1, reportId );
|
||||
|
||||
reportId = hidGetNextValidReportId(reportId);
|
||||
TEST_ASSERT_EQUAL_UINT( 2, reportId );
|
||||
|
||||
reportId = hidGetNextValidReportId(reportId);
|
||||
TEST_ASSERT_EQUAL_UINT( 3, reportId );
|
||||
|
||||
reportId = hidGetNextValidReportId(reportId);
|
||||
TEST_ASSERT_EQUAL_UINT( 1, reportId );
|
||||
}
|
||||
|
||||
// Basic report descriptor tests
|
||||
void test_unprepared_hidGetReportDescriptor( void )
|
||||
{
|
||||
unsigned char* reportDescPtr = hidGetReportDescriptor();
|
||||
TEST_ASSERT_NULL( reportDescPtr );
|
||||
|
||||
for (unsigned reportId = 1; reportId <= HID_REPORT_COUNT; reportId++)
|
||||
{
|
||||
unsigned reportLength = hidGetReportLength( reportId );
|
||||
TEST_ASSERT_EQUAL_UINT( 0, reportLength );
|
||||
}
|
||||
}
|
||||
|
||||
void test_prepared_hidGetReportDescriptor( void )
|
||||
{
|
||||
hidPrepareReportDescriptor();
|
||||
unsigned char* reportDescPtr = hidGetReportDescriptor();
|
||||
TEST_ASSERT_NOT_NULL( reportDescPtr );
|
||||
|
||||
unsigned reportId = 1;
|
||||
unsigned reportLength = hidGetReportLength( reportId );
|
||||
TEST_ASSERT_EQUAL_UINT( 1, reportLength );
|
||||
|
||||
reportId = 2;
|
||||
reportLength = hidGetReportLength( reportId );
|
||||
TEST_ASSERT_EQUAL_UINT( 2, reportLength );
|
||||
|
||||
reportId = 3;
|
||||
reportLength = hidGetReportLength( reportId );
|
||||
TEST_ASSERT_EQUAL_UINT( 1, reportLength );
|
||||
}
|
||||
|
||||
void test_reset_unprepared_hidGetReportDescriptor( void )
|
||||
{
|
||||
hidPrepareReportDescriptor();
|
||||
hidResetReportDescriptor();
|
||||
unsigned char* reportDescPtr = hidGetReportDescriptor();
|
||||
TEST_ASSERT_NULL( reportDescPtr );
|
||||
}
|
||||
|
||||
void test_reset_prepared_hidGetReportDescriptor( void )
|
||||
{
|
||||
hidPrepareReportDescriptor();
|
||||
hidResetReportDescriptor();
|
||||
hidPrepareReportDescriptor();
|
||||
unsigned char* reportDescPtr = hidGetReportDescriptor();
|
||||
TEST_ASSERT_NOT_NULL( reportDescPtr );
|
||||
}
|
||||
|
||||
void test_report_id_limit( void )
|
||||
{
|
||||
unsigned reportIdLimit = hidGetReportIdLimit();
|
||||
TEST_ASSERT_EQUAL_UINT( HID_REPORTID_LIMIT, reportIdLimit );
|
||||
}
|
||||
|
||||
// Basic item tests
|
||||
void test_max_loc_hidGetReportItem( void )
|
||||
{
|
||||
unsigned char data[ HID_REPORT_ITEM_MAX_SIZE ];
|
||||
unsigned char header;
|
||||
unsigned char page;
|
||||
|
||||
unsigned reportId = 1;
|
||||
unsigned bit = REPORT1_MAX_VALID_BIT;
|
||||
unsigned byte = REPORT1_MAX_VALID_BYTE;
|
||||
unsigned retVal = hidGetReportItem( reportId, byte, bit, &page, &header, data );
|
||||
TEST_ASSERT_EQUAL_UINT( HID_STATUS_GOOD, retVal );
|
||||
TEST_ASSERT_EQUAL_UINT( KEYBOARD_PAGE, page );
|
||||
TEST_ASSERT_EQUAL_UINT( 0x09, header );
|
||||
TEST_ASSERT_EQUAL_UINT( 0x73, data[ 0 ]);
|
||||
TEST_ASSERT_EQUAL_UINT( 0x00, data[ 1 ]);
|
||||
|
||||
reportId = 2;
|
||||
bit = REPORT2_MAX_VALID_BIT;
|
||||
byte = REPORT2_MAX_VALID_BYTE;
|
||||
retVal = hidGetReportItem( reportId, byte, bit, &page, &header, data );
|
||||
TEST_ASSERT_EQUAL_UINT( HID_STATUS_GOOD, retVal );
|
||||
TEST_ASSERT_EQUAL_UINT( CONSUMER_PAGE, page );
|
||||
TEST_ASSERT_EQUAL_UINT( 0x09, header );
|
||||
TEST_ASSERT_EQUAL_UINT( 0xE5, data[ 0 ]);
|
||||
TEST_ASSERT_EQUAL_UINT( 0x00, data[ 1 ]);
|
||||
|
||||
reportId = 3;
|
||||
bit = REPORT3_MAX_VALID_BIT;
|
||||
byte = REPORT3_MAX_VALID_BYTE;
|
||||
retVal = hidGetReportItem( reportId, byte, bit, &page, &header, data );
|
||||
TEST_ASSERT_EQUAL_UINT( HID_STATUS_GOOD, retVal );
|
||||
TEST_ASSERT_EQUAL_UINT( TELEPHONY_DEVICE_PAGE, page );
|
||||
TEST_ASSERT_EQUAL_UINT( 0x09, header );
|
||||
TEST_ASSERT_EQUAL_UINT( 0x2F, data[ 0 ]);
|
||||
TEST_ASSERT_EQUAL_UINT( 0x00, data[ 1 ]);
|
||||
}
|
||||
|
||||
|
||||
void test_min_loc_hidGetReportItem( void )
|
||||
{
|
||||
unsigned char data[ HID_REPORT_ITEM_MAX_SIZE ];
|
||||
unsigned char header;
|
||||
unsigned char page;
|
||||
|
||||
unsigned reportId = 1;
|
||||
unsigned bit = REPORT1_MIN_VALID_BIT;
|
||||
unsigned byte = REPORT1_MIN_VALID_BYTE;
|
||||
unsigned retVal = hidGetReportItem( reportId, byte, bit, &page, &header, data );
|
||||
TEST_ASSERT_EQUAL_UINT( HID_STATUS_GOOD, retVal );
|
||||
TEST_ASSERT_EQUAL_UINT( KEYBOARD_PAGE, page );
|
||||
TEST_ASSERT_EQUAL_UINT( 0x09, header );
|
||||
TEST_ASSERT_EQUAL_UINT( 0x17, data[ 0 ]);
|
||||
TEST_ASSERT_EQUAL_UINT( 0x00, data[ 1 ]);
|
||||
|
||||
reportId = 2;
|
||||
bit = REPORT2_MIN_VALID_BIT;
|
||||
byte = REPORT2_MIN_VALID_BYTE;
|
||||
retVal = hidGetReportItem( reportId, byte, bit, &page, &header, data );
|
||||
TEST_ASSERT_EQUAL_UINT( HID_STATUS_GOOD, retVal );
|
||||
TEST_ASSERT_EQUAL_UINT( CONSUMER_PAGE, page );
|
||||
TEST_ASSERT_EQUAL_UINT( 0x0A, header );
|
||||
TEST_ASSERT_EQUAL_UINT( 0x26, data[ 0 ]);
|
||||
TEST_ASSERT_EQUAL_UINT( 0x02, data[ 1 ]);
|
||||
|
||||
reportId = 3;
|
||||
bit = REPORT3_MIN_VALID_BIT;
|
||||
byte = REPORT3_MIN_VALID_BYTE;
|
||||
retVal = hidGetReportItem( reportId, byte, bit, &page, &header, data );
|
||||
TEST_ASSERT_EQUAL_UINT( HID_STATUS_GOOD, retVal );
|
||||
TEST_ASSERT_EQUAL_UINT( TELEPHONY_DEVICE_PAGE, page );
|
||||
TEST_ASSERT_EQUAL_UINT( 0x09, header );
|
||||
TEST_ASSERT_EQUAL_UINT( 0x20, data[ 0 ]);
|
||||
TEST_ASSERT_EQUAL_UINT( 0x00, data[ 1 ]);
|
||||
}
|
||||
|
||||
void test_invalid_report_id( void )
|
||||
{
|
||||
unsigned char data[ HID_REPORT_ITEM_MAX_SIZE ] = { 0xBA, 0xD2 };
|
||||
unsigned char header = 0x33;
|
||||
unsigned char page = 0x44;
|
||||
|
||||
unsigned reportId = 0;
|
||||
unsigned bit = REPORT1_MIN_VALID_BIT;
|
||||
unsigned byte = REPORT1_MIN_VALID_BYTE;
|
||||
unsigned retVal = hidGetReportItem( reportId, byte, bit, &page, &header, data );
|
||||
TEST_ASSERT_EQUAL_UINT( HID_STATUS_BAD_ID, retVal );
|
||||
TEST_ASSERT_EQUAL_UINT( 0x44, page );
|
||||
TEST_ASSERT_EQUAL_UINT( 0x33, header );
|
||||
TEST_ASSERT_EQUAL_UINT( 0xBA, data[ 0 ]);
|
||||
TEST_ASSERT_EQUAL_UINT( 0xD2, data[ 1 ]);
|
||||
}
|
||||
|
||||
void test_unused_report_id( void )
|
||||
{
|
||||
unsigned char data[ HID_REPORT_ITEM_MAX_SIZE ] = { 0xBA, 0xD2 };
|
||||
unsigned char header = 0x33;
|
||||
unsigned char page = 0x44;
|
||||
|
||||
unsigned reportId = 8;
|
||||
unsigned bit = REPORT1_MIN_VALID_BIT;
|
||||
unsigned byte = REPORT1_MIN_VALID_BYTE;
|
||||
unsigned retVal = hidGetReportItem( reportId, byte, bit, &page, &header, data );
|
||||
TEST_ASSERT_EQUAL_UINT( HID_STATUS_BAD_ID, retVal );
|
||||
TEST_ASSERT_EQUAL_UINT( 0x44, page );
|
||||
TEST_ASSERT_EQUAL_UINT( 0x33, header );
|
||||
TEST_ASSERT_EQUAL_UINT( 0xBA, data[ 0 ]);
|
||||
TEST_ASSERT_EQUAL_UINT( 0xD2, data[ 1 ]);
|
||||
}
|
||||
|
||||
void test_overflow_bit_hidGetReportItem( void )
|
||||
{
|
||||
unsigned char data[ HID_REPORT_ITEM_MAX_SIZE ] = { 0xBA, 0xD1 };
|
||||
unsigned char header = 0xAA;
|
||||
unsigned char page = 0x44;
|
||||
|
||||
unsigned reportId = 1;
|
||||
unsigned bit = REPORT1_MAX_VALID_BIT + 1;
|
||||
unsigned byte = REPORT1_MAX_VALID_BYTE;
|
||||
unsigned retVal = hidGetReportItem( reportId, byte, bit, &page, &header, data );
|
||||
TEST_ASSERT_EQUAL_UINT( HID_STATUS_BAD_LOCATION, retVal );
|
||||
TEST_ASSERT_EQUAL_UINT( 0x44, page );
|
||||
TEST_ASSERT_EQUAL_UINT( 0xAA, header );
|
||||
TEST_ASSERT_EQUAL_UINT( 0xBA, data[ 0 ]);
|
||||
TEST_ASSERT_EQUAL_UINT( 0xD1, data[ 1 ]);
|
||||
|
||||
reportId = 2;
|
||||
bit = REPORT2_MAX_VALID_BIT + 1;
|
||||
byte = REPORT2_MAX_VALID_BYTE;
|
||||
retVal = hidGetReportItem( reportId, byte, bit, &page, &header, data );
|
||||
TEST_ASSERT_EQUAL_UINT( HID_STATUS_BAD_LOCATION, retVal );
|
||||
TEST_ASSERT_EQUAL_UINT( 0x44, page );
|
||||
TEST_ASSERT_EQUAL_UINT( 0xAA, header );
|
||||
TEST_ASSERT_EQUAL_UINT( 0xBA, data[ 0 ]);
|
||||
TEST_ASSERT_EQUAL_UINT( 0xD1, data[ 1 ]);
|
||||
|
||||
reportId = 3;
|
||||
bit = REPORT3_MAX_VALID_BIT + 1;
|
||||
byte = REPORT3_MAX_VALID_BYTE;
|
||||
retVal = hidGetReportItem( reportId, byte, bit, &page, &header, data );
|
||||
TEST_ASSERT_EQUAL_UINT( HID_STATUS_BAD_LOCATION, retVal );
|
||||
TEST_ASSERT_EQUAL_UINT( 0x44, page );
|
||||
TEST_ASSERT_EQUAL_UINT( 0xAA, header );
|
||||
TEST_ASSERT_EQUAL_UINT( 0xBA, data[ 0 ]);
|
||||
TEST_ASSERT_EQUAL_UINT( 0xD1, data[ 1 ]);
|
||||
}
|
||||
|
||||
void test_overflow_byte_hidGetReportItem( void )
|
||||
{
|
||||
unsigned char data[ HID_REPORT_ITEM_MAX_SIZE ] = { 0xBA, 0xD1 };
|
||||
unsigned char header = 0xAA;
|
||||
unsigned char page = 0x44;
|
||||
|
||||
unsigned reportId = 1;
|
||||
unsigned bit = REPORT1_MAX_VALID_BIT;
|
||||
unsigned byte = REPORT1_MAX_VALID_BYTE + 1;
|
||||
unsigned retVal = hidGetReportItem( reportId, byte, bit, &page, &header, data );
|
||||
TEST_ASSERT_EQUAL_UINT( HID_STATUS_BAD_LOCATION, retVal );
|
||||
TEST_ASSERT_EQUAL_UINT( 0x44, page );
|
||||
TEST_ASSERT_EQUAL_UINT( 0xAA, header );
|
||||
TEST_ASSERT_EQUAL_UINT( 0xBA, data[ 0 ]);
|
||||
TEST_ASSERT_EQUAL_UINT( 0xD1, data[ 1 ]);
|
||||
|
||||
reportId = 2;
|
||||
bit = REPORT2_MAX_VALID_BIT;
|
||||
byte = REPORT2_MAX_VALID_BYTE + 1;
|
||||
retVal = hidGetReportItem( reportId, byte, bit, &page, &header, data );
|
||||
TEST_ASSERT_EQUAL_UINT( HID_STATUS_BAD_LOCATION, retVal );
|
||||
TEST_ASSERT_EQUAL_UINT( 0x44, page );
|
||||
TEST_ASSERT_EQUAL_UINT( 0xAA, header );
|
||||
TEST_ASSERT_EQUAL_UINT( 0xBA, data[ 0 ]);
|
||||
TEST_ASSERT_EQUAL_UINT( 0xD1, data[ 1 ]);
|
||||
|
||||
reportId = 3;
|
||||
bit = REPORT3_MAX_VALID_BIT;
|
||||
byte = REPORT3_MAX_VALID_BYTE + 1;
|
||||
retVal = hidGetReportItem( reportId, byte, bit, &page, &header, data );
|
||||
TEST_ASSERT_EQUAL_UINT( HID_STATUS_BAD_LOCATION, retVal );
|
||||
TEST_ASSERT_EQUAL_UINT( 0x44, page );
|
||||
TEST_ASSERT_EQUAL_UINT( 0xAA, header );
|
||||
TEST_ASSERT_EQUAL_UINT( 0xBA, data[ 0 ]);
|
||||
TEST_ASSERT_EQUAL_UINT( 0xD1, data[ 1 ]);
|
||||
}
|
||||
|
||||
void test_underflow_bit_hidGetReportItem( void )
|
||||
{
|
||||
unsigned char data[ HID_REPORT_ITEM_MAX_SIZE ] = { 0xBA, 0xD1 };
|
||||
unsigned char header = 0xAA;
|
||||
unsigned char page = 0x44;
|
||||
|
||||
unsigned reportId = 1;
|
||||
unsigned bit = REPORT1_MIN_VALID_BIT - 1;
|
||||
unsigned byte = REPORT1_MIN_VALID_BYTE;
|
||||
unsigned retVal = hidGetReportItem( reportId, byte, bit, &page, &header, data );
|
||||
TEST_ASSERT_EQUAL_UINT( HID_STATUS_BAD_LOCATION, retVal );
|
||||
TEST_ASSERT_EQUAL_UINT( 0x44, page );
|
||||
TEST_ASSERT_EQUAL_UINT( 0xAA, header );
|
||||
TEST_ASSERT_EQUAL_UINT( 0xBA, data[ 0 ]);
|
||||
TEST_ASSERT_EQUAL_UINT( 0xD1, data[ 1 ]);
|
||||
|
||||
reportId = 2;
|
||||
bit = REPORT2_MIN_VALID_BIT - 1;
|
||||
byte = REPORT2_MIN_VALID_BYTE;
|
||||
retVal = hidGetReportItem( reportId, byte, bit, &page, &header, data );
|
||||
TEST_ASSERT_EQUAL_UINT( HID_STATUS_BAD_LOCATION, retVal );
|
||||
TEST_ASSERT_EQUAL_UINT( 0x44, page );
|
||||
TEST_ASSERT_EQUAL_UINT( 0xAA, header );
|
||||
TEST_ASSERT_EQUAL_UINT( 0xBA, data[ 0 ]);
|
||||
TEST_ASSERT_EQUAL_UINT( 0xD1, data[ 1 ]);
|
||||
|
||||
reportId = 3;
|
||||
bit = REPORT3_MIN_VALID_BIT - 1;
|
||||
byte = REPORT3_MIN_VALID_BYTE;
|
||||
retVal = hidGetReportItem( reportId, byte, bit, &page, &header, data );
|
||||
TEST_ASSERT_EQUAL_UINT( HID_STATUS_BAD_LOCATION, retVal );
|
||||
TEST_ASSERT_EQUAL_UINT( 0x44, page );
|
||||
TEST_ASSERT_EQUAL_UINT( 0xAA, header );
|
||||
TEST_ASSERT_EQUAL_UINT( 0xBA, data[ 0 ]);
|
||||
TEST_ASSERT_EQUAL_UINT( 0xD1, data[ 1 ]);
|
||||
}
|
||||
|
||||
void test_underflow_byte_hidGetReportItem( void )
|
||||
{
|
||||
unsigned char data[ HID_REPORT_ITEM_MAX_SIZE ] = { 0xBA, 0xD1 };
|
||||
unsigned char header = 0xAA;
|
||||
unsigned char page = 0x44;
|
||||
|
||||
unsigned reportId = 1;
|
||||
unsigned bit = REPORT1_MIN_VALID_BIT;
|
||||
unsigned byte = REPORT1_MIN_VALID_BYTE - 1;
|
||||
unsigned retVal = hidGetReportItem( reportId, byte, bit, &page, &header, data );
|
||||
TEST_ASSERT_EQUAL_UINT( HID_STATUS_BAD_LOCATION, retVal );
|
||||
TEST_ASSERT_EQUAL_UINT( 0x44, page );
|
||||
TEST_ASSERT_EQUAL_UINT( 0xAA, header );
|
||||
TEST_ASSERT_EQUAL_UINT( 0xBA, data[ 0 ]);
|
||||
TEST_ASSERT_EQUAL_UINT( 0xD1, data[ 1 ]);
|
||||
|
||||
reportId = 2;
|
||||
bit = REPORT2_MIN_VALID_BIT;
|
||||
byte = REPORT2_MIN_VALID_BYTE - 1;
|
||||
retVal = hidGetReportItem( reportId, byte, bit, &page, &header, data );
|
||||
TEST_ASSERT_EQUAL_UINT( HID_STATUS_BAD_LOCATION, retVal );
|
||||
TEST_ASSERT_EQUAL_UINT( 0x44, page );
|
||||
TEST_ASSERT_EQUAL_UINT( 0xAA, header );
|
||||
TEST_ASSERT_EQUAL_UINT( 0xBA, data[ 0 ]);
|
||||
TEST_ASSERT_EQUAL_UINT( 0xD1, data[ 1 ]);
|
||||
|
||||
reportId = 3;
|
||||
bit = REPORT3_MIN_VALID_BIT;
|
||||
byte = REPORT3_MIN_VALID_BYTE - 1;
|
||||
retVal = hidGetReportItem( reportId, byte, bit, &page, &header, data );
|
||||
TEST_ASSERT_EQUAL_UINT( HID_STATUS_BAD_LOCATION, retVal );
|
||||
TEST_ASSERT_EQUAL_UINT( 0x44, page );
|
||||
TEST_ASSERT_EQUAL_UINT( 0xAA, header );
|
||||
TEST_ASSERT_EQUAL_UINT( 0xBA, data[ 0 ]);
|
||||
TEST_ASSERT_EQUAL_UINT( 0xD1, data[ 1 ]);
|
||||
}
|
||||
|
||||
// Configurable and non-configurable item tests
|
||||
void test_configurable_item_hidSetReportItem( void )
|
||||
{
|
||||
const unsigned reportId = 1;
|
||||
const unsigned bit = REPORT1_MIN_VALID_BIT;
|
||||
const unsigned byte = REPORT1_MIN_VALID_BYTE;
|
||||
unsigned char data[ 1 ] = { KEYBOARD_X };
|
||||
unsigned char header = construct_usage_header( sizeof( data ) / sizeof( unsigned char ));
|
||||
unsigned char page = KEYBOARD_PAGE;
|
||||
|
||||
unsigned retVal = hidSetReportItem( reportId, byte, bit, page, header, data );
|
||||
TEST_ASSERT_EQUAL_UINT( HID_STATUS_GOOD, retVal );
|
||||
|
||||
retVal = hidGetReportItem( reportId, byte, bit, &page, &header, data );
|
||||
TEST_ASSERT_EQUAL_UINT( HID_STATUS_GOOD, retVal );
|
||||
TEST_ASSERT_EQUAL_UINT( KEYBOARD_PAGE, page );
|
||||
TEST_ASSERT_EQUAL_UINT( 0x09, header );
|
||||
TEST_ASSERT_EQUAL_UINT( KEYBOARD_X, data[ 0 ]);
|
||||
TEST_ASSERT_EQUAL_UINT( 0x00, data[ 1 ]);
|
||||
}
|
||||
|
||||
// Testing that the high byte of the report gets correctly cleared
|
||||
void test_configurable_item_hidSetReportItem_multibyte_orig( void )
|
||||
{
|
||||
const unsigned reportId = 2;
|
||||
const unsigned bit = 1; // This byte&bit combo is originally set be 2 bytes long in the header
|
||||
const unsigned byte = 0;
|
||||
unsigned char data[ 1 ] = { LOUDNESS_CONTROL };
|
||||
unsigned char header = construct_usage_header( sizeof( data ) / sizeof( unsigned char ));
|
||||
unsigned char page = CONSUMER_PAGE;
|
||||
|
||||
unsigned retVal = hidSetReportItem( reportId, byte, bit, page, header, data );
|
||||
TEST_ASSERT_EQUAL_UINT( HID_STATUS_GOOD, retVal );
|
||||
|
||||
retVal = hidGetReportItem( reportId, byte, bit, &page, &header, data );
|
||||
TEST_ASSERT_EQUAL_UINT( HID_STATUS_GOOD, retVal );
|
||||
TEST_ASSERT_EQUAL_UINT( CONSUMER_PAGE, page );
|
||||
TEST_ASSERT_EQUAL_UINT( 0x09, header );
|
||||
TEST_ASSERT_EQUAL_UINT( LOUDNESS_CONTROL, data[ 0 ]);
|
||||
TEST_ASSERT_EQUAL_UINT( 0x00, data[ 1 ]);
|
||||
}
|
||||
|
||||
void test_nonconfigurable_item_hidSetReportItem( void )
|
||||
{
|
||||
const unsigned reportId = 1;
|
||||
const unsigned bit = 1; // This bit and byte combination should not appear in the
|
||||
const unsigned byte = 0; // hidConfigurableElements list in hid_report_descriptors.c.
|
||||
const unsigned char data[ 1 ] = { KEYBOARD_X };
|
||||
const unsigned char header = construct_usage_header( sizeof data / sizeof( unsigned char ));
|
||||
const unsigned char page = KEYBOARD_PAGE;
|
||||
|
||||
unsigned retVal = hidSetReportItem( reportId, byte, bit, page, header, data );
|
||||
TEST_ASSERT_EQUAL_UINT( HID_STATUS_BAD_LOCATION, retVal );
|
||||
}
|
||||
|
||||
// Bit range tests
|
||||
void test_max_bit_hidSetReportItem( void )
|
||||
{
|
||||
const unsigned char header = construct_usage_header( 0 );
|
||||
|
||||
unsigned reportId = 1;
|
||||
unsigned bit = REPORT1_MAX_VALID_BIT; // See the hidConfigurableElements list in hid_report_descriptors.c.
|
||||
unsigned byte = REPORT1_MAX_VALID_BYTE;
|
||||
unsigned char page = KEYBOARD_PAGE;
|
||||
unsigned retVal = hidSetReportItem( reportId, byte, bit, page, header, NULL );
|
||||
TEST_ASSERT_EQUAL_UINT( HID_STATUS_GOOD, retVal );
|
||||
|
||||
reportId = 2;
|
||||
bit = REPORT2_MAX_VALID_BIT;
|
||||
byte = REPORT2_MAX_VALID_BYTE;
|
||||
page = CONSUMER_PAGE;
|
||||
retVal = hidSetReportItem( reportId, byte, bit, page, header, NULL );
|
||||
TEST_ASSERT_EQUAL_UINT( HID_STATUS_GOOD, retVal );
|
||||
|
||||
reportId = 3;
|
||||
bit = REPORT3_MAX_VALID_BIT;
|
||||
byte = REPORT3_MAX_VALID_BYTE;
|
||||
page = TELEPHONY_DEVICE_PAGE;
|
||||
retVal = hidSetReportItem( reportId, byte, bit, page, header, NULL );
|
||||
TEST_ASSERT_EQUAL_UINT( HID_STATUS_GOOD, retVal );
|
||||
}
|
||||
|
||||
void test_min_bit_hidSetReportItem( void )
|
||||
{
|
||||
const unsigned char header = construct_usage_header( 0 );
|
||||
|
||||
unsigned reportId = 1;
|
||||
unsigned bit = REPORT1_MIN_VALID_BIT; // See the hidConfigurableElements list in hid_report_descriptors.c.
|
||||
unsigned byte = REPORT1_MIN_VALID_BYTE;
|
||||
unsigned char page = KEYBOARD_PAGE;
|
||||
unsigned retVal = hidSetReportItem( reportId, byte, bit, page, header, NULL );
|
||||
TEST_ASSERT_EQUAL_UINT( HID_STATUS_GOOD, retVal );
|
||||
|
||||
reportId = 2;
|
||||
bit = REPORT2_MIN_VALID_BIT;
|
||||
byte = REPORT2_MIN_VALID_BYTE;
|
||||
page = CONSUMER_PAGE;
|
||||
retVal = hidSetReportItem( reportId, byte, bit, page, header, NULL );
|
||||
TEST_ASSERT_EQUAL_UINT( HID_STATUS_GOOD, retVal );
|
||||
|
||||
reportId = 3;
|
||||
bit = REPORT3_MIN_VALID_BIT;
|
||||
byte = REPORT3_MIN_VALID_BYTE;
|
||||
page = TELEPHONY_DEVICE_PAGE;
|
||||
retVal = hidSetReportItem( reportId, byte, bit, page, header, NULL );
|
||||
TEST_ASSERT_EQUAL_UINT( HID_STATUS_GOOD, retVal );
|
||||
}
|
||||
|
||||
void test_overflow_bit_hidSetReportItem( void )
|
||||
{
|
||||
const unsigned char header = construct_usage_header( 0 );
|
||||
|
||||
unsigned reportId = 1;
|
||||
unsigned bit = REPORT1_MAX_VALID_BIT + 1; // See the hidConfigurableElements list in hid_report_descriptors.c.
|
||||
unsigned byte = REPORT1_MAX_VALID_BYTE;
|
||||
unsigned char page = KEYBOARD_PAGE;
|
||||
unsigned retVal = hidSetReportItem( reportId, byte, bit, page, header, NULL );
|
||||
TEST_ASSERT_EQUAL_UINT( HID_STATUS_BAD_LOCATION, retVal );
|
||||
|
||||
reportId = 2;
|
||||
bit = REPORT2_MAX_VALID_BIT + 1;
|
||||
byte = REPORT2_MAX_VALID_BYTE;
|
||||
page = CONSUMER_PAGE;
|
||||
retVal = hidSetReportItem( reportId, byte, bit, page, header, NULL );
|
||||
TEST_ASSERT_EQUAL_UINT( HID_STATUS_BAD_LOCATION, retVal );
|
||||
|
||||
reportId = 3;
|
||||
bit = REPORT3_MAX_VALID_BIT + 1;
|
||||
byte = REPORT3_MAX_VALID_BYTE;
|
||||
page = TELEPHONY_DEVICE_PAGE;
|
||||
retVal = hidSetReportItem( reportId, byte, bit, page, header, NULL );
|
||||
TEST_ASSERT_EQUAL_UINT( HID_STATUS_BAD_LOCATION, retVal );
|
||||
}
|
||||
|
||||
void test_underflow_bit_hidSetReportItem( void )
|
||||
{
|
||||
const unsigned char header = construct_usage_header( 0 );
|
||||
|
||||
unsigned reportId = 1;
|
||||
unsigned bit = REPORT1_MIN_VALID_BIT - 1; // See the hidConfigurableElements list in hid_report_descriptors.c.
|
||||
unsigned byte = REPORT1_MIN_VALID_BYTE;
|
||||
unsigned char page = KEYBOARD_PAGE;
|
||||
unsigned retVal = hidSetReportItem( reportId, byte, bit, page, header, NULL );
|
||||
TEST_ASSERT_EQUAL_UINT( HID_STATUS_BAD_LOCATION, retVal );
|
||||
|
||||
reportId = 2;
|
||||
bit = REPORT2_MIN_VALID_BIT - 1;
|
||||
byte = REPORT2_MIN_VALID_BYTE;
|
||||
page = CONSUMER_PAGE;
|
||||
retVal = hidSetReportItem( reportId, byte, bit, page, header, NULL );
|
||||
TEST_ASSERT_EQUAL_UINT( HID_STATUS_BAD_LOCATION, retVal );
|
||||
|
||||
reportId = 3;
|
||||
bit = REPORT3_MIN_VALID_BIT - 1;
|
||||
byte = REPORT3_MIN_VALID_BYTE;
|
||||
page = TELEPHONY_DEVICE_PAGE;
|
||||
retVal = hidSetReportItem( reportId, byte, bit, page, header, NULL );
|
||||
TEST_ASSERT_EQUAL_UINT( HID_STATUS_BAD_LOCATION, retVal );
|
||||
}
|
||||
|
||||
void test_overflow_byte_hidSetReportItem( void )
|
||||
{
|
||||
const unsigned char header = construct_usage_header( 0 );
|
||||
|
||||
unsigned reportId = 1;
|
||||
unsigned bit = REPORT1_MAX_VALID_BIT; // See the hidConfigurableElements list in hid_report_descriptors.c.
|
||||
unsigned byte = REPORT1_MAX_VALID_BYTE + 1;
|
||||
unsigned char page = KEYBOARD_PAGE;
|
||||
unsigned retVal = hidSetReportItem( reportId, byte, bit, page, header, NULL );
|
||||
TEST_ASSERT_EQUAL_UINT( HID_STATUS_BAD_LOCATION, retVal );
|
||||
|
||||
reportId = 2;
|
||||
bit = REPORT2_MAX_VALID_BIT;
|
||||
byte = REPORT2_MAX_VALID_BYTE + 1;
|
||||
page = CONSUMER_PAGE;
|
||||
retVal = hidSetReportItem( reportId, byte, bit, page, header, NULL );
|
||||
TEST_ASSERT_EQUAL_UINT( HID_STATUS_BAD_LOCATION, retVal );
|
||||
|
||||
reportId = 3;
|
||||
bit = REPORT3_MAX_VALID_BIT;
|
||||
byte = REPORT3_MAX_VALID_BYTE + 1;
|
||||
page = TELEPHONY_DEVICE_PAGE;
|
||||
retVal = hidSetReportItem( reportId, byte, bit, page, header, NULL );
|
||||
TEST_ASSERT_EQUAL_UINT( HID_STATUS_BAD_LOCATION, retVal );
|
||||
}
|
||||
|
||||
void test_underflow_byte_hidSetReportItem( void )
|
||||
{
|
||||
const unsigned char header = construct_usage_header( 0 );
|
||||
|
||||
unsigned reportId = 1;
|
||||
unsigned bit = REPORT1_MIN_VALID_BIT; // See the hidConfigurableElements list in hid_report_descriptors.c.
|
||||
unsigned byte = REPORT1_MIN_VALID_BYTE - 1;
|
||||
unsigned char page = KEYBOARD_PAGE;
|
||||
unsigned retVal = hidSetReportItem( reportId, byte, bit, page, header, NULL );
|
||||
TEST_ASSERT_EQUAL_UINT( HID_STATUS_BAD_LOCATION, retVal );
|
||||
|
||||
reportId = 2;
|
||||
bit = REPORT2_MIN_VALID_BIT;
|
||||
byte = REPORT2_MIN_VALID_BYTE - 1;
|
||||
page = CONSUMER_PAGE;
|
||||
retVal = hidSetReportItem( reportId, byte, bit, page, header, NULL );
|
||||
TEST_ASSERT_EQUAL_UINT( HID_STATUS_BAD_LOCATION, retVal );
|
||||
|
||||
reportId = 3;
|
||||
bit = REPORT3_MIN_VALID_BIT;
|
||||
byte = REPORT3_MIN_VALID_BYTE - 1;
|
||||
page = TELEPHONY_DEVICE_PAGE;
|
||||
retVal = hidSetReportItem( reportId, byte, bit, page, header, NULL );
|
||||
TEST_ASSERT_EQUAL_UINT( HID_STATUS_BAD_LOCATION, retVal );
|
||||
}
|
||||
|
||||
// Size range tests
|
||||
void test_max_size_hidSetReportItem( void )
|
||||
{
|
||||
const unsigned reportId = 1;
|
||||
const unsigned bit = REPORT1_MIN_VALID_BIT;
|
||||
const unsigned byte = REPORT1_MIN_VALID_BYTE;
|
||||
const unsigned char data[ HID_REPORT_ITEM_MAX_SIZE ] = { 0x00 };
|
||||
const unsigned char header = construct_usage_header( HID_REPORT_ITEM_MAX_SIZE );
|
||||
const unsigned char page = KEYBOARD_PAGE;
|
||||
|
||||
unsigned retVal = hidSetReportItem( reportId, byte, bit, page, header, data );
|
||||
TEST_ASSERT_EQUAL_UINT( HID_STATUS_GOOD, retVal );
|
||||
}
|
||||
|
||||
void test_min_size_hidSetReportItem( void )
|
||||
{
|
||||
const unsigned reportId = 1;
|
||||
const unsigned bit = REPORT1_MIN_VALID_BIT;
|
||||
const unsigned byte = REPORT1_MIN_VALID_BYTE;
|
||||
const unsigned char header = construct_usage_header( 0x00 );
|
||||
const unsigned char page = KEYBOARD_PAGE;
|
||||
|
||||
unsigned retVal = hidSetReportItem( reportId, byte, bit, page, header, NULL );
|
||||
TEST_ASSERT_EQUAL_UINT( HID_STATUS_GOOD, retVal );
|
||||
}
|
||||
|
||||
void test_unsupported_size_hidSetReportItem( void )
|
||||
{
|
||||
const unsigned reportId = 0;
|
||||
const unsigned bit = REPORT1_MIN_VALID_BIT;
|
||||
const unsigned byte = REPORT1_MIN_VALID_BYTE;
|
||||
const unsigned char header = construct_usage_header( 0x03 );
|
||||
const unsigned char page = KEYBOARD_PAGE;
|
||||
|
||||
unsigned retVal = hidSetReportItem( reportId, byte, bit, page, header, NULL );
|
||||
TEST_ASSERT_EQUAL_UINT( HID_STATUS_BAD_HEADER, retVal );
|
||||
}
|
||||
|
||||
// Combined function tests
|
||||
void test_initial_modification_without_subsequent_preparation( void )
|
||||
{
|
||||
const unsigned reportId = 2;
|
||||
const unsigned bit = REPORT2_MIN_VALID_BIT;
|
||||
const unsigned byte = REPORT2_MIN_VALID_BYTE;
|
||||
const unsigned char data[ 1 ] = { LOUDNESS_CONTROL };
|
||||
const unsigned char header = construct_usage_header( sizeof data / sizeof( unsigned char ));
|
||||
const unsigned char page = CONSUMER_PAGE;
|
||||
|
||||
unsigned retVal = hidSetReportItem( reportId, byte, bit, page, header, data );
|
||||
TEST_ASSERT_EQUAL_UINT( HID_STATUS_GOOD, retVal );
|
||||
|
||||
unsigned char* reportDescPtr = hidGetReportDescriptor();
|
||||
TEST_ASSERT_NULL( reportDescPtr );
|
||||
}
|
||||
|
||||
void test_initial_modification_with_subsequent_preparation( void )
|
||||
{
|
||||
const unsigned reportId = 2;
|
||||
const unsigned bit = REPORT2_MIN_VALID_BIT;
|
||||
const unsigned byte = REPORT2_MIN_VALID_BYTE;
|
||||
const unsigned char data[ 1 ] = { LOUDNESS_CONTROL };
|
||||
const unsigned char header = construct_usage_header( sizeof data / sizeof( unsigned char ));
|
||||
const unsigned char page = CONSUMER_PAGE;
|
||||
|
||||
unsigned retVal = hidSetReportItem( reportId, byte, bit, page, header, data );
|
||||
TEST_ASSERT_EQUAL_UINT( HID_STATUS_GOOD, retVal );
|
||||
|
||||
hidPrepareReportDescriptor();
|
||||
unsigned char* reportDescPtr = hidGetReportDescriptor();
|
||||
TEST_ASSERT_NOT_NULL( reportDescPtr );
|
||||
}
|
||||
|
||||
void test_initial_modification_with_subsequent_verification_1( void )
|
||||
{
|
||||
const unsigned reportId = 2;
|
||||
const unsigned bit = REPORT2_MIN_VALID_BIT;
|
||||
const unsigned byte = REPORT2_MIN_VALID_BYTE;
|
||||
|
||||
unsigned char get_data[ HID_REPORT_ITEM_MAX_SIZE ] = { 0xFF, 0xFF };
|
||||
unsigned char get_header = 0xFF;
|
||||
unsigned char get_page = 0xFF;
|
||||
|
||||
const unsigned char set_data[ 1 ] = { LOUDNESS_CONTROL };
|
||||
const unsigned char set_header = construct_usage_header( sizeof set_data / sizeof( unsigned char ));
|
||||
const unsigned char set_page = CONSUMER_PAGE;
|
||||
|
||||
unsigned setRetVal = hidSetReportItem( reportId, byte, bit, set_page, set_header, set_data );
|
||||
TEST_ASSERT_EQUAL_UINT( HID_STATUS_GOOD, setRetVal );
|
||||
|
||||
unsigned getRetVal = hidGetReportItem( reportId, byte, bit, &get_page, &get_header, get_data );
|
||||
TEST_ASSERT_EQUAL_UINT( HID_STATUS_GOOD, getRetVal );
|
||||
TEST_ASSERT_EQUAL_UINT( set_page, get_page );
|
||||
TEST_ASSERT_EQUAL_UINT( set_header, get_header );
|
||||
TEST_ASSERT_EQUAL_UINT( set_data[ 0 ], get_data[ 0 ]);
|
||||
TEST_ASSERT_EQUAL_UINT( 0, get_data[ 1 ]); // Should be MSB of data from hidUsageByte0Bit0 in hid_report_descriptor.h
|
||||
}
|
||||
|
||||
void test_initial_modification_with_subsequent_verification_2( void )
|
||||
{
|
||||
const unsigned reportId = 3;
|
||||
const unsigned bit = REPORT3_MIN_VALID_BIT;
|
||||
const unsigned byte = REPORT3_MIN_VALID_BYTE;
|
||||
|
||||
{
|
||||
unsigned char get_data[ HID_REPORT_ITEM_MAX_SIZE ] = { 0xFF, 0xFF };
|
||||
unsigned char get_header = 0xFF;
|
||||
unsigned char get_page = 0xFF;
|
||||
|
||||
const unsigned char set_data[ 2 ] = {( PHONE_HOST_HOLD & 0x00FF ), (( PHONE_HOST_HOLD & 0xFF00 ) >> 8 )};
|
||||
const unsigned char set_header = construct_usage_header( sizeof set_data / sizeof( unsigned char ));
|
||||
const unsigned char set_page = TELEPHONY_DEVICE_PAGE;
|
||||
|
||||
unsigned setRetVal = hidSetReportItem( reportId, byte, bit, set_page, set_header, set_data );
|
||||
TEST_ASSERT_EQUAL_UINT( HID_STATUS_GOOD, setRetVal );
|
||||
|
||||
unsigned getRetVal = hidGetReportItem( reportId, byte, bit, &get_page, &get_header, get_data );
|
||||
TEST_ASSERT_EQUAL_UINT( HID_STATUS_GOOD, getRetVal );
|
||||
TEST_ASSERT_EQUAL_UINT( set_page, get_page );
|
||||
TEST_ASSERT_EQUAL_UINT( set_header, get_header );
|
||||
TEST_ASSERT_EQUAL_UINT( set_data[ 0 ], get_data[ 0 ]);
|
||||
TEST_ASSERT_EQUAL_UINT( set_data[ 1 ], get_data[ 1 ]);
|
||||
}
|
||||
|
||||
{
|
||||
unsigned char get_data[ HID_REPORT_ITEM_MAX_SIZE ] = { 0xFF, 0xFF };
|
||||
unsigned char get_header = 0xFF;
|
||||
unsigned char get_page = 0xFF;
|
||||
|
||||
const unsigned char set_data[ 1 ] = { PHONE_KEY_9 };
|
||||
const unsigned char set_header = construct_usage_header( sizeof set_data / sizeof( unsigned char ));
|
||||
const unsigned char set_page = TELEPHONY_DEVICE_PAGE;
|
||||
|
||||
unsigned setRetVal = hidSetReportItem( reportId, byte, bit, set_page, set_header, set_data );
|
||||
TEST_ASSERT_EQUAL_UINT( HID_STATUS_GOOD, setRetVal );
|
||||
|
||||
unsigned getRetVal = hidGetReportItem( reportId, byte, bit, &get_page, &get_header, get_data );
|
||||
TEST_ASSERT_EQUAL_UINT( HID_STATUS_GOOD, getRetVal );
|
||||
TEST_ASSERT_EQUAL_UINT( set_page, get_page );
|
||||
TEST_ASSERT_EQUAL_UINT( set_header, get_header );
|
||||
TEST_ASSERT_EQUAL_UINT( set_data[ 0 ], get_data[ 0 ]);
|
||||
TEST_ASSERT_EQUAL_UINT( 0, get_data[ 1 ]); // The call to hidSetReportItem with size 1 in the header should return the MSB to zero
|
||||
}
|
||||
}
|
||||
|
||||
//setIdle and associated timing functionality tests
|
||||
void test_set_idle( void )
|
||||
{
|
||||
unsigned reportIdAll = 0;
|
||||
unsigned reportId = 1;
|
||||
unsigned reportId2 = 2;
|
||||
|
||||
unsigned setIdle = hidIsIdleActive( reportId );
|
||||
TEST_ASSERT_EQUAL_UINT( 0, setIdle );
|
||||
|
||||
setIdle = hidIsIdleActive( reportId2 );
|
||||
TEST_ASSERT_EQUAL_UINT( 0, setIdle );
|
||||
|
||||
setIdle = hidIsIdleActive( reportIdAll );
|
||||
TEST_ASSERT_EQUAL_UINT( 0, setIdle );
|
||||
|
||||
hidSetIdle( reportId, 1 );
|
||||
setIdle = hidIsIdleActive( reportId );
|
||||
TEST_ASSERT_EQUAL_UINT( 1, setIdle );
|
||||
|
||||
setIdle = hidIsIdleActive( reportIdAll );
|
||||
TEST_ASSERT_EQUAL_UINT( 0, setIdle );
|
||||
|
||||
setIdle = hidIsIdleActive( reportId2 );
|
||||
TEST_ASSERT_EQUAL_UINT( 0, setIdle );
|
||||
}
|
||||
|
||||
void test_set_all_idle( void )
|
||||
{
|
||||
unsigned reportIdAll = 0;
|
||||
unsigned reportId = 1;
|
||||
unsigned reportId2 = 2;
|
||||
|
||||
unsigned setIdle = hidIsIdleActive( reportId );
|
||||
TEST_ASSERT_EQUAL_UINT( 0, setIdle );
|
||||
|
||||
setIdle = hidIsIdleActive( reportId2 );
|
||||
TEST_ASSERT_EQUAL_UINT( 0, setIdle );
|
||||
|
||||
setIdle = hidIsIdleActive( reportIdAll );
|
||||
TEST_ASSERT_EQUAL_UINT( 0, setIdle );
|
||||
|
||||
for ( reportId = 1; reportId <= HID_REPORT_COUNT; ++reportId ) {
|
||||
hidSetIdle( reportId, 1 );
|
||||
setIdle = hidIsIdleActive( reportId );
|
||||
TEST_ASSERT_EQUAL_UINT( 1, setIdle );
|
||||
}
|
||||
|
||||
setIdle = hidIsIdleActive( reportIdAll );
|
||||
TEST_ASSERT_EQUAL_UINT( 1, setIdle );
|
||||
}
|
||||
|
||||
void test_change_pending( void )
|
||||
{
|
||||
unsigned reportIdAll = 0;
|
||||
unsigned reportId = 1;
|
||||
unsigned reportId2 = 2;
|
||||
|
||||
unsigned changePending = hidIsChangePending( reportId );
|
||||
TEST_ASSERT_EQUAL_UINT( 0, changePending );
|
||||
|
||||
changePending = hidIsChangePending( reportId2 );
|
||||
TEST_ASSERT_EQUAL_UINT( 0, changePending );
|
||||
|
||||
changePending = hidIsChangePending( reportIdAll );
|
||||
TEST_ASSERT_EQUAL_UINT( 0, changePending );
|
||||
|
||||
hidSetChangePending( reportId );
|
||||
changePending = hidIsChangePending( reportId );
|
||||
TEST_ASSERT_EQUAL_UINT( 1, changePending );
|
||||
|
||||
changePending = hidIsChangePending( reportIdAll );
|
||||
TEST_ASSERT_EQUAL_UINT( 1, changePending );
|
||||
|
||||
changePending = hidIsChangePending( reportId2 );
|
||||
TEST_ASSERT_EQUAL_UINT( 0, changePending );
|
||||
}
|
||||
|
||||
void test_change_pending_all( void )
|
||||
{
|
||||
unsigned reportIdAll = 0;
|
||||
unsigned reportId = 1;
|
||||
|
||||
unsigned changePending = hidIsChangePending( reportId );
|
||||
TEST_ASSERT_EQUAL_UINT( 0, changePending );
|
||||
|
||||
changePending = hidIsChangePending( reportIdAll );
|
||||
TEST_ASSERT_EQUAL_UINT( 0, changePending );
|
||||
|
||||
for ( reportId = 1; reportId <= HID_REPORT_COUNT; ++reportId ) {
|
||||
hidSetChangePending( reportId );
|
||||
changePending = hidIsChangePending( reportId );
|
||||
TEST_ASSERT_EQUAL_UINT( 1, changePending );
|
||||
}
|
||||
|
||||
changePending = hidIsChangePending( reportIdAll );
|
||||
TEST_ASSERT_EQUAL_UINT( 1, changePending );
|
||||
}
|
||||
|
||||
void test_report_time( void )
|
||||
{
|
||||
unsigned reportTime1 = 123;
|
||||
unsigned reportTime2 = 456;
|
||||
|
||||
hidCaptureReportTime(1, reportTime1);
|
||||
hidCaptureReportTime(2, reportTime2);
|
||||
reportTime1 = hidGetReportTime(1);
|
||||
reportTime2 = hidGetReportTime(2);
|
||||
|
||||
TEST_ASSERT_EQUAL_UINT(123, reportTime1);
|
||||
TEST_ASSERT_EQUAL_UINT(456, reportTime2);
|
||||
}
|
||||
|
||||
void test_report_time_calc( void )
|
||||
{
|
||||
unsigned reportTime1 = 123;
|
||||
unsigned reportTime2 = 456;
|
||||
unsigned reportPeriod1 = 10;
|
||||
unsigned reportPeriod2 = 5;
|
||||
|
||||
hidCaptureReportTime(1, reportTime1);
|
||||
hidCaptureReportTime(2, reportTime2);
|
||||
hidSetReportPeriod(1, reportPeriod1);
|
||||
hidSetReportPeriod(2, reportPeriod2);
|
||||
reportTime1 = hidGetReportTime(1);
|
||||
reportTime2 = hidGetReportTime(2);
|
||||
reportPeriod1 = hidGetReportPeriod(1);
|
||||
reportPeriod2 = hidGetReportPeriod(2);
|
||||
|
||||
TEST_ASSERT_EQUAL_UINT(123, reportTime1);
|
||||
TEST_ASSERT_EQUAL_UINT(456, reportTime2);
|
||||
TEST_ASSERT_EQUAL_UINT(10, reportPeriod1);
|
||||
TEST_ASSERT_EQUAL_UINT(5, reportPeriod2);
|
||||
|
||||
hidCalcNextReportTime(1);
|
||||
hidCalcNextReportTime(2);
|
||||
unsigned nextReportTime1 = hidGetNextReportTime(1);
|
||||
unsigned nextReportTime2 = hidGetNextReportTime(2);
|
||||
TEST_ASSERT_EQUAL_UINT( reportTime1 + reportPeriod1, nextReportTime1 );
|
||||
TEST_ASSERT_EQUAL_UINT( reportTime2 + reportPeriod2, nextReportTime2 );
|
||||
}
|
||||
145
tests/xua_unit_tests/src/test_simple/hid_report_descriptor.h
Normal file
145
tests/xua_unit_tests/src/test_simple/hid_report_descriptor.h
Normal file
@@ -0,0 +1,145 @@
|
||||
// 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.h"
|
||||
|
||||
/*
|
||||
* Define non-configurable items in the HID Report descriptor.
|
||||
* (These are short items as the location field isn't relevant for them)
|
||||
*/
|
||||
static const USB_HID_Short_Item_t hidCollectionApplication = {
|
||||
.header = HID_REPORT_SET_HEADER(1, HID_REPORT_ITEM_TYPE_MAIN, HID_REPORT_ITEM_TAG_COLLECTION),
|
||||
.data = { 0x01, 0x00 } };
|
||||
static const USB_HID_Short_Item_t hidCollectionEnd = {
|
||||
.header = HID_REPORT_SET_HEADER(0, HID_REPORT_ITEM_TYPE_MAIN, HID_REPORT_ITEM_TAG_END_COLLECTION),
|
||||
.data = { 0x00, 0x00 } };
|
||||
static const USB_HID_Short_Item_t hidCollectionLogical = {
|
||||
.header = HID_REPORT_SET_HEADER(1, HID_REPORT_ITEM_TYPE_MAIN, HID_REPORT_ITEM_TAG_COLLECTION),
|
||||
.data = { 0x02, 0x00 } };
|
||||
|
||||
static const USB_HID_Short_Item_t hidInputConstArray = {
|
||||
.header = HID_REPORT_SET_HEADER(1, HID_REPORT_ITEM_TYPE_MAIN, HID_REPORT_ITEM_TAG_INPUT),
|
||||
.data = { 0x01, 0x00 } };
|
||||
static const USB_HID_Short_Item_t hidInputDataVar = {
|
||||
.header = HID_REPORT_SET_HEADER(1, HID_REPORT_ITEM_TYPE_MAIN, HID_REPORT_ITEM_TAG_INPUT),
|
||||
.data = { 0x02, 0x00 } };
|
||||
|
||||
static const USB_HID_Short_Item_t hidLogicalMaximum0 = {
|
||||
.header = HID_REPORT_SET_HEADER(1, HID_REPORT_ITEM_TYPE_GLOBAL, HID_REPORT_ITEM_TAG_LOGICAL_MAXIMUM),
|
||||
.data = { 0x00, 0x00 } };
|
||||
static const USB_HID_Short_Item_t hidLogicalMaximum1 = {
|
||||
.header = HID_REPORT_SET_HEADER(1, HID_REPORT_ITEM_TYPE_GLOBAL, HID_REPORT_ITEM_TAG_LOGICAL_MAXIMUM),
|
||||
.data = { 0x01, 0x00 } };
|
||||
static const USB_HID_Short_Item_t hidLogicalMinimum0 = {
|
||||
.header = HID_REPORT_SET_HEADER(1, HID_REPORT_ITEM_TYPE_GLOBAL, HID_REPORT_ITEM_TAG_LOGICAL_MINIMUM),
|
||||
.data = { 0x00, 0x00 } };
|
||||
|
||||
static const USB_HID_Short_Item_t hidReportCount1 = {
|
||||
.header = HID_REPORT_SET_HEADER(1, HID_REPORT_ITEM_TYPE_GLOBAL, HID_REPORT_ITEM_TAG_REPORT_COUNT),
|
||||
.data = { 0x01, 0x00 } };
|
||||
static const USB_HID_Short_Item_t hidReportCount6 = {
|
||||
.header = HID_REPORT_SET_HEADER(1, HID_REPORT_ITEM_TYPE_GLOBAL, HID_REPORT_ITEM_TAG_REPORT_COUNT),
|
||||
.data = { 0x06, 0x00 } };
|
||||
static const USB_HID_Short_Item_t hidReportCount7 = {
|
||||
.header = HID_REPORT_SET_HEADER(1, HID_REPORT_ITEM_TYPE_GLOBAL, HID_REPORT_ITEM_TAG_REPORT_COUNT),
|
||||
.data = { 0x07, 0x00 } };
|
||||
static const USB_HID_Short_Item_t hidReportSize1 = {
|
||||
.header = HID_REPORT_SET_HEADER(1, HID_REPORT_ITEM_TYPE_GLOBAL, HID_REPORT_ITEM_TAG_REPORT_SIZE),
|
||||
.data = { 0x01, 0x00 } };
|
||||
|
||||
static const USB_HID_Short_Item_t hidUsageConsumerControl = {
|
||||
.header = HID_REPORT_SET_HEADER(1, HID_REPORT_ITEM_TYPE_LOCAL, HID_REPORT_ITEM_TAG_USAGE),
|
||||
.data = { 0x01, 0x00 } };
|
||||
|
||||
/*
|
||||
* Define the HID Report Descriptor Item, Usage Page, Report ID and length for each HID Report
|
||||
* For internal purposes, a report element with ID of 0 must be included if report IDs are not being used.
|
||||
*/
|
||||
static const USB_HID_Report_Element_t hidReportPageConsumer = {
|
||||
.item.header = HID_REPORT_SET_HEADER(1, HID_REPORT_ITEM_TYPE_GLOBAL, HID_REPORT_ITEM_TAG_USAGE_PAGE),
|
||||
.item.data = { USB_HID_USAGE_PAGE_ID_CONSUMER, 0x00 },
|
||||
.location = HID_REPORT_SET_LOC( 0, 2, 0, 0 )
|
||||
};
|
||||
|
||||
/*
|
||||
* Define configurable items in the HID Report descriptor.
|
||||
*/
|
||||
static USB_HID_Report_Element_t hidUsageByte0Bit0 = {
|
||||
.item.header = HID_REPORT_SET_HEADER(1, HID_REPORT_ITEM_TYPE_LOCAL, HID_REPORT_ITEM_TAG_USAGE),
|
||||
.item.data = { 0xE2, 0x00 },
|
||||
.location = HID_REPORT_SET_LOC(0, 0, 0, 0)
|
||||
}; // Mute
|
||||
|
||||
static USB_HID_Report_Element_t hidUsageByte1Bit7 = {
|
||||
.item.header = HID_REPORT_SET_HEADER(1, HID_REPORT_ITEM_TYPE_LOCAL, HID_REPORT_ITEM_TAG_USAGE),
|
||||
.item.data = { 0xEA, 0x00 },
|
||||
.location = HID_REPORT_SET_LOC(0, 0, 1, 7)
|
||||
}; // Vol-
|
||||
static USB_HID_Report_Element_t hidUsageByte1Bit0 = {
|
||||
.item.header = HID_REPORT_SET_HEADER(1, HID_REPORT_ITEM_TYPE_LOCAL, HID_REPORT_ITEM_TAG_USAGE),
|
||||
.item.data = { 0xE9, 0x00 },
|
||||
.location = HID_REPORT_SET_LOC(0, 0, 1, 0)
|
||||
}; // Vol+
|
||||
|
||||
/*
|
||||
* List the configurable elements in the HID Report descriptor.
|
||||
*/
|
||||
static USB_HID_Report_Element_t* const hidConfigurableElements[] = {
|
||||
&hidUsageByte0Bit0,
|
||||
&hidUsageByte1Bit0,
|
||||
&hidUsageByte1Bit7
|
||||
};
|
||||
|
||||
/*
|
||||
* List HID Reports, one per Report ID. This should be a usage page item with the relevant
|
||||
* If not using report IDs - still have one with report ID 0
|
||||
*/
|
||||
static const USB_HID_Report_Element_t* const hidReports[] = {
|
||||
&hidReportPageConsumer
|
||||
};
|
||||
|
||||
/*
|
||||
* List all items in the HID Report descriptor.
|
||||
*/
|
||||
static const USB_HID_Short_Item_t* const hidReportDescriptorItems[] = {
|
||||
&(hidReportPageConsumer.item),
|
||||
&hidUsageConsumerControl,
|
||||
&hidCollectionApplication,
|
||||
&hidReportSize1,
|
||||
&hidLogicalMinimum0,
|
||||
&hidCollectionLogical, // Byte 0
|
||||
&hidLogicalMaximum1,
|
||||
&hidReportCount1,
|
||||
&(hidUsageByte0Bit0.item),
|
||||
&hidInputDataVar,
|
||||
&hidLogicalMaximum0,
|
||||
&hidReportCount7,
|
||||
&hidInputConstArray,
|
||||
&hidCollectionEnd,
|
||||
&hidCollectionLogical, // Byte 1
|
||||
&hidLogicalMaximum1,
|
||||
&hidReportCount1,
|
||||
&(hidUsageByte1Bit0.item),
|
||||
&hidInputDataVar,
|
||||
&hidLogicalMaximum0,
|
||||
&hidReportCount6,
|
||||
&hidInputConstArray,
|
||||
&hidReportCount1,
|
||||
&hidLogicalMaximum1,
|
||||
&(hidUsageByte1Bit7.item),
|
||||
&hidInputDataVar,
|
||||
&hidCollectionEnd,
|
||||
&hidCollectionEnd
|
||||
};
|
||||
|
||||
/*
|
||||
* Define the number of HID Reports
|
||||
* Due to XC not supporting designated initializers, this constant has a hard-coded value.
|
||||
* It must equal ( sizeof hidReports / sizeof ( USB_HID_Report_Element_t* ))
|
||||
*/
|
||||
#define HID_REPORT_COUNT ( 1 )
|
||||
|
||||
#endif // __hid_report_descriptor_h__
|
||||
@@ -4,14 +4,20 @@
|
||||
#include <stdio.h>
|
||||
|
||||
#include "xua_unit_tests.h"
|
||||
#include "xua_hid_report_descriptor.h"
|
||||
#include "hid_report_descriptor.h"
|
||||
#include "xua_hid_report.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 )
|
||||
// Test constants related to the report descriptor defined in hid_report_descriptor.h
|
||||
#define MAX_VALID_BIT ( 7 )
|
||||
#define MAX_VALID_BYTE ( 1 )
|
||||
|
||||
#define MIN_VALID_BIT ( 0 )
|
||||
#define MIN_VALID_BYTE ( 0 )
|
||||
|
||||
#define HID_REPORT_LENGTH ( 2 )
|
||||
#define HID_REPORT_COUNT ( 1 )
|
||||
#define HID_REPORTID_LIMIT ( 1 )
|
||||
|
||||
// Constants from the USB HID Usage Tables
|
||||
#define CONSUMER_CONTROL_PAGE ( 0x0C )
|
||||
#define LOUDNESS_CONTROL ( 0xE7 )
|
||||
#define AL_CONTROL_PANEL ( 0x019F )
|
||||
@@ -30,26 +36,50 @@ static unsigned construct_usage_header( unsigned size )
|
||||
|
||||
void setUp( void )
|
||||
{
|
||||
hidReportInit();
|
||||
hidResetReportDescriptor();
|
||||
}
|
||||
|
||||
void test_validate_report( void ) {
|
||||
unsigned retVal = hidReportValidate();
|
||||
TEST_ASSERT_EQUAL_UINT( HID_STATUS_GOOD, retVal );
|
||||
}
|
||||
|
||||
void test_reportid_in_use( void ) {
|
||||
unsigned reportIdInUse = hidIsReportIdInUse();
|
||||
TEST_ASSERT_EQUAL_UINT( 0, reportIdInUse );
|
||||
}
|
||||
|
||||
void test_get_next_valid_report_id( void ) {
|
||||
unsigned reportId = 0U;
|
||||
|
||||
reportId = hidGetNextValidReportId(reportId);
|
||||
TEST_ASSERT_EQUAL_UINT( 0, reportId );
|
||||
|
||||
reportId = hidGetNextValidReportId(reportId);
|
||||
TEST_ASSERT_EQUAL_UINT( 0, reportId );
|
||||
}
|
||||
|
||||
// Basic report descriptor tests
|
||||
void test_unprepared_hidGetReportDescriptor( void )
|
||||
{
|
||||
const unsigned reportId = 0;
|
||||
unsigned char* reportDescPtr = hidGetReportDescriptor();
|
||||
TEST_ASSERT_NULL( reportDescPtr );
|
||||
|
||||
unsigned reportLength = hidGetReportLength();
|
||||
unsigned reportLength = hidGetReportLength( reportId );
|
||||
TEST_ASSERT_EQUAL_UINT( 0, reportLength );
|
||||
}
|
||||
|
||||
void test_prepared_hidGetReportDescriptor( void )
|
||||
{
|
||||
const unsigned reportId = 0;
|
||||
|
||||
hidPrepareReportDescriptor();
|
||||
unsigned char* reportDescPtr = hidGetReportDescriptor();
|
||||
TEST_ASSERT_NOT_NULL( reportDescPtr );
|
||||
|
||||
unsigned reportLength = hidGetReportLength();
|
||||
unsigned reportLength = hidGetReportLength( reportId );
|
||||
TEST_ASSERT_EQUAL_UINT( HID_REPORT_LENGTH, reportLength );
|
||||
}
|
||||
|
||||
@@ -70,16 +100,23 @@ void test_reset_prepared_hidGetReportDescriptor( void )
|
||||
TEST_ASSERT_NOT_NULL( reportDescPtr );
|
||||
}
|
||||
|
||||
void test_report_id_limit( void )
|
||||
{
|
||||
unsigned reportIdLimit = hidGetReportIdLimit();
|
||||
TEST_ASSERT_EQUAL_UINT( HID_REPORTID_LIMIT, reportIdLimit );
|
||||
}
|
||||
|
||||
// Basic item tests
|
||||
void test_max_loc_hidGetReportItem( void )
|
||||
{
|
||||
const unsigned reportId = 0;
|
||||
const unsigned bit = MAX_VALID_BIT;
|
||||
const unsigned byte = MAX_VALID_BYTE;
|
||||
unsigned char data[ HID_REPORT_ITEM_MAX_SIZE ];
|
||||
unsigned char header;
|
||||
unsigned char page;
|
||||
|
||||
unsigned retVal = hidGetReportItem( byte, bit, &page, &header, data );
|
||||
unsigned retVal = hidGetReportItem( reportId, byte, bit, &page, &header, data );
|
||||
TEST_ASSERT_EQUAL_UINT( HID_STATUS_GOOD, retVal );
|
||||
TEST_ASSERT_EQUAL_UINT( CONSUMER_CONTROL_PAGE, page );
|
||||
TEST_ASSERT_EQUAL_UINT( 0x09, header );
|
||||
@@ -89,13 +126,14 @@ void test_max_loc_hidGetReportItem( void )
|
||||
|
||||
void test_min_loc_hidGetReportItem( void )
|
||||
{
|
||||
const unsigned reportId = 0;
|
||||
const unsigned bit = MIN_VALID_BIT;
|
||||
const unsigned byte = MIN_VALID_BYTE;
|
||||
unsigned char data[ HID_REPORT_ITEM_MAX_SIZE ];
|
||||
unsigned char header;
|
||||
unsigned char page;
|
||||
|
||||
unsigned retVal = hidGetReportItem( byte, bit, &page, &header, data );
|
||||
unsigned retVal = hidGetReportItem( reportId, byte, bit, &page, &header, data );
|
||||
TEST_ASSERT_EQUAL_UINT( HID_STATUS_GOOD, retVal );
|
||||
TEST_ASSERT_EQUAL_UINT( CONSUMER_CONTROL_PAGE, page );
|
||||
TEST_ASSERT_EQUAL_UINT( 0x09, header );
|
||||
@@ -105,13 +143,14 @@ void test_min_loc_hidGetReportItem( void )
|
||||
|
||||
void test_overflow_bit_hidGetReportItem( void )
|
||||
{
|
||||
const unsigned reportId = 0;
|
||||
const unsigned bit = MAX_VALID_BIT + 1;
|
||||
const unsigned byte = MAX_VALID_BYTE;
|
||||
unsigned char data[ HID_REPORT_ITEM_MAX_SIZE ] = { 0xBA, 0xD1 };
|
||||
unsigned char header = 0xAA;
|
||||
unsigned char page = 0x44;
|
||||
|
||||
unsigned retVal = hidGetReportItem( byte, bit, &page, &header, data );
|
||||
unsigned retVal = hidGetReportItem( reportId, byte, bit, &page, &header, data );
|
||||
TEST_ASSERT_EQUAL_UINT( HID_STATUS_BAD_LOCATION, retVal );
|
||||
TEST_ASSERT_EQUAL_UINT( 0x44, page );
|
||||
TEST_ASSERT_EQUAL_UINT( 0xAA, header );
|
||||
@@ -121,13 +160,14 @@ void test_overflow_bit_hidGetReportItem( void )
|
||||
|
||||
void test_overflow_byte_hidGetReportItem( void )
|
||||
{
|
||||
const unsigned reportId = 0;
|
||||
const unsigned bit = MAX_VALID_BIT;
|
||||
const unsigned byte = MAX_VALID_BYTE + 1;
|
||||
unsigned char data[ HID_REPORT_ITEM_MAX_SIZE ] = { 0xBA, 0xD1 };
|
||||
unsigned char header = 0xAA;
|
||||
unsigned char page = 0x44;
|
||||
|
||||
unsigned retVal = hidGetReportItem( byte, bit, &page, &header, data );
|
||||
unsigned retVal = hidGetReportItem( reportId, byte, bit, &page, &header, data );
|
||||
TEST_ASSERT_EQUAL_UINT( HID_STATUS_BAD_LOCATION, retVal );
|
||||
TEST_ASSERT_EQUAL_UINT( 0x44, page );
|
||||
TEST_ASSERT_EQUAL_UINT( 0xAA, header );
|
||||
@@ -137,13 +177,14 @@ void test_overflow_byte_hidGetReportItem( void )
|
||||
|
||||
void test_underflow_bit_hidGetReportItem( void )
|
||||
{
|
||||
const int bit = MIN_VALID_BIT - 1;
|
||||
const unsigned reportId = 0;
|
||||
const int bit = MIN_VALID_BIT - 1;
|
||||
const unsigned byte = MIN_VALID_BYTE;
|
||||
unsigned char data[ HID_REPORT_ITEM_MAX_SIZE ] = { 0xBA, 0xD1 };
|
||||
unsigned char header = 0xAA;
|
||||
unsigned char page = 0x44;
|
||||
|
||||
unsigned retVal = hidGetReportItem( byte, ( unsigned ) bit, &page, &header, data );
|
||||
unsigned retVal = hidGetReportItem( reportId, byte, ( unsigned ) bit, &page, &header, data );
|
||||
TEST_ASSERT_EQUAL_UINT( HID_STATUS_BAD_LOCATION, retVal );
|
||||
TEST_ASSERT_EQUAL_UINT( 0x44, page );
|
||||
TEST_ASSERT_EQUAL_UINT( 0xAA, header );
|
||||
@@ -153,13 +194,14 @@ void test_underflow_bit_hidGetReportItem( void )
|
||||
|
||||
void test_underflow_byte_hidGetReportItem( void )
|
||||
{
|
||||
const unsigned reportId = 0;
|
||||
const unsigned bit = MIN_VALID_BIT;
|
||||
const int byte = MIN_VALID_BYTE - 1;
|
||||
unsigned char data[ HID_REPORT_ITEM_MAX_SIZE ] = { 0xBA, 0xD1 };
|
||||
unsigned char header = 0xAA;
|
||||
unsigned char page = 0x44;
|
||||
|
||||
unsigned retVal = hidGetReportItem(( unsigned ) byte, bit, &page, &header, data );
|
||||
unsigned retVal = hidGetReportItem( reportId, ( unsigned ) byte, bit, &page, &header, data );
|
||||
TEST_ASSERT_EQUAL_UINT( HID_STATUS_BAD_LOCATION, retVal );
|
||||
TEST_ASSERT_EQUAL_UINT( 0x44, page );
|
||||
TEST_ASSERT_EQUAL_UINT( 0xAA, header );
|
||||
@@ -170,226 +212,245 @@ void test_underflow_byte_hidGetReportItem( void )
|
||||
// Configurable and non-configurable item tests
|
||||
void test_configurable_item_hidSetReportItem( void )
|
||||
{
|
||||
const unsigned reportId = 0;
|
||||
const unsigned bit = MIN_VALID_BIT;
|
||||
const unsigned byte = MIN_VALID_BYTE;
|
||||
const unsigned char data[ 1 ] = { LOUDNESS_CONTROL };
|
||||
const unsigned char header = construct_usage_header( sizeof data / sizeof( unsigned char ));
|
||||
const unsigned char page = CONSUMER_CONTROL_PAGE;
|
||||
|
||||
unsigned retVal = hidSetReportItem( byte, bit, page, header, data );
|
||||
unsigned retVal = hidSetReportItem( reportId, byte, bit, page, header, data );
|
||||
TEST_ASSERT_EQUAL_UINT( HID_STATUS_GOOD, retVal );
|
||||
}
|
||||
|
||||
void test_nonconfigurable_item_hidSetReportItem( void )
|
||||
{
|
||||
const unsigned reportId = 0;
|
||||
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 byte = MIN_VALID_BYTE; // hidConfigurableElements list in hid_report_descriptors.c.
|
||||
const unsigned char data[ 1 ] = { LOUDNESS_CONTROL };
|
||||
const unsigned char header = construct_usage_header( sizeof data / sizeof( unsigned char ));
|
||||
const unsigned char page = CONSUMER_CONTROL_PAGE;
|
||||
|
||||
unsigned retVal = hidSetReportItem( byte, bit, page, header, data );
|
||||
unsigned retVal = hidSetReportItem( reportId, byte, bit, page, header, data );
|
||||
TEST_ASSERT_EQUAL_UINT( HID_STATUS_BAD_LOCATION, retVal );
|
||||
}
|
||||
|
||||
// Bit range tests
|
||||
void test_max_bit_hidSetReportItem( void )
|
||||
{
|
||||
const unsigned reportId = 0;
|
||||
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 byte = MAX_VALID_BYTE; // hidConfigurableElements list in hid_report_descriptors.c.
|
||||
const unsigned char header = construct_usage_header( 0 );
|
||||
const unsigned char page = CONSUMER_CONTROL_PAGE;
|
||||
|
||||
unsigned retVal = hidSetReportItem( byte, bit, page, header, NULL );
|
||||
unsigned retVal = hidSetReportItem( reportId, byte, bit, page, header, NULL );
|
||||
TEST_ASSERT_EQUAL_UINT( HID_STATUS_GOOD, retVal );
|
||||
}
|
||||
|
||||
void test_min_bit_hidSetReportItem( void )
|
||||
{
|
||||
const unsigned reportId = 0;
|
||||
const unsigned bit = MIN_VALID_BIT;
|
||||
const unsigned byte = MIN_VALID_BYTE;
|
||||
const unsigned char header = construct_usage_header( 0 );
|
||||
const unsigned char page = CONSUMER_CONTROL_PAGE;
|
||||
|
||||
unsigned retVal = hidSetReportItem( byte, bit, page, header, NULL );
|
||||
unsigned retVal = hidSetReportItem( reportId, byte, bit, page, header, NULL );
|
||||
TEST_ASSERT_EQUAL_UINT( HID_STATUS_GOOD, retVal );
|
||||
}
|
||||
|
||||
void test_overflow_bit_hidSetReportItem( void )
|
||||
{
|
||||
const unsigned reportId = 0;
|
||||
const unsigned bit = MAX_VALID_BIT + 1;
|
||||
const unsigned byte = MIN_VALID_BYTE;
|
||||
const unsigned char header = construct_usage_header( 0 );
|
||||
const unsigned char page = CONSUMER_CONTROL_PAGE;
|
||||
|
||||
unsigned retVal = hidSetReportItem( byte, bit, page, header, NULL );
|
||||
unsigned retVal = hidSetReportItem( reportId, byte, bit, page, header, NULL );
|
||||
TEST_ASSERT_EQUAL_UINT( HID_STATUS_BAD_LOCATION, retVal );
|
||||
}
|
||||
|
||||
void test_underflow_bit_hidSetReportItem( void )
|
||||
{
|
||||
const unsigned reportId = 0;
|
||||
const int bit = MIN_VALID_BIT - 1;
|
||||
const unsigned byte = MIN_VALID_BYTE;
|
||||
const unsigned char header = construct_usage_header( 0 );
|
||||
const unsigned char page = CONSUMER_CONTROL_PAGE;
|
||||
|
||||
unsigned retVal = hidSetReportItem( byte, ( unsigned ) bit, page, header, NULL );
|
||||
unsigned retVal = hidSetReportItem( reportId, byte, ( unsigned ) bit, page, header, NULL );
|
||||
TEST_ASSERT_EQUAL_UINT( HID_STATUS_BAD_LOCATION, retVal );
|
||||
}
|
||||
|
||||
// Byte range tests
|
||||
void test_max_byte_hidSetReportItem( void )
|
||||
{
|
||||
const unsigned reportId = 0;
|
||||
const unsigned bit = MIN_VALID_BIT;
|
||||
const unsigned byte = MAX_VALID_BYTE;
|
||||
const unsigned char header = construct_usage_header( 0 );
|
||||
const unsigned char page = CONSUMER_CONTROL_PAGE;
|
||||
|
||||
unsigned retVal = hidSetReportItem( byte, bit, page, header, NULL );
|
||||
unsigned retVal = hidSetReportItem( reportId, byte, bit, page, header, NULL );
|
||||
TEST_ASSERT_EQUAL_UINT( HID_STATUS_GOOD, retVal );
|
||||
}
|
||||
|
||||
void test_min_byte_hidSetReportItem( void )
|
||||
{
|
||||
const unsigned reportId = 0;
|
||||
const unsigned bit = MIN_VALID_BIT;
|
||||
const unsigned byte = MIN_VALID_BYTE;
|
||||
const unsigned char header = construct_usage_header( 0 );
|
||||
const unsigned char page = CONSUMER_CONTROL_PAGE;
|
||||
|
||||
unsigned retVal = hidSetReportItem( byte, bit, page, header, NULL );
|
||||
unsigned retVal = hidSetReportItem( reportId, byte, bit, page, header, NULL );
|
||||
TEST_ASSERT_EQUAL_UINT( HID_STATUS_GOOD, retVal );
|
||||
}
|
||||
|
||||
void test_overflow_byte_hidSetReportItem( void )
|
||||
{
|
||||
const unsigned reportId = 0;
|
||||
const unsigned bit = MIN_VALID_BIT;
|
||||
const unsigned byte = MAX_VALID_BYTE + 1;
|
||||
const unsigned char header = construct_usage_header( 0 );
|
||||
const unsigned char page = CONSUMER_CONTROL_PAGE;
|
||||
|
||||
unsigned retVal = hidSetReportItem( byte, bit, page, header, NULL );
|
||||
unsigned retVal = hidSetReportItem( reportId, byte, bit, page, header, NULL );
|
||||
TEST_ASSERT_EQUAL_UINT( HID_STATUS_BAD_LOCATION, retVal );
|
||||
}
|
||||
|
||||
void test_underflow_byte_hidSetReportItem( void )
|
||||
{
|
||||
const unsigned reportId = 0;
|
||||
const unsigned bit = MIN_VALID_BIT;
|
||||
const int byte = MIN_VALID_BYTE - 1;
|
||||
const unsigned char header = construct_usage_header( 0 );
|
||||
const unsigned char page = CONSUMER_CONTROL_PAGE;
|
||||
|
||||
unsigned retVal = hidSetReportItem( ( unsigned ) byte, bit, page, header, NULL );
|
||||
unsigned retVal = hidSetReportItem( reportId, ( unsigned ) byte, bit, page, header, NULL );
|
||||
TEST_ASSERT_EQUAL_UINT( HID_STATUS_BAD_LOCATION, retVal );
|
||||
}
|
||||
|
||||
// Size range tests
|
||||
void test_max_size_hidSetReportItem( void )
|
||||
{
|
||||
const unsigned reportId = 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 );
|
||||
const unsigned char page = CONSUMER_CONTROL_PAGE;
|
||||
|
||||
unsigned retVal = hidSetReportItem( byte, bit, page, header, data );
|
||||
unsigned retVal = hidSetReportItem( reportId, byte, bit, page, header, data );
|
||||
TEST_ASSERT_EQUAL_UINT( HID_STATUS_GOOD, retVal );
|
||||
}
|
||||
|
||||
void test_min_size_hidSetReportItem( void )
|
||||
{
|
||||
const unsigned reportId = 0;
|
||||
const unsigned bit = MIN_VALID_BIT;
|
||||
const unsigned byte = MIN_VALID_BYTE;
|
||||
const unsigned char header = construct_usage_header( 0x00 );
|
||||
const unsigned char page = CONSUMER_CONTROL_PAGE;
|
||||
|
||||
unsigned retVal = hidSetReportItem( byte, bit, page, header, NULL );
|
||||
unsigned retVal = hidSetReportItem( reportId, byte, bit, page, header, NULL );
|
||||
TEST_ASSERT_EQUAL_UINT( HID_STATUS_GOOD, retVal );
|
||||
}
|
||||
|
||||
void test_unsupported_size_hidSetReportItem( void )
|
||||
{
|
||||
const unsigned reportId = 0;
|
||||
const unsigned bit = MIN_VALID_BIT;
|
||||
const unsigned byte = MIN_VALID_BYTE;
|
||||
const unsigned char header = construct_usage_header( 0x03 );
|
||||
const unsigned char page = CONSUMER_CONTROL_PAGE;
|
||||
|
||||
unsigned retVal = hidSetReportItem( byte, bit, page, header, NULL );
|
||||
unsigned retVal = hidSetReportItem( reportId, byte, bit, page, header, NULL );
|
||||
TEST_ASSERT_EQUAL_UINT( HID_STATUS_BAD_HEADER, retVal );
|
||||
}
|
||||
|
||||
// Header tag and type tests
|
||||
void test_bad_tag_hidSetReportItem( void )
|
||||
{
|
||||
const unsigned reportId = 0;
|
||||
const unsigned bit = MIN_VALID_BIT;
|
||||
const unsigned byte = MIN_VALID_BYTE;
|
||||
const unsigned char good_header = construct_usage_header( 0x00 );
|
||||
const unsigned char page = CONSUMER_CONTROL_PAGE;
|
||||
|
||||
for( unsigned tag = 0x01; tag <= 0x0F; ++tag ) {
|
||||
unsigned char bad_header = good_header | (( 0x0F << HID_REPORT_ITEM_HDR_TAG_SHIFT ) & HID_REPORT_ITEM_HDR_TAG_MASK );
|
||||
unsigned retVal = hidSetReportItem( byte, bit, page, bad_header, NULL );
|
||||
unsigned char bad_header = good_header | (( tag << HID_REPORT_ITEM_HDR_TAG_SHIFT ) & HID_REPORT_ITEM_HDR_TAG_MASK );
|
||||
unsigned retVal = hidSetReportItem( reportId, byte, bit, page, bad_header, NULL );
|
||||
TEST_ASSERT_EQUAL_UINT( HID_STATUS_BAD_HEADER, retVal );
|
||||
}
|
||||
}
|
||||
|
||||
void test_global_type_hidSetReportItem( void )
|
||||
{
|
||||
const unsigned reportId = 0;
|
||||
const unsigned bit = MIN_VALID_BIT;
|
||||
const unsigned byte = MIN_VALID_BYTE;
|
||||
const unsigned char header = ( construct_usage_header( 0x00 ) & ~HID_REPORT_ITEM_HDR_TYPE_MASK ) |
|
||||
(( HID_REPORT_ITEM_TYPE_GLOBAL << HID_REPORT_ITEM_HDR_TYPE_SHIFT ) & HID_REPORT_ITEM_HDR_TYPE_MASK );
|
||||
const unsigned char page = CONSUMER_CONTROL_PAGE;
|
||||
|
||||
unsigned retVal = hidSetReportItem( byte, bit, page, header, NULL );
|
||||
unsigned retVal = hidSetReportItem( reportId, byte, bit, page, header, NULL );
|
||||
TEST_ASSERT_EQUAL_UINT( HID_STATUS_BAD_HEADER, retVal );
|
||||
}
|
||||
|
||||
void test_local_type_hidSetReportItem( void )
|
||||
{
|
||||
const unsigned reportId = 0;
|
||||
const unsigned bit = MIN_VALID_BIT;
|
||||
const unsigned byte = MIN_VALID_BYTE;
|
||||
const unsigned char header = ( construct_usage_header( 0x00 ) & ~HID_REPORT_ITEM_HDR_TYPE_MASK ) |
|
||||
(( HID_REPORT_ITEM_TYPE_LOCAL << HID_REPORT_ITEM_HDR_TYPE_SHIFT ) & HID_REPORT_ITEM_HDR_TYPE_MASK );
|
||||
const unsigned char page = CONSUMER_CONTROL_PAGE;
|
||||
|
||||
unsigned retVal = hidSetReportItem( byte, bit, page, header, NULL );
|
||||
unsigned retVal = hidSetReportItem( reportId, byte, bit, page, header, NULL );
|
||||
TEST_ASSERT_EQUAL_UINT( HID_STATUS_GOOD, retVal );
|
||||
}
|
||||
|
||||
void test_main_type_hidSetReportItem( void )
|
||||
{
|
||||
const unsigned reportId = 0;
|
||||
const unsigned bit = MIN_VALID_BIT;
|
||||
const unsigned byte = MIN_VALID_BYTE;
|
||||
const unsigned char header = ( construct_usage_header( 0x00 ) & ~HID_REPORT_ITEM_HDR_TYPE_MASK ) |
|
||||
(( HID_REPORT_ITEM_TYPE_MAIN << HID_REPORT_ITEM_HDR_TYPE_SHIFT ) & HID_REPORT_ITEM_HDR_TYPE_MASK );
|
||||
const unsigned char page = CONSUMER_CONTROL_PAGE;
|
||||
|
||||
unsigned retVal = hidSetReportItem( byte, bit, page, header, NULL );
|
||||
unsigned retVal = hidSetReportItem( reportId, byte, bit, page, header, NULL );
|
||||
TEST_ASSERT_EQUAL_UINT( HID_STATUS_BAD_HEADER, retVal );
|
||||
}
|
||||
|
||||
void test_reserved_type_hidSetReportItem( void )
|
||||
{
|
||||
const unsigned reportId = 0;
|
||||
const unsigned bit = MIN_VALID_BIT;
|
||||
const unsigned byte = MIN_VALID_BYTE;
|
||||
const unsigned char header = ( construct_usage_header( 0x00 ) & ~HID_REPORT_ITEM_HDR_TYPE_MASK ) |
|
||||
(( HID_REPORT_ITEM_TYPE_RESERVED << HID_REPORT_ITEM_HDR_TYPE_SHIFT ) & HID_REPORT_ITEM_HDR_TYPE_MASK );
|
||||
const unsigned char page = CONSUMER_CONTROL_PAGE;
|
||||
|
||||
unsigned retVal = hidSetReportItem( byte, bit, page, header, NULL );
|
||||
unsigned retVal = hidSetReportItem( reportId, byte, bit, page, header, NULL );
|
||||
TEST_ASSERT_EQUAL_UINT( HID_STATUS_BAD_HEADER, retVal );
|
||||
}
|
||||
|
||||
// Combined function tests
|
||||
void test_initial_modification_without_subsequent_preparation( void )
|
||||
{
|
||||
const unsigned reportId = 0;
|
||||
const unsigned bit = MIN_VALID_BIT;
|
||||
const unsigned byte = MIN_VALID_BYTE;
|
||||
const unsigned char data[ 1 ] = { LOUDNESS_CONTROL };
|
||||
const unsigned char header = construct_usage_header( sizeof data / sizeof( unsigned char ));
|
||||
const unsigned char page = CONSUMER_CONTROL_PAGE;
|
||||
|
||||
unsigned retVal = hidSetReportItem( byte, bit, page, header, data );
|
||||
unsigned retVal = hidSetReportItem( reportId, byte, bit, page, header, data );
|
||||
TEST_ASSERT_EQUAL_UINT( HID_STATUS_GOOD, retVal );
|
||||
|
||||
unsigned char* reportDescPtr = hidGetReportDescriptor();
|
||||
@@ -398,13 +459,14 @@ void test_initial_modification_without_subsequent_preparation( void )
|
||||
|
||||
void test_initial_modification_with_subsequent_preparation( void )
|
||||
{
|
||||
const unsigned reportId = 0;
|
||||
const unsigned bit = MIN_VALID_BIT;
|
||||
const unsigned byte = MIN_VALID_BYTE;
|
||||
const unsigned char data[ 1 ] = { LOUDNESS_CONTROL };
|
||||
const unsigned char header = construct_usage_header( sizeof data / sizeof( unsigned char ));
|
||||
const unsigned char page = CONSUMER_CONTROL_PAGE;
|
||||
|
||||
unsigned retVal = hidSetReportItem( byte, bit, page, header, data );
|
||||
unsigned retVal = hidSetReportItem( reportId, byte, bit, page, header, data );
|
||||
TEST_ASSERT_EQUAL_UINT( HID_STATUS_GOOD, retVal );
|
||||
|
||||
hidPrepareReportDescriptor();
|
||||
@@ -414,6 +476,7 @@ void test_initial_modification_with_subsequent_preparation( void )
|
||||
|
||||
void test_initial_modification_with_subsequent_verification_1( void )
|
||||
{
|
||||
const unsigned reportId = 0;
|
||||
const unsigned bit = MIN_VALID_BIT;
|
||||
const unsigned byte = MIN_VALID_BYTE;
|
||||
|
||||
@@ -425,10 +488,10 @@ void test_initial_modification_with_subsequent_verification_1( void )
|
||||
const unsigned char set_header = construct_usage_header( sizeof set_data / sizeof( unsigned char ));
|
||||
const unsigned char set_page = CONSUMER_CONTROL_PAGE;
|
||||
|
||||
unsigned setRetVal = hidSetReportItem( byte, bit, set_page, set_header, set_data );
|
||||
unsigned setRetVal = hidSetReportItem( reportId, byte, bit, set_page, set_header, set_data );
|
||||
TEST_ASSERT_EQUAL_UINT( HID_STATUS_GOOD, setRetVal );
|
||||
|
||||
unsigned getRetVal = hidGetReportItem( byte, bit, &get_page, &get_header, get_data );
|
||||
unsigned getRetVal = hidGetReportItem( reportId, byte, bit, &get_page, &get_header, get_data );
|
||||
TEST_ASSERT_EQUAL_UINT( HID_STATUS_GOOD, getRetVal );
|
||||
TEST_ASSERT_EQUAL_UINT( set_page, get_page );
|
||||
TEST_ASSERT_EQUAL_UINT( set_header, get_header );
|
||||
@@ -438,6 +501,7 @@ void test_initial_modification_with_subsequent_verification_1( void )
|
||||
|
||||
void test_initial_modification_with_subsequent_verification_2( void )
|
||||
{
|
||||
const unsigned reportId = 0;
|
||||
const unsigned bit = MIN_VALID_BIT;
|
||||
const unsigned byte = MIN_VALID_BYTE;
|
||||
|
||||
@@ -450,10 +514,10 @@ void test_initial_modification_with_subsequent_verification_2( void )
|
||||
const unsigned char set_header = construct_usage_header( sizeof set_data / sizeof( unsigned char ));
|
||||
const unsigned char set_page = CONSUMER_CONTROL_PAGE;
|
||||
|
||||
unsigned setRetVal = hidSetReportItem( byte, bit, set_page, set_header, set_data );
|
||||
unsigned setRetVal = hidSetReportItem( reportId, byte, bit, set_page, set_header, set_data );
|
||||
TEST_ASSERT_EQUAL_UINT( HID_STATUS_GOOD, setRetVal );
|
||||
|
||||
unsigned getRetVal = hidGetReportItem( byte, bit, &get_page, &get_header, get_data );
|
||||
unsigned getRetVal = hidGetReportItem( reportId, byte, bit, &get_page, &get_header, get_data );
|
||||
TEST_ASSERT_EQUAL_UINT( HID_STATUS_GOOD, getRetVal );
|
||||
TEST_ASSERT_EQUAL_UINT( set_page, get_page );
|
||||
TEST_ASSERT_EQUAL_UINT( set_header, get_header );
|
||||
@@ -470,10 +534,10 @@ void test_initial_modification_with_subsequent_verification_2( void )
|
||||
const unsigned char set_header = construct_usage_header( sizeof set_data / sizeof( unsigned char ));
|
||||
const unsigned char set_page = CONSUMER_CONTROL_PAGE;
|
||||
|
||||
unsigned setRetVal = hidSetReportItem( byte, bit, set_page, set_header, set_data );
|
||||
unsigned setRetVal = hidSetReportItem( reportId, byte, bit, set_page, set_header, set_data );
|
||||
TEST_ASSERT_EQUAL_UINT( HID_STATUS_GOOD, setRetVal );
|
||||
|
||||
unsigned getRetVal = hidGetReportItem( byte, bit, &get_page, &get_header, get_data );
|
||||
unsigned getRetVal = hidGetReportItem( reportId, byte, bit, &get_page, &get_header, get_data );
|
||||
TEST_ASSERT_EQUAL_UINT( HID_STATUS_GOOD, getRetVal );
|
||||
TEST_ASSERT_EQUAL_UINT( set_page, get_page );
|
||||
TEST_ASSERT_EQUAL_UINT( set_header, get_header );
|
||||
@@ -488,6 +552,7 @@ void test_modification_without_subsequent_preparation( void )
|
||||
unsigned char* reportDescPtr = hidGetReportDescriptor();
|
||||
TEST_ASSERT_NOT_NULL( reportDescPtr );
|
||||
|
||||
const unsigned reportId = 0;
|
||||
const unsigned bit = MIN_VALID_BIT;
|
||||
const unsigned byte = MIN_VALID_BYTE;
|
||||
const unsigned char data[ 1 ] = { LOUDNESS_CONTROL };
|
||||
@@ -495,7 +560,7 @@ void test_modification_without_subsequent_preparation( void )
|
||||
const unsigned char page = CONSUMER_CONTROL_PAGE;
|
||||
|
||||
hidResetReportDescriptor();
|
||||
unsigned retVal = hidSetReportItem( byte, bit, page, header, data );
|
||||
unsigned retVal = hidSetReportItem( reportId, byte, bit, page, header, data );
|
||||
TEST_ASSERT_EQUAL_UINT( HID_STATUS_GOOD, retVal );
|
||||
|
||||
reportDescPtr = hidGetReportDescriptor();
|
||||
@@ -508,6 +573,7 @@ void test_modification_with_subsequent_preparation( void )
|
||||
unsigned char* reportDescPtr = hidGetReportDescriptor();
|
||||
TEST_ASSERT_NOT_NULL( reportDescPtr );
|
||||
|
||||
const unsigned reportId = 0;
|
||||
const unsigned bit = MIN_VALID_BIT;
|
||||
const unsigned byte = MIN_VALID_BYTE;
|
||||
const unsigned char data[ 1 ] = { LOUDNESS_CONTROL };
|
||||
@@ -515,10 +581,58 @@ void test_modification_with_subsequent_preparation( void )
|
||||
const unsigned char page = CONSUMER_CONTROL_PAGE;
|
||||
|
||||
hidResetReportDescriptor();
|
||||
unsigned retVal = hidSetReportItem( byte, bit, page, header, data );
|
||||
unsigned retVal = hidSetReportItem( reportId, byte, bit, page, header, data );
|
||||
TEST_ASSERT_EQUAL_UINT( HID_STATUS_GOOD, retVal );
|
||||
|
||||
hidPrepareReportDescriptor();
|
||||
reportDescPtr = hidGetReportDescriptor();
|
||||
TEST_ASSERT_NOT_NULL( reportDescPtr );
|
||||
}
|
||||
|
||||
//setIdle functionality tests
|
||||
void test_set_idle( void )
|
||||
{
|
||||
unsigned reportId = 0;
|
||||
|
||||
unsigned setIdle = hidIsIdleActive( reportId );
|
||||
TEST_ASSERT_EQUAL_UINT( 0, setIdle );
|
||||
|
||||
hidSetIdle( reportId, 1 );
|
||||
setIdle = hidIsIdleActive( reportId );
|
||||
TEST_ASSERT_EQUAL_UINT( 1, setIdle );
|
||||
}
|
||||
|
||||
void test_change_pending( void )
|
||||
{
|
||||
unsigned reportId = 0;
|
||||
|
||||
unsigned changePending = hidIsChangePending( reportId );
|
||||
TEST_ASSERT_EQUAL_UINT( 0, changePending );
|
||||
|
||||
hidSetChangePending( reportId );
|
||||
changePending = hidIsChangePending( reportId );
|
||||
TEST_ASSERT_EQUAL_UINT( 1, changePending );
|
||||
|
||||
hidClearChangePending( reportId );
|
||||
changePending = hidIsChangePending( reportId );
|
||||
TEST_ASSERT_EQUAL_UINT( 0, changePending );
|
||||
}
|
||||
|
||||
void test_report_time( void )
|
||||
{
|
||||
unsigned reportTime = 123;
|
||||
unsigned reportPeriod = 10;
|
||||
|
||||
hidSetReportPeriod(0, reportPeriod);
|
||||
hidCaptureReportTime(0, reportTime);
|
||||
reportTime = hidGetReportTime(0);
|
||||
reportPeriod = hidGetReportPeriod(0);
|
||||
|
||||
TEST_ASSERT_EQUAL_UINT(123, reportTime);
|
||||
TEST_ASSERT_EQUAL_UINT(10, reportPeriod);
|
||||
|
||||
hidCalcNextReportTime(0);
|
||||
|
||||
unsigned nextReportTime = hidGetNextReportTime(0);
|
||||
TEST_ASSERT_EQUAL_UINT(133, nextReportTime);
|
||||
}
|
||||
@@ -95,6 +95,7 @@ def add_unity_runner_build_config(waf_conf, project_root_path, unity_test_path,
|
||||
|
||||
def prepare_unity_test_for_build(waf_conf, project_root_path, unity_test_path,
|
||||
unity_runner_dir, unity_runner_suffix, target):
|
||||
print("unity_test_path: " + str(unity_test_path))
|
||||
generate_unity_runner(project_root_path, unity_test_path,
|
||||
unity_runner_dir, unity_runner_suffix)
|
||||
runner_build_flags = '' # Could extract flags from the test name
|
||||
@@ -107,7 +108,12 @@ 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+'*'))
|
||||
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):
|
||||
@@ -116,7 +122,7 @@ def find_unity_tests(unity_test_dir, unity_test_prefix):
|
||||
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)
|
||||
return {get_test_name(path): {"language": get_file_type(path), "dir": os.path.dirname(path)}
|
||||
for path in unity_test_paths}
|
||||
|
||||
|
||||
@@ -139,8 +145,8 @@ def generate_all_unity_runners(waf_conf, project_root_path,
|
||||
# TODO: can the xwaf boilerplate help here?
|
||||
def create_waf_contexts(configs):
|
||||
for trgt in TARGETS:
|
||||
for test_name, test_language in configs.items():
|
||||
print(f"test_name {test_name}, test_language {test_language}")
|
||||
for test_name, params in configs.items():
|
||||
print(f"test_name {test_name}, test_language {params['language']}")
|
||||
for ctx in (BuildContext, CleanContext):
|
||||
raw_context = ctx.__name__.replace('Context', '').lower()
|
||||
|
||||
@@ -149,9 +155,10 @@ def create_waf_contexts(configs):
|
||||
variant = test_name + '_' + trgt
|
||||
#cmd = raw_context + '_' + test_name
|
||||
#variant = test_name
|
||||
language = test_language
|
||||
language = params["language"]
|
||||
target = trgt
|
||||
runner = test_name
|
||||
directory = params["dir"]
|
||||
print(f"cmd {cmd}, variant {variant}, language {language}")
|
||||
|
||||
|
||||
@@ -161,6 +168,8 @@ UNITY_RUNNER_DIR = 'runners'
|
||||
UNITY_RUNNER_SUFFIX = '_Runner'
|
||||
UNITY_TESTS = find_unity_tests(UNITY_TEST_DIR, UNITY_TEST_PREFIX)
|
||||
|
||||
print("UNITY_TESTS: " + str(UNITY_TESTS))
|
||||
|
||||
create_waf_contexts(UNITY_TESTS)
|
||||
|
||||
def options(opt):
|
||||
@@ -175,7 +184,6 @@ def configure(conf):
|
||||
UNITY_RUNNER_DIR, UNITY_RUNNER_SUFFIX)
|
||||
conf.load('xwaf.xcommon')
|
||||
|
||||
|
||||
def build(bld):
|
||||
if not bld.variant:
|
||||
print('Adding test runners to build queue')
|
||||
@@ -204,7 +212,7 @@ def build(bld):
|
||||
'Unity']
|
||||
|
||||
makefile_opts = {}
|
||||
makefile_opts['SOURCE_DIRS'] = ['src', os.path.join('runners',bld.runner)]
|
||||
makefile_opts['SOURCE_DIRS'] = ['src', bld.directory, os.path.join('runners',bld.runner)]
|
||||
if(bld.target == 'xcoreai'):
|
||||
print('TARGET XCOREAI')
|
||||
makefile_opts['TARGET'] = ['XCORE-AI-EXPLORER']
|
||||
@@ -213,6 +221,7 @@ def build(bld):
|
||||
makefile_opts['TARGET'] = ['XCORE-200-EXPLORER']
|
||||
|
||||
makefile_opts['INCLUDE_DIRS'] = ['src',
|
||||
bld.directory,
|
||||
'../../lib_xua/api',
|
||||
'../../lib_xua/src/core/pdm_mics',
|
||||
'../../lib_xua/src/hid',
|
||||
|
||||
Reference in New Issue
Block a user