192 Commits

Author SHA1 Message Date
xross
c6c1b48839 'Release: 3.2.0rc0' 2022-06-01 14:22:44 +01:00
xross
206a895b74 xpd: Cleaned up whitespace 2022-06-01 14:21:44 +01:00
xross
55e01e5b49 Merge branch 'develop' 2022-06-01 14:19:26 +01:00
xross
4ffcef2347 Remove commited pdf file 2022-06-01 14:04:03 +01:00
Ross Owen
9edef4a1f1 Fixes for doc build (#270)
Document moving and rename. Fixes for latest xdoc.
2022-06-01 10:39:02 +01:00
xross
266711caf7 Merge remote-tracking branch 'upstream/develop' into develop 2022-05-30 18:50:33 +01:00
xross
4e5634167b Added CODEOWNERS 2022-05-30 18:48:10 +01:00
xross
d7a9b160c2 Automated changelog dep update 2022-05-30 18:18:42 +01:00
xross
0d8f080604 Moved to version 3.2.0 2022-05-30 18:17:31 +01:00
xross
24d0c51818 Updated dependency versions 2022-05-30 17:59:28 +01:00
xross
41cb59dc8d Removed IAP related defines 2022-05-30 17:59:18 +01:00
xross
fca2ec2058 Comment only 2022-05-30 11:44:12 +01:00
xross
0f8b9dae8c Removed extra bracing and fixed bad comment 2022-05-30 11:44:12 +01:00
xross
d5946b91a4 Resolve device hang on sample rate cange when both mixer cores are running and NUM_USB_CHAN_OUT = 0 2022-05-30 11:44:12 +01:00
Luciano Martin
d3fafdfbac Overwrite output channel descriptors only if output channels are defined (#269)
Overwrite output channel descriptors only if output channels are defined
2022-05-30 11:25:48 +01:00
Ross Owen
0e77b159c6 Merge pull request #262 from xmos/fix/261
Fix checking of return value of GetBuffer() in AudioEndpointRequests_1()
2022-04-26 14:39:21 +01:00
Ross Owen
116e7a5b90 Merge pull request #264 from xmos/fix/263
Fix sourceID of Audio In Output Term when volume control disabled
2022-04-26 14:39:03 +01:00
Ross Owen
f6a6fb9c5c Fix sourceID of Audio In Output Term when volume control disabled
#263
2022-04-26 13:36:25 +01:00
Ross Owen
392e00f989 Fix checking of return value of GetBuffer() in AudioEndpointRequests_1() 2022-04-26 13:26:41 +01:00
Ross Owen
edd34ac157 Merge pull request #251 from xross/fix/250
Enable explicit feedback EP by default
2022-03-29 15:22:52 +01:00
xross
fd58827b88 Fix build issue in AN00248 2022-03-15 12:42:18 +00:00
xross
8bf991eb76 Fixed issue where DSD_NATIVE is always enabled if DSD_CHANS_DAC defined as 0 2022-03-15 11:40:10 +00:00
xross
46a7b7ac22 Fix example builds 2022-03-14 16:17:12 +00:00
xross
ea3dffb05c Changelog update 2022-03-14 11:21:10 +00:00
xross
cf826e910d Copyright date 2022-03-14 11:20:20 +00:00
xross
a270972bf9 Enable explicit feedback EP by default 2022-03-14 11:18:26 +00:00
Brennan Magee
9a25e0538e Merge pull request #249 from kieran-kohtz/feature/jenkinsversion
Update Jenkins Shared Library Version
2022-03-09 15:22:33 +00:00
Kieran Kohtz
93959376c5 Merge remote-tracking branch 'origin/develop' into feature/jenkinsversion 2022-03-09 14:54:12 +00:00
kieran-kohtz
c09e515455 Update jenkins labels 2022-03-09 13:48:59 +00:00
Ross Owen
449a899597 Merge pull request #244 from xross/changelog
Sanitised changelog
2022-03-09 11:43:42 +00:00
Ross Owen
f0cd906730 Merge branch 'develop' into changelog 2022-03-09 11:43:30 +00:00
Ross Owen
1865b2c3f1 Merge pull request #248 from danielpieczko/fix/interface_descriptor_bytes_define
Move INTERFACE_DESCRIPTOR_BYTES definition
2022-03-09 11:41:31 +00:00
kieran-kohtz
2ba4c37363 Removed Brewfile 2022-03-08 16:15:02 +00:00
kieran-kohtz
99e61b0cd9 Removed Brew Labels 2022-03-08 16:15:01 +00:00
kieran-kohtz
2f298f84e5 Updated jenkins shared library version to v0.18.0 2022-03-08 16:15:00 +00:00
Ross Owen
6a0688d908 Update xmos_jenkins_shared_library 0.16.2 -> 0.18.0 2022-03-08 13:12:42 +00:00
Daniel Pieczko
0ce5b17c2b Move INTERFACE_DESCRIPTOR_BYTES definition 2022-03-08 12:05:05 +00:00
Ross Owen
fdc99ffccb Merge pull request #175 from xmos/QuinnWang-patch-1
decouple update for DFU "fake" SET_SAMPLE_FREQ special processing
2022-03-07 11:11:23 +00:00
xross
1f994be63e Merge branch 'develop' of github.com:xmos/lib_xua into develop 2022-03-03 12:42:31 +00:00
xross
3e87d0ec30 Added missing default case 2022-03-03 12:42:21 +00:00
Ross Owen
136fbcf08c Merge pull request #247 from danielpieczko/fix/hid_report_xua_include
Include xua_conf_full.h before checking HID_CONTROLS to ensure it's d…
2022-03-02 15:18:58 +00:00
Daniel Pieczko
c027e2df18 Include xua_conf_full.h before checking HID_CONTROLS to ensure it's defined 2022-03-02 13:45:24 +00:00
Ross Owen
2931d41882 Merge pull request #246 from danielpieczko/fix/ep_buffer_ifdefs
Fix ifdefs/endifs in ep_buffer.xc
2022-03-02 11:05:38 +00:00
Daniel Pieczko
7a493ca479 Fix ifdefs/endifs in ep_buffer.xc 2022-03-02 09:25:52 +00:00
Michael Banther
769bfa1a5a Remove unnecessary HID functionality (#243)
* Include HID report functionality only when the HID feature is enabled
* Define HID_CONTROLS=1 so HID unit tests work correctly
2022-02-21 13:20:52 +00:00
xross
7198dbf02c Sanitised changelog 2022-02-18 16:01:06 +00:00
danielpieczko
29c9b3ea75 Support lib_i2c in legacy_tests (#242)
Support lib_i2c in legacy_tests and remove dummy module_locks
2022-02-18 11:39:28 +00:00
Ross Owen
0ad3048e63 Update README.rst 2022-01-21 11:48:38 +00:00
Ross Owen
de8fbd428b Update README.rst 2022-01-21 11:47:45 +00:00
Ross Owen
1e5d57ae2c Update README.rst 2022-01-20 16:48:29 +00:00
Michael Banther
073bc9552a Merge pull request #240 from xmos/release/v3.1.0
Release v3.1.0
2022-01-13 14:04:36 +00:00
Michael Banther
39fda0a178 Merge pull request #239 from xmos/develop
Prepare release v3.1.0
2022-01-13 12:31:34 +00:00
Michael Banther
91d16b13a2 Merge pull request #238 from ACascarino/changelog_update
Upversioned, updated changelog, and removed .?project files
2022-01-13 11:42:42 +00:00
Angel Cascarino
ad889247a0 Merge pull request #3 from mbanth/changelog_update
Update module_build_info
2022-01-13 10:14:01 +00:00
mbanth
a7675ba997 Require lib_locks v2.0.3 or later since that's the latest released version 2022-01-13 10:04:56 +00:00
Angel Cascarino
41c6b90549 Pruned extraneous whitespace. 2022-01-12 17:57:16 +00:00
Angel Cascarino
b62782faa0 Moved the word "to" one line up in the changelog 2022-01-12 17:50:06 +00:00
Angel Cascarino
8c30ce60f2 Removed trailing whitespace in changelog entry 2022-01-12 17:41:52 +00:00
Angel Cascarino
b3d66f4ca4 Upversioned, updated changelog, and removed .?project files 2022-01-12 17:37:48 +00:00
Michael Banther
bdb5c56f7c Merge pull request #236 from ACascarino/feature/set_idle_work
Add swlocks to HID files, and correct operation of SetIdle
2022-01-12 16:35:39 +00:00
Angel Cascarino
a08f5d78fb Another code neatness change 2022-01-12 16:09:54 +00:00
Angel Cascarino
515ec9c022 More code neatness changes 2022-01-12 16:08:46 +00:00
Angel Cascarino
c0104fcf48 Merge branch 'feature/set_idle_work' of github.com:ACascarino/lib_xua into feature/set_idle_work 2022-01-12 15:44:09 +00:00
Angel Cascarino
f88e5877be Documentation updates 2022-01-12 15:44:05 +00:00
Angel Cascarino
d33397164b Whitespace changes in ep_buffer.xc 2022-01-12 15:30:43 +00:00
Angel Cascarino
a087e31b0f Merge pull request #2 from lucianomartin/feature/dummy_module
Add dummy module_locks
2022-01-12 14:54:35 +00:00
Angel Cascarino
418622c593 Disable debug printing in hid.xc 2022-01-12 14:49:00 +00:00
Angel Cascarino
6b0688d23e Updated ep_buffer to match 3610's xua_buffer_lite 2022-01-12 14:47:40 +00:00
lucianom
37ce235594 Add dummy module_locks 2022-01-12 14:30:30 +00:00
lucianom
64cbd072f4 Revert "Remove dependency to lib_locks"
4d68b26b42
2022-01-12 12:51:51 +00:00
lucianom
9b0e541e95 Revert "Use test view"
662b24386d
2022-01-12 12:51:43 +00:00
lucianom
4d68b26b42 Remove dependency to lib_locks 2022-01-12 12:37:33 +00:00
lucianom
662b24386d Use test view 2022-01-12 12:28:44 +00:00
Angel Cascarino
c60da7fd82 Reversed renaming function to avoid upversioning 2022-01-11 17:57:18 +00:00
Angel Cascarino
45ab345521 Update copyright 2022-01-11 16:35:44 +00:00
Angel Cascarino
692c4ee7ed Missed brace 2022-01-11 16:31:07 +00:00
Angel Cascarino
5fa86dabbb Updated unit tests to remove "reportAll" tests 2022-01-11 16:27:28 +00:00
Angel Cascarino
9863b37ead Remove ref. to IsReportIdInUse in ep_buffer 2022-01-11 16:12:05 +00:00
Angel Cascarino
46f516ddbc Updated header 2022-01-11 16:10:21 +00:00
Angel Cascarino
a404138903 Removed "reset" ability of UpdateReportPeriod
In the event where an invalid reportDuration is supplied, previously HidUpdateReportPeriod
would reset the period for the specified ID to
ENDPOINT_INT_INTERVAL_IN_HID * MS_IN_TICKS.
As the default period is now application-specific,
hid.xc cannot know what the appropriate value is,
and so this has been removed.
2022-01-11 16:06:11 +00:00
Angel Cascarino
147b5fb7f7 Corrected hidAreReportIDsInUse 2022-01-11 15:58:42 +00:00
Angel Cascarino
ebb3a0bfcb Merge branch 'feature/set_idle_work' of github.com:ACascarino/lib_xua into feature/set_idle_work 2022-01-11 15:56:35 +00:00
Angel Cascarino
ec87a43dbf Removed "0 means all" logic throughout 2022-01-11 15:56:32 +00:00
Michael Banther
b0a8735623 Merge pull request #1 from mbanth/feature/set_idle_work
Feature/set idle work
2022-01-11 14:29:42 +00:00
mbanth
93721f3144 Added missing dependency change log entry 2022-01-11 14:24:32 +00:00
mbanth
d7b41cd35f Update copyright date range 2022-01-11 14:22:03 +00:00
Angel Cascarino
d3560ca7fe Merge branch 'feature/set_idle_work' of github.com:ACascarino/lib_xua into feature/set_idle_work 2022-01-11 12:26:04 +00:00
Angel Cascarino
ff86ac8d2a Added debug printing 2022-01-11 12:26:00 +00:00
Angel Cascarino
eebd438620 Update module_build_info 2022-01-11 11:56:29 +00:00
Angel Cascarino
5bb44c54e1 Fixed the fix for swlock work 2022-01-11 11:42:41 +00:00
Angel Cascarino
36d325a457 Fixed swlock change 2022-01-11 11:40:31 +00:00
xmos-jenkins
d40ede1525 Merged in older changes 2022-01-11 11:32:14 +00:00
xmos-jenkins
4f37069efb Merge remote-tracking branch 'angel/feature/multiple_hid_report_exception' into feature/set_idle_work 2022-01-11 11:27:09 +00:00
xmos-jenkins
9f667d96f8 Added alternative hidIsGetIdleSilenced function 2022-01-11 11:23:28 +00:00
Angel Cascarino
c352ed1132 Alphabetise main functions in hid_report.c 2022-01-07 17:46:25 +00:00
Angel Cascarino
a18e5a976f Change hwlock to swlock in hid_report.c 2022-01-07 17:30:27 +00:00
mbanth
737c5bd7d0 Manually revert to capture the current time within the HidIsSetIdleSilenced() function 2022-01-05 17:52:07 +00:00
mbanth
7a0cfca280 Experiment with obtaining the time used in HidIsSetIdleSilenced() from outside of the function 2022-01-05 17:01:28 +00:00
mbanth
3988906e39 Add locks around references to included static variables. 2022-01-05 14:58:04 +00:00
Angel Cascarino
cd0248c162 Removed locks in isReportDesciptorPrepared 2022-01-04 14:19:54 +00:00
Angel Cascarino
55de7a8abd Removed locks from hidSetReportItem 2022-01-04 14:07:06 +00:00
Angel Cascarino
911c8c51f2 Change initialisation of hwlock 2022-01-04 13:48:48 +00:00
Angel Cascarino
fa9d483d2f Updated hwlock allocation 2022-01-04 13:23:15 +00:00
Angel Cascarino
1ae9c55477 Added hardware locks 2022-01-04 12:37:05 +00:00
Michael Banther
94a05a8ece Merge pull request #232 from xmos/release/v3.0.0
Release v3.0.0
2021-12-24 15:55:13 +00:00
Michael Banther
a93987d281 Merge pull request #227 from xmos/develop
Merge develop into release/v3.0.0
2021-12-23 15:50:22 +00:00
Michael Banther
4f35551547 Merge pull request #230 from CiaranWoodward/feature/unit-functional
Modify unit test report descriptor to match the working 3610
2021-12-23 15:06:48 +00:00
Ciaran Woodward
cb774f3c11 Modify unit test report descriptor to match the working 3610 2021-12-23 12:38:27 +00:00
Michael Banther
66a611f4fd Merge pull request #229 from mbanth/feature/multiple_hid_reports
Iterate through the correct set of HID Report IDs, plus some clean up.
2021-12-23 11:04:18 +00:00
mbanth
b61ea63d40 Iterate through the correct set of HID Report IDs, plus some clean up. 2021-12-23 10:31:07 +00:00
Michael Banther
8c132af069 Merge pull request #228 from CiaranWoodward/feature/multiple_hid_reports
Fix the handling of setidle requests
2021-12-22 17:15:05 +00:00
Ciaran Woodward
93229a7509 Fix refactoring error 2021-12-22 16:52:54 +00:00
Ciaran Woodward
466cc0abbb Fix the handling of setidle requests 2021-12-22 16:29:03 +00:00
Michael Banther
d5d5bd0637 Merge pull request #226 from CiaranWoodward/feature/multiple_hid_reports
Support multiple HID Reports & update examples for new API
2021-12-21 16:53:54 +00:00
Ciaran Woodward
ee6c22bd37 Loosen up usage page check in validate
While the implementation can only support one usage per report id,
the report collections themselves have usages, which are acceptable.
This change allows these usages to pass the validate check.
2021-12-21 12:43:34 +00:00
Ciaran Woodward
703a277059 Remove debug printfs 2021-12-21 12:18:57 +00:00
Ciaran Woodward
b88342ab2b Add new hid page ID constant 2021-12-21 11:21:17 +00:00
Ciaran Woodward
e7f9428731 Fix typos in unit tests 2021-12-20 17:34:01 +00:00
Ciaran Woodward
6400e146d0 Add an iterator style mechanism for iterating through report IDs 2021-12-20 17:26:08 +00:00
Ciaran Woodward
da114a1dea Merge pull request #1 from ACascarino/feature/multiple_hid_reports
Update lib_xua multiple_hid_reports from review
2021-12-20 17:21:25 +00:00
Angel Cascarino
77398218b5 Apply suggestions from code review
Co-authored-by: Ciaran Woodward <ciaranwoodward@gmail.com>
2021-12-20 17:17:34 +00:00
Angel Cascarino
244a7718a1 Corrected type in documentation 2021-12-20 17:11:50 +00:00
Angel Cascarino
e71ffdba00 Missed a semicolon... 2021-12-20 17:10:48 +00:00
Angel Cascarino
625123e4a6 Clarified ep_buffer.xc setup stall
Added getter hidIsReportDescriptorPrepared(),
allowing more readable logic in the setup phase of
ep_buffer.xc
2021-12-20 16:45:24 +00:00
Angel Cascarino
548992ab5c Removed USB_HID_REPORT_ID_CONSUMER as per review. 2021-12-20 15:46:15 +00:00
Ciaran Woodward
ccc1ee4021 Fix inverted isSilenced logic, add INVALID_ID constant 2021-12-20 14:47:20 +00:00
Angel Cascarino
ab96a726d6 Altered format on test report_descriptor.h 2021-12-20 12:51:26 +00:00
Ciaran Woodward
d3d9b5ba23 Add hidReportIdInUse command to determine whether report IDs are used 2021-12-17 14:35:23 +00:00
Ciaran Woodward
c3e95a379f Add some report time tests & fix comments] 2021-12-15 12:44:39 +00:00
Ciaran Woodward
5be97ac227 Begin work on setidle unit tests 2021-12-14 14:15:48 +00:00
Ciaran Woodward
8799f5f36e Refactor HID report descriptor validation function 2021-12-13 12:51:40 +00:00
Ciaran Woodward
71dd8b5409 Add descriptor validation function & fix issues it found
Note this is in progress, I either want to move the check function somewhere else,
or convert the printf calls to something else (I imagine some kind of log function
exists?)
2021-12-10 18:00:04 +00:00
Ciaran Woodward
e41aed6ffb Update examples to work with new API 2021-12-10 11:46:01 +00:00
Ciaran Woodward
548ccebb27 Propegate constants and helper macro around codebase 2021-12-10 11:32:04 +00:00
Ciaran Woodward
3895b486ab Add constants header for common constants; helper macro for header 2021-12-10 10:45:54 +00:00
Michael Banther
ebeae1fa17 Merge pull request #2 from CiaranWoodward/feature/multiple_hid_reports_tests
Update tests to work with new report-id api
2021-12-09 18:45:08 +00:00
Ciaran Woodward
f328deb336 style 2021-12-09 18:02:42 +00:00
Ciaran Woodward
353d7c3c8d Fix merge issues 2021-12-09 17:28:16 +00:00
Ciaran Woodward
5f971af054 Merge remote-tracking branch 'michael/feature/multiple_hid_reports' into feature/multiple_hid_reports_tests 2021-12-09 17:19:04 +00:00
mbanth
2b5dab51b5 Add explicit initialization of static variables in hid_report.c 2021-12-09 16:15:29 +00:00
Ciaran Woodward
19be25809b Fix implementation of hidGetReportIdLimit to match docs & usage 2021-12-09 16:10:28 +00:00
mbanth
26cac1abb1 Update includes of xua_hid_report.h 2021-12-09 15:58:51 +00:00
mbanth
03a5024520 Renamed xua_hid_report_descriptor.h to xua_hid_report.h 2021-12-09 15:45:05 +00:00
mbanth
08ed5ee668 Renamed hid_report_descriptor.c to hid_report.c 2021-12-09 15:44:19 +00:00
mbanth
2b96ea0171 Increment major version and add change log entries 2021-12-09 15:29:45 +00:00
Ciaran Woodward
1b186a0c2f Remove test-specific information from hid_report_descriptor.h 2021-12-09 14:55:38 +00:00
Ciaran Woodward
ed7a33b40f Write a bunch of unit tests that exercise the HID report IDs 2021-12-09 11:45:03 +00:00
Ciaran Woodward
459ce6bd63 Begin building up a set of multi-report unit tests
This work is starting by expanding the tests written for
single report purposes. I have also added a couple of
extra simple tests that made sense (under/overflow of
report IDs) as I went along.
2021-12-08 17:55:33 +00:00
Ciaran Woodward
3819f30ad0 Enable waf building unit tests in different confgurations 2021-12-08 15:47:15 +00:00
Ciaran Woodward
79e256f829 Update existing unit tests to work with the new API 2021-12-08 12:34:14 +00:00
Ciaran Woodward
be90779db5 Temporary workaround for ENDPOINT_INT_INTERVAL_IN_HID definition 2021-12-08 12:33:37 +00:00
Ciaran Woodward
de382e5cc0 Merge remote-tracking branch 'angel/feature/multiple_hid_reports' into feature/multiple_hid_reports_tests 2021-12-08 11:28:37 +00:00
Angel Cascarino
6dfc934d36 Correct error in hidCaptureReportTime 2021-12-08 11:14:52 +00:00
Ciaran Woodward
7dfd78deb4 Update unit test header to match new report id api 2021-12-08 11:01:33 +00:00
Angel Cascarino
fac0542920 Merge branch 'mbanth:feature/multiple_hid_reports' into feature/multiple_hid_reports 2021-12-08 10:47:55 +00:00
mbanth
8c9e8b11b9 Changes to support the Set Idle request with multiple Report IDs 2021-12-07 18:50:28 +00:00
Angel Cascarino
21b259bc88 Update legacy_test to new HID API 2021-12-07 18:12:00 +00:00
Angel Cascarino
589c16d56c Updated gitignore 2021-12-07 17:17:14 +00:00
mbanth
b4d5cb93f1 Use an unsigned constant with an unsigned variable 2021-12-07 10:35:20 +00:00
mbanth
1d22975fd2 Update HID initialisation and handling to include multiple reports and the effect of the Set Idle command 2021-12-06 17:28:30 +00:00
mbanth
5354d94987 Remove unused pointer 2021-12-06 17:16:11 +00:00
mbanth
171ef30f42 Remove redundant function declaration 2021-12-06 13:53:20 +00:00
mbanth
8c175187c8 Modify hidClearChangePending(), hidIsChangePending() amd hidSetChangePending() to operate on a Report ID basis 2021-12-01 12:26:26 +00:00
mbanth
53f80dfba4 Add documentation 2021-12-01 12:25:18 +00:00
mbanth
21c1e661ae Change static variable names to indicate that they are static. 2021-12-01 09:47:52 +00:00
mbanth
d515458b83 Add id parameter to hidClearChangePending(), hidIsChangePending() and hidSetChangePending(). Correct the name of the underlying static variable. 2021-12-01 09:42:32 +00:00
mbanth
b853589120 Move the HID Clear Pending, Is Pending and Set Pending functions from hid.xc to hid_report_descriptor.c.
These functions are called from the application so they do not belong in hid.xc which contains internal XUA functionality.
2021-11-30 18:29:17 +00:00
mbanth
966d8db9a9 Additional documentation and a minor renaming of an automatic variable 2021-11-30 15:05:37 +00:00
mbanth
dc22b0593f Additional documentation 2021-11-30 15:04:33 +00:00
mbanth
0892ff9a8b Move the declaration of the HID Get Report Limit function and provide its definition 2021-11-29 17:09:26 +00:00
mbanth
65b1b41ec4 Change the interface to UserHIDGetData() and UserHIDRecordEvent() 2021-11-26 16:32:12 +00:00
mbanth
3b6f1c80e2 Move HID_REPORT_COUNT to hid_report_descriptor.h 2021-11-26 16:30:47 +00:00
mbanth
bf9e150310 Use size_t for each index into an array. 2021-11-26 13:40:58 +00:00
mbanth
1857ddbc67 Set constant values explicitly to unsigned. Add access function for HID Report length. Update hidGetReportItem() and hidSetReportItem() to check for correct Reporty ID. Update hidGetReportLength() to report the length of the given HID Report. Update hidGetUsagePage() to iterate across all HID Reports. 2021-11-26 10:50:53 +00:00
mbanth
145c0cb80f Set constant values explicitly to unsigned 2021-11-26 10:46:03 +00:00
mbanth
1fe4fc6771 Safety commit. Builds but not run. 2021-11-25 17:30:30 +00:00
mbanth
88a3d6b20d Initial commit made to keep a safe copy. Builds but will not run and definitely very incomplete. 2021-11-24 16:06:17 +00:00
Ross Owen
33ec43134c Merge pull request #224 from xross/fix/223
fix/223
2021-10-26 14:57:45 +01:00
xross
2bbebc0a39 Further removed of XS1 support items 2021-10-18 17:05:35 +01:00
xross
32af5b7b20 Removed XS1 implementation in fastmix.S 2021-10-18 16:54:54 +01:00
xross
fc6915be6f Removed XS3 related warning from reboot.xc 2021-10-18 16:49:46 +01:00
xross
d9dc7cc7c7 XS2 now special case in DFU flag check 2021-10-18 16:45:07 +01:00
xross
898a6c2410 Remove XS1 related USB port. Also fixed errors related to removing XS1 support from ADAT 2021-10-18 16:38:32 +01:00
xross
da758f48fa Removed remaining references to SU1 devices 2021-10-18 16:37:33 +01:00
Michael Banther
2923f7574b Merge pull request #220 from xmos/release/v2.1.1
Release v2.1.1
2021-09-08 15:02:41 +01:00
Michael Banther
436a268781 Merge pull request #219 from xmos/develop
Prepare release of v2.1.1
2021-09-08 11:28:45 +01:00
Michael Banther
8233ef1d47 Merge pull request #218 from mbanth/feature/fix_hid_set_report_item
Fix hid set report item
2021-08-26 16:52:06 +01:00
mbanth
1109e08dd8 Increment version and add change log entry 2021-08-26 16:25:40 +01:00
mbanth
15f1d4de59 Use correct order of expected vs actual results in test assertions 2021-08-26 16:13:23 +01:00
mbanth
911a82cd83 Add test for the case of a modified item that of length 1 that overwrites data of length 2 2021-08-25 18:16:54 +01:00
mbanth
ec657d1e8d Zero the MSB if given an item of length 1 2021-08-25 18:13:12 +01:00
QuinnWang
cd5f7272c8 decouple update for DFU "fake" SET_SAMPLE_FREQ special processing
DFU will send the AUDIO_STOP_FOR_DFU from endpoint0 to audio core in order to trigger the audio core running dummy_deliver instead of the deliver. The current code didn't distinguish the read SET_SAMPLE_FREQ or "fake" SET_SAMPLE_FREQ (not a real sampFreq, but is AUDIO_STOP_FOR_DFU), so when it is AUDIO_STOP_FOR_DFU, the current decouple code will reset the buffer just as it is sample rate switch, but this will cause the USB hub incorrectly reboot when there is a USB hub connected between XMOS device and the host. The MSFT XUF208 project, using a USB2.0 hub connected to Linux xhci, the error from xhci is "buffer overrun event on the endpoint, followed by a hub re-enabling from khubd. Modified like this commit will solve the problem.
So update decouple for DFU "fake" SET_SAMPLE_FREQ special processing just like what did in the ep_buffer.
2021-01-15 15:56:18 +08:00
88 changed files with 4196 additions and 2678 deletions

1
.github/CODEOWNERS vendored Normal file
View File

@@ -0,0 +1 @@
* @xross

3
.gitignore vendored
View File

@@ -20,6 +20,9 @@
test_results.csv
_build*
**/.venv/**
**/.vscode/**
**.egg-info
*.pdf
# waf build files
.lock-waf_*

View File

@@ -1,7 +0,0 @@
tap 'homebrew/core'
brew 'perl'
brew 'cpanm'
brew 'python@2'
brew 'pipenv'

View File

@@ -1,60 +1,104 @@
lib_xua Change Log
==================
3.2.0
-----
* CHANGED: Updated tests to use lib_locks (was legacy module_locks)
* CHANGED: Exclude HID Report functions unless the HID feature is enabled
* CHANGED: Explicit feedback EP enabled by default (see
UAC_FORCE_FEEDBACK_EP)
* FIXED: Incorrect conditional compilation of HID report code
* FIXED: Input/output descriptors written when input/output not enabled. (Audio
class 1.0 mode using XUA_USB_DESCRIPTOR_OVERWRITE_RATE_RES)
* Changes to dependencies:
- lib_dsp: 5.0.0 -> 6.2.1
- lib_locks: Added dependency 2.1.0
- lib_logging: 3.0.0 -> 3.1.1
- lib_mic_array: 4.0.0 -> 4.3.0
- lib_spdif: 4.0.0 -> 4.1.0
- lib_xassert: 4.0.0 -> 4.1.0
- lib_xud: 2.0.0 -> 2.2.0
3.1.0
-----
* CHANGED: Removed logic from HID API functions allowing a Report ID of 0 to
be used as "all/any" Report
3.0.0
-----
* ADDED: Support for HID Report IDs
* CHANGED: Renamed the HID API file xua_hid_report_descriptor.h to
xua_hid_report.h
* REMOVED: Support for HID Reports containing controls from mixed usage
pages
2.1.1
-----
* CHANGED: Setting of HID report items
2.1.0
-----
* CHANGED: Updated clock blocks to support lib_xud v2.0.0
* CHANGED: Updated dependency on lib_xud to v2.0.0 for use by XVF3600
2.0.1
-----
* Changes to dependencies:
* CHANGED: Reverted dependency on lib_xud to v1.2.0 for use by XVF3510
- lib_xud: 1.2.0 -> 2.0.0
2.0.0
-----
* ADDED: Function to get a Report item description
* ADDED: Support for multiple flash specs defined by DFU_FLASH_DEVICE
* ADDED: Nullable c_aud_ctl chan-end optimisation for fixed rate devices
* CHANGED: Check HID Usage Page when changing a Report item description
* CHANGED: HID event ID from list to bit and byte location in HID Report
* CHANGED: Interface to UserHIDRecordEvent()
* ADDED: Support for multiple flash specs defined by DFU_FLASH_DEVICE
* ADDED: Nullable c_aud_ctl chan-end optimisation for fixed rate devices
1.3.0
-----
* ADDED: Build default HID Report descriptor at boot-time
* ADDED: Function to return length of HID Report
* CHANGED: Move HID descriptors to ease maintenance
* CHANGED: Move legacy tests to separate directory
* CHANGED: Replace unused GPI-specific HID event names with generic ones
* ADDED: Build default HID Report descriptor at boot-time
* ADDED: Function to return length of HID Report
* CHANGED: HID Report to return multiple bytes
* CHANGED: NO_USB conditional compilation switch with XUA_USB_EN
* REMOVED: XS1 support
* CHANGED: Clock blocks used for BCLK and MCLK
* REMOVED: Arguments no longer supported by XUD_Main
* CHANGED: Arguments no longer supported by XUD_Main
* REMOVED: Support for XS1 based devices
1.2.0
-----
* ADDED: Updates for xcore.ai/XS3 compatibility
* ADDED: Makefile.Win32 for xmosdfu on Windows
* CHANGED: Use XMOS Public Licence Version 1
* FIXED: Bump default BCD device number to v1.2.0
* FIXED: xmosdfu now fails with an error when given a directory (#119)
* FIXED: Compilation errors related to HID code
* FIXED: Runtime error when using mic array interface
* CHANGED: Use XMOS Public Licence Version 1
* FIXED: Automate HID Report Descriptor length in AC1 HID Descriptor
1.1.1
-----
* RESOLVED: Zero length input packets generated before enumeration causing I2S
timing pushout at startup
* CHANGED: Pin Python package versions
* REMOVED: not necessary cpanfile
* CHANGED: Pin Python package versions
* FIXED: Zero length input packets generated before enumeration causing
I2S timing pushout at startup
1.1.0
-----
@@ -74,13 +118,12 @@ lib_xua Change Log
* ADDED: Support for USB HID Set Idle request
* ADDED: Pre-processor symbols to enable single-threaded, dual-PDM
microphone operation
* FIXED: Descriptors for XUA_ADAPTIVE incorrectly defined for IN endpoint
* ADDED: Guards to user_hid.h and xua_hid.h
* ADDED: UAC1 HID support for AC Stop (End Call), Volume Increment and
Volume Decrement
* CHANGE: UAC1 HID to report function keys f21 through f24 as specified by
* CHANGED: UAC1 HID to report function keys f21 through f24 as specified by
customer
* CHANGE: HID interface for user to set and clear events from global
* CHANGED: HID interface for user to set and clear events from global
variable to function
* CHANGE HID report descriptor to use generic events instead of GPI
events, to report Key-phrase detection as AC Search, and to report end-call
@@ -90,11 +133,24 @@ lib_xua Change Log
* ADDED: Override USB descriptor with sampling frequency and
bit-resolution set at boot time.
* ADDED: Global pointer to allow external access to masterClockFreq
* FIXED: Descriptors for XUA_ADAPTIVE incorrectly defined for IN endpoint
* Changes to dependencies:
- lib_spdif: 3.1.0 -> 4.0.0
- lib_xassert: 3.0.1 -> 4.0.0
0.2.1
-----
* HOTFIX: Fix descriptors for XUA_ADAPTIVE
* FIXED: Fix descriptors for XUA_ADAPTIVE
* Changes to dependencies:
- lib_logging: 2.1.1 -> 3.0.0
- lib_xud: 0.1.0 -> 0.2.0
0.2.0
-----
@@ -102,17 +158,17 @@ lib_xua Change Log
* ADDED: Initial library documentation
* ADDED: Application note AN00247: Using lib_xua with lib_spdif (transmit)
* ADDED: Separate callbacks for input/output audio stream start/stop
* CHANGE: I2S hardware resources no longer used globally and must be passed
* CHANGED: I2S hardware resources no longer used globally and must be passed
to XUA_AudioHub()
* CHANGE: XUA_AudioHub() no longer pars S/PDIF transmitter task
* CHANGE: Moved to lib_spdif (from module_spdif_tx & module_spdif_rx)
* CHANGE: Define NUM_PDM_MICS renamed to XUA_NUM_PDM_MICS
* CHANGE: Define NO_USB renamed to XUA_USB_EN
* CHANGE: Build files updated to support new "xcommon" behaviour in xwaf.
* RESOLVED: wChannelConfig in UAC1 descriptor set according to output channel
* CHANGED: XUA_AudioHub() no longer pars S/PDIF transmitter task
* CHANGED: Moved to lib_spdif (from module_spdif_tx & module_spdif_rx)
* CHANGED: Define NUM_PDM_MICS renamed to XUA_NUM_PDM_MICS
* CHANGED: Define NO_USB renamed to XUA_USB_EN
* CHANGED: Build files updated to support new "xcommon" behaviour in xwaf.
* FIXED: wChannelConfig in UAC1 descriptor set according to output channel
count
* RESOLVED: Indexing of ADAT channel strings (#18059)
* RESOLVED: Rebooting device fails when PLL config "not reset" bit is set
* FIXED: Indexing of ADAT channel strings (#18059)
* FIXED: Rebooting device fails when PLL config "not reset" bit is set
* Changes to dependencies:
@@ -128,20 +184,19 @@ lib_xua Change Log
-----
* ADDED: Application note AN00246: Simple USB Audio Device using lib_xua
* CHANGE: xmosdfu emits warning if empty image read via upload
* CHANGE: Simplified mclk port sharing - no longer uses unsafe pointer
* RESOLVED: Runtime exception issues when incorrect feedback calculated
* CHANGED: xmosdfu emits warning if empty image read via upload
* CHANGED: Simplified mclk port sharing - no longer uses unsafe pointer
* FIXED: Runtime exception issues when incorrect feedback calculated
(introduced in sc_usb_audio 6.13)
* RESOLVED: Output sample counter reset on stream start. Caused playback
* FIXED: Output sample counter reset on stream start. Caused playback
issues on some Linux based hosts
0.1.1
-----
* RESOLVED: Configurations where I2S_CHANS_DAC and I2S_CHANS_ADC are both 0
now build
* RESOLVED: Deadlock in mixer when MAX_MIX_COUNT > 0 for larger channel
counts
* FIXED: Configurations where I2S_CHANS_DAC and I2S_CHANS_ADC are both 0 now
build
* FIXED: Deadlock in mixer when MAX_MIX_COUNT > 0 for larger channel counts
* Changes to dependencies:
@@ -152,31 +207,31 @@ lib_xua Change Log
0.1.0
-----
* ADDED: FB_USE_REF_CLOCK to allow feedback generation from xCORE
internal reference
* ADDED: Linux Makefile for xmosdfu host application
* ADDED: Raspberry Pi Makefile for xmosdfu host application
* ADDED: Documentation of PID argument to xmosdfu
* ADDED: Optional build time microphone delay line (MIC_BUFFER_DEPTH)
* CHANGE: Removal of audManage_if, users should define their own
interfaces as required
* CHANGE: Vendor specific control interface in UAC1 descriptor now has a
* ADDED: FB_USE_REF_CLOCK to allow feedback generation from xCORE internal
reference
* ADDED: Linux Makefile for xmosdfu host application
* ADDED: Raspberry Pi Makefile for xmosdfu host application
* ADDED: Documentation of PID argument to xmosdfu
* ADDED: Optional build time microphone delay line (MIC_BUFFER_DEPTH)
* CHANGED: Removal of audManage_if, users should define their own interfaces
as required
* CHANGED: Vendor specific control interface in UAC1 descriptor now has a
string descriptor so it shows up with a descriptive name in Windows Device
Manager
* CHANGE: DFU_BCD_DEVICE removed (now uses BCD_DEVICE)
* CHANGE: Renaming in descriptors.h to avoid clashes with application
* CHANGE: Make device reboot function no-argument (was one channel end)
* RESOLVED: FIR gain compensation for PDM mics set incorrectly for divide of
* CHANGED: DFU_BCD_DEVICE removed (now uses BCD_DEVICE)
* CHANGED: Renaming in descriptors.h to avoid clashes with application
* CHANGED: Make device reboot function no-argument (was one channel end)
* FIXED: FIR gain compensation for PDM mics set incorrectly for divide of
8
* RESOLVED: Incorrect xmosdfu DYLD path in test script code
* RESOLVED: xmosdfu cannot find XMOS device on modern MacBook Pro (#17897)
* RESOLVED: Issue when feedback is initially incorrect when two SOF's are
not yet received
* RESOLVED: AUDIO_TILE and PDM_TILE may now share the same value/tile
* RESOLVED: Cope with out of order interface numbers in xmosdfu
* RESOLVED: DSD playback not functional on xCORE-200 (introduced in
* FIXED: Incorrect xmosdfu DYLD path in test script code
* FIXED: xmosdfu cannot find XMOS device on modern MacBook Pro (#17897)
* FIXED: Issue when feedback is initially incorrect when two SOF's are not
yet received
* FIXED: AUDIO_TILE and PDM_TILE may now share the same value/tile
* FIXED: Cope with out of order interface numbers in xmosdfu
* FIXED: DSD playback not functional on xCORE-200 (introduced in
sc_usb_audio 6.14)
* RESOLVED: Improvements made to clock sync code in TDM slave mode
* FIXED: Improvements made to clock sync code in TDM slave mode
Legacy release history
@@ -186,105 +241,105 @@ Legacy release history
7.4.1
-----
- RESOLVED: Exception due to null chanend when using NO_USB
- FIXED: Exception due to null chanend when using NO_USB
7.4.0
-----
- RESOLVED: PID_DFU now based on AUDIO_CLASS. This potentially caused issues
- FIXED: PID_DFU now based on AUDIO_CLASS. This potentially caused issues
with UAC1 DFU
7.3.0
-----
- CHANGE: Example OSX DFU host app updated to now take PID as runtime
- CHANGED: Example OSX DFU host app updated to now take PID as runtime
argument. This enabled multiple XMOS devices to be attached to the host
during DFU process
7.2.0
-----
- ADDED: DFU to UAC1 descriptors (guarded by DFU and FORCE_UAC1_DFU)
- RESOLVED: Removed 'reinterpretation to type of larger alignment' warnings
- RESOLVED: DFU flash code run on tile[0] even if XUD_TILE and AUDIO_IO_TILE are not 0
- FIXED: Removed 'reinterpretation to type of larger alignment' warnings
- FIXED: DFU flash code run on tile[0] even if XUD_TILE and AUDIO_IO_TILE are not 0
7.1.0
-----
- ADDED: UserBufferManagementInit() to reset any state required in UserBufferManagement()
- ADDED: I2S output up-sampling (enabled when AUD_TO_USB_RATIO is > 1)
- ADDED: PDM Mic decimator output rate can now be controlled independently (via AUD_TO_MICS_RATIO)
- CHANGE: Rename I2S input down-sampling (enabled when AUD_TO_USB_RATIO is > 1, rather than via I2S_DOWNSAMPLE_FACTOR)
- RESOLVED: Crosstalk between input channels when I2S input down-sampling is enabled
- RESOLVED: Mic decimation data tables properly sized when mic sample-rate < USB audio sample-rate
- CHANGED: Rename I2S input down-sampling (enabled when AUD_TO_USB_RATIO is > 1, rather than via I2S_DOWNSAMPLE_FACTOR)
- FIXED: Crosstalk between input channels when I2S input down-sampling is enabled
- FIXED: Mic decimation data tables properly sized when mic sample-rate < USB audio sample-rate
7.0.1
-----
- RESOLVED: PDM microphone decimation issue at some sample rates caused by integration
- FIXED: PDM microphone decimation issue at some sample rates caused by integration
7.0.0
------
- ADDED: I2S down-sampling (I2S_DOWNSAMPLE_FACTOR)
- ADDED: I2S resynchronisation when in slave mode (CODEC_MASTER=1)
- CHANGE: Various memory optimisations when MAX_FREQ = MIN_FREQ
- CHANGE: Memory optimisations in audio buffering
- CHANGE: Various memory optimisations in UAC1 mode
- CHANGE: user_pdm_process() API change
- CHANGE: PDM Mic decimator table now related to MIN_FREQ (memory optimisation)
- RESOLVED: Audio request interrupt handler properly eliminated
- CHANGED: Various memory optimisations when MAX_FREQ = MIN_FREQ
- CHANGED: Memory optimisations in audio buffering
- CHANGED: Various memory optimisations in UAC1 mode
- CHANGED: user_pdm_process() API change
- CHANGED: PDM Mic decimator table now related to MIN_FREQ (memory optimisation)
- FIXED: Audio request interrupt handler properly eliminated
6.30.0
------
- RESOLVED: Number of PDM microphone channels configured now based on NUM_PDM_MICS define
(previously hard-coded)
- RESOLVED: PDM microphone clock divide now based MCLK defines (previously hard-coded)
- CHANGE: Second microphone decimation core only run if NUM_PDM_MICS > 4
- FIXED: Number of PDM microphone channels configured now based on NUM_PDM_MICS define
(previously hard-coded)
- FIXED: PDM microphone clock divide now based MCLK defines (previously hard-coded)
- CHANGED: Second microphone decimation core only run if NUM_PDM_MICS > 4
6.20.0
------
- RESOLVED: Intra-frame sample delays of 1/2 samples on input streaming in TDM mode
- RESOLVED: Build issue with NUM_USB_CHAN_OUT set to 0 and MIXER enabled
- RESOLVED: SPDIF_TX_INDEX not defined build warning only emitted when SPDIF_TX defined
- RESOLVED: Failure to enter DFU mode when configured without input volume control
- FIXED: Intra-frame sample delays of 1/2 samples on input streaming in TDM mode
- FIXED: Build issue with NUM_USB_CHAN_OUT set to 0 and MIXER enabled
- FIXED: SPDIF_TX_INDEX not defined build warning only emitted when SPDIF_TX defined
- FIXED: Failure to enter DFU mode when configured without input volume control
6.19.0
------
- RESOLVED: SPDIF_TX_INDEX not defined build warning only emitted when SPDIF_TX defined
- RESOLVED: Failure to enter DFU mode when configured without input volume control
- FIXED: SPDIF_TX_INDEX not defined build warning only emitted when SPDIF_TX defined
- FIXED: Failure to enter DFU mode when configured without input volume control
6.18.1
------
- ADDED: Vendor Specific control interface added to UAC1 descriptors to allow control of
XVSM params from Windows (via lib_usb)
- ADDED: Vendor Specific control interface added to UAC1 descriptors to allow control of
XVSM params from Windows (via lib_usb)
6.18.0
------
- ADDED: Call to VendorRequests() and VendorRequests_Init() to Endpoint 0
- ADDED: VENDOR_REQUESTS_PARAMS define to allow for custom parameters to VendorRequest calls
- RESOLVED: FIR gain compensation set appropriately in lib_mic_array usage
- CHANGE: i_dsp interface renamed i_audManage
- ADDED: Call to VendorRequests() and VendorRequests_Init() to Endpoint 0
- ADDED: VENDOR_REQUESTS_PARAMS define to allow for custom parameters to VendorRequest calls
- FIXED: FIR gain compensation set appropriately in lib_mic_array usage
- CHANGED: i_dsp interface renamed i_audManage
6.16.0
------
- ADDED: Call to UserBufferManagement()
- ADDED: PDM_MIC_INDEX in devicedefines.h and usage
- CHANGE: pdm_buffer() task now combinable
- CHANGE: Audio I/O task now takes i_dsp interface as a parameter
- CHANGE: Removed built-in support for A/U series internal ADC
- CHANGE: User PDM Microphone processing now uses an interface (previously function call)
- CHANGED: pdm_buffer() task now combinable
- CHANGED: Audio I/O task now takes i_dsp interface as a parameter
- CHANGED: Removed built-in support for A/U series internal ADC
- CHANGED: User PDM Microphone processing now uses an interface (previously function call)
6.15.2
------
- RESOLVED: interrupt.h (used in audio buffering) now compatible with xCORE-200 ABI
- FIXED: interrupt.h (used in audio buffering) now compatible with xCORE-200 ABI
6.15.1
------
- RESOLVED: DAC data mis-alignment issue in TDM/I2S slave mode
- CHANGE: Updates to support API changes in lib_mic_array version 2.0
- FIXED: DAC data mis-alignment issue in TDM/I2S slave mode
- CHANGED: Updates to support API changes in lib_mic_array version 2.0
6.15.0
------
- RESOLVED: UAC 1.0 descriptors now support multi-channel volume control (previously were
- FIXED: UAC 1.0 descriptors now support multi-channel volume control (previously were
hard-coded as stereo)
- CHANGE: Removed 32kHz sample-rate support when PDM microphones enabled (lib_mic_array
- CHANGED: Removed 32kHz sample-rate support when PDM microphones enabled (lib_mic_array
currently does not support non-integer decimation factors)
6.14.0
@@ -298,75 +353,75 @@ Legacy release history
list and UAC 1.0 descriptors
- ADDED: Support for the use and integration of PDM microphones (including PDM to PCM
conversion) via lib_mic_array
- RESOLVED: MIDI data not accepted after "sleep" in OSX 10.11 (El Capitan) - related to sc_xud
- FIXED: MIDI data not accepted after "sleep" in OSX 10.11 (El Capitan) - related to sc_xud
issue #17092
- CHANGE: Asynchronous feedback system re-implemented to allow for the first two ADDED
- CHANGED: Asynchronous feedback system re-implemented to allow for the first two ADDED
changelog items
- CHANGE: Hardware divider used to generate bit-clock from master clock (xCORE-200 only).
- CHANGED: Hardware divider used to generate bit-clock from master clock (xCORE-200 only).
Allows easy support for greater number of master-clock to sample-rate ratios.
- CHANGE: module_queue no longer uses any assert module/lib
- CHANGED: module_queue no longer uses any assert module/lib
6.13.0
------
- ADDED: Device now uses implicit feedback when input stream is available (previously explicit
feedback pipe always used). This saves chanend/EP resources and means less processing
burden for the host. Previous behaviour available by enabling UAC_FORCE_FEEDBACK_EP
- RESOLVED: Exception when SPDIF_TX and ADAT_TX both enabled due to clock-block being configured
- FIXED: Exception when SPDIF_TX and ADAT_TX both enabled due to clock-block being configured
after already started. Caused by SPDIF_TX define check typo
- RESOLVED: DFU flag address changed to properly conform to memory address range allocated to
- FIXED: DFU flag address changed to properly conform to memory address range allocated to
apps by tools
- RESOLVED: Build failure when DFU disabled
- RESOLVED: Build issue when I2S_CHANS_ADC/DAC set to 0 and CODEC_MASTER enabled
- RESOLVED: Typo in MCLK_441 checking for MIN_FREQ define
- CHANGE: Mixer and non-mixer channel comms scheme (decouple <-> audio path) now identical
- CHANGE: Input stream buffering modified such that during overflow older samples are removed
- FIXED: Build failure when DFU disabled
- FIXED: Build issue when I2S_CHANS_ADC/DAC set to 0 and CODEC_MASTER enabled
- FIXED: Typo in MCLK_441 checking for MIN_FREQ define
- CHANGED: Mixer and non-mixer channel comms scheme (decouple <-> audio path) now identical
- CHANGED: Input stream buffering modified such that during overflow older samples are removed
rather than ignoring most recent samples. Removes any chance of stale input packets
being sent to host
- CHANGE: module_queue (in sc_usb_audio) now uses lib_xassert rather than module_xassert
- CHANGED: module_queue (in sc_usb_audio) now uses lib_xassert rather than module_xassert
6.12.6
------
- RESOLVED: Build error when DFU is disabled
- RESOLVED: Build error when I2S_CHANS_ADC or I2S_CHANS_DAC set to 0 and CODEC_MASTER enabled
- FIXED: Build error when DFU is disabled
- FIXED: Build error when I2S_CHANS_ADC or I2S_CHANS_DAC set to 0 and CODEC_MASTER enabled
6.12.5
------
- RESOLVED: Stream issue when NUM_USB_CHAN_IN < I2S_CHANS_ADC
- FIXED: Stream issue when NUM_USB_CHAN_IN < I2S_CHANS_ADC
6.12.4
------
- RESOLVED: DFU fail when DSD enabled and USB library not running on tile[0]
- FIXED: DFU fail when DSD enabled and USB library not running on tile[0]
6.12.3
------
- RESOLVED: Method for storing persistent state over a DFU reboot modified to improve resilience
- FIXED: Method for storing persistent state over a DFU reboot modified to improve resilience
against code-base and tools changes
6.12.2
------
- RESOLVED: Reboot code (used for DFU) failure in tools versions > 14.0.2 (xCORE-200 only)
- RESOLVED: Run-time exception in mixer when MAX_MIX_COUNT > 0 (xCORE-200 only)
- RESOLVED: MAX_MIX_COUNT checked properly for mix strings in string table
- CHANGE: DFU code re-written to use an XC interface. The flash-part may now be connected
- FIXED: Reboot code (used for DFU) failure in tools versions > 14.0.2 (xCORE-200 only)
- FIXED: Run-time exception in mixer when MAX_MIX_COUNT > 0 (xCORE-200 only)
- FIXED: MAX_MIX_COUNT checked properly for mix strings in string table
- CHANGED: DFU code re-written to use an XC interface. The flash-part may now be connected
to a separate tile to the tile running USB code
- CHANGE: DFU code can now use quad-SPI flash
- CHANGE: Example xmos_dfu application now uses a list of PIDs to allow adding PIDs easier.
- CHANGED: DFU code can now use quad-SPI flash
- CHANGED: Example xmos_dfu application now uses a list of PIDs to allow adding PIDs easier.
--listdevices command also added.
- CHANGE: I2S_CHANS_PER_FRAME and I2S_WIRES_xxx defines tidied
- CHANGED: I2S_CHANS_PER_FRAME and I2S_WIRES_xxx defines tidied
6.12.1
------
- RESOLVED: Fixes to TDM input timing/sample-alignment when BCLK=MCLK
- RESOLVED: Various minor fixes to allow ADAT_RX to run on xCORE 200 MC AUDIO hardware
- CHANGE: Moved from old SPDIF define to SPDIF_TX
- FIXED: Fixes to TDM input timing/sample-alignment when BCLK=MCLK
- FIXED: Various minor fixes to allow ADAT_RX to run on xCORE 200 MC AUDIO hardware
- CHANGED: Moved from old SPDIF define to SPDIF_TX
6.12.0
------
- ADDED: Checks for XUD_200_SERIES define where required
- RESOLVED: Run-time exception due to decouple interrupt not entering correct issue mode
- FIXED: Run-time exception due to decouple interrupt not entering correct issue mode
(affects XCORE-200 only)
- CHANGE: SPDIF Tx Core may now reside on a different tile from I2S
- CHANGE: I2C ports now in structure to match new module_i2c_singleport/shared API.
- CHANGED: SPDIF Tx Core may now reside on a different tile from I2S
- CHANGED: I2C ports now in structure to match new module_i2c_singleport/shared API.
* Changes to dependencies:
@@ -376,48 +431,48 @@ Legacy release history
6.11.3
------
- RESOLVED: (Major) Streaming issue when mixer not enabled (introduced in 6.11.2)
- FIXED: (Major) Streaming issue when mixer not enabled (introduced in 6.11.2)
6.11.2
------
- RESOLVED: (Major) Enumeration issue when MAX_MIX_COUNT > 0 only. Introduced in mixer
- FIXED: (Major) Enumeration issue when MAX_MIX_COUNT > 0 only. Introduced in mixer
optimisations in 6.11.0. Only affects designs using mixer functionality.
- RESOLVED: (Normal) Audio buffering request system modified such that the mixer output is
- FIXED: (Normal) Audio buffering request system modified such that the mixer output is
not silent when in underflow case (i.e. host output stream not active) This issue was
introduced with the addition of DSD functionality and only affects designs using
mixer functionality.
- RESOLVED: (Minor) Potential build issue due to duplicate labels in inline asm in
- FIXED: (Minor) Potential build issue due to duplicate labels in inline asm in
set_interrupt_handler macro
- RESOLVED: (Minor) BCD_DEVICE define in devicedefines.h now guarded by ifndef (caused issues
- FIXED: (Minor) BCD_DEVICE define in devicedefines.h now guarded by ifndef (caused issues
with DFU test build configs.
- RESOLVED: (Minor) String descriptor for Clock Selector unit incorrectly reported
- RESOLVED: (Minor) BCD_DEVICE in devicedefines.h now guarded by #ifndef (Caused issues with
- FIXED: (Minor) String descriptor for Clock Selector unit incorrectly reported
- FIXED: (Minor) BCD_DEVICE in devicedefines.h now guarded by #ifndef (Caused issues with
default DFU test build configs.
- CHANGE: HID report descriptor defines added to shared user_hid.h
- CHANGE: Now uses module_adat_rx from sc_adat (local module_usb_audio_adat removed)
- CHANGED: HID report descriptor defines added to shared user_hid.h
- CHANGED: Now uses module_adat_rx from sc_adat (local module_usb_audio_adat removed)
6.11.1
------
- ADDED: ADAT transmit functionality, including SMUX. See ADAT_TX and ADAT_TX_INDEX.
- RESOLVED: (Normal) Build issue with CODEC_MASTER (xCore is I2S slave) enabled
- RESOLVED: (Minor) Channel ordering issue in when TDM and CODEC_MASTER mode enabled
- RESOLVED: (Normal) DFU fails when SPDIF_RX enabled due to clock block being shared between SPDIF
- FIXED: (Normal) Build issue with CODEC_MASTER (xCore is I2S slave) enabled
- FIXED: (Minor) Channel ordering issue in when TDM and CODEC_MASTER mode enabled
- FIXED: (Normal) DFU fails when SPDIF_RX enabled due to clock block being shared between SPDIF
core and FlashLib
6.11.0
------
- ADDED: Basic TDM I2S functionality added. See I2S_CHANS_PER_FRAME and I2S_MODE_TDM
- CHANGE: Various optimisations in 'mixer' core to improve performance for higher
- CHANGED: Various optimisations in 'mixer' core to improve performance for higher
channel counts including the use of XC unsafe pointers instead of inline ASM
- CHANGE: Mixer mapping disabled when MAX_MIX_COUNT is 0 since this is wasted processing.
- CHANGE: Descriptor changes to allow for channel input/output channel count up to 32
- CHANGED: Mixer mapping disabled when MAX_MIX_COUNT is 0 since this is wasted processing.
- CHANGED: Descriptor changes to allow for channel input/output channel count up to 32
(previous limit was 18)
6.10.0
------
- CHANGE: Endpoint management for iAP EA Native Transport now merged into buffer() core.
- CHANGED: Endpoint management for iAP EA Native Transport now merged into buffer() core.
Previously was separate core (as added in 6.8.0).
- CHANGE: Minor optimisation to I2S port code for inputs from ADC
- CHANGED: Minor optimisation to I2S port code for inputs from ADC
6.9.0
-----
@@ -425,35 +480,35 @@ Legacy release history
supported (4 channels at 96kHz).
- ADDED: Explicit build warnings if sample rate/depth & channel combination exceeds
available USB bus bandwidth.
- RESOLVED: (Major) Reinstated ADAT input functionality, including descriptors and clock
- FIXED: (Major) Reinstated ADAT input functionality, including descriptors and clock
generation/control and stream configuration defines/tables.
- RESOLVED: (Major) S/PDIF/ADAT sample transfer code in audio() (from ClockGen()) moved to
- FIXED: (Major) S/PDIF/ADAT sample transfer code in audio() (from ClockGen()) moved to
aid timing.
- CHANGE: Modifying mix map now only affects specified mix, previous was applied to all
- CHANGED: Modifying mix map now only affects specified mix, previous was applied to all
mixes. CS_XU_MIXSEL control selector now takes values 0 to MAX_MIX_COUNT + 1
(with 0 affecting all mixes).
- CHANGE: Channel c_dig_rx is no longer nullable, assists with timing due to removal of
- CHANGED: Channel c_dig_rx is no longer nullable, assists with timing due to removal of
null checks inserted by compiler.
- CHANGE: ADAT SMUX selection now based on device sample frequency rather than selected
- CHANGED: ADAT SMUX selection now based on device sample frequency rather than selected
stream format - Endpoint 0 now configures clockgen() on a sample-rate change
rather than stream start.
6.8.0
-----
- ADDED: Evaluation support for iAP EA Native Transport endpoints
- RESOLVED: (Minor) Reverted change in 6.5.1 release where sample rate listing in Audio Class
- FIXED: (Minor) Reverted change in 6.5.1 release where sample rate listing in Audio Class
1.0 descriptors was trimmed (previously 4 rates were always reported). This change
appears to highlight a Windows (only) enumeration issue with the Input & Output
configs
- RESOLVED: (Major) Mixer functionality re-instated, including descriptors and various required
- FIXED: (Major) Mixer functionality re-instated, including descriptors and various required
updates compatibility with 13 tools
- RESOLVED: (Major) Endpoint 0 was requesting an out of bounds channel whilst requesting level data
- RESOLVED: (Major) Fast mix code not operates correctly in 13 tools, assembler inserting long jmp
- FIXED: (Major) Endpoint 0 was requesting an out of bounds channel whilst requesting level data
- FIXED: (Major) Fast mix code not operates correctly in 13 tools, assembler inserting long jmp
instructions
- RESOLVED: (Minor) LED level meter code now compatible with 13 tools (shared mem access)
- RESOLVED (Minor) Ordering of level data from the device now matches channel ordering into
- FIXED: (Minor) LED level meter code now compatible with 13 tools (shared mem access)
- FIXED: (Minor) Ordering of level data from the device now matches channel ordering into
mixer (previously the device input data and the stream from host were swapped)
- CHANGE: Level meter buffer naming now resemble functionality
- CHANGED: Level meter buffer naming now resemble functionality
Legacy release history

12
Jenkinsfile vendored
View File

@@ -1,4 +1,4 @@
@Library('xmos_jenkins_shared_library@v0.16.2') _
@Library('xmos_jenkins_shared_library@v0.18.0') _
getApproval()
@@ -14,7 +14,7 @@ pipeline {
stages {
stage('Basic tests') {
agent {
label 'x86_64&&brew'
label 'x86_64 && linux'
}
stages {
stage('Get view') {
@@ -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")
}
}
}
@@ -113,7 +113,7 @@ pipeline {
parallel {
stage('Build Linux host app') {
agent {
label 'x86_64&&brew&&linux'
label 'x86_64&&linux'
}
steps {
xcorePrepareSandbox("${VIEW}", "${REPO}")
@@ -129,7 +129,7 @@ pipeline {
}
stage('Build Mac host app') {
agent {
label 'x86_64&&brew&&macOS'
label 'x86_64&&macOS'
}
steps {
xcorePrepareSandbox("${VIEW}", "${REPO}")
@@ -183,7 +183,7 @@ pipeline {
}
stage('Update') {
agent {
label 'x86_64&&brew'
label 'x86_64 && linux'
}
steps {
updateViewfiles()

View File

@@ -1,6 +1,10 @@
lib_xua
=======
:Latest release: 3.2.0rc0
:Scope: General Use
Summary
-------
@@ -33,6 +37,12 @@ Key features of the various applications in this repository are as follows
- ADAT input
- Synchronisation to external digital streams i.e. S/PDIF or ADAT
- I2S slave & master modes
- TDM slave & master modes
- MIDI input/output (Compliant to USB Class Specification for MIDI devices)
- DSD output (Native and DoP mode) at DSD64 and DSD128 rates
@@ -45,7 +55,6 @@ Key features of the various applications in this repository are as follows
Note, not all features may be supported at all sample frequencies, simultaneously or on all devices. Some features also require specific host driver support.
Software version and dependencies
.................................
@@ -60,3 +69,15 @@ The following application notes use this library:
* AN000246 - Simple USB Audio Device using lib_xua
* AN000247 - Using lib_xua with lib_spdif (transmit)
* AN000248 - Using lib_xua with lib_mic_array
Required software (dependencies)
================================
* lib_logging (git@github.com:xmos/lib_logging.git)
* lib_xassert (git@github.com:xmos/lib_xassert.git)
* lib_xud (git@github.com:xmos/lib_xud.git)
* lib_spdif (git@github.com:xmos/lib_spdif.git)
* lib_mic_array (git@github.com:xmos/lib_mic_array.git)
* lib_dsp (git@github.com:xmos/lib_dsp)
* lib_locks (git@github.com:xmos/lib_locks.git)

3
doc/dfu/rst/xdoc.conf Normal file
View File

@@ -0,0 +1,3 @@
XMOSNEWSTYLE=2
SOURCE_INCLUDE_DIRS=../../../lib_xua/host/xmosdfu
SPHINX_MASTER_DOC=dfu

1
doc_dfu/.gitignore vendored
View File

@@ -1 +0,0 @@
_build

View File

@@ -1,84 +0,0 @@
*******************************
XMOS PUBLIC LICENCE: Version 1
*******************************
Subject to the conditions and limitations below, permission is hereby granted by XMOS LIMITED (“XMOS”), free of charge, to any person or entity obtaining a copy of the XMOS Software.
**1. Definitions**
**“Applicable Patent Rights”** means: (a) where XMOS is the grantor of the rights, (i) claims of patents that are now or in future owned by or assigned to XMOS and (ii) that cover subject matter contained in the Software, but only to the extent it is necessary to use, reproduce or distribute the Software without infringement; and (b) where you are the grantor of the rights, (i) claims of patents that are now or in future owned by or assigned to you and (ii) that cover the subject matter contained in your Derivatives, taken alone or in combination with the Software.
**“Compiled Code”** means any compiled, binary, machine readable or executable version of the Source Code.
**“Contributor”** means any person or entity that creates or contributes to the creation of Derivatives.
**“Derivatives”** means any addition to, deletion from and/or change to the substance, structure of the Software, any previous Derivatives, the combination of the Derivatives and the Software and/or any respective portions thereof.
**“Source Code”** means the human readable code that is suitable for making modifications but excluding any Compiled Code.
**“Software”** means the software and associated documentation files which XMOS makes available and which contain a notice identifying the software as original XMOS software and referring to the software being subject to the terms of this XMOS Public Licence.
This Licence refers to XMOS Software and does not relate to any XMOS hardware or devices which are protected by intellectual property rights (including patent and trade marks) which may be sold to you under a separate agreement.
**2. Licence**
**Permitted Uses, Conditions and Restrictions.** Subject to the conditions below, XMOS grants you a worldwide, royalty free, non-exclusive licence, to the extent of any Patent Rights to do the following:
2.1 **Unmodified Software.** You may use, copy, display, publish, distribute and make available unmodified copies of the Software:
2.1.1 for personal or academic, non-commercial purposes; or
2.1.2 for commercial purposes provided the Software is at all times used on a device designed, licensed or developed by XMOS and, provided that in each instance (2.1.1 and 2.1.2):
(a) you must retain and reproduce in all copies of the Software the copyright and proprietary notices and disclaimers of XMOS as they appear in the Software, and keep intact all notices and disclaimers in the Software files that refer to this Licence; and
(b) you must include a copy of this Licence with every copy of the Software and documentation you publish, distribute and make available and you may not offer or impose any terms on such Software that alter or restrict this Licence or the intent of such Licence, except as permitted below (Additional Terms).
The licence above does not include any Compiled Code which XMOS may make available under a separate support and licence agreement.
2.2 **Derivatives.** You may create and modify Derivatives and use, copy, display, publish, distribute and make available Derivatives:
2.2.1 for personal or academic, non-commercial purposes; or
2.2.2 for commercial purposes, provided the Derivatives are at all times used on a device designed, licensed or developed by XMOS and, provided that in each instance (2.2.1 and 2.2.2):
(a) you must comply with the terms of clause 2.1 with respect to the Derivatives;
(b) you must copy (to the extent it doesnt already exist) the notice below in each file of the Derivatives, and ensure all the modified files carry prominent notices stating that you have changed the files and the date of any change; and
(c) if you sublicence, distribute or otherwise make the Software and/or the Derivatives available for commercial purposes, you must provide that the Software and Derivatives are at all times used on a device designed, licensed or developed by XMOS.
Without limitation to these terms and clause 3 below, the Source Code and Compiled Code to your Derivatives may at your discretion (but without obligation) be released, copied, displayed, published, distributed and made available; and if you elect to do so, it must be under the terms of this Licence including the terms of the licence at clauses 2.2.1, 2.2.2 and clause 3 below.
2.3 **Distribution of Executable Versions.** If you distribute or make available Derivatives, you must include a prominent notice in the code itself as well as in all related documentation, stating that the Source Code of the Software from which the Derivatives are based is available under the terms of this Licence, with information on how and where to obtain such Source Code.
**3. Your Grant of Rights.** In consideration and as a condition to this Licence, you grant to any person or entity receiving or distributing any Derivatives, a non-exclusive, royalty free, perpetual, irrevocable license under your Applicable Patent Rights and all other intellectual property rights owned or controlled by you, to use, copy, display, publish, distribute and make available your Derivatives of the same scope and extent as XMOSs licence under clause 2.2 above.
**4. Combined Products.** You may create a combined product by combining Software, Derivatives and other code not covered by this Licence as a single application or product. In such instance, you must comply with the requirements of this Licence for any portion of the Software and/or Derivatives.
**5. Additional Terms.** You may choose to offer, and to charge a fee for, warranty, support, indemnity or liability obligations and/or other rights consistent with the term of this Licence (“Additional Terms”) to any legitimate recipients of the Software and/or Derivatives. The terms on which you provide such Additional Terms are on your sole responsibility and you shall indemnify, defend and hold XMOS harmless against any claims asserted against XMOS.
**6. New Versions.** XMOS may publish revised and/or new versions of this Licence from time to time to accommodate changes to the Licence terms, new versions, updates and bug fixes of the Software. Each version will be given a distinguishing version number. Once Software has been published under a particular version of this Licence, you may continue to use it under the terms of that version. You may also choose to use the latest version of the Software under any subsequent version published by XMOS. Only XMOS shall have the right to modify these terms.
**7. IPR and Ownership**
Any rights, including all intellectual property rights and all trademarks not expressly granted herein are reserved in full by the authors or copyright holders. Any requests for additional permissions by XMOS including any rights to use XMOS trademarks, should be made (without obligation) to XMOS at **support@xmos.com**
Nothing herein shall limit any rights that XMOS is otherwise entitled to under the doctrines of patent exhaustion, implied license, or legal estoppel. Neither the name of the authors, the copyright holders or any contributors may be used to endorse or promote any Derivatives from this Software without specific written permission. Any attempt to deal with the Software which does not comply with this Licence shall be void and shall automatically terminate any rights granted under this licence (including any licence of any intellectual property rights granted herein).
Subject to the licences granted under this Licence any Contributor retains all rights, title and interest in and to any Derivatives made by Contributor subject to the underlying rights of XMOS in the Software. XMOS shall retain all rights, title and interest in the Software and any Derivatives made by XMOS (“XMOS Derivatives”). XMOS Derivatives will not automatically be subject to this Licence and XMOS shall be entitled to licence such rights on any terms (without obligation) as it sees fit.
**8. Termination**
8.1 This Licence will automatically terminate immediately, without notice to you, if:
(a) you fail to comply with the terms of this Licence; and/or
(b) you directly or indirectly commence any action for patent or intellectual property right infringement against XMOS, or any parent, group, affiliate or subsidiary of XMOS; provided XMOS did not first commence an action or patent infringement against you in that instance; and/or
(c) the terms of this Licence are held by any court of competent jurisdiction to be unenforceable in whole or in part.
**9. Critical Applications.** Unless XMOS has agreed in writing with you an agreement specifically governing use of the Goods in military, aerospace, automotive or medically related functions (collectively and individually hereinafter referred to as "Special Use"), any permitted use of the Software excludes Special Use. Notwithstanding any agreement between XMOS and you for Special Use, Special Use shall be at your own risk, and you shall fully indemnify XMOS against any damages, losses, costs and claims (direct and indirect) arising out of any Special Use.
**10. NO WARRANTY OR SUPPORT.** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL XMOS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, WARRANTY, CIVIL TORT (INCLUDING NEGLIGENCE), PRODUCTS LIABILITY OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE INCLUDING GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES EVEN IF SUCH PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES AND NOT WITHSTANDING THE FAILURE OF ESSENTIAL PURPOSE. IN SOME JURISDICTIONS PARTIES ARE UNABLE TO LIMIT LIABILTY IN THIS WAY, IF THIS APPLIES TO YOUR JURISDICTION THIS LIABILITY CLAUSE ABOVE MAY NOT APPLY. NOTWITHSTANDING THE ABOVE, IN NO EVENT SHALL XMOSs TOTAL LIABILITY TO YOU FOR ALL DAMAGES, LOSS OR OTHERWISE EXCEED $50.
**11. Governing Law and Jurisdiction.** This Licence constitutes the entire agreement between the parties with respect to the subject matter hereof. The Licence shall be governed by the laws of England and the conflict of laws and UN Convention on Contracts for the International Sale of Goods, shall not apply.

View File

@@ -1 +0,0 @@
SOURCE_INCLUDE_DIRS=../lib_xua/host/xmosdfu

View File

@@ -5,10 +5,8 @@ TARGET = xk-audio-216-mc.xn
# The flags passed to xcc when building the application
XCC_FLAGS = -fcomment-asm -Xmapper --map -Xmapper MAPFILE -O3 -report -save-temps \
-g -Wno-unused-function -Wno-timing -DXUD_SERIES_SUPPORT=XUD_X200_SERIES \
-DXUD_CORE_CLOCK=600 -DUSB_TILE=tile[1] -fxscope
-DXUD_CORE_CLOCK=600 -DUSB_TILE=tile[1] -fxscope -DUAC_FORCE_FEEDBACK_EP=0
#-DSDA_HIGH=2 -DSCL_HIGH=1 -fxscope
# The USED_MODULES variable lists other module used by the application. These
# modules will extend the SOURCE_DIRS, INCLUDE_DIRS and LIB_DIRS variables.
# Modules are expected to be in the directory above the BASE_DIR directory.

View File

@@ -1,2 +1,3 @@
XMOSNEWSTYLE=1
SOURCE_INCLUDE_DIRS=../../src
XMOSNEWSTYLE=2
SOURCE_INCLUDE_DIRS=../../src
SPHINX_MASTER_DOC=AN00246_xua_example

View File

@@ -3,11 +3,11 @@
/* A very simple *example* of a USB audio application (and as such is un-verified for production)
*
* It uses the main blocks from the lib_xua
* It uses the main blocks from the lib_xua
*
* - 2 in/ 2 out I2S only
* - No DFU
* - I2S only
* - I2S only
*
*/
@@ -31,7 +31,7 @@ in port p_for_mclk_count = PORT_MCLK_COUNT; /* Extra port for count
in port p_mclk_in_usb = PORT_MCLK_IN_USB; /* Extra master clock input for the USB tile */
/* Clock-block declarations */
clock clk_audio_bclk = on tile[0]: XS1_CLKBLK_4; /* Bit clock */
clock clk_audio_bclk = on tile[0]: XS1_CLKBLK_4; /* Bit clock */
clock clk_audio_mclk = on tile[0]: XS1_CLKBLK_5; /* Master clock */
clock clk_audio_mclk_usb = on tile[1]: XS1_CLKBLK_1; /* Master clock for USB tile */
@@ -51,17 +51,17 @@ int main()
/* Channel for audio data between buffering cores and AudioHub/IO core */
chan c_aud;
/* Channel for communicating control messages from EP0 to the rest of the device (via the buffering cores) */
chan c_aud_ctl;
par
{
/* Low level USB device layer core */
/* Low level USB device layer core */
on tile[1]: XUD_Main(c_ep_out, 2, c_ep_in, 2,
c_sof, epTypeTableOut, epTypeTableIn,
c_sof, epTypeTableOut, epTypeTableIn,
XUD_SPEED_HS, XUD_PWR_SELF);
/* Endpoint 0 core from lib_xua */
/* Note, since we are not using many features we pass in null for quite a few params.. */
on tile[1]: XUA_Endpoint0(c_ep_out[0], c_ep_in[0], c_aud_ctl, null, null, null, null);
@@ -69,7 +69,7 @@ int main()
/* Buffering cores - handles audio data to/from EP's and gives/gets data to/from the audio I/O core */
/* Note, this spawns two cores */
on tile[1]: {
/* Connect master-clock clock-block to clock-block pin */
set_clock_src(clk_audio_mclk_usb, p_mclk_in_usb); /* Clock clock-block from mclk pin */
set_port_clock(p_for_mclk_count, clk_audio_mclk_usb); /* Clock the "count" port from the clock block */
@@ -82,7 +82,7 @@ int main()
/* AudioHub/IO core does most of the audio IO i.e. I2S (also serves as a hub for all audio) */
on tile[0]: XUA_AudioHub(c_aud, clk_audio_mclk, clk_audio_bclk, p_mclk_in, p_lrclk, p_bclk, p_i2s_dac, p_i2s_adc);
}
return 0;
}

View File

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

View File

@@ -50,7 +50,7 @@ void AudioHwConfig2(unsigned samFreq, unsigned mClk, unsigned dsdMode, unsigned
delay_microseconds(20000);
/* Take ADC out of reset */
gpioVal |= P_GPIO_ADC_RST_N;
gpioVal |= P_GPIO_ADC_RST_N;
p_gpio <: gpioVal;
/* Configure ADC for I2S slave mode via I2C */
@@ -58,7 +58,7 @@ void AudioHwConfig2(unsigned samFreq, unsigned mClk, unsigned dsdMode, unsigned
dif = 0x01; /* I2S */
mode = 0x03; /* Slave mode all speeds */
/* Reg 0x01: (GCTL) Global Mode Control Register
/* Reg 0x01: (GCTL) Global Mode Control Register
* Bit[7]: CP-EN: Manages control-port mode
* Bit[6]: CLKMODE: Setting puts part in 384x mode
* Bit[5:4]: MDIV[1:0]: Set to 01 for /2
@@ -91,7 +91,7 @@ void AudioHwConfig2(unsigned samFreq, unsigned mClk, unsigned dsdMode, unsigned
* bit[0] : Power Down (PDN) : Powered down
*/
DAC_REGWRITE(CS4384_MODE_CTRL, 0b11000001);
/* PCM Control (Address: 0x03) */
/* bit[7:4] : Digital Interface Format (DIF) : 0b0001 for I2S up to 24bit
* bit[3:2] : Reserved

View File

@@ -1,7 +1,7 @@
// Copyright 2017-2021 XMOS LIMITED.
// This Software is subject to the terms of the XMOS Public Licence: Version 1.
#ifndef _XUA_CONF_H_
#ifndef _XUA_CONF_H_
#define _XUA_CONF_H_
#define NUM_USB_CHAN_OUT 2 /* Number of channels from host to device */
@@ -19,7 +19,7 @@
#define VENDOR_ID 0x20B1
#define PRODUCT_STR_A2 "XUA Example"
#define PRODUCT_STR_A1 "XUA Example"
#define PID_AUDIO_1 1
#define PID_AUDIO_1 1
#define PID_AUDIO_2 2
#define XUA_DFU_EN 0 /* Disable DFU (for simplicity of example */
#define MIC_DUAL_ENABLED 0 // Use multi-threaded design

View File

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

View File

@@ -1,2 +1,3 @@
XMOSNEWSTYLE=1
SOURCE_INCLUDE_DIRS=../../src
XMOSNEWSTYLE=2
SOURCE_INCLUDE_DIRS=../../src
SPHINX_MASTER_DOC=AN00247_xua_example_spdif_tx

View File

@@ -3,7 +3,7 @@
/* A very simple *example* of a USB audio application (and as such is un-verified for production)
*
* It uses the main blocks from the lib_xua
* It uses the main blocks from the lib_xua
*
* - S/PDIF output only
* - No DFU
@@ -51,7 +51,7 @@ int main()
/* Channel for audio data between buffering cores and AudioHub/IO core */
chan c_aud;
/* Channel for communicating control messages from EP0 to the rest of the device (via the buffering cores) */
chan c_aud_ctl;
@@ -60,9 +60,9 @@ int main()
par
{
/* Low level USB device layer core */
/* Low level USB device layer core */
on tile[1]: XUD_Main(c_ep_out, 2, c_ep_in, 2, c_sof, epTypeTableOut, epTypeTableIn, XUD_SPEED_HS, XUD_PWR_SELF);
/* Endpoint 0 core from lib_xua */
/* Note, since we are not using many features we pass in null for quite a few params.. */
on tile[1]: XUA_Endpoint0(c_ep_out[0], c_ep_in[0], c_aud_ctl, null, null, null, null);
@@ -70,7 +70,7 @@ int main()
/* Buffering cores - handles audio data to/from EP's and gives/gets data to/from the audio I/O core */
/* Note, this spawns two cores */
on tile[1]: {
/* Connect master-clock clock-block to clock-block pin */
set_clock_src(clk_audio_mclk_usb, p_mclk_in_usb); /* Clock clock-block from mclk pin */
set_port_clock(p_for_mclk_count, clk_audio_mclk_usb); /* Clock the "count" port from the clock block */
@@ -78,28 +78,28 @@ int main()
XUA_Buffer(c_ep_out[1], c_ep_in[1], c_sof, c_aud_ctl, p_for_mclk_count, c_aud);
}
/* AudioHub() (I2S) and S/SPDIF Tx are on the same tile */
on tile[0]: {
/* Setup S/PDIF tx port from clock etc - note we do this before par to avoid parallel usage */
spdif_tx_port_config(p_spdif_tx, clk_spdif_tx, p_mclk_in, 7);
par
{
while(1)
{
/* Run the S/PDIF transmitter task */
spdif_tx(p_spdif_tx, c_spdif_tx);
spdif_tx(p_spdif_tx, c_spdif_tx);
}
/* AudioHub/IO core does most of the audio IO i.e. I2S (also serves as a hub for all audio) */
/* Note, since we are not using I2S we pass in null for LR and Bit clock ports and the I2S dataline ports */
XUA_AudioHub(c_aud, clk_audio_mclk, null, p_mclk_in, null, null, null, null, c_spdif_tx);
}
}
}
return 0;
}

View File

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

View File

@@ -1,7 +1,7 @@
// Copyright 2017-2021 XMOS LIMITED.
// This Software is subject to the terms of the XMOS Public Licence: Version 1.
#ifndef _XUA_CONF_H_
#ifndef _XUA_CONF_H_
#define _XUA_CONF_H_
#define NUM_USB_CHAN_OUT 2

View File

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

View File

@@ -1,2 +1,3 @@
XMOSNEWSTYLE=1
SOURCE_INCLUDE_DIRS=../../src
XMOSNEWSTYLE=2
SOURCE_INCLUDE_DIRS=../../src
SPHINX_MASTER_DOC=AN00248_xua_example_pdm_mics

View File

@@ -3,7 +3,7 @@
/* A very simple *example* of a USB audio application (and as such is un-verified for production)
*
* It uses the main blocks from the lib_xua with the addition of PDM mic support using lib_mic_array
* It uses the main blocks from the lib_xua with the addition of PDM mic support using lib_mic_array
*
* - No DFU
*
@@ -24,7 +24,7 @@ in port p_pdm_mclk = PORT_PDM_MCLK; /* Master clock f
in buffered port:32 p_pdm_mics = PORT_PDM_DATA; /* Port for PDM mic data */
clock clk_pdm = on tile[0]: XS1_CLKBLK_1; /* Clock-block for PDM mics */
clock clk_pdm = on tile[0]: XS1_CLKBLK_1; /* Clock-block for PDM mics */
/* Lib_xua port declarations. Note, the defines come from the xn file */
@@ -52,7 +52,7 @@ int main()
/* Channel for audio data between buffering cores and AudioHub/IO core */
chan c_aud;
/* Channel for communicating control messages from EP0 to the rest of the device (via the buffering cores) */
chan c_aud_ctl;
@@ -64,26 +64,26 @@ int main()
par
{
/* Low level USB device layer core */
/* Low level USB device layer core */
on tile[1]: XUD_Main(c_ep_out, 2, c_ep_in, 2, c_sof, epTypeTableOut, epTypeTableIn, XUD_SPEED_HS, XUD_PWR_BUS);
/* Endpoint 0 core from lib_xua */
/* Note, since we are not using many features we pass in null for quite a few params.. */
on tile[1]: XUA_Endpoint0(c_ep_out[0], c_ep_in[0], c_aud_ctl, null, null, null, null);
on tile[1]:
on tile[1]:
{
/* Connect master-clock clock-block to clock-block pin */
set_clock_src(clk_audio_mclk, p_mclk_in); /* Clock clock-block from mclk pin */
set_port_clock(p_for_mclk_count, clk_audio_mclk); /* Clock the "count" port from the clock block */
/* Note, AudioHub() will start the clock */
par
{
/* Buffering task - handles audio data to/from EP's and gives/gets data to/from the audio I/O core */
/* Note, this spawns two cores */
XUA_Buffer(c_ep_out[1], c_ep_in[1], c_sof, c_aud_ctl, p_for_mclk_count, c_aud);
/* AudioHub/IO core does most of the audio IO i.e. I2S (also serves as a hub for all audio) */
/* Note, since we are not using I2S we pass in null for LR and Bit clock ports and the I2S dataline ports */
XUA_AudioHub(c_aud, clk_audio_mclk, null, p_mclk_in, null, null, null, null, c_mic_pcm);
@@ -105,7 +105,7 @@ int main()
{
/* PDM receive I/O task */
mic_array_pdm_rx(p_pdm_mics, c_4x_pdm_mic_0, c_4x_pdm_mic_1);
/* Run two decimator tasks for 8 mics */
mic_array_decimate_to_pcm_4ch(c_4x_pdm_mic_0, c_ds_output[0], MIC_ARRAY_NO_INTERNAL_CHANS);
mic_array_decimate_to_pcm_4ch(c_4x_pdm_mic_1, c_ds_output[1], MIC_ARRAY_NO_INTERNAL_CHANS);
@@ -114,7 +114,7 @@ int main()
}
}
}
return 0;
}

View File

@@ -16,7 +16,7 @@ void AudioHwInit()
/* DAC in reset */
p_gpio <: 0;
return;
return;
}
/* Configures the external audio hardware for the required sample frequency */

View File

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

View File

@@ -1,7 +1,7 @@
// Copyright 2017-2021 XMOS LIMITED.
// This Software is subject to the terms of the XMOS Public Licence: Version 1.
#ifndef _XUA_CONF_H_
#ifndef _XUA_CONF_H_
#define _XUA_CONF_H_
#define NUM_USB_CHAN_OUT 0

View File

@@ -1,7 +1,5 @@
# Copyright (c) 2016, XMOS Ltd, All rights reserved
TARGET = xk-audio-216-mc.xn
USED_MODULES = lib_xua \
module_i2c_shared module_i2c_single_port lib_logging
USED_MODULES = lib_xua lib_i2c lib_logging
BUILD_FLAGS = -O0 -g -lflash -DXUD_SERIES_SUPPORT=4 -DXUD_CORE_CLOCK=600 -fxscope -save-temps -march=xs2a -DUSB_TILE=tile[1]

View File

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

View File

@@ -81,7 +81,7 @@ buffered out port:32 p_bclk = PORT_I2S_BCLK; /* I2S L/R-clock */
in port p_mclk_in = PORT_MCLK_IN;
/* Clock-block declarations */
clock clk_audio_bclk = on tile[AUDIO_IO_TILE]: XS1_CLKBLK_1; /* Bit clock */
clock clk_audio_bclk = on tile[AUDIO_IO_TILE]: XS1_CLKBLK_1; /* Bit clock */
clock clk_audio_mclk = on tile[AUDIO_IO_TILE]: XS1_CLKBLK_2; /* Master clock */
#ifdef SIMULATION
@@ -189,14 +189,14 @@ void checker(chanend c_checker, int disable)
#ifdef SIMULATION
out port p_mclk_gen = on tile[AUDIO_IO_TILE] : XS1_PORT_1A;
out port p_mclk_gen = on tile[AUDIO_IO_TILE] : XS1_PORT_1A;
clock clk_audio_mclk_gen = on tile[AUDIO_IO_TILE] : XS1_CLKBLK_3;
void master_mode_clk_setup(void);
#if CODEC_MASTER
out port p_bclk_gen = on tile[AUDIO_IO_TILE] : XS1_PORT_1B;
out port p_bclk_gen = on tile[AUDIO_IO_TILE] : XS1_PORT_1B;
clock clk_audio_bclk_gen = on tile[AUDIO_IO_TILE] : XS1_CLKBLK_4;
out port p_lrclk_gen = on tile[AUDIO_IO_TILE] : XS1_PORT_1C;
out port p_lrclk_gen = on tile[AUDIO_IO_TILE] : XS1_PORT_1C;
clock clk_audio_lrclk_gen = on tile[AUDIO_IO_TILE] : XS1_CLKBLK_5;
void slave_mode_clk_setup(const unsigned samFreq, const unsigned chans_per_frame);
#endif
@@ -214,11 +214,11 @@ int main(void)
chan c_checker;
chan c_out;
par
par
{
on tile[AUDIO_IO_TILE]:
{
par
on tile[AUDIO_IO_TILE]:
{
par
{
XUA_AudioHub(c_out, clk_audio_mclk, clk_audio_bclk, p_mclk_in, p_lrclk, p_bclk, p_i2s_dac, p_i2s_adc);
generator(c_checker, c_out);

View File

@@ -22,7 +22,7 @@ void AudioHwInit()
extern clock clk_audio_mclk_gen;
extern out port p_mclk_gen;
extern out port p_mclk_gen;
void master_mode_clk_setup(void)
{
configure_clock_rate(clk_audio_mclk_gen, 25, 1); // Slighly faster than typical MCLK of 24.576MHz
@@ -35,17 +35,17 @@ void master_mode_clk_setup(void)
#if CODEC_MASTER
extern out port p_bclk_gen;
extern out port p_bclk_gen;
extern clock clk_audio_bclk_gen;
extern out port p_lrclk_gen;
extern out port p_lrclk_gen;
extern clock clk_audio_lrclk_gen;
void slave_mode_clk_setup(const unsigned samFreq, const unsigned chans_per_frame){
const unsigned data_bits = 32;
const unsigned mclk_freq = 24576000;
const unsigned mclk_bclk_ratio = mclk_freq / (chans_per_frame * samFreq * data_bits);
const unsigned bclk_lrclk_ratio = (chans_per_frame * data_bits); // 48.828Hz LRCLK
const unsigned mclk_bclk_ratio = mclk_freq / (chans_per_frame * samFreq * data_bits);
const unsigned bclk_lrclk_ratio = (chans_per_frame * data_bits); // 48.828Hz LRCLK
//bclk
configure_clock_src_divide(clk_audio_bclk_gen, p_mclk_gen, mclk_bclk_ratio/2);

View File

@@ -1,4 +1,4 @@
// Copyright 2016-2021 XMOS LIMITED.
// Copyright 2016-2022 XMOS LIMITED.
// This Software is subject to the terms of the XMOS Public Licence: Version 1.
#ifdef HARDWARE
@@ -8,7 +8,7 @@
#include "devicedefines.h"
#include <platform.h>
#include "gpio_access.h"
#include "i2c_shared.h"
#include "i2c.h"
#include "cs4384.h"
#include "cs5368.h"
#include "cs2100.h"
@@ -25,16 +25,10 @@
on tile[0] : out port p_gpio = XS1_PORT_8C;
#ifndef IAP
/* If IAP not enabled, i2c ports not declared - still needs for DAC config */
on tile [0] : struct r_i2c r_i2c = {XS1_PORT_4A};
#else
extern struct r_i2c r_i2c;
#endif
port p_i2c = on tile[0]:PORT_I2C;
#define DAC_REGWRITE(reg, val) {data[0] = val; i2c_shared_master_write_reg(r_i2c, CS4384_I2C_ADDR, reg, data, 1);}
#define DAC_REGREAD(reg, val) {i2c_shared_master_read_reg(r_i2c, CS4384_I2C_ADDR, reg, val, 1);}
#define ADC_REGWRITE(reg, val) {data[0] = val; i2c_shared_master_write_reg(r_i2c, CS5368_I2C_ADDR, reg, data, 1);}
#define DAC_REGWRITE(reg, val) {result = i2c.write_reg(CS4384_I2C_ADDR, reg, val);}
#define ADC_REGWRITE(reg, val) {result = i2c.write_reg(CS5368_I2C_ADDR, reg, val);}
#ifdef USE_FRACTIONAL_N
@@ -45,14 +39,15 @@ extern struct r_i2c r_i2c;
#define PLL_SYNC_FREQ 300
#endif
#define CS2100_REGREAD(reg, data) {data[0] = 0xAA; i2c_master_read_reg(CS2100_I2C_DEVICE_ADDR, reg, data, 1, r_i2c);}
#define CS2100_REGREAD_ASSERT(reg, data, expected) {data[0] = 0xAA; i2c_master_read_reg(CS2100_I2C_DEVICE_ADDR, reg, data, 1, r_i2c); assert(data[0] == expected);}
#define CS2100_REGWRITE(reg, val) {data[0] = val; i2c_master_write_reg(CS2100_I2C_DEVICE_ADDR, reg, data, 1, r_i2c);}
#define CS2100_REGREAD(reg, data) {data[0] = i2c.read_reg(CS2100_I2C_DEVICE_ADDR, reg, result);}
#define CS2100_REGREAD_ASSERT(reg, data, expected) {data[0] = i2c.read_reg(CS2100_I2C_DEVICE_ADDR, reg, result); assert(data[0] == expected);}
#define CS2100_REGWRITE(reg, val) {result = i2c.write_reg(CS2100_I2C_DEVICE_ADDR, reg, val);}
/* Init of CS2100 */
void PllInit(void)
void PllInit(client interface i2c_master_if i2c)
{
unsigned char data[1] = {0};
i2c_regop_res_t result;
#if XCORE_200_MC_AUDIO_HW_VERSION < 2
/* Enable init */
@@ -73,12 +68,15 @@ void PllInit(void)
CS2100_REGREAD_ASSERT(CS2100_GLOBAL_CONFIG, data, 0x01);
CS2100_REGREAD_ASSERT(CS2100_FUNC_CONFIG_1, data, 0x08);
CS2100_REGREAD_ASSERT(CS2100_FUNC_CONFIG_2, data, 0x00);
i2c.shutdown();
}
/* Setup PLL multiplier */
void PllMult(unsigned output, unsigned ref)
void PllMult(unsigned output, unsigned ref, client interface i2c_master_if i2c)
{
unsigned char data[1] = {0};
i2c_regop_res_t result;
/* PLL expects 12:20 format, convert output and ref to 12:20 */
/* Shift up the dividend by 12 to retain format... */
@@ -120,9 +118,6 @@ void AudioHwInit(chanend ?c_codec)
start_clock(clk_pll_sync);
#endif
/* Init the i2c module */
i2c_shared_master_init(r_i2c);
/* Assert reset to ADC and DAC */
set_gpio(P_GPIO_DAC_RST_N, 0);
set_gpio(P_GPIO_ADC_RST_N, 0);
@@ -143,7 +138,12 @@ void AudioHwInit(chanend ?c_codec)
set_gpio(P_GPIO_PLL_SEL, 1);
/* Initialise external PLL */
PllInit();
i2c_master_if i2c[1];
par
{
i2c_master_single_port(i2c, 1, p_i2c, 10, 0, 1, 0);
PllInit(i2c[0]);
}
#endif
#ifdef IAP
@@ -155,10 +155,11 @@ void AudioHwInit(chanend ?c_codec)
/* Configures the external audio hardware for the required sample frequency.
* See gpio.h for I2C helper functions and gpio access
*/
void AudioHwConfig(unsigned samFreq, unsigned mClk, chanend ?c_codec, unsigned dsdMode,
unsigned sampRes_DAC, unsigned sampRes_ADC)
void AudioHwConfig2(unsigned samFreq, unsigned mClk, chanend ?c_codec, unsigned dsdMode,
unsigned sampRes_DAC, unsigned sampRes_ADC, client interface i2c_master_if i2c)
{
unsigned char data[1] = {0};
unsigned char data[1] = {0};
i2c_regop_res_t result;
/* Put ADC and DAC into reset */
set_gpio(P_GPIO_ADC_RST_N, 0);
@@ -167,7 +168,7 @@ void AudioHwConfig(unsigned samFreq, unsigned mClk, chanend ?c_codec, unsigned d
/* Set master clock select appropriately */
#if defined(USE_FRACTIONAL_N)
/* Configure external fractional-n clock multiplier for 300Hz -> mClkFreq */
PllMult(mClk, PLL_SYNC_FREQ);
PllMult(mClk, PLL_SYNC_FREQ, i2c);
#endif
/* Allow some time for mclk to lock and MCLK to stabilise - this is important to avoid glitches at start of stream */
{
@@ -365,8 +366,20 @@ void AudioHwConfig(unsigned samFreq, unsigned mClk, chanend ?c_codec, unsigned d
DAC_REGWRITE(CS4384_MODE_CTRL, 0b10000000);
}
#endif
i2c.shutdown();
return;
}
//:
void AudioHwConfig(unsigned samFreq, unsigned mClk, chanend ?c_codec, unsigned dsdMode,
unsigned sampRes_DAC, unsigned sampRes_ADC)
{
i2c_master_if i2c[1];
par
{
i2c_master_single_port(i2c, 1, p_i2c, 10, 0, 1, 0);
AudioHwConfig2(samFreq, mClk, c_codec, dsdMode, sampRes_DAC, sampRes_ADC, i2c[0]);
}
}
#endif

View File

@@ -1,860 +0,0 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<?fileVersion 4.0.0?><cproject storage_type_id="org.eclipse.cdt.core.XmlProjectDescriptionStorage">
<storageModule moduleId="org.eclipse.cdt.core.settings">
<cconfiguration id="com.xmos.cdt.toolchain.1285928753">
<storageModule buildSystemId="org.eclipse.cdt.managedbuilder.core.configurationDataProvider" id="com.xmos.cdt.toolchain.1285928753" moduleId="org.eclipse.cdt.core.settings" name="Default">
<externalSettings/>
<extensions>
<extension id="com.xmos.cdt.core.XdeErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
<extension id="org.eclipse.cdt.core.GCCErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
<extension id="org.eclipse.cdt.core.GNU_ELF" point="org.eclipse.cdt.core.BinaryParser"/>
<extension id="com.xmos.cdt.core.XEBinaryParser" point="org.eclipse.cdt.core.BinaryParser"/>
</extensions>
</storageModule>
<storageModule moduleId="cdtBuildSystem" version="4.0.0">
<configuration buildProperties="" description="" id="com.xmos.cdt.toolchain.1285928753" name="Default" parent="org.eclipse.cdt.build.core.emptycfg">
<folderInfo id="com.xmos.cdt.toolchain.1285928753.790908561" name="/" resourcePath="">
<toolChain id="com.xmos.cdt.toolchain.1969897956" name="com.xmos.cdt.toolchain" superClass="com.xmos.cdt.toolchain">
<targetPlatform archList="all" binaryParser="com.xmos.cdt.core.XEBinaryParser;org.eclipse.cdt.core.GNU_ELF" id="com.xmos.cdt.core.platform.1615568037" isAbstract="false" osList="linux,win32,macosx" superClass="com.xmos.cdt.core.platform"/>
<builder arguments="-f .makefile" id="com.xmos.cdt.builder.base.45159417" keepEnvironmentInBuildfile="false" managedBuildOn="false" superClass="com.xmos.cdt.builder.base">
<outputEntries>
<entry flags="VALUE_WORKSPACE_PATH" kind="outputPath" name="bin"/>
</outputEntries>
</builder>
<tool id="com.xmos.cdt.xc.compiler.404499215" name="com.xmos.cdt.xc.compiler" superClass="com.xmos.cdt.xc.compiler">
<option id="com.xmos.xc.compiler.option.defined.symbols.1492092903" name="com.xmos.xc.compiler.option.defined.symbols" superClass="com.xmos.xc.compiler.option.defined.symbols" valueType="definedSymbols">
<listOptionValue builtIn="false" value="__XC__=1"/>
<listOptionValue builtIn="false" value="__llvm__=1"/>
<listOptionValue builtIn="false" value="__ATOMIC_RELAXED=0"/>
<listOptionValue builtIn="false" value="__ATOMIC_CONSUME=1"/>
<listOptionValue builtIn="false" value="__ATOMIC_ACQUIRE=2"/>
<listOptionValue builtIn="false" value="__ATOMIC_RELEASE=3"/>
<listOptionValue builtIn="false" value="__ATOMIC_ACQ_REL=4"/>
<listOptionValue builtIn="false" value="__ATOMIC_SEQ_CST=5"/>
<listOptionValue builtIn="false" value="__PRAGMA_REDEFINE_EXTNAME=1"/>
<listOptionValue builtIn="false" value="__VERSION__=&quot;4.2.1"/>
<listOptionValue builtIn="false" value="__CONSTANT_CFSTRINGS__=1"/>
<listOptionValue builtIn="false" value="__ORDER_LITTLE_ENDIAN__=1234"/>
<listOptionValue builtIn="false" value="__ORDER_BIG_ENDIAN__=4321"/>
<listOptionValue builtIn="false" value="__ORDER_PDP_ENDIAN__=3412"/>
<listOptionValue builtIn="false" value="__BYTE_ORDER__=__ORDER_LITTLE_ENDIAN__"/>
<listOptionValue builtIn="false" value="__LITTLE_ENDIAN__=1"/>
<listOptionValue builtIn="false" value="_ILP32=1"/>
<listOptionValue builtIn="false" value="__ILP32__=1"/>
<listOptionValue builtIn="false" value="__CHAR_BIT__=8"/>
<listOptionValue builtIn="false" value="__SCHAR_MAX__=127"/>
<listOptionValue builtIn="false" value="__SHRT_MAX__=32767"/>
<listOptionValue builtIn="false" value="__INT_MAX__=2147483647"/>
<listOptionValue builtIn="false" value="__LONG_MAX__=2147483647L"/>
<listOptionValue builtIn="false" value="__LONG_LONG_MAX__=9223372036854775807LL"/>
<listOptionValue builtIn="false" value="__WCHAR_MAX__=255"/>
<listOptionValue builtIn="false" value="__INTMAX_MAX__=9223372036854775807LL"/>
<listOptionValue builtIn="false" value="__SIZE_MAX__=4294967295U"/>
<listOptionValue builtIn="false" value="__SIZEOF_DOUBLE__=8"/>
<listOptionValue builtIn="false" value="__SIZEOF_FLOAT__=4"/>
<listOptionValue builtIn="false" value="__SIZEOF_INT__=4"/>
<listOptionValue builtIn="false" value="__SIZEOF_LONG__=4"/>
<listOptionValue builtIn="false" value="__SIZEOF_LONG_DOUBLE__=8"/>
<listOptionValue builtIn="false" value="__SIZEOF_LONG_LONG__=8"/>
<listOptionValue builtIn="false" value="__SIZEOF_POINTER__=4"/>
<listOptionValue builtIn="false" value="__SIZEOF_SHORT__=2"/>
<listOptionValue builtIn="false" value="__SIZEOF_PTRDIFF_T__=4"/>
<listOptionValue builtIn="false" value="__SIZEOF_SIZE_T__=4"/>
<listOptionValue builtIn="false" value="__SIZEOF_WCHAR_T__=1"/>
<listOptionValue builtIn="false" value="__SIZEOF_WINT_T__=4"/>
<listOptionValue builtIn="false" value="__INTMAX_TYPE__=long"/>
<listOptionValue builtIn="false" value="__INTMAX_FMTd__=&quot;lld&quot;"/>
<listOptionValue builtIn="false" value="__INTMAX_FMTi__=&quot;lli&quot;"/>
<listOptionValue builtIn="false" value="__INTMAX_C_SUFFIX__=LL"/>
<listOptionValue builtIn="false" value="__UINTMAX_TYPE__=long"/>
<listOptionValue builtIn="false" value="__UINTMAX_FMTo__=&quot;llo&quot;"/>
<listOptionValue builtIn="false" value="__UINTMAX_FMTu__=&quot;llu&quot;"/>
<listOptionValue builtIn="false" value="__UINTMAX_FMTx__=&quot;llx&quot;"/>
<listOptionValue builtIn="false" value="__UINTMAX_FMTX__=&quot;llX&quot;"/>
<listOptionValue builtIn="false" value="__UINTMAX_C_SUFFIX__=ULL"/>
<listOptionValue builtIn="false" value="__INTMAX_WIDTH__=64"/>
<listOptionValue builtIn="false" value="__PTRDIFF_TYPE__=int"/>
<listOptionValue builtIn="false" value="__PTRDIFF_FMTd__=&quot;d&quot;"/>
<listOptionValue builtIn="false" value="__PTRDIFF_FMTi__=&quot;i&quot;"/>
<listOptionValue builtIn="false" value="__PTRDIFF_WIDTH__=32"/>
<listOptionValue builtIn="false" value="__INTPTR_TYPE__=int"/>
<listOptionValue builtIn="false" value="__INTPTR_FMTd__=&quot;d&quot;"/>
<listOptionValue builtIn="false" value="__INTPTR_FMTi__=&quot;i&quot;"/>
<listOptionValue builtIn="false" value="__INTPTR_WIDTH__=32"/>
<listOptionValue builtIn="false" value="__SIZE_TYPE__=unsigned"/>
<listOptionValue builtIn="false" value="__SIZE_FMTo__=&quot;o&quot;"/>
<listOptionValue builtIn="false" value="__SIZE_FMTu__=&quot;u&quot;"/>
<listOptionValue builtIn="false" value="__SIZE_FMTx__=&quot;x&quot;"/>
<listOptionValue builtIn="false" value="__SIZE_FMTX__=&quot;X&quot;"/>
<listOptionValue builtIn="false" value="__SIZE_WIDTH__=32"/>
<listOptionValue builtIn="false" value="__WCHAR_TYPE__=unsigned"/>
<listOptionValue builtIn="false" value="__WCHAR_WIDTH__=8"/>
<listOptionValue builtIn="false" value="__WINT_TYPE__=unsigned"/>
<listOptionValue builtIn="false" value="__WINT_WIDTH__=32"/>
<listOptionValue builtIn="false" value="__SIG_ATOMIC_WIDTH__=32"/>
<listOptionValue builtIn="false" value="__SIG_ATOMIC_MAX__=2147483647"/>
<listOptionValue builtIn="false" value="__CHAR16_TYPE__=unsigned"/>
<listOptionValue builtIn="false" value="__CHAR32_TYPE__=unsigned"/>
<listOptionValue builtIn="false" value="__FLT_DENORM_MIN__=1.40129846e-45F"/>
<listOptionValue builtIn="false" value="__FLT_HAS_DENORM__=1"/>
<listOptionValue builtIn="false" value="__FLT_DIG__=6"/>
<listOptionValue builtIn="false" value="__FLT_EPSILON__=1.19209290e-7F"/>
<listOptionValue builtIn="false" value="__FLT_HAS_INFINITY__=1"/>
<listOptionValue builtIn="false" value="__FLT_HAS_QUIET_NAN__=1"/>
<listOptionValue builtIn="false" value="__FLT_MANT_DIG__=24"/>
<listOptionValue builtIn="false" value="__FLT_MAX_10_EXP__=38"/>
<listOptionValue builtIn="false" value="__FLT_MAX_EXP__=128"/>
<listOptionValue builtIn="false" value="__FLT_MAX__=3.40282347e+38F"/>
<listOptionValue builtIn="false" value="__FLT_MIN_10_EXP__=(-37)"/>
<listOptionValue builtIn="false" value="__FLT_MIN_EXP__=(-125)"/>
<listOptionValue builtIn="false" value="__FLT_MIN__=1.17549435e-38F"/>
<listOptionValue builtIn="false" value="__DBL_DENORM_MIN__=4.9406564584124654e-324"/>
<listOptionValue builtIn="false" value="__DBL_HAS_DENORM__=1"/>
<listOptionValue builtIn="false" value="__DBL_DIG__=15"/>
<listOptionValue builtIn="false" value="__DBL_EPSILON__=2.2204460492503131e-16"/>
<listOptionValue builtIn="false" value="__DBL_HAS_INFINITY__=1"/>
<listOptionValue builtIn="false" value="__DBL_HAS_QUIET_NAN__=1"/>
<listOptionValue builtIn="false" value="__DBL_MANT_DIG__=53"/>
<listOptionValue builtIn="false" value="__DBL_MAX_10_EXP__=308"/>
<listOptionValue builtIn="false" value="__DBL_MAX_EXP__=1024"/>
<listOptionValue builtIn="false" value="__DBL_MAX__=1.7976931348623157e+308"/>
<listOptionValue builtIn="false" value="__DBL_MIN_10_EXP__=(-307)"/>
<listOptionValue builtIn="false" value="__DBL_MIN_EXP__=(-1021)"/>
<listOptionValue builtIn="false" value="__DBL_MIN__=2.2250738585072014e-308"/>
<listOptionValue builtIn="false" value="__LDBL_DENORM_MIN__=4.9406564584124654e-324L"/>
<listOptionValue builtIn="false" value="__LDBL_HAS_DENORM__=1"/>
<listOptionValue builtIn="false" value="__LDBL_DIG__=15"/>
<listOptionValue builtIn="false" value="__LDBL_EPSILON__=2.2204460492503131e-16L"/>
<listOptionValue builtIn="false" value="__LDBL_HAS_INFINITY__=1"/>
<listOptionValue builtIn="false" value="__LDBL_HAS_QUIET_NAN__=1"/>
<listOptionValue builtIn="false" value="__LDBL_MANT_DIG__=53"/>
<listOptionValue builtIn="false" value="__LDBL_MAX_10_EXP__=308"/>
<listOptionValue builtIn="false" value="__LDBL_MAX_EXP__=1024"/>
<listOptionValue builtIn="false" value="__LDBL_MAX__=1.7976931348623157e+308L"/>
<listOptionValue builtIn="false" value="__LDBL_MIN_10_EXP__=(-307)"/>
<listOptionValue builtIn="false" value="__LDBL_MIN_EXP__=(-1021)"/>
<listOptionValue builtIn="false" value="__LDBL_MIN__=2.2250738585072014e-308L"/>
<listOptionValue builtIn="false" value="__POINTER_WIDTH__=32"/>
<listOptionValue builtIn="false" value="__CHAR_UNSIGNED__=1"/>
<listOptionValue builtIn="false" value="__WCHAR_UNSIGNED__=1"/>
<listOptionValue builtIn="false" value="__WINT_UNSIGNED__=1"/>
<listOptionValue builtIn="false" value="__INT8_TYPE__=signed"/>
<listOptionValue builtIn="false" value="__INT8_FMTd__=&quot;hhd&quot;"/>
<listOptionValue builtIn="false" value="__INT8_FMTi__=&quot;hhi&quot;"/>
<listOptionValue builtIn="false" value="__INT8_C_SUFFIX__"/>
<listOptionValue builtIn="false" value="__INT16_TYPE__=short"/>
<listOptionValue builtIn="false" value="__INT16_FMTd__=&quot;hd&quot;"/>
<listOptionValue builtIn="false" value="__INT16_FMTi__=&quot;hi&quot;"/>
<listOptionValue builtIn="false" value="__INT16_C_SUFFIX__"/>
<listOptionValue builtIn="false" value="__INT32_TYPE__=int"/>
<listOptionValue builtIn="false" value="__INT32_FMTd__=&quot;d&quot;"/>
<listOptionValue builtIn="false" value="__INT32_FMTi__=&quot;i&quot;"/>
<listOptionValue builtIn="false" value="__INT32_C_SUFFIX__"/>
<listOptionValue builtIn="false" value="__INT64_TYPE__=long"/>
<listOptionValue builtIn="false" value="__INT64_FMTd__=&quot;lld&quot;"/>
<listOptionValue builtIn="false" value="__INT64_FMTi__=&quot;lli&quot;"/>
<listOptionValue builtIn="false" value="__INT64_C_SUFFIX__=LL"/>
<listOptionValue builtIn="false" value="__USER_LABEL_PREFIX__=_"/>
<listOptionValue builtIn="false" value="__FINITE_MATH_ONLY__=0"/>
<listOptionValue builtIn="false" value="__FLT_EVAL_METHOD__=0"/>
<listOptionValue builtIn="false" value="__FLT_RADIX__=2"/>
<listOptionValue builtIn="false" value="__DECIMAL_DIG__=17"/>
<listOptionValue builtIn="false" value="__xcore__=1"/>
<listOptionValue builtIn="false" value="__XS1B__=1"/>
<listOptionValue builtIn="false" value="__STDC_HOSTED__=1"/>
<listOptionValue builtIn="false" value="__STDC_UTF_16__=1"/>
<listOptionValue builtIn="false" value="__STDC_UTF_32__=1"/>
<listOptionValue builtIn="false" value="XCC_VERSION_YEAR=14"/>
<listOptionValue builtIn="false" value="XCC_VERSION_MONTH=3"/>
<listOptionValue builtIn="false" value="XCC_VERSION_MAJOR=1403"/>
<listOptionValue builtIn="false" value="XCC_VERSION_MINOR=2"/>
<listOptionValue builtIn="false" value="__XCC_HAVE_FLOAT__=1"/>
<listOptionValue builtIn="false" value="_XSCOPE_PROBES_INCLUDE_FILE=&quot;/var/folders/0l/8jd0xy095ps890m302j532580000h5/T//cc8JvR3b.h&quot;"/>
</option>
<option id="com.xmos.xc.compiler.option.include.paths.834699451" name="com.xmos.xc.compiler.option.include.paths" superClass="com.xmos.xc.compiler.option.include.paths" valueType="includePath">
<listOptionValue builtIn="false" value="&quot;${XMOS_TOOL_PATH}/target/include/xc&quot;"/>
<listOptionValue builtIn="false" value="&quot;${XMOS_TOOL_PATH}/target/include&quot;"/>
<listOptionValue builtIn="false" value="&quot;${XMOS_TOOL_PATH}/target/include/clang&quot;"/>
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/lib_logging/doc}&quot;"/>
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/lib_xud/doc/rst/images}&quot;"/>
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/lib_xud/src/user/client}&quot;"/>
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/lib_xud/src/user/class}&quot;"/>
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/lib_xud/src/core/included}&quot;"/>
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/lib_xud/src/core}&quot;"/>
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/lib_logging/doc/rst}&quot;"/>
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/lib_logging/src}&quot;"/>
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/lib_xud}&quot;"/>
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/lib_logging}&quot;"/>
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/lib_xud/src/user/control}&quot;"/>
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/lib_logging/api}&quot;"/>
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/lib_xud/doc/rst}&quot;"/>
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/lib_xud/api}&quot;"/>
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/lib_xud/src}&quot;"/>
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/lib_xud/doc}&quot;"/>
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/lib_xud/src/user}&quot;"/>
</option>
<inputType id="com.xmos.cdt.xc.compiler.input.2062798368" name="XC" superClass="com.xmos.cdt.xc.compiler.input"/>
</tool>
<tool id="com.xmos.cdt.c.compiler.1931691289" name="com.xmos.cdt.c.compiler" superClass="com.xmos.cdt.c.compiler">
<option id="com.xmos.c.compiler.option.defined.symbols.534062814" name="com.xmos.c.compiler.option.defined.symbols" superClass="com.xmos.c.compiler.option.defined.symbols" valueType="definedSymbols">
<listOptionValue builtIn="false" value="__llvm__=1"/>
<listOptionValue builtIn="false" value="__clang__=1"/>
<listOptionValue builtIn="false" value="__clang_major__=3"/>
<listOptionValue builtIn="false" value="__clang_minor__=6"/>
<listOptionValue builtIn="false" value="__clang_patchlevel__=0"/>
<listOptionValue builtIn="false" value="__clang_version__=&quot;3.6.0"/>
<listOptionValue builtIn="false" value="__GNUC_MINOR__=2"/>
<listOptionValue builtIn="false" value="__GNUC_PATCHLEVEL__=1"/>
<listOptionValue builtIn="false" value="__GNUC__=4"/>
<listOptionValue builtIn="false" value="__GXX_ABI_VERSION=1002"/>
<listOptionValue builtIn="false" value="__ATOMIC_RELAXED=0"/>
<listOptionValue builtIn="false" value="__ATOMIC_CONSUME=1"/>
<listOptionValue builtIn="false" value="__ATOMIC_ACQUIRE=2"/>
<listOptionValue builtIn="false" value="__ATOMIC_RELEASE=3"/>
<listOptionValue builtIn="false" value="__ATOMIC_ACQ_REL=4"/>
<listOptionValue builtIn="false" value="__ATOMIC_SEQ_CST=5"/>
<listOptionValue builtIn="false" value="__PRAGMA_REDEFINE_EXTNAME=1"/>
<listOptionValue builtIn="false" value="__VERSION__=&quot;4.2.1"/>
<listOptionValue builtIn="false" value="__CONSTANT_CFSTRINGS__=1"/>
<listOptionValue builtIn="false" value="__GXX_RTTI=1"/>
<listOptionValue builtIn="false" value="__ORDER_LITTLE_ENDIAN__=1234"/>
<listOptionValue builtIn="false" value="__ORDER_BIG_ENDIAN__=4321"/>
<listOptionValue builtIn="false" value="__ORDER_PDP_ENDIAN__=3412"/>
<listOptionValue builtIn="false" value="__BYTE_ORDER__=__ORDER_LITTLE_ENDIAN__"/>
<listOptionValue builtIn="false" value="__LITTLE_ENDIAN__=1"/>
<listOptionValue builtIn="false" value="_ILP32=1"/>
<listOptionValue builtIn="false" value="__ILP32__=1"/>
<listOptionValue builtIn="false" value="__CHAR_BIT__=8"/>
<listOptionValue builtIn="false" value="__SCHAR_MAX__=127"/>
<listOptionValue builtIn="false" value="__SHRT_MAX__=32767"/>
<listOptionValue builtIn="false" value="__INT_MAX__=2147483647"/>
<listOptionValue builtIn="false" value="__LONG_MAX__=2147483647L"/>
<listOptionValue builtIn="false" value="__LONG_LONG_MAX__=9223372036854775807LL"/>
<listOptionValue builtIn="false" value="__WCHAR_MAX__=255"/>
<listOptionValue builtIn="false" value="__INTMAX_MAX__=9223372036854775807LL"/>
<listOptionValue builtIn="false" value="__SIZE_MAX__=4294967295U"/>
<listOptionValue builtIn="false" value="__UINTMAX_MAX__=18446744073709551615ULL"/>
<listOptionValue builtIn="false" value="__PTRDIFF_MAX__=2147483647"/>
<listOptionValue builtIn="false" value="__INTPTR_MAX__=2147483647"/>
<listOptionValue builtIn="false" value="__UINTPTR_MAX__=4294967295U"/>
<listOptionValue builtIn="false" value="__SIZEOF_DOUBLE__=8"/>
<listOptionValue builtIn="false" value="__SIZEOF_FLOAT__=4"/>
<listOptionValue builtIn="false" value="__SIZEOF_INT__=4"/>
<listOptionValue builtIn="false" value="__SIZEOF_LONG__=4"/>
<listOptionValue builtIn="false" value="__SIZEOF_LONG_DOUBLE__=8"/>
<listOptionValue builtIn="false" value="__SIZEOF_LONG_LONG__=8"/>
<listOptionValue builtIn="false" value="__SIZEOF_POINTER__=4"/>
<listOptionValue builtIn="false" value="__SIZEOF_SHORT__=2"/>
<listOptionValue builtIn="false" value="__SIZEOF_PTRDIFF_T__=4"/>
<listOptionValue builtIn="false" value="__SIZEOF_SIZE_T__=4"/>
<listOptionValue builtIn="false" value="__SIZEOF_WCHAR_T__=1"/>
<listOptionValue builtIn="false" value="__SIZEOF_WINT_T__=4"/>
<listOptionValue builtIn="false" value="__INTMAX_TYPE__=long"/>
<listOptionValue builtIn="false" value="__INTMAX_FMTd__=&quot;lld&quot;"/>
<listOptionValue builtIn="false" value="__INTMAX_FMTi__=&quot;lli&quot;"/>
<listOptionValue builtIn="false" value="__INTMAX_C_SUFFIX__=LL"/>
<listOptionValue builtIn="false" value="__UINTMAX_TYPE__=long"/>
<listOptionValue builtIn="false" value="__UINTMAX_FMTo__=&quot;llo&quot;"/>
<listOptionValue builtIn="false" value="__UINTMAX_FMTu__=&quot;llu&quot;"/>
<listOptionValue builtIn="false" value="__UINTMAX_FMTx__=&quot;llx&quot;"/>
<listOptionValue builtIn="false" value="__UINTMAX_FMTX__=&quot;llX&quot;"/>
<listOptionValue builtIn="false" value="__UINTMAX_C_SUFFIX__=ULL"/>
<listOptionValue builtIn="false" value="__INTMAX_WIDTH__=64"/>
<listOptionValue builtIn="false" value="__PTRDIFF_TYPE__=int"/>
<listOptionValue builtIn="false" value="__PTRDIFF_FMTd__=&quot;d&quot;"/>
<listOptionValue builtIn="false" value="__PTRDIFF_FMTi__=&quot;i&quot;"/>
<listOptionValue builtIn="false" value="__PTRDIFF_WIDTH__=32"/>
<listOptionValue builtIn="false" value="__INTPTR_TYPE__=int"/>
<listOptionValue builtIn="false" value="__INTPTR_FMTd__=&quot;d&quot;"/>
<listOptionValue builtIn="false" value="__INTPTR_FMTi__=&quot;i&quot;"/>
<listOptionValue builtIn="false" value="__INTPTR_WIDTH__=32"/>
<listOptionValue builtIn="false" value="__SIZE_TYPE__=unsigned"/>
<listOptionValue builtIn="false" value="__SIZE_FMTo__=&quot;o&quot;"/>
<listOptionValue builtIn="false" value="__SIZE_FMTu__=&quot;u&quot;"/>
<listOptionValue builtIn="false" value="__SIZE_FMTx__=&quot;x&quot;"/>
<listOptionValue builtIn="false" value="__SIZE_FMTX__=&quot;X&quot;"/>
<listOptionValue builtIn="false" value="__SIZE_WIDTH__=32"/>
<listOptionValue builtIn="false" value="__WCHAR_TYPE__=unsigned"/>
<listOptionValue builtIn="false" value="__WCHAR_WIDTH__=8"/>
<listOptionValue builtIn="false" value="__WINT_TYPE__=unsigned"/>
<listOptionValue builtIn="false" value="__WINT_WIDTH__=32"/>
<listOptionValue builtIn="false" value="__SIG_ATOMIC_WIDTH__=32"/>
<listOptionValue builtIn="false" value="__SIG_ATOMIC_MAX__=2147483647"/>
<listOptionValue builtIn="false" value="__CHAR16_TYPE__=unsigned"/>
<listOptionValue builtIn="false" value="__CHAR32_TYPE__=unsigned"/>
<listOptionValue builtIn="false" value="__UINTMAX_WIDTH__=64"/>
<listOptionValue builtIn="false" value="__UINTPTR_TYPE__=unsigned"/>
<listOptionValue builtIn="false" value="__UINTPTR_FMTo__=&quot;o&quot;"/>
<listOptionValue builtIn="false" value="__UINTPTR_FMTu__=&quot;u&quot;"/>
<listOptionValue builtIn="false" value="__UINTPTR_FMTx__=&quot;x&quot;"/>
<listOptionValue builtIn="false" value="__UINTPTR_FMTX__=&quot;X&quot;"/>
<listOptionValue builtIn="false" value="__UINTPTR_WIDTH__=32"/>
<listOptionValue builtIn="false" value="__FLT_DENORM_MIN__=1.40129846e-45F"/>
<listOptionValue builtIn="false" value="__FLT_HAS_DENORM__=1"/>
<listOptionValue builtIn="false" value="__FLT_DIG__=6"/>
<listOptionValue builtIn="false" value="__FLT_EPSILON__=1.19209290e-7F"/>
<listOptionValue builtIn="false" value="__FLT_HAS_INFINITY__=1"/>
<listOptionValue builtIn="false" value="__FLT_HAS_QUIET_NAN__=1"/>
<listOptionValue builtIn="false" value="__FLT_MANT_DIG__=24"/>
<listOptionValue builtIn="false" value="__FLT_MAX_10_EXP__=38"/>
<listOptionValue builtIn="false" value="__FLT_MAX_EXP__=128"/>
<listOptionValue builtIn="false" value="__FLT_MAX__=3.40282347e+38F"/>
<listOptionValue builtIn="false" value="__FLT_MIN_10_EXP__=(-37)"/>
<listOptionValue builtIn="false" value="__FLT_MIN_EXP__=(-125)"/>
<listOptionValue builtIn="false" value="__FLT_MIN__=1.17549435e-38F"/>
<listOptionValue builtIn="false" value="__DBL_DENORM_MIN__=4.9406564584124654e-324"/>
<listOptionValue builtIn="false" value="__DBL_HAS_DENORM__=1"/>
<listOptionValue builtIn="false" value="__DBL_DIG__=15"/>
<listOptionValue builtIn="false" value="__DBL_EPSILON__=2.2204460492503131e-16"/>
<listOptionValue builtIn="false" value="__DBL_HAS_INFINITY__=1"/>
<listOptionValue builtIn="false" value="__DBL_HAS_QUIET_NAN__=1"/>
<listOptionValue builtIn="false" value="__DBL_MANT_DIG__=53"/>
<listOptionValue builtIn="false" value="__DBL_MAX_10_EXP__=308"/>
<listOptionValue builtIn="false" value="__DBL_MAX_EXP__=1024"/>
<listOptionValue builtIn="false" value="__DBL_MAX__=1.7976931348623157e+308"/>
<listOptionValue builtIn="false" value="__DBL_MIN_10_EXP__=(-307)"/>
<listOptionValue builtIn="false" value="__DBL_MIN_EXP__=(-1021)"/>
<listOptionValue builtIn="false" value="__DBL_MIN__=2.2250738585072014e-308"/>
<listOptionValue builtIn="false" value="__LDBL_DENORM_MIN__=4.9406564584124654e-324L"/>
<listOptionValue builtIn="false" value="__LDBL_HAS_DENORM__=1"/>
<listOptionValue builtIn="false" value="__LDBL_DIG__=15"/>
<listOptionValue builtIn="false" value="__LDBL_EPSILON__=2.2204460492503131e-16L"/>
<listOptionValue builtIn="false" value="__LDBL_HAS_INFINITY__=1"/>
<listOptionValue builtIn="false" value="__LDBL_HAS_QUIET_NAN__=1"/>
<listOptionValue builtIn="false" value="__LDBL_MANT_DIG__=53"/>
<listOptionValue builtIn="false" value="__LDBL_MAX_10_EXP__=308"/>
<listOptionValue builtIn="false" value="__LDBL_MAX_EXP__=1024"/>
<listOptionValue builtIn="false" value="__LDBL_MAX__=1.7976931348623157e+308L"/>
<listOptionValue builtIn="false" value="__LDBL_MIN_10_EXP__=(-307)"/>
<listOptionValue builtIn="false" value="__LDBL_MIN_EXP__=(-1021)"/>
<listOptionValue builtIn="false" value="__LDBL_MIN__=2.2250738585072014e-308L"/>
<listOptionValue builtIn="false" value="__POINTER_WIDTH__=32"/>
<listOptionValue builtIn="false" value="__CHAR_UNSIGNED__=1"/>
<listOptionValue builtIn="false" value="__WCHAR_UNSIGNED__=1"/>
<listOptionValue builtIn="false" value="__WINT_UNSIGNED__=1"/>
<listOptionValue builtIn="false" value="__INT8_TYPE__=signed"/>
<listOptionValue builtIn="false" value="__INT8_FMTd__=&quot;hhd&quot;"/>
<listOptionValue builtIn="false" value="__INT8_FMTi__=&quot;hhi&quot;"/>
<listOptionValue builtIn="false" value="__INT8_C_SUFFIX__"/>
<listOptionValue builtIn="false" value="__INT16_TYPE__=short"/>
<listOptionValue builtIn="false" value="__INT16_FMTd__=&quot;hd&quot;"/>
<listOptionValue builtIn="false" value="__INT16_FMTi__=&quot;hi&quot;"/>
<listOptionValue builtIn="false" value="__INT16_C_SUFFIX__"/>
<listOptionValue builtIn="false" value="__INT32_TYPE__=int"/>
<listOptionValue builtIn="false" value="__INT32_FMTd__=&quot;d&quot;"/>
<listOptionValue builtIn="false" value="__INT32_FMTi__=&quot;i&quot;"/>
<listOptionValue builtIn="false" value="__INT32_C_SUFFIX__"/>
<listOptionValue builtIn="false" value="__INT64_TYPE__=long"/>
<listOptionValue builtIn="false" value="__INT64_FMTd__=&quot;lld&quot;"/>
<listOptionValue builtIn="false" value="__INT64_FMTi__=&quot;lli&quot;"/>
<listOptionValue builtIn="false" value="__INT64_C_SUFFIX__=LL"/>
<listOptionValue builtIn="false" value="__UINT8_TYPE__=unsigned"/>
<listOptionValue builtIn="false" value="__UINT8_FMTo__=&quot;hho&quot;"/>
<listOptionValue builtIn="false" value="__UINT8_FMTu__=&quot;hhu&quot;"/>
<listOptionValue builtIn="false" value="__UINT8_FMTx__=&quot;hhx&quot;"/>
<listOptionValue builtIn="false" value="__UINT8_FMTX__=&quot;hhX&quot;"/>
<listOptionValue builtIn="false" value="__UINT8_C_SUFFIX__"/>
<listOptionValue builtIn="false" value="__UINT8_MAX__=255"/>
<listOptionValue builtIn="false" value="__INT8_MAX__=127"/>
<listOptionValue builtIn="false" value="__UINT16_TYPE__=unsigned"/>
<listOptionValue builtIn="false" value="__UINT16_FMTo__=&quot;ho&quot;"/>
<listOptionValue builtIn="false" value="__UINT16_FMTu__=&quot;hu&quot;"/>
<listOptionValue builtIn="false" value="__UINT16_FMTx__=&quot;hx&quot;"/>
<listOptionValue builtIn="false" value="__UINT16_FMTX__=&quot;hX&quot;"/>
<listOptionValue builtIn="false" value="__UINT16_C_SUFFIX__"/>
<listOptionValue builtIn="false" value="__UINT16_MAX__=65535"/>
<listOptionValue builtIn="false" value="__INT16_MAX__=32767"/>
<listOptionValue builtIn="false" value="__UINT32_TYPE__=unsigned"/>
<listOptionValue builtIn="false" value="__UINT32_FMTo__=&quot;o&quot;"/>
<listOptionValue builtIn="false" value="__UINT32_FMTu__=&quot;u&quot;"/>
<listOptionValue builtIn="false" value="__UINT32_FMTx__=&quot;x&quot;"/>
<listOptionValue builtIn="false" value="__UINT32_FMTX__=&quot;X&quot;"/>
<listOptionValue builtIn="false" value="__UINT32_C_SUFFIX__=U"/>
<listOptionValue builtIn="false" value="__UINT32_MAX__=4294967295U"/>
<listOptionValue builtIn="false" value="__INT32_MAX__=2147483647"/>
<listOptionValue builtIn="false" value="__UINT64_TYPE__=long"/>
<listOptionValue builtIn="false" value="__UINT64_FMTo__=&quot;llo&quot;"/>
<listOptionValue builtIn="false" value="__UINT64_FMTu__=&quot;llu&quot;"/>
<listOptionValue builtIn="false" value="__UINT64_FMTx__=&quot;llx&quot;"/>
<listOptionValue builtIn="false" value="__UINT64_FMTX__=&quot;llX&quot;"/>
<listOptionValue builtIn="false" value="__UINT64_C_SUFFIX__=ULL"/>
<listOptionValue builtIn="false" value="__UINT64_MAX__=18446744073709551615ULL"/>
<listOptionValue builtIn="false" value="__INT64_MAX__=9223372036854775807LL"/>
<listOptionValue builtIn="false" value="__INT_LEAST8_TYPE__=signed"/>
<listOptionValue builtIn="false" value="__INT_LEAST8_MAX__=127"/>
<listOptionValue builtIn="false" value="__INT_LEAST8_FMTd__=&quot;hhd&quot;"/>
<listOptionValue builtIn="false" value="__INT_LEAST8_FMTi__=&quot;hhi&quot;"/>
<listOptionValue builtIn="false" value="__UINT_LEAST8_TYPE__=unsigned"/>
<listOptionValue builtIn="false" value="__UINT_LEAST8_MAX__=255"/>
<listOptionValue builtIn="false" value="__UINT_LEAST8_FMTo__=&quot;hho&quot;"/>
<listOptionValue builtIn="false" value="__UINT_LEAST8_FMTu__=&quot;hhu&quot;"/>
<listOptionValue builtIn="false" value="__UINT_LEAST8_FMTx__=&quot;hhx&quot;"/>
<listOptionValue builtIn="false" value="__UINT_LEAST8_FMTX__=&quot;hhX&quot;"/>
<listOptionValue builtIn="false" value="__INT_LEAST16_TYPE__=short"/>
<listOptionValue builtIn="false" value="__INT_LEAST16_MAX__=32767"/>
<listOptionValue builtIn="false" value="__INT_LEAST16_FMTd__=&quot;hd&quot;"/>
<listOptionValue builtIn="false" value="__INT_LEAST16_FMTi__=&quot;hi&quot;"/>
<listOptionValue builtIn="false" value="__UINT_LEAST16_TYPE__=unsigned"/>
<listOptionValue builtIn="false" value="__UINT_LEAST16_MAX__=65535"/>
<listOptionValue builtIn="false" value="__UINT_LEAST16_FMTo__=&quot;ho&quot;"/>
<listOptionValue builtIn="false" value="__UINT_LEAST16_FMTu__=&quot;hu&quot;"/>
<listOptionValue builtIn="false" value="__UINT_LEAST16_FMTx__=&quot;hx&quot;"/>
<listOptionValue builtIn="false" value="__UINT_LEAST16_FMTX__=&quot;hX&quot;"/>
<listOptionValue builtIn="false" value="__INT_LEAST32_TYPE__=int"/>
<listOptionValue builtIn="false" value="__INT_LEAST32_MAX__=2147483647"/>
<listOptionValue builtIn="false" value="__INT_LEAST32_FMTd__=&quot;d&quot;"/>
<listOptionValue builtIn="false" value="__INT_LEAST32_FMTi__=&quot;i&quot;"/>
<listOptionValue builtIn="false" value="__UINT_LEAST32_TYPE__=unsigned"/>
<listOptionValue builtIn="false" value="__UINT_LEAST32_MAX__=4294967295U"/>
<listOptionValue builtIn="false" value="__UINT_LEAST32_FMTo__=&quot;o&quot;"/>
<listOptionValue builtIn="false" value="__UINT_LEAST32_FMTu__=&quot;u&quot;"/>
<listOptionValue builtIn="false" value="__UINT_LEAST32_FMTx__=&quot;x&quot;"/>
<listOptionValue builtIn="false" value="__UINT_LEAST32_FMTX__=&quot;X&quot;"/>
<listOptionValue builtIn="false" value="__INT_LEAST64_TYPE__=long"/>
<listOptionValue builtIn="false" value="__INT_LEAST64_MAX__=9223372036854775807LL"/>
<listOptionValue builtIn="false" value="__INT_LEAST64_FMTd__=&quot;lld&quot;"/>
<listOptionValue builtIn="false" value="__INT_LEAST64_FMTi__=&quot;lli&quot;"/>
<listOptionValue builtIn="false" value="__UINT_LEAST64_TYPE__=long"/>
<listOptionValue builtIn="false" value="__UINT_LEAST64_MAX__=18446744073709551615ULL"/>
<listOptionValue builtIn="false" value="__UINT_LEAST64_FMTo__=&quot;llo&quot;"/>
<listOptionValue builtIn="false" value="__UINT_LEAST64_FMTu__=&quot;llu&quot;"/>
<listOptionValue builtIn="false" value="__UINT_LEAST64_FMTx__=&quot;llx&quot;"/>
<listOptionValue builtIn="false" value="__UINT_LEAST64_FMTX__=&quot;llX&quot;"/>
<listOptionValue builtIn="false" value="__INT_FAST8_TYPE__=signed"/>
<listOptionValue builtIn="false" value="__INT_FAST8_MAX__=127"/>
<listOptionValue builtIn="false" value="__INT_FAST8_FMTd__=&quot;hhd&quot;"/>
<listOptionValue builtIn="false" value="__INT_FAST8_FMTi__=&quot;hhi&quot;"/>
<listOptionValue builtIn="false" value="__UINT_FAST8_TYPE__=unsigned"/>
<listOptionValue builtIn="false" value="__UINT_FAST8_MAX__=255"/>
<listOptionValue builtIn="false" value="__UINT_FAST8_FMTo__=&quot;hho&quot;"/>
<listOptionValue builtIn="false" value="__UINT_FAST8_FMTu__=&quot;hhu&quot;"/>
<listOptionValue builtIn="false" value="__UINT_FAST8_FMTx__=&quot;hhx&quot;"/>
<listOptionValue builtIn="false" value="__UINT_FAST8_FMTX__=&quot;hhX&quot;"/>
<listOptionValue builtIn="false" value="__INT_FAST16_TYPE__=short"/>
<listOptionValue builtIn="false" value="__INT_FAST16_MAX__=32767"/>
<listOptionValue builtIn="false" value="__INT_FAST16_FMTd__=&quot;hd&quot;"/>
<listOptionValue builtIn="false" value="__INT_FAST16_FMTi__=&quot;hi&quot;"/>
<listOptionValue builtIn="false" value="__UINT_FAST16_TYPE__=unsigned"/>
<listOptionValue builtIn="false" value="__UINT_FAST16_MAX__=65535"/>
<listOptionValue builtIn="false" value="__UINT_FAST16_FMTo__=&quot;ho&quot;"/>
<listOptionValue builtIn="false" value="__UINT_FAST16_FMTu__=&quot;hu&quot;"/>
<listOptionValue builtIn="false" value="__UINT_FAST16_FMTx__=&quot;hx&quot;"/>
<listOptionValue builtIn="false" value="__UINT_FAST16_FMTX__=&quot;hX&quot;"/>
<listOptionValue builtIn="false" value="__INT_FAST32_TYPE__=int"/>
<listOptionValue builtIn="false" value="__INT_FAST32_MAX__=2147483647"/>
<listOptionValue builtIn="false" value="__INT_FAST32_FMTd__=&quot;d&quot;"/>
<listOptionValue builtIn="false" value="__INT_FAST32_FMTi__=&quot;i&quot;"/>
<listOptionValue builtIn="false" value="__UINT_FAST32_TYPE__=unsigned"/>
<listOptionValue builtIn="false" value="__UINT_FAST32_MAX__=4294967295U"/>
<listOptionValue builtIn="false" value="__UINT_FAST32_FMTo__=&quot;o&quot;"/>
<listOptionValue builtIn="false" value="__UINT_FAST32_FMTu__=&quot;u&quot;"/>
<listOptionValue builtIn="false" value="__UINT_FAST32_FMTx__=&quot;x&quot;"/>
<listOptionValue builtIn="false" value="__UINT_FAST32_FMTX__=&quot;X&quot;"/>
<listOptionValue builtIn="false" value="__INT_FAST64_TYPE__=long"/>
<listOptionValue builtIn="false" value="__INT_FAST64_MAX__=9223372036854775807LL"/>
<listOptionValue builtIn="false" value="__INT_FAST64_FMTd__=&quot;lld&quot;"/>
<listOptionValue builtIn="false" value="__INT_FAST64_FMTi__=&quot;lli&quot;"/>
<listOptionValue builtIn="false" value="__UINT_FAST64_TYPE__=long"/>
<listOptionValue builtIn="false" value="__UINT_FAST64_MAX__=18446744073709551615ULL"/>
<listOptionValue builtIn="false" value="__UINT_FAST64_FMTo__=&quot;llo&quot;"/>
<listOptionValue builtIn="false" value="__UINT_FAST64_FMTu__=&quot;llu&quot;"/>
<listOptionValue builtIn="false" value="__UINT_FAST64_FMTx__=&quot;llx&quot;"/>
<listOptionValue builtIn="false" value="__UINT_FAST64_FMTX__=&quot;llX&quot;"/>
<listOptionValue builtIn="false" value="__USER_LABEL_PREFIX__=_"/>
<listOptionValue builtIn="false" value="__FINITE_MATH_ONLY__=0"/>
<listOptionValue builtIn="false" value="__GNUC_STDC_INLINE__=1"/>
<listOptionValue builtIn="false" value="__GCC_ATOMIC_TEST_AND_SET_TRUEVAL=1"/>
<listOptionValue builtIn="false" value="__GCC_ATOMIC_BOOL_LOCK_FREE=1"/>
<listOptionValue builtIn="false" value="__GCC_ATOMIC_CHAR_LOCK_FREE=1"/>
<listOptionValue builtIn="false" value="__GCC_ATOMIC_CHAR16_T_LOCK_FREE=1"/>
<listOptionValue builtIn="false" value="__GCC_ATOMIC_CHAR32_T_LOCK_FREE=1"/>
<listOptionValue builtIn="false" value="__GCC_ATOMIC_WCHAR_T_LOCK_FREE=1"/>
<listOptionValue builtIn="false" value="__GCC_ATOMIC_SHORT_LOCK_FREE=1"/>
<listOptionValue builtIn="false" value="__GCC_ATOMIC_INT_LOCK_FREE=1"/>
<listOptionValue builtIn="false" value="__GCC_ATOMIC_LONG_LOCK_FREE=1"/>
<listOptionValue builtIn="false" value="__GCC_ATOMIC_LLONG_LOCK_FREE=1"/>
<listOptionValue builtIn="false" value="__GCC_ATOMIC_POINTER_LOCK_FREE=1"/>
<listOptionValue builtIn="false" value="__NO_INLINE__=1"/>
<listOptionValue builtIn="false" value="__FLT_EVAL_METHOD__=0"/>
<listOptionValue builtIn="false" value="__FLT_RADIX__=2"/>
<listOptionValue builtIn="false" value="__DECIMAL_DIG__=17"/>
<listOptionValue builtIn="false" value="__xcore__=1"/>
<listOptionValue builtIn="false" value="__XS1B__=1"/>
<listOptionValue builtIn="false" value="__STDC__=1"/>
<listOptionValue builtIn="false" value="__STDC_HOSTED__=1"/>
<listOptionValue builtIn="false" value="__STDC_VERSION__=199901L"/>
<listOptionValue builtIn="false" value="__STDC_UTF_16__=1"/>
<listOptionValue builtIn="false" value="__STDC_UTF_32__=1"/>
<listOptionValue builtIn="false" value="XCC_VERSION_YEAR=14"/>
<listOptionValue builtIn="false" value="XCC_VERSION_MONTH=3"/>
<listOptionValue builtIn="false" value="XCC_VERSION_MAJOR=1403"/>
<listOptionValue builtIn="false" value="XCC_VERSION_MINOR=2"/>
<listOptionValue builtIn="false" value="__XCC_HAVE_FLOAT__=1"/>
<listOptionValue builtIn="false" value="_XSCOPE_PROBES_INCLUDE_FILE=&quot;/var/folders/0l/8jd0xy095ps890m302j532580000h5/T//ccVdKn1b.h&quot;"/>
</option>
<option id="com.xmos.c.compiler.option.include.paths.1661660573" name="com.xmos.c.compiler.option.include.paths" superClass="com.xmos.c.compiler.option.include.paths" valueType="includePath">
<listOptionValue builtIn="false" value="&quot;${XMOS_TOOL_PATH}/target/include&quot;"/>
<listOptionValue builtIn="false" value="&quot;${XMOS_TOOL_PATH}/target/include/clang&quot;"/>
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/lib_logging/doc}&quot;"/>
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/lib_xud/doc/rst/images}&quot;"/>
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/lib_xud/src/user/client}&quot;"/>
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/lib_xud/src/user/class}&quot;"/>
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/lib_xud/src/core/included}&quot;"/>
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/lib_xud/src/core}&quot;"/>
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/lib_logging/doc/rst}&quot;"/>
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/lib_logging/src}&quot;"/>
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/lib_xud}&quot;"/>
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/lib_logging}&quot;"/>
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/lib_xud/src/user/control}&quot;"/>
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/lib_logging/api}&quot;"/>
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/lib_xud/doc/rst}&quot;"/>
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/lib_xud/api}&quot;"/>
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/lib_xud/src}&quot;"/>
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/lib_xud/doc}&quot;"/>
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/lib_xud/src/user}&quot;"/>
</option>
<inputType id="com.xmos.cdt.c.compiler.input.c.1188610778" name="C" superClass="com.xmos.cdt.c.compiler.input.c"/>
</tool>
<tool id="com.xmos.cdt.cxx.compiler.1403352573" name="com.xmos.cdt.cxx.compiler" superClass="com.xmos.cdt.cxx.compiler">
<option id="com.xmos.cxx.compiler.option.defined.symbols.665306874" name="com.xmos.cxx.compiler.option.defined.symbols" superClass="com.xmos.cxx.compiler.option.defined.symbols" valueType="definedSymbols">
<listOptionValue builtIn="false" value="__llvm__=1"/>
<listOptionValue builtIn="false" value="__clang__=1"/>
<listOptionValue builtIn="false" value="__clang_major__=3"/>
<listOptionValue builtIn="false" value="__clang_minor__=6"/>
<listOptionValue builtIn="false" value="__clang_patchlevel__=0"/>
<listOptionValue builtIn="false" value="__clang_version__=&quot;3.6.0"/>
<listOptionValue builtIn="false" value="__GNUC_MINOR__=2"/>
<listOptionValue builtIn="false" value="__GNUC_PATCHLEVEL__=1"/>
<listOptionValue builtIn="false" value="__GNUC__=4"/>
<listOptionValue builtIn="false" value="__GXX_ABI_VERSION=1002"/>
<listOptionValue builtIn="false" value="__ATOMIC_RELAXED=0"/>
<listOptionValue builtIn="false" value="__ATOMIC_CONSUME=1"/>
<listOptionValue builtIn="false" value="__ATOMIC_ACQUIRE=2"/>
<listOptionValue builtIn="false" value="__ATOMIC_RELEASE=3"/>
<listOptionValue builtIn="false" value="__ATOMIC_ACQ_REL=4"/>
<listOptionValue builtIn="false" value="__ATOMIC_SEQ_CST=5"/>
<listOptionValue builtIn="false" value="__PRAGMA_REDEFINE_EXTNAME=1"/>
<listOptionValue builtIn="false" value="__VERSION__=&quot;4.2.1"/>
<listOptionValue builtIn="false" value="__CONSTANT_CFSTRINGS__=1"/>
<listOptionValue builtIn="false" value="__GXX_RTTI=1"/>
<listOptionValue builtIn="false" value="__DEPRECATED=1"/>
<listOptionValue builtIn="false" value="__GNUG__=4"/>
<listOptionValue builtIn="false" value="__GXX_WEAK__=1"/>
<listOptionValue builtIn="false" value="__private_extern__=extern"/>
<listOptionValue builtIn="false" value="__ORDER_LITTLE_ENDIAN__=1234"/>
<listOptionValue builtIn="false" value="__ORDER_BIG_ENDIAN__=4321"/>
<listOptionValue builtIn="false" value="__ORDER_PDP_ENDIAN__=3412"/>
<listOptionValue builtIn="false" value="__BYTE_ORDER__=__ORDER_LITTLE_ENDIAN__"/>
<listOptionValue builtIn="false" value="__LITTLE_ENDIAN__=1"/>
<listOptionValue builtIn="false" value="_ILP32=1"/>
<listOptionValue builtIn="false" value="__ILP32__=1"/>
<listOptionValue builtIn="false" value="__CHAR_BIT__=8"/>
<listOptionValue builtIn="false" value="__SCHAR_MAX__=127"/>
<listOptionValue builtIn="false" value="__SHRT_MAX__=32767"/>
<listOptionValue builtIn="false" value="__INT_MAX__=2147483647"/>
<listOptionValue builtIn="false" value="__LONG_MAX__=2147483647L"/>
<listOptionValue builtIn="false" value="__LONG_LONG_MAX__=9223372036854775807LL"/>
<listOptionValue builtIn="false" value="__WCHAR_MAX__=255"/>
<listOptionValue builtIn="false" value="__INTMAX_MAX__=9223372036854775807LL"/>
<listOptionValue builtIn="false" value="__SIZE_MAX__=4294967295U"/>
<listOptionValue builtIn="false" value="__UINTMAX_MAX__=18446744073709551615ULL"/>
<listOptionValue builtIn="false" value="__PTRDIFF_MAX__=2147483647"/>
<listOptionValue builtIn="false" value="__INTPTR_MAX__=2147483647"/>
<listOptionValue builtIn="false" value="__UINTPTR_MAX__=4294967295U"/>
<listOptionValue builtIn="false" value="__SIZEOF_DOUBLE__=8"/>
<listOptionValue builtIn="false" value="__SIZEOF_FLOAT__=4"/>
<listOptionValue builtIn="false" value="__SIZEOF_INT__=4"/>
<listOptionValue builtIn="false" value="__SIZEOF_LONG__=4"/>
<listOptionValue builtIn="false" value="__SIZEOF_LONG_DOUBLE__=8"/>
<listOptionValue builtIn="false" value="__SIZEOF_LONG_LONG__=8"/>
<listOptionValue builtIn="false" value="__SIZEOF_POINTER__=4"/>
<listOptionValue builtIn="false" value="__SIZEOF_SHORT__=2"/>
<listOptionValue builtIn="false" value="__SIZEOF_PTRDIFF_T__=4"/>
<listOptionValue builtIn="false" value="__SIZEOF_SIZE_T__=4"/>
<listOptionValue builtIn="false" value="__SIZEOF_WCHAR_T__=1"/>
<listOptionValue builtIn="false" value="__SIZEOF_WINT_T__=4"/>
<listOptionValue builtIn="false" value="__INTMAX_TYPE__=long"/>
<listOptionValue builtIn="false" value="__INTMAX_FMTd__=&quot;lld&quot;"/>
<listOptionValue builtIn="false" value="__INTMAX_FMTi__=&quot;lli&quot;"/>
<listOptionValue builtIn="false" value="__INTMAX_C_SUFFIX__=LL"/>
<listOptionValue builtIn="false" value="__UINTMAX_TYPE__=long"/>
<listOptionValue builtIn="false" value="__UINTMAX_FMTo__=&quot;llo&quot;"/>
<listOptionValue builtIn="false" value="__UINTMAX_FMTu__=&quot;llu&quot;"/>
<listOptionValue builtIn="false" value="__UINTMAX_FMTx__=&quot;llx&quot;"/>
<listOptionValue builtIn="false" value="__UINTMAX_FMTX__=&quot;llX&quot;"/>
<listOptionValue builtIn="false" value="__UINTMAX_C_SUFFIX__=ULL"/>
<listOptionValue builtIn="false" value="__INTMAX_WIDTH__=64"/>
<listOptionValue builtIn="false" value="__PTRDIFF_TYPE__=int"/>
<listOptionValue builtIn="false" value="__PTRDIFF_FMTd__=&quot;d&quot;"/>
<listOptionValue builtIn="false" value="__PTRDIFF_FMTi__=&quot;i&quot;"/>
<listOptionValue builtIn="false" value="__PTRDIFF_WIDTH__=32"/>
<listOptionValue builtIn="false" value="__INTPTR_TYPE__=int"/>
<listOptionValue builtIn="false" value="__INTPTR_FMTd__=&quot;d&quot;"/>
<listOptionValue builtIn="false" value="__INTPTR_FMTi__=&quot;i&quot;"/>
<listOptionValue builtIn="false" value="__INTPTR_WIDTH__=32"/>
<listOptionValue builtIn="false" value="__SIZE_TYPE__=unsigned"/>
<listOptionValue builtIn="false" value="__SIZE_FMTo__=&quot;o&quot;"/>
<listOptionValue builtIn="false" value="__SIZE_FMTu__=&quot;u&quot;"/>
<listOptionValue builtIn="false" value="__SIZE_FMTx__=&quot;x&quot;"/>
<listOptionValue builtIn="false" value="__SIZE_FMTX__=&quot;X&quot;"/>
<listOptionValue builtIn="false" value="__SIZE_WIDTH__=32"/>
<listOptionValue builtIn="false" value="__WCHAR_TYPE__=unsigned"/>
<listOptionValue builtIn="false" value="__WCHAR_WIDTH__=8"/>
<listOptionValue builtIn="false" value="__WINT_TYPE__=unsigned"/>
<listOptionValue builtIn="false" value="__WINT_WIDTH__=32"/>
<listOptionValue builtIn="false" value="__SIG_ATOMIC_WIDTH__=32"/>
<listOptionValue builtIn="false" value="__SIG_ATOMIC_MAX__=2147483647"/>
<listOptionValue builtIn="false" value="__CHAR16_TYPE__=unsigned"/>
<listOptionValue builtIn="false" value="__CHAR32_TYPE__=unsigned"/>
<listOptionValue builtIn="false" value="__UINTMAX_WIDTH__=64"/>
<listOptionValue builtIn="false" value="__UINTPTR_TYPE__=unsigned"/>
<listOptionValue builtIn="false" value="__UINTPTR_FMTo__=&quot;o&quot;"/>
<listOptionValue builtIn="false" value="__UINTPTR_FMTu__=&quot;u&quot;"/>
<listOptionValue builtIn="false" value="__UINTPTR_FMTx__=&quot;x&quot;"/>
<listOptionValue builtIn="false" value="__UINTPTR_FMTX__=&quot;X&quot;"/>
<listOptionValue builtIn="false" value="__UINTPTR_WIDTH__=32"/>
<listOptionValue builtIn="false" value="__FLT_DENORM_MIN__=1.40129846e-45F"/>
<listOptionValue builtIn="false" value="__FLT_HAS_DENORM__=1"/>
<listOptionValue builtIn="false" value="__FLT_DIG__=6"/>
<listOptionValue builtIn="false" value="__FLT_EPSILON__=1.19209290e-7F"/>
<listOptionValue builtIn="false" value="__FLT_HAS_INFINITY__=1"/>
<listOptionValue builtIn="false" value="__FLT_HAS_QUIET_NAN__=1"/>
<listOptionValue builtIn="false" value="__FLT_MANT_DIG__=24"/>
<listOptionValue builtIn="false" value="__FLT_MAX_10_EXP__=38"/>
<listOptionValue builtIn="false" value="__FLT_MAX_EXP__=128"/>
<listOptionValue builtIn="false" value="__FLT_MAX__=3.40282347e+38F"/>
<listOptionValue builtIn="false" value="__FLT_MIN_10_EXP__=(-37)"/>
<listOptionValue builtIn="false" value="__FLT_MIN_EXP__=(-125)"/>
<listOptionValue builtIn="false" value="__FLT_MIN__=1.17549435e-38F"/>
<listOptionValue builtIn="false" value="__DBL_DENORM_MIN__=4.9406564584124654e-324"/>
<listOptionValue builtIn="false" value="__DBL_HAS_DENORM__=1"/>
<listOptionValue builtIn="false" value="__DBL_DIG__=15"/>
<listOptionValue builtIn="false" value="__DBL_EPSILON__=2.2204460492503131e-16"/>
<listOptionValue builtIn="false" value="__DBL_HAS_INFINITY__=1"/>
<listOptionValue builtIn="false" value="__DBL_HAS_QUIET_NAN__=1"/>
<listOptionValue builtIn="false" value="__DBL_MANT_DIG__=53"/>
<listOptionValue builtIn="false" value="__DBL_MAX_10_EXP__=308"/>
<listOptionValue builtIn="false" value="__DBL_MAX_EXP__=1024"/>
<listOptionValue builtIn="false" value="__DBL_MAX__=1.7976931348623157e+308"/>
<listOptionValue builtIn="false" value="__DBL_MIN_10_EXP__=(-307)"/>
<listOptionValue builtIn="false" value="__DBL_MIN_EXP__=(-1021)"/>
<listOptionValue builtIn="false" value="__DBL_MIN__=2.2250738585072014e-308"/>
<listOptionValue builtIn="false" value="__LDBL_DENORM_MIN__=4.9406564584124654e-324L"/>
<listOptionValue builtIn="false" value="__LDBL_HAS_DENORM__=1"/>
<listOptionValue builtIn="false" value="__LDBL_DIG__=15"/>
<listOptionValue builtIn="false" value="__LDBL_EPSILON__=2.2204460492503131e-16L"/>
<listOptionValue builtIn="false" value="__LDBL_HAS_INFINITY__=1"/>
<listOptionValue builtIn="false" value="__LDBL_HAS_QUIET_NAN__=1"/>
<listOptionValue builtIn="false" value="__LDBL_MANT_DIG__=53"/>
<listOptionValue builtIn="false" value="__LDBL_MAX_10_EXP__=308"/>
<listOptionValue builtIn="false" value="__LDBL_MAX_EXP__=1024"/>
<listOptionValue builtIn="false" value="__LDBL_MAX__=1.7976931348623157e+308L"/>
<listOptionValue builtIn="false" value="__LDBL_MIN_10_EXP__=(-307)"/>
<listOptionValue builtIn="false" value="__LDBL_MIN_EXP__=(-1021)"/>
<listOptionValue builtIn="false" value="__LDBL_MIN__=2.2250738585072014e-308L"/>
<listOptionValue builtIn="false" value="__POINTER_WIDTH__=32"/>
<listOptionValue builtIn="false" value="__CHAR_UNSIGNED__=1"/>
<listOptionValue builtIn="false" value="__WCHAR_UNSIGNED__=1"/>
<listOptionValue builtIn="false" value="__WINT_UNSIGNED__=1"/>
<listOptionValue builtIn="false" value="__INT8_TYPE__=signed"/>
<listOptionValue builtIn="false" value="__INT8_FMTd__=&quot;hhd&quot;"/>
<listOptionValue builtIn="false" value="__INT8_FMTi__=&quot;hhi&quot;"/>
<listOptionValue builtIn="false" value="__INT8_C_SUFFIX__"/>
<listOptionValue builtIn="false" value="__INT16_TYPE__=short"/>
<listOptionValue builtIn="false" value="__INT16_FMTd__=&quot;hd&quot;"/>
<listOptionValue builtIn="false" value="__INT16_FMTi__=&quot;hi&quot;"/>
<listOptionValue builtIn="false" value="__INT16_C_SUFFIX__"/>
<listOptionValue builtIn="false" value="__INT32_TYPE__=int"/>
<listOptionValue builtIn="false" value="__INT32_FMTd__=&quot;d&quot;"/>
<listOptionValue builtIn="false" value="__INT32_FMTi__=&quot;i&quot;"/>
<listOptionValue builtIn="false" value="__INT32_C_SUFFIX__"/>
<listOptionValue builtIn="false" value="__INT64_TYPE__=long"/>
<listOptionValue builtIn="false" value="__INT64_FMTd__=&quot;lld&quot;"/>
<listOptionValue builtIn="false" value="__INT64_FMTi__=&quot;lli&quot;"/>
<listOptionValue builtIn="false" value="__INT64_C_SUFFIX__=LL"/>
<listOptionValue builtIn="false" value="__UINT8_TYPE__=unsigned"/>
<listOptionValue builtIn="false" value="__UINT8_FMTo__=&quot;hho&quot;"/>
<listOptionValue builtIn="false" value="__UINT8_FMTu__=&quot;hhu&quot;"/>
<listOptionValue builtIn="false" value="__UINT8_FMTx__=&quot;hhx&quot;"/>
<listOptionValue builtIn="false" value="__UINT8_FMTX__=&quot;hhX&quot;"/>
<listOptionValue builtIn="false" value="__UINT8_C_SUFFIX__"/>
<listOptionValue builtIn="false" value="__UINT8_MAX__=255"/>
<listOptionValue builtIn="false" value="__INT8_MAX__=127"/>
<listOptionValue builtIn="false" value="__UINT16_TYPE__=unsigned"/>
<listOptionValue builtIn="false" value="__UINT16_FMTo__=&quot;ho&quot;"/>
<listOptionValue builtIn="false" value="__UINT16_FMTu__=&quot;hu&quot;"/>
<listOptionValue builtIn="false" value="__UINT16_FMTx__=&quot;hx&quot;"/>
<listOptionValue builtIn="false" value="__UINT16_FMTX__=&quot;hX&quot;"/>
<listOptionValue builtIn="false" value="__UINT16_C_SUFFIX__"/>
<listOptionValue builtIn="false" value="__UINT16_MAX__=65535"/>
<listOptionValue builtIn="false" value="__INT16_MAX__=32767"/>
<listOptionValue builtIn="false" value="__UINT32_TYPE__=unsigned"/>
<listOptionValue builtIn="false" value="__UINT32_FMTo__=&quot;o&quot;"/>
<listOptionValue builtIn="false" value="__UINT32_FMTu__=&quot;u&quot;"/>
<listOptionValue builtIn="false" value="__UINT32_FMTx__=&quot;x&quot;"/>
<listOptionValue builtIn="false" value="__UINT32_FMTX__=&quot;X&quot;"/>
<listOptionValue builtIn="false" value="__UINT32_C_SUFFIX__=U"/>
<listOptionValue builtIn="false" value="__UINT32_MAX__=4294967295U"/>
<listOptionValue builtIn="false" value="__INT32_MAX__=2147483647"/>
<listOptionValue builtIn="false" value="__UINT64_TYPE__=long"/>
<listOptionValue builtIn="false" value="__UINT64_FMTo__=&quot;llo&quot;"/>
<listOptionValue builtIn="false" value="__UINT64_FMTu__=&quot;llu&quot;"/>
<listOptionValue builtIn="false" value="__UINT64_FMTx__=&quot;llx&quot;"/>
<listOptionValue builtIn="false" value="__UINT64_FMTX__=&quot;llX&quot;"/>
<listOptionValue builtIn="false" value="__UINT64_C_SUFFIX__=ULL"/>
<listOptionValue builtIn="false" value="__UINT64_MAX__=18446744073709551615ULL"/>
<listOptionValue builtIn="false" value="__INT64_MAX__=9223372036854775807LL"/>
<listOptionValue builtIn="false" value="__INT_LEAST8_TYPE__=signed"/>
<listOptionValue builtIn="false" value="__INT_LEAST8_MAX__=127"/>
<listOptionValue builtIn="false" value="__INT_LEAST8_FMTd__=&quot;hhd&quot;"/>
<listOptionValue builtIn="false" value="__INT_LEAST8_FMTi__=&quot;hhi&quot;"/>
<listOptionValue builtIn="false" value="__UINT_LEAST8_TYPE__=unsigned"/>
<listOptionValue builtIn="false" value="__UINT_LEAST8_MAX__=255"/>
<listOptionValue builtIn="false" value="__UINT_LEAST8_FMTo__=&quot;hho&quot;"/>
<listOptionValue builtIn="false" value="__UINT_LEAST8_FMTu__=&quot;hhu&quot;"/>
<listOptionValue builtIn="false" value="__UINT_LEAST8_FMTx__=&quot;hhx&quot;"/>
<listOptionValue builtIn="false" value="__UINT_LEAST8_FMTX__=&quot;hhX&quot;"/>
<listOptionValue builtIn="false" value="__INT_LEAST16_TYPE__=short"/>
<listOptionValue builtIn="false" value="__INT_LEAST16_MAX__=32767"/>
<listOptionValue builtIn="false" value="__INT_LEAST16_FMTd__=&quot;hd&quot;"/>
<listOptionValue builtIn="false" value="__INT_LEAST16_FMTi__=&quot;hi&quot;"/>
<listOptionValue builtIn="false" value="__UINT_LEAST16_TYPE__=unsigned"/>
<listOptionValue builtIn="false" value="__UINT_LEAST16_MAX__=65535"/>
<listOptionValue builtIn="false" value="__UINT_LEAST16_FMTo__=&quot;ho&quot;"/>
<listOptionValue builtIn="false" value="__UINT_LEAST16_FMTu__=&quot;hu&quot;"/>
<listOptionValue builtIn="false" value="__UINT_LEAST16_FMTx__=&quot;hx&quot;"/>
<listOptionValue builtIn="false" value="__UINT_LEAST16_FMTX__=&quot;hX&quot;"/>
<listOptionValue builtIn="false" value="__INT_LEAST32_TYPE__=int"/>
<listOptionValue builtIn="false" value="__INT_LEAST32_MAX__=2147483647"/>
<listOptionValue builtIn="false" value="__INT_LEAST32_FMTd__=&quot;d&quot;"/>
<listOptionValue builtIn="false" value="__INT_LEAST32_FMTi__=&quot;i&quot;"/>
<listOptionValue builtIn="false" value="__UINT_LEAST32_TYPE__=unsigned"/>
<listOptionValue builtIn="false" value="__UINT_LEAST32_MAX__=4294967295U"/>
<listOptionValue builtIn="false" value="__UINT_LEAST32_FMTo__=&quot;o&quot;"/>
<listOptionValue builtIn="false" value="__UINT_LEAST32_FMTu__=&quot;u&quot;"/>
<listOptionValue builtIn="false" value="__UINT_LEAST32_FMTx__=&quot;x&quot;"/>
<listOptionValue builtIn="false" value="__UINT_LEAST32_FMTX__=&quot;X&quot;"/>
<listOptionValue builtIn="false" value="__INT_LEAST64_TYPE__=long"/>
<listOptionValue builtIn="false" value="__INT_LEAST64_MAX__=9223372036854775807LL"/>
<listOptionValue builtIn="false" value="__INT_LEAST64_FMTd__=&quot;lld&quot;"/>
<listOptionValue builtIn="false" value="__INT_LEAST64_FMTi__=&quot;lli&quot;"/>
<listOptionValue builtIn="false" value="__UINT_LEAST64_TYPE__=long"/>
<listOptionValue builtIn="false" value="__UINT_LEAST64_MAX__=18446744073709551615ULL"/>
<listOptionValue builtIn="false" value="__UINT_LEAST64_FMTo__=&quot;llo&quot;"/>
<listOptionValue builtIn="false" value="__UINT_LEAST64_FMTu__=&quot;llu&quot;"/>
<listOptionValue builtIn="false" value="__UINT_LEAST64_FMTx__=&quot;llx&quot;"/>
<listOptionValue builtIn="false" value="__UINT_LEAST64_FMTX__=&quot;llX&quot;"/>
<listOptionValue builtIn="false" value="__INT_FAST8_TYPE__=signed"/>
<listOptionValue builtIn="false" value="__INT_FAST8_MAX__=127"/>
<listOptionValue builtIn="false" value="__INT_FAST8_FMTd__=&quot;hhd&quot;"/>
<listOptionValue builtIn="false" value="__INT_FAST8_FMTi__=&quot;hhi&quot;"/>
<listOptionValue builtIn="false" value="__UINT_FAST8_TYPE__=unsigned"/>
<listOptionValue builtIn="false" value="__UINT_FAST8_MAX__=255"/>
<listOptionValue builtIn="false" value="__UINT_FAST8_FMTo__=&quot;hho&quot;"/>
<listOptionValue builtIn="false" value="__UINT_FAST8_FMTu__=&quot;hhu&quot;"/>
<listOptionValue builtIn="false" value="__UINT_FAST8_FMTx__=&quot;hhx&quot;"/>
<listOptionValue builtIn="false" value="__UINT_FAST8_FMTX__=&quot;hhX&quot;"/>
<listOptionValue builtIn="false" value="__INT_FAST16_TYPE__=short"/>
<listOptionValue builtIn="false" value="__INT_FAST16_MAX__=32767"/>
<listOptionValue builtIn="false" value="__INT_FAST16_FMTd__=&quot;hd&quot;"/>
<listOptionValue builtIn="false" value="__INT_FAST16_FMTi__=&quot;hi&quot;"/>
<listOptionValue builtIn="false" value="__UINT_FAST16_TYPE__=unsigned"/>
<listOptionValue builtIn="false" value="__UINT_FAST16_MAX__=65535"/>
<listOptionValue builtIn="false" value="__UINT_FAST16_FMTo__=&quot;ho&quot;"/>
<listOptionValue builtIn="false" value="__UINT_FAST16_FMTu__=&quot;hu&quot;"/>
<listOptionValue builtIn="false" value="__UINT_FAST16_FMTx__=&quot;hx&quot;"/>
<listOptionValue builtIn="false" value="__UINT_FAST16_FMTX__=&quot;hX&quot;"/>
<listOptionValue builtIn="false" value="__INT_FAST32_TYPE__=int"/>
<listOptionValue builtIn="false" value="__INT_FAST32_MAX__=2147483647"/>
<listOptionValue builtIn="false" value="__INT_FAST32_FMTd__=&quot;d&quot;"/>
<listOptionValue builtIn="false" value="__INT_FAST32_FMTi__=&quot;i&quot;"/>
<listOptionValue builtIn="false" value="__UINT_FAST32_TYPE__=unsigned"/>
<listOptionValue builtIn="false" value="__UINT_FAST32_MAX__=4294967295U"/>
<listOptionValue builtIn="false" value="__UINT_FAST32_FMTo__=&quot;o&quot;"/>
<listOptionValue builtIn="false" value="__UINT_FAST32_FMTu__=&quot;u&quot;"/>
<listOptionValue builtIn="false" value="__UINT_FAST32_FMTx__=&quot;x&quot;"/>
<listOptionValue builtIn="false" value="__UINT_FAST32_FMTX__=&quot;X&quot;"/>
<listOptionValue builtIn="false" value="__INT_FAST64_TYPE__=long"/>
<listOptionValue builtIn="false" value="__INT_FAST64_MAX__=9223372036854775807LL"/>
<listOptionValue builtIn="false" value="__INT_FAST64_FMTd__=&quot;lld&quot;"/>
<listOptionValue builtIn="false" value="__INT_FAST64_FMTi__=&quot;lli&quot;"/>
<listOptionValue builtIn="false" value="__UINT_FAST64_TYPE__=long"/>
<listOptionValue builtIn="false" value="__UINT_FAST64_MAX__=18446744073709551615ULL"/>
<listOptionValue builtIn="false" value="__UINT_FAST64_FMTo__=&quot;llo&quot;"/>
<listOptionValue builtIn="false" value="__UINT_FAST64_FMTu__=&quot;llu&quot;"/>
<listOptionValue builtIn="false" value="__UINT_FAST64_FMTx__=&quot;llx&quot;"/>
<listOptionValue builtIn="false" value="__UINT_FAST64_FMTX__=&quot;llX&quot;"/>
<listOptionValue builtIn="false" value="__USER_LABEL_PREFIX__=_"/>
<listOptionValue builtIn="false" value="__FINITE_MATH_ONLY__=0"/>
<listOptionValue builtIn="false" value="__GNUC_GNU_INLINE__=1"/>
<listOptionValue builtIn="false" value="__GCC_ATOMIC_TEST_AND_SET_TRUEVAL=1"/>
<listOptionValue builtIn="false" value="__GCC_ATOMIC_BOOL_LOCK_FREE=1"/>
<listOptionValue builtIn="false" value="__GCC_ATOMIC_CHAR_LOCK_FREE=1"/>
<listOptionValue builtIn="false" value="__GCC_ATOMIC_CHAR16_T_LOCK_FREE=1"/>
<listOptionValue builtIn="false" value="__GCC_ATOMIC_CHAR32_T_LOCK_FREE=1"/>
<listOptionValue builtIn="false" value="__GCC_ATOMIC_WCHAR_T_LOCK_FREE=1"/>
<listOptionValue builtIn="false" value="__GCC_ATOMIC_SHORT_LOCK_FREE=1"/>
<listOptionValue builtIn="false" value="__GCC_ATOMIC_INT_LOCK_FREE=1"/>
<listOptionValue builtIn="false" value="__GCC_ATOMIC_LONG_LOCK_FREE=1"/>
<listOptionValue builtIn="false" value="__GCC_ATOMIC_LLONG_LOCK_FREE=1"/>
<listOptionValue builtIn="false" value="__GCC_ATOMIC_POINTER_LOCK_FREE=1"/>
<listOptionValue builtIn="false" value="__NO_INLINE__=1"/>
<listOptionValue builtIn="false" value="__FLT_EVAL_METHOD__=0"/>
<listOptionValue builtIn="false" value="__FLT_RADIX__=2"/>
<listOptionValue builtIn="false" value="__DECIMAL_DIG__=17"/>
<listOptionValue builtIn="false" value="__xcore__=1"/>
<listOptionValue builtIn="false" value="__XS1B__=1"/>
<listOptionValue builtIn="false" value="__STDC__=1"/>
<listOptionValue builtIn="false" value="__STDC_HOSTED__=1"/>
<listOptionValue builtIn="false" value="__cplusplus=199711L"/>
<listOptionValue builtIn="false" value="__STDC_UTF_16__=1"/>
<listOptionValue builtIn="false" value="__STDC_UTF_32__=1"/>
<listOptionValue builtIn="false" value="XCC_VERSION_YEAR=14"/>
<listOptionValue builtIn="false" value="XCC_VERSION_MONTH=3"/>
<listOptionValue builtIn="false" value="XCC_VERSION_MAJOR=1403"/>
<listOptionValue builtIn="false" value="XCC_VERSION_MINOR=2"/>
<listOptionValue builtIn="false" value="__XCC_HAVE_FLOAT__=1"/>
<listOptionValue builtIn="false" value="_XSCOPE_PROBES_INCLUDE_FILE=&quot;/var/folders/0l/8jd0xy095ps890m302j532580000h5/T//cc8vh80e.h&quot;"/>
</option>
<option id="com.xmos.cxx.compiler.option.include.paths.1031009526" name="com.xmos.cxx.compiler.option.include.paths" superClass="com.xmos.cxx.compiler.option.include.paths" valueType="includePath">
<listOptionValue builtIn="false" value="&quot;${XMOS_TOOL_PATH}/target/include&quot;"/>
<listOptionValue builtIn="false" value="&quot;${XMOS_TOOL_PATH}/target/include/clang&quot;"/>
<listOptionValue builtIn="false" value="&quot;${XMOS_TOOL_PATH}/target/include/c++/v1&quot;"/>
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/lib_logging/doc}&quot;"/>
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/lib_xud/doc/rst/images}&quot;"/>
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/lib_xud/src/user/client}&quot;"/>
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/lib_xud/src/user/class}&quot;"/>
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/lib_xud/src/core/included}&quot;"/>
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/lib_xud/src/core}&quot;"/>
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/lib_logging/doc/rst}&quot;"/>
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/lib_logging/src}&quot;"/>
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/lib_xud}&quot;"/>
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/lib_logging}&quot;"/>
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/lib_xud/src/user/control}&quot;"/>
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/lib_logging/api}&quot;"/>
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/lib_xud/doc/rst}&quot;"/>
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/lib_xud/api}&quot;"/>
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/lib_xud/src}&quot;"/>
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/lib_xud/doc}&quot;"/>
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/lib_xud/src/user}&quot;"/>
</option>
<inputType id="com.xmos.cdt.cxx.compiler.input.cpp.223196941" name="C++" superClass="com.xmos.cdt.cxx.compiler.input.cpp"/>
</tool>
</toolChain>
</folderInfo>
<sourceEntries>
<entry excluding=".build*" flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name=""/>
</sourceEntries>
</configuration>
</storageModule>
<storageModule moduleId="org.eclipse.cdt.core.externalSettings"/>
</cconfiguration>
</storageModule>
<storageModule moduleId="cdtBuildSystem" version="4.0.0">
<project id="lib_xua.null.1378855182" name="lib_xua"/>
</storageModule>
<storageModule moduleId="scannerConfiguration">
<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId=""/>
</storageModule>
<storageModule moduleId="org.eclipse.cdt.core.LanguageSettingsProviders"/>
</cproject>

View File

@@ -1,42 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<projectDescription>
<name>lib_xua</name>
<comment></comment>
<projects>
</projects>
<buildSpec>
<buildCommand>
<name>com.xmos.cdt.core.ProjectInfoSyncBuilder</name>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>com.xmos.cdt.core.LegacyProjectCheckerBuilder</name>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>com.xmos.cdt.core.ModulePathBuilder</name>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>org.eclipse.cdt.managedbuilder.core.genmakebuilder</name>
<triggers>clean,full,incremental,</triggers>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder</name>
<triggers>full,incremental,</triggers>
<arguments>
</arguments>
</buildCommand>
</buildSpec>
<natures>
<nature>org.eclipse.cdt.core.cnature</nature>
<nature>org.eclipse.cdt.managedbuilder.core.managedBuildNature</nature>
<nature>org.eclipse.cdt.managedbuilder.core.ScannerConfigNature</nature>
<nature>com.xmos.cdt.core.XdeProjectNature</nature>
</natures>
</projectDescription>

View File

@@ -1 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?><xproject><repository>lib_xua</repository><partnum>XM-012639-SM</partnum></xproject>

View File

@@ -37,13 +37,13 @@
* \param c_dig channel connected to the clockGen() thread for
* receiving/transmitting samples
*/
void XUA_AudioHub(chanend ?c_aud,
clock ?clk_audio_mclk,
clock ?clk_audio_bclk,
void XUA_AudioHub(chanend ?c_aud,
clock ?clk_audio_mclk,
clock ?clk_audio_bclk,
in port p_mclk_in,
buffered _XUA_CLK_DIR port:32 ?p_lrclk,
buffered _XUA_CLK_DIR port:32 ?p_bclk,
buffered out port:32 (&?p_i2s_dac)[I2S_WIRES_DAC],
buffered out port:32 (&?p_i2s_dac)[I2S_WIRES_DAC],
buffered in port:32 (&?p_i2s_adc)[I2S_WIRES_ADC]
#if (XUA_SPDIF_TX_EN) //&& (SPDIF_TX_TILE != AUDIO_IO_TILE)
, chanend c_spdif_tx

View File

@@ -1,4 +1,4 @@
// Copyright 2011-2021 XMOS LIMITED.
// Copyright 2011-2022 XMOS LIMITED.
// This Software is subject to the terms of the XMOS Public Licence: Version 1.
/*
* @brief Defines relating to device configuration and customisation of lib_xua
@@ -57,8 +57,8 @@
#define PDM_TILE AUDIO_IO_TILE
#endif
/**
* @brief Disable USB functionalty just leaving AudioHub
/**
* @brief Disable USB functionalty just leaving AudioHub
*/
#ifndef XUA_USB_EN
#define XUA_USB_EN 1
@@ -83,7 +83,7 @@
/**
* @brief Number of DSD output channels. Default: 0 (disabled)
*/
#if defined(DSD_CHANS_DAC)
#if defined(DSD_CHANS_DAC) && (DSD_CHANS_DAC != 0)
#if defined(NATIVE_DSD) && (NATIVE_DSD == 0)
#undef NATIVE_DSD
#else
@@ -1140,38 +1140,11 @@
#endif
#endif
/* IAP */
#if defined(IAP) && (IAP == 0)
#undef IAP
/* Always enable explicit feedback EP, even when input stream is present */
#ifndef UAC_FORCE_FEEDBACK_EP
#define UAC_FORCE_FEEDBACK_EP (1)
#endif
/* IAP Interrupt endpoint */
#if defined(IAP_INT_EP) && (IAP_INT_EP == 0)
#undef IAP_INT_EP
#endif
/* IAP EA Native Transport */
#if defined(IAP_EA_NATIVE_TRANS) && (IAP_EA_NATIVE_TRANS == 0)
#undef IAP_EA_NATIVE_TRANS
#endif
#if defined(IAP_EA_NATIVE_TRANS) || defined(__DOXYGEN__)
/**
* @brief Number of supported EA Native Interface Alternative settings.
*
* Only 1 supported
*/
#ifndef IAP_EA_NATIVE_TRANS_ALT_COUNT
#define IAP_EA_NATIVE_TRANS_ALT_COUNT 1
#endif
#if (IAP_EA_NATIVE_TRANS_ALT_COUNT > 1)
/* Only 1 supported */
#error
#endif
#endif
#if (defined(UAC_FORCE_FEEDBACK_EP) && UAC_FORCE_FEEDBACK_EP == 0)
#undef UAC_FORCE_FEEDBACK_EP
#endif
@@ -1228,7 +1201,7 @@ enum USBEndpointNumber_Out
#endif
#ifndef XUA_ENDPOINT_COUNT_CUSTOM_IN
#define XUA_ENDPOINT_COUNT_CUSTOM_IN 0
#define XUA_ENDPOINT_COUNT_CUSTOM_IN 0
#endif
#define ENDPOINT_COUNT_IN (XUA_ENDPOINT_COUNT_IN + XUA_ENDPOINT_COUNT_CUSTOM_IN)
@@ -1244,10 +1217,6 @@ enum USBEndpointNumber_Out
#define MAX_VOL (0x20000000)
#if defined(SU1_ADC_ENABLE) && (SU1_ADC_ENABLE == 0)
#undef SU1_ADC_ENABLE
#endif
#if defined(LEVEL_METER_LEDS) && !defined(LEVEL_UPDATE_RATE)
#define LEVEL_UPDATE_RATE 400000
#endif
@@ -1480,6 +1449,6 @@ enum USBEndpointNumber_Out
#define _XUA_CLK_DIR out
#endif
#if (CODEC_MASTER == 1) && (DSD_CHANS_DAC != 0)
#error CODEC_MASTER with DSD is currently unsupported
#if (CODEC_MASTER == 1) && (DSD_CHANS_DAC != 0)
#error CODEC_MASTER with DSD is currently unsupported
#endif

View File

@@ -1,4 +1,4 @@
// Copyright 2017-2021 XMOS LIMITED.
// Copyright 2017-2022 XMOS LIMITED.
// This Software is subject to the terms of the XMOS Public Licence: Version 1.
#ifndef __XUA_CONF_FULL_H__
#define __XUA_CONF_FULL_H__
@@ -9,6 +9,4 @@
#include "xua_conf_default.h"
#endif

Binary file not shown.

View File

@@ -36,4 +36,3 @@ Older versions of Windows are not guaranteed to operate as expected. Devices are
.. include:: ../../../CHANGELOG.rst

View File

@@ -55,7 +55,7 @@ audio driver and handles locking to the S/PDIF clock source if required (see Ext
Ideally the parity of each word/sample received should be checked. This is done using the built in
``crc32`` function (see ``xs1.h``):
.. literalinclude:: sc_usb_audio/module_usb_audio/clocking/clockgen.xc
.. literalinclude:: lib_xua/src/core/clocking/clockgen.xc
:start-after: //:badParity
:end-before: //:

View File

@@ -1,2 +1,5 @@
XMOSNEWSTYLE = 1
XMOSNEWSTYLE = 2
DOXYGEN_DIRS=../../api
SOURCE_INCLUDE_DIRS=../../../lib_xua
SPHINX_MASTER_DOC=lib_xua

View File

@@ -1277,7 +1277,7 @@ enum libusb_capability {
* still have to call additional libusb functions such as
* \ref libusb_detach_kernel_driver(). */
LIBUSB_CAP_HAS_HID_ACCESS = 0x0100,
/** The library supports detaching of the default USB driver, using
/** The library supports detaching of the default USB driver, using
* \ref libusb_detach_kernel_driver(), if one is set by the OS kernel */
LIBUSB_CAP_SUPPORTS_DETACH_KERNEL_DRIVER = 0x0101
};

View File

@@ -1273,7 +1273,7 @@ enum libusb_capability {
* still have to call additional libusb functions such as
* \ref libusb_detach_kernel_driver(). */
LIBUSB_CAP_HAS_HID_ACCESS = 0x0100,
/** The library supports detaching of the default USB driver, using
/** The library supports detaching of the default USB driver, using
* \ref libusb_detach_kernel_driver(), if one is set by the OS kernel */
LIBUSB_CAP_SUPPORTS_DETACH_KERNEL_DRIVER = 0x0101
};

View File

@@ -1,10 +1,11 @@
VERSION = 2.1.0
VERSION = 3.2.0
DEPENDENT_MODULES = lib_logging(>=3.0.0) \
lib_xassert(>=4.0.0) \
lib_xud(>=2.0.1) \
DEPENDENT_MODULES = lib_logging(>=3.1.0) \
lib_xassert(>=4.1.0) \
lib_xud(>=2.0.2) \
lib_spdif(>=4.0.0) \
lib_mic_array(>=4.0.0)
lib_mic_array(>=4.0.0) \
lib_locks(>=2.1.0)
MODULE_XCC_FLAGS = $(XCC_FLAGS) \
-O3 \

View File

@@ -28,7 +28,7 @@ static inline void DoDsdNative(unsigned samplesOut[], unsigned &dsdSample_l, uns
asm volatile("out res[%0], %1"::"r"(p_dsd_dac[1]),"r"(dsdSample_r));
}
/* This function performs the DOP loop and collects 16b of DSD per loop
/* This function performs the DOP loop and collects 16b of DSD per loop
and outputs a 32b word into the port buffer every other cycle. */
static inline void DoDsdDop(int &everyOther, unsigned samplesOut[], unsigned &dsdSample_l, unsigned &dsdSample_r, unsigned divide)
{
@@ -38,7 +38,7 @@ static inline void DoDsdDop(int &everyOther, unsigned samplesOut[], unsigned &ds
dsdSample_r = ((samplesOut[1] & 0xffff00) << 8);
everyOther = 1;
}
else
else
{
everyOther = 0;
dsdSample_l = dsdSample_l | ((samplesOut[0] & 0xffff00) >> 8);
@@ -77,7 +77,7 @@ static inline int DoDsdDopCheck(unsigned &dsdMode, int &dsdCount, unsigned curSa
dsdMarker = DSD_MARKER_2;
}
}
else if(dsdMode == DSD_MODE_DOP)
else if(dsdMode == DSD_MODE_DOP)
{
/* If we are running in DOP mode, check if we need to come out */
if((DSD_MASK(samplesOut[0]) != DSD_MARKER_1) && (DSD_MASK(samplesOut[1]) != DSD_MARKER_1))

View File

@@ -73,7 +73,7 @@ void InitPorts_master(unsigned divide, buffered _XUA_CLK_DIR port:32 p_lrclk, bu
#endif
}
#else
#else
void InitPorts_slave(unsigned divide, buffered _XUA_CLK_DIR port:32 p_lrclk, buffered _XUA_CLK_DIR port:32 p_bclk, buffered out port:32 (&?p_i2s_dac)[I2S_WIRES_DAC], buffered in port:32 (&?p_i2s_adc)[I2S_WIRES_ADC])
{

View File

@@ -32,7 +32,7 @@
#if (XUA_NUM_PDM_MICS > 0)
#include "xua_pdm_mic.h"
#endif
#endif
#if (AUD_TO_USB_RATIO > 1)
#include "src.h"
@@ -76,7 +76,7 @@ void InitPorts_slave
#else
void InitPorts_master
#endif
(unsigned divide, buffered _XUA_CLK_DIR port:32 p_lrclk, buffered _XUA_CLK_DIR port:32 p_bclk, buffered out port:32 (&?p_i2s_dac)[I2S_WIRES_DAC],
(unsigned divide, buffered _XUA_CLK_DIR port:32 p_lrclk, buffered _XUA_CLK_DIR port:32 p_bclk, buffered out port:32 (&?p_i2s_dac)[I2S_WIRES_DAC],
buffered in port:32 (&?p_i2s_adc)[I2S_WIRES_ADC]);
@@ -164,7 +164,7 @@ static inline int HandleSampleClock(int frameCount, buffered _XUA_CLK_DIR port:3
if(I2S_MODE_TDM)
{
/* Only check for the rising edge of frame sync being in the right place because falling edge timing not specified */
if (frameCount == 1)
if (frameCount == 1)
{
lrval &= 0xc0000000; // Mask off last two (MSB) frame clock bits which are the most recently sampled
syncError += (lrval != 0x80000000); // We need MSB = 1 and MSB-1 = 0 to signify rising edge
@@ -177,12 +177,12 @@ static inline int HandleSampleClock(int frameCount, buffered _XUA_CLK_DIR port:3
}
else
{
if(frameCount == 0)
if(frameCount == 0)
syncError += (lrval != 0x80000000);
else
syncError += (lrval != 0x7FFFFFFF);
}
return syncError;
#else
@@ -200,7 +200,7 @@ static inline int HandleSampleClock(int frameCount, buffered _XUA_CLK_DIR port:3
else
p_lrclk <: 0x7fffffff;
}
return 0;
#endif
@@ -219,7 +219,7 @@ unsigned static AudioHub_MainLoop(chanend ?c_out, chanend ?c_spd_out
#if (XUA_NUM_PDM_MICS > 0)
, chanend c_pdm_pcm
#endif
, buffered _XUA_CLK_DIR port:32 ?p_lrclk,
, buffered _XUA_CLK_DIR port:32 ?p_lrclk,
buffered _XUA_CLK_DIR port:32 ?p_bclk,
buffered out port:32 (&?p_i2s_dac)[I2S_WIRES_DAC],
buffered in port:32 (&?p_i2s_adc)[I2S_WIRES_ADC]
@@ -322,14 +322,14 @@ unsigned static AudioHub_MainLoop(chanend ?c_out, chanend ?c_spd_out
InitPorts_master(divide, p_lrclk, p_bclk, p_i2s_dac, p_i2s_adc);
#endif
}
/* Note we always expect syncError to be 0 when we are master */
while(!syncError)
{
#if (DSD_CHANS_DAC != 0) && (NUM_USB_CHAN_OUT > 0)
if(dsdMode == DSD_MODE_NATIVE)
if(dsdMode == DSD_MODE_NATIVE)
DoDsdNative(samplesOut, dsdSample_l, dsdSample_r, divide);
else if(dsdMode == DSD_MODE_DOP)
else if(dsdMode == DSD_MODE_DOP)
DoDsdDop(everyOther, samplesOut, dsdSample_l, dsdSample_r, divide);
else
#endif
@@ -471,7 +471,7 @@ unsigned static AudioHub_MainLoop(chanend ?c_out, chanend ?c_spd_out
#endif
}
frameCount++;
frameCount++;
#if (I2S_CHANS_ADC != 0)
index = 0;
@@ -663,7 +663,7 @@ void XUA_AudioHub(chanend ?c_aud, clock ?clk_audio_mclk, clock ?clk_audio_bclk,
in port p_mclk_in,
buffered _XUA_CLK_DIR port:32 ?p_lrclk,
buffered _XUA_CLK_DIR port:32 ?p_bclk,
buffered out port:32 (&?p_i2s_dac)[I2S_WIRES_DAC],
buffered out port:32 (&?p_i2s_dac)[I2S_WIRES_DAC],
buffered in port:32 (&?p_i2s_adc)[I2S_WIRES_ADC]
#if (XUA_SPDIF_TX_EN) //&& (SPDIF_TX_TILE != AUDIO_IO_TILE)
, chanend c_spdif_out
@@ -717,7 +717,7 @@ void XUA_AudioHub(chanend ?c_aud, clock ?clk_audio_mclk, clock ?clk_audio_bclk,
start_clock(clk_mst_spd);
#endif
#endif
/* Perform required CODEC/ADC/DAC initialisation */
AudioHwInit();

View File

@@ -748,28 +748,31 @@ void XUA_Buffer_Decouple(chanend c_mix_out
outct(c_mix_out, SET_SAMPLE_FREQ);
outuint(c_mix_out, sampFreq);
inUnderflow = 1;
SET_SHARED_GLOBAL(g_aud_to_host_rdptr, aud_to_host_fifo_start);
SET_SHARED_GLOBAL(g_aud_to_host_wrptr, aud_to_host_fifo_start);
SET_SHARED_GLOBAL(g_aud_to_host_dptr,aud_to_host_fifo_start+4);
/* Set buffer to send back to zeros buffer */
SET_SHARED_GLOBAL(g_aud_to_host_buffer, g_aud_to_host_zeros);
/* Update size of zeros buffer (and sampsToWrite) */
SetupZerosSendBuffer(aud_to_host_usb_ep, sampFreq, g_curSubSlot_In);
/* Reset OUT buffer state */
outUnderflow = 1;
SET_SHARED_GLOBAL(g_aud_from_host_rdptr, aud_from_host_fifo_start);
SET_SHARED_GLOBAL(g_aud_from_host_wrptr, aud_from_host_fifo_start);
SET_SHARED_GLOBAL(aud_data_remaining_to_device, 0);
if(outOverflow)
if(sampFreq != AUDIO_STOP_FOR_DFU)
{
/* If we were previously in overflow we wont have marked as ready */
XUD_SetReady_OutPtr(aud_from_host_usb_ep, aud_from_host_fifo_start+4);
outOverflow = 0;
inUnderflow = 1;
SET_SHARED_GLOBAL(g_aud_to_host_rdptr, aud_to_host_fifo_start);
SET_SHARED_GLOBAL(g_aud_to_host_wrptr, aud_to_host_fifo_start);
SET_SHARED_GLOBAL(g_aud_to_host_dptr,aud_to_host_fifo_start+4);
/* Set buffer to send back to zeros buffer */
SET_SHARED_GLOBAL(g_aud_to_host_buffer, g_aud_to_host_zeros);
/* Update size of zeros buffer (and sampsToWrite) */
SetupZerosSendBuffer(aud_to_host_usb_ep, sampFreq, g_curSubSlot_In);
/* Reset OUT buffer state */
outUnderflow = 1;
SET_SHARED_GLOBAL(g_aud_from_host_rdptr, aud_from_host_fifo_start);
SET_SHARED_GLOBAL(g_aud_from_host_wrptr, aud_from_host_fifo_start);
SET_SHARED_GLOBAL(aud_data_remaining_to_device, 0);
if(outOverflow)
{
/* If we were previously in overflow we wont have marked as ready */
XUD_SetReady_OutPtr(aud_from_host_usb_ep, aud_from_host_fifo_start+4);
outOverflow = 0;
}
}
/* Wait for handshake back and pass back up */
@@ -780,7 +783,8 @@ void XUA_Buffer_Decouple(chanend c_mix_out
ENABLE_INTERRUPTS();
speedRem = 0;
if(sampFreq != AUDIO_STOP_FOR_DFU)
speedRem = 0;
continue;
}
#if (AUDIO_CLASS == 2)

View File

@@ -72,13 +72,8 @@
//int ksp_enter, ksp_exit, r11_store;
#if defined(__XS2A__) || defined(__XS3A__)
#define ISSUE_MODE_SINGLE ".issue_mode single\n"
#define ISSUE_MODE_DUAL ".issue_mode dual\n"
#else
#define ISSUE_MODE_SINGLE
#define ISSUE_MODE_DUAL
#endif
#define do_interrupt_handler(f,args) \
asm(ISSUE_MODE_SINGLE\

View File

@@ -1,4 +1,4 @@
// Copyright 2011-2021 XMOS LIMITED.
// Copyright 2011-2022 XMOS LIMITED.
// This Software is subject to the terms of the XMOS Public Licence: Version 1.
#include "xua.h"
#if XUA_USB_EN
@@ -21,9 +21,10 @@
#include "testct_byref.h"
#if( 0 < HID_CONTROLS )
#include "xua_hid_report_descriptor.h"
#include "xua_hid_report.h"
#include "user_hid.h"
unsigned char g_hidData[HID_MAX_DATA_BYTES] = {0};
#include "xua_hid.h"
unsigned char g_hidData[HID_MAX_DATA_BYTES] = {0U};
#endif
void GetADCCounts(unsigned samFreq, int &min, int &mid, int &max);
@@ -90,9 +91,9 @@ unsigned int fb_clocks[4];
#define FB_TOLERANCE 0x100
void XUA_Buffer(
register chanend c_aud_out,
register chanend c_aud_out,
#if (NUM_USB_CHAN_IN > 0)
register chanend c_aud_in,
register chanend c_aud_in,
#endif
#if (NUM_USB_CHAN_IN == 0) || defined (UAC_FORCE_FEEDBACK_EP)
chanend c_aud_fb,
@@ -195,9 +196,9 @@ unsafe{volatile unsigned * unsafe masterClockFreq_ptr;}
* @param c_aud_fb chanend for feeback to xud
* @return void
*/
void XUA_Buffer_Ep(register chanend c_aud_out,
void XUA_Buffer_Ep(register chanend c_aud_out,
#if (NUM_USB_CHAN_IN > 0)
register chanend c_aud_in,
register chanend c_aud_in,
#endif
#if (NUM_USB_CHAN_IN == 0) || defined (UAC_FORCE_FEEDBACK_EP)
chanend c_aud_fb,
@@ -372,10 +373,14 @@ void XUA_Buffer_Ep(register chanend c_aud_out,
#endif
#if( 0 < HID_CONTROLS )
{
int hidDataLength = hidGetReportLength();
XUD_SetReady_In(ep_hid, g_hidData, hidDataLength);
}
while (!hidIsReportDescriptorPrepared())
;
UserHIDInit();
unsigned hid_ready_flag = 0U;
unsigned hid_ready_id = 0U;
#endif
#if (AUDIO_CLASS == 1)
@@ -385,6 +390,8 @@ void XUA_Buffer_Ep(register chanend c_aud_out,
#endif
#endif
timer tmr;
while(1)
{
XUD_Result_t result;
@@ -441,9 +448,9 @@ void XUA_Buffer_Ep(register chanend c_aud_out,
if(receivedSampleFreq != AUDIO_STOP_FOR_DFU)
{
sampleFreq = receivedSampleFreq;
#ifdef FB_TOLERANCE_TEST
#ifdef FB_TOLERANCE_TEST
expected_fb = ((sampleFreq * 0x2000) / frameTime);
#endif
#endif
/* Reset FB */
/* Note, Endpoint 0 will hold off host for a sufficient period to allow our feedback
* to stabilise (i.e. sofCount == 128 to fire) */
@@ -559,7 +566,7 @@ void XUA_Buffer_Ep(register chanend c_aud_out,
{
unsigned usb_speed;
GET_SHARED_GLOBAL(usb_speed, g_curUsbSpeed);
#if FB_USE_REF_CLOCK
unsigned long long feedbackMul = 64ULL;
@@ -635,7 +642,7 @@ void XUA_Buffer_Ep(register chanend c_aud_out,
clockcounter = 0;
}
#else
/* Assuming 48kHz from a 24.576 master clock (0.0407uS period)
* MCLK ticks per SOF = 125uS / 0.0407 = 3072 MCLK ticks per SOF.
* expected Feedback is 48000/8000 = 6 samples. so 0x60000 in 16:16 format.
@@ -704,7 +711,7 @@ void XUA_Buffer_Ep(register chanend c_aud_out,
#endif
sofCount++;
}
break;
break;
#if (NUM_USB_CHAN_IN > 0)
/* Sent audio packet DEVICE -> HOST */
@@ -712,8 +719,8 @@ void XUA_Buffer_Ep(register chanend c_aud_out,
{
/* Inform stream that buffer sent */
SET_SHARED_GLOBAL0(g_aud_to_host_flag, bufferIn+1);
break;
}
break;
#endif
#if (NUM_USB_CHAN_OUT > 0)
@@ -733,8 +740,8 @@ void XUA_Buffer_Ep(register chanend c_aud_out,
{
XUD_SetReady_In(ep_aud_fb, (fb_clocks, unsigned char[]), 3);
}
break;
}
break;
#endif
/* Received Audio packet HOST -> DEVICE. Datalength written to length */
case XUD_GetData_Select(c_aud_out, ep_aud_out, length, result):
@@ -745,164 +752,165 @@ void XUA_Buffer_Ep(register chanend c_aud_out,
/* Sync with decouple thread */
SET_SHARED_GLOBAL0(g_aud_from_host_flag, 1);
}
break;
}
#endif
#ifdef MIDI
case XUD_GetData_Select(c_midi_from_host, ep_midi_from_host, length, result):
case XUD_GetData_Select(c_midi_from_host, ep_midi_from_host, length, result):
if((result == XUD_RES_OKAY) && (length > 0))
{
/* Get buffer data from host - MIDI OUT from host always into a single buffer */
midi_data_remaining_to_device = length;
midi_from_host_rdptr = midi_from_host_buffer;
if (midi_data_remaining_to_device)
if((result == XUD_RES_OKAY) && (length > 0))
{
read_via_xc_ptr(datum, midi_from_host_rdptr);
outuint(c_midi, datum);
midi_from_host_rdptr += 4;
midi_data_remaining_to_device -= 4;
/* Get buffer data from host - MIDI OUT from host always into a single buffer */
midi_data_remaining_to_device = length;
midi_from_host_rdptr = midi_from_host_buffer;
if (midi_data_remaining_to_device)
{
read_via_xc_ptr(datum, midi_from_host_rdptr);
outuint(c_midi, datum);
midi_from_host_rdptr += 4;
midi_data_remaining_to_device -= 4;
}
}
}
break;
break;
/* MIDI IN to host */
case XUD_SetData_Select(c_midi_to_host, ep_midi_to_host, result):
/* MIDI IN to host */
case XUD_SetData_Select(c_midi_to_host, ep_midi_to_host, result):
/* The buffer has been sent to the host, so we can ack the midi thread */
if (midi_data_collected_from_device != 0)
{
/* Swap the collecting and sending buffer */
swap(midi_to_host_buffer_being_collected, midi_to_host_buffer_being_sent);
/* The buffer has been sent to the host, so we can ack the midi thread */
if (midi_data_collected_from_device != 0)
{
/* Swap the collecting and sending buffer */
swap(midi_to_host_buffer_being_collected, midi_to_host_buffer_being_sent);
/* Request to send packet */
XUD_SetReady_InPtr(ep_midi_to_host, midi_to_host_buffer_being_sent, midi_data_collected_from_device);
/* Request to send packet */
XUD_SetReady_InPtr(ep_midi_to_host, midi_to_host_buffer_being_sent, midi_data_collected_from_device);
/* Mark as waiting for host to poll us */
midi_waiting_on_send_to_host = 1;
/* Reset the collected data count */
midi_data_collected_from_device = 0;
}
else
{
midi_waiting_on_send_to_host = 0;
}
break;
/* Mark as waiting for host to poll us */
midi_waiting_on_send_to_host = 1;
/* Reset the collected data count */
midi_data_collected_from_device = 0;
}
else
{
midi_waiting_on_send_to_host = 0;
}
break;
#endif
#ifdef IAP
/* IAP OUT from host. Datalength writen to tmp */
case XUD_GetData_Select(c_iap_from_host, ep_iap_from_host, length, result):
/* IAP OUT from host. Datalength writen to tmp */
case XUD_GetData_Select(c_iap_from_host, ep_iap_from_host, length, result):
if((result == XUD_RES_OKAY) && (length > 0))
{
iap_data_remaining_to_device = length;
if(iap_data_remaining_to_device)
if((result == XUD_RES_OKAY) && (length > 0))
{
// Send length first so iAP thread knows how much data to expect
// Don't expect ack from this to make it simpler
outuint(c_iap, iap_data_remaining_to_device);
iap_data_remaining_to_device = length;
/* Send out first byte in buffer */
datum_iap = iap_from_host_buffer[0];
outuint(c_iap, datum_iap);
if(iap_data_remaining_to_device)
{
// Send length first so iAP thread knows how much data to expect
// Don't expect ack from this to make it simpler
outuint(c_iap, iap_data_remaining_to_device);
/* Set read ptr to next byte in buffer */
iap_from_host_rdptr = 1;
iap_data_remaining_to_device -= 1;
/* Send out first byte in buffer */
datum_iap = iap_from_host_buffer[0];
outuint(c_iap, datum_iap);
/* Set read ptr to next byte in buffer */
iap_from_host_rdptr = 1;
iap_data_remaining_to_device -= 1;
}
}
}
break;
break;
/* IAP IN to host */
case XUD_SetData_Select(c_iap_to_host, ep_iap_to_host, result):
/* IAP IN to host */
case XUD_SetData_Select(c_iap_to_host, ep_iap_to_host, result):
if(result == XUD_RES_RST)
{
XUD_ResetEndpoint(ep_iap_to_host, null);
if(result == XUD_RES_RST)
{
XUD_ResetEndpoint(ep_iap_to_host, null);
#ifdef IAP_INT_EP
XUD_ResetEndpoint(ep_iap_to_host_int, null);
XUD_ResetEndpoint(ep_iap_to_host_int, null);
#endif
iap_send_reset(c_iap);
iap_draining_chan = 1; // Drain c_iap until a reset is sent back
iap_data_collected_from_device = 0;
iap_data_remaining_to_device = -1;
iap_expected_data_length = 0;
iap_from_host_rdptr = 0;
}
else
{
/* Send out an iAP packet to host, ACK last msg from iAP to let it know we can move on..*/
iap_send_ack(c_iap);
}
break; /* IAP IN to host */
iap_send_reset(c_iap);
iap_draining_chan = 1; // Drain c_iap until a reset is sent back
iap_data_collected_from_device = 0;
iap_data_remaining_to_device = -1;
iap_expected_data_length = 0;
iap_from_host_rdptr = 0;
}
else
{
/* Send out an iAP packet to host, ACK last msg from iAP to let it know we can move on..*/
iap_send_ack(c_iap);
}
break; /* IAP IN to host */
#ifdef IAP_INT_EP
case XUD_SetData_Select(c_iap_to_host_int, ep_iap_to_host_int, result):
case XUD_SetData_Select(c_iap_to_host_int, ep_iap_to_host_int, result):
/* Do nothing.. */
/* Note, could get a reset notification here, but deal with it in the case above */
break;
/* Do nothing.. */
/* Note, could get a reset notification here, but deal with it in the case above */
break;
#endif
#ifdef IAP_EA_NATIVE_TRANS
/* iAP EA Native Transport OUT from host */
case XUD_GetData_Select(c_iap_ea_native_out, ep_iap_ea_native_out, iap_ea_native_rx_length, result):
if ((result == XUD_RES_OKAY) && iap_ea_native_rx_length > 0)
{
// Notify EA Protocol user code we have iOS app data from XUD
iAP2_EANativeTransport_writeToChan_start(c_iap_ea_native_data, EA_NATIVE_SEND_DATA);
}
break;
/* iAP EA Native Transport OUT from host */
case XUD_GetData_Select(c_iap_ea_native_out, ep_iap_ea_native_out, iap_ea_native_rx_length, result):
if ((result == XUD_RES_OKAY) && iap_ea_native_rx_length > 0)
{
// Notify EA Protocol user code we have iOS app data from XUD
iAP2_EANativeTransport_writeToChan_start(c_iap_ea_native_data, EA_NATIVE_SEND_DATA);
}
break;
/* iAP EA Native Transport IN to host */
case XUD_SetData_Select(c_iap_ea_native_in, ep_iap_ea_native_in, result):
switch (result)
{
case XUD_RES_RST:
XUD_ResetEndpoint(ep_iap_ea_native_in, null);
// Notify user code of USB reset to allow any state to be cleared
iAP2_EANativeTransport_writeToChan_start(c_iap_ea_native_data, EA_NATIVE_SEND_CONTROL);
// Set up the control flag to send to EA Protocol user code when it responds
iap_ea_native_control_flag = EA_NATIVE_RESET;
iap_ea_native_control_to_send = 1;
break;
/* iAP EA Native Transport IN to host */
case XUD_SetData_Select(c_iap_ea_native_in, ep_iap_ea_native_in, result):
switch (result)
{
case XUD_RES_RST:
XUD_ResetEndpoint(ep_iap_ea_native_in, null);
// Notify user code of USB reset to allow any state to be cleared
iAP2_EANativeTransport_writeToChan_start(c_iap_ea_native_data, EA_NATIVE_SEND_CONTROL);
// Set up the control flag to send to EA Protocol user code when it responds
iap_ea_native_control_flag = EA_NATIVE_RESET;
iap_ea_native_control_to_send = 1;
break;
case XUD_RES_OKAY: // EA Protocol user data successfully passed to XUD
// Notify user code
iAP2_EANativeTransport_writeToChan_start(c_iap_ea_native_data, EA_NATIVE_SEND_CONTROL);
// Set up the control flag to send to EA Protocol user code when it responds
iap_ea_native_control_flag = EA_NATIVE_DATA_SENT;
iap_ea_native_control_to_send = 1;
break;
}
break;
//::
case XUD_RES_OKAY: // EA Protocol user data successfully passed to XUD
// Notify user code
iAP2_EANativeTransport_writeToChan_start(c_iap_ea_native_data, EA_NATIVE_SEND_CONTROL);
// Set up the control flag to send to EA Protocol user code when it responds
iap_ea_native_control_flag = EA_NATIVE_DATA_SENT;
iap_ea_native_control_to_send = 1;
break;
}
break;
//::
#endif
#endif
#if( 0 < HID_CONTROLS )
/* HID Report Data */
/* HID Report Data */
case XUD_SetData_Select(c_hid, ep_hid, result):
{
int hidDataLength = hidGetReportLength();
UserHIDGetData(g_hidData);
XUD_SetReady_In(ep_hid, g_hidData, hidDataLength);
}
break;
hid_ready_flag = 0U;
unsigned reportTime;
tmr :> reportTime;
hidCaptureReportTime(hid_ready_id, reportTime);
hidCalcNextReportTime(hid_ready_id);
hidClearChangePending(hid_ready_id);
break;
#endif
#ifdef MIDI
/* Received word from MIDI thread - Check for ACK or Data */
/* Received word from MIDI thread - Check for ACK or Data */
case midi_get_ack_or_data(c_midi, is_ack, datum):
if (is_ack)
{
/* An ack from the midi/uart thread means it has accepted some data we sent it
* we are okay to send another word */
* we are okay to send another word */
if (midi_data_remaining_to_device <= 0)
{
/* We have read an entire packet - Mark ready to receive another */
@@ -967,7 +975,7 @@ void XUA_Buffer_Ep(register chanend c_aud_out,
if (is_ack_iap)
{
/* An ack from the iap/uart thread means it has accepted some data we sent it
* we are okay to send another word */
* we are okay to send another word */
if (iap_data_remaining_to_device == 0)
{
/* We have read an entire packet - Mark ready to receive another */
@@ -1000,7 +1008,7 @@ void XUA_Buffer_Ep(register chanend c_aud_out,
}
else
{
// Too many events from device - drop
// Too many events from device - drop
}
/* Once we have the whole message, sent it to host */
@@ -1038,7 +1046,7 @@ void XUA_Buffer_Ep(register chanend c_aud_out,
}
break;
# if IAP_EA_NATIVE_TRANS
# if IAP_EA_NATIVE_TRANS
/* Change of EA Native Transport interface setting */
case inuint_byref(c_iap_ea_native_ctrl, iap_ea_native_interface_alt_setting):
/* Handshake */
@@ -1096,14 +1104,33 @@ void XUA_Buffer_Ep(register chanend c_aud_out,
break;
}
break;
//::
#endif
#endif // if IAP_EA_NATIVE_TRANS
#endif // ifdef IAP
default:
#if ( 0 < HID_CONTROLS )
if (!hid_ready_flag)
{
for (unsigned id = hidIsReportIdInUse(); id < hidGetReportIdLimit(); id++)
{
if ( hidIsChangePending(id) || !HidIsSetIdleSilenced(id) )
{
int hidDataLength = (int) UserHIDGetData(id, g_hidData);
XUD_SetReady_In(ep_hid, g_hidData, hidDataLength);
hid_ready_id = id;
hid_ready_flag = 1U;
break;
}
}
}
#endif
break;
//::
}
}
}
#endif /* XUA_USB_EN */

View File

@@ -1,4 +1,4 @@
// Copyright 2011-2021 XMOS LIMITED.
// Copyright 2011-2022 XMOS LIMITED.
// This Software is subject to the terms of the XMOS Public Licence: Version 1.
#include <xs1.h>
@@ -665,7 +665,7 @@ void clockGen (streaming chanend ?c_spdif_rx, chanend ?c_adat_rx, out port p, ch
/* Inspect for if we need to produce an edge */
if ((adatCounters.receivedSamples >= adatCounters.samplesPerTick))
{
/* Check edge is about right... S/PDIF may have changed freq... */
/* Check edge is about right... ADAT may have changed freq... */
if (timeafter(adatReceivedTime, (timeLastEdge + LOCAL_CLOCK_INCREMENT - LOCAL_CLOCK_MARGIN)))
{
/* Record edge time */

View File

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

View File

@@ -1,4 +1,4 @@
// Copyright 2011-2021 XMOS LIMITED.
// Copyright 2011-2022 XMOS LIMITED.
// This Software is subject to the terms of the XMOS Public Licence: Version 1.
/**
* @brief Implements endpoint zero for an USB Audio 1.0/2.0 device
@@ -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
@@ -258,8 +258,8 @@ void XUA_Endpoint0_setVendorId(unsigned short vid) {
}
void concatenateAndCopyStrings(char* string1, char* string2, char* string_buffer) {
debug_printf("concatenateAndCopyStrings() for \"%s\" and \"%s\"\n", string1, string2);
debug_printf("concatenateAndCopyStrings() for \"%s\" and \"%s\"\n", string1, string2);
memset(string_buffer, '\0', strlen(string_buffer));
uint32_t remaining_buffer_size = MIN(strlen(string1), XUA_MAX_STR_LEN-1);
@@ -313,7 +313,7 @@ void XUA_Endpoint0_setStrTable() {
concatenateAndCopyStrings(g_product_str, "", g_strTable.usbInputTermStr_Audio2);
concatenateAndCopyStrings(g_product_str, "", g_strTable.usbOutputTermStr_Audio2);
#endif
// update Serial strings
concatenateAndCopyStrings(g_serial_str, "", g_strTable.serialStr);
}
@@ -483,7 +483,7 @@ void XUA_Endpoint0_init(chanend c_ep0_out, chanend c_ep0_in, NULLABLE_RESOURCE(c
if (DFUReportResetState(null))
{
assert((c_audioControl != NULL) && msg("DFU not supported when c_audioControl is null"));
/* Stop audio */
outuint(c_audioControl, SET_SAMPLE_FREQ);
outuint(c_audioControl, AUDIO_STOP_FOR_DFU);
@@ -492,39 +492,47 @@ void XUA_Endpoint0_init(chanend c_ep0_out, chanend c_ep0_in, NULLABLE_RESOURCE(c
}
#endif
#ifdef XUA_USB_DESCRIPTOR_OVERWRITE_RATE_RES //change USB descriptor frequencies and bit resolution values here
#ifdef XUA_USB_DESCRIPTOR_OVERWRITE_RATE_RES //change USB descriptor frequencies and bit resolution values here
cfgDesc_Audio1[USB_AS_IN_INTERFACE_DESCRIPTOR_OFFSET_SUB_FRAME] = get_device_to_usb_bit_res() >> 3; //sub frame rate = bit rate /8
cfgDesc_Audio1[USB_AS_IN_INTERFACE_DESCRIPTOR_OFFSET_SUB_FRAME + 1] = (get_device_to_usb_bit_res() & 0xff); //bit resolution
const int num_of_usb_descriptor_freq = 3; //This should be =3 according to the comments "using a value of <=2 or > 7 for num_freqs_a1 causes enumeration issues on Windows" in xua_ep0_descriptors.h
cfgDesc_Audio1[USB_AS_OUT_INTERFACE_DESCRIPTOR_OFFSET_SUB_FRAME] = get_usb_to_device_bit_res() >> 3; //sub frame rate = bit rate /8
cfgDesc_Audio1[USB_AS_OUT_INTERFACE_DESCRIPTOR_OFFSET_SUB_FRAME + 1] = (get_usb_to_device_bit_res() & 0xff); //bit resolution
#if( 0 < NUM_USB_CHAN_IN )
const unsigned num_of_usb_descriptor_freq=3; //This should be =3 according to the comments "using a value of <=2 or > 7 for num_freqs_a1 causes enumeration issues on Windows" in xua_ep0_descriptors.h
int i=0;
for(i=0;i<num_of_usb_descriptor_freq;i++)
cfgDesc_Audio1[USB_AS_IN_INTERFACE_DESCRIPTOR_OFFSET_SUB_FRAME] = get_device_to_usb_bit_res() >> 3; //sub frame rate = bit rate /8
cfgDesc_Audio1[USB_AS_IN_INTERFACE_DESCRIPTOR_OFFSET_SUB_FRAME + 1] = (get_device_to_usb_bit_res() & 0xff); //bit resolution
for(int i=0;i<num_of_usb_descriptor_freq;i++)
{
cfgDesc_Audio1[USB_AS_IN_INTERFACE_DESCRIPTOR_OFFSET_FREQ + 3*i] = get_device_to_usb_rate() & 0xff;
cfgDesc_Audio1[USB_AS_IN_INTERFACE_DESCRIPTOR_OFFSET_FREQ + 3*i + 1] = (get_device_to_usb_rate() & 0xff00)>> 8;
cfgDesc_Audio1[USB_AS_IN_INTERFACE_DESCRIPTOR_OFFSET_FREQ + 3*i + 2] = (get_device_to_usb_rate() & 0xff0000)>> 16;
}
cfgDesc_Audio1[USB_AS_IN_EP_DESCRIPTOR_OFFSET_MAXPACKETSIZE] = ((get_device_to_usb_bit_res() >> 3) * MAX_PACKET_SIZE_MULT_IN_FS) & 0xff; //max packet size
cfgDesc_Audio1[USB_AS_IN_EP_DESCRIPTOR_OFFSET_MAXPACKETSIZE + 1] = (((get_device_to_usb_bit_res() >> 3) * MAX_PACKET_SIZE_MULT_IN_FS) & 0xff00) >> 8; //max packet size
for(i=0;i<num_of_usb_descriptor_freq;i++)
#endif // NUM_USB_CHAN_IN
#if( 0 < NUM_USB_CHAN_OUT )
cfgDesc_Audio1[USB_AS_OUT_INTERFACE_DESCRIPTOR_OFFSET_SUB_FRAME] = get_usb_to_device_bit_res() >> 3; //sub frame rate = bit rate /8
cfgDesc_Audio1[USB_AS_OUT_INTERFACE_DESCRIPTOR_OFFSET_SUB_FRAME + 1] = (get_usb_to_device_bit_res() & 0xff); //bit resolution
for(int i=0;i<num_of_usb_descriptor_freq;i++)
{
cfgDesc_Audio1[USB_AS_OUT_INTERFACE_DESCRIPTOR_OFFSET_FREQ + 3*i] = get_usb_to_device_rate() & 0xff;
cfgDesc_Audio1[USB_AS_OUT_INTERFACE_DESCRIPTOR_OFFSET_FREQ + 3*i + 1] = (get_usb_to_device_rate() & 0xff00)>> 8;
cfgDesc_Audio1[USB_AS_OUT_INTERFACE_DESCRIPTOR_OFFSET_FREQ + 3*i + 2] = (get_usb_to_device_rate() & 0xff0000)>> 16;
}
cfgDesc_Audio1[USB_AS_IN_EP_DESCRIPTOR_OFFSET_MAXPACKETSIZE] = ((get_device_to_usb_bit_res() >> 3) * MAX_PACKET_SIZE_MULT_IN_FS) & 0xff; //max packet size
cfgDesc_Audio1[USB_AS_IN_EP_DESCRIPTOR_OFFSET_MAXPACKETSIZE + 1] = (((get_device_to_usb_bit_res() >> 3) * MAX_PACKET_SIZE_MULT_IN_FS) & 0xff00) >> 8; //max packet size
cfgDesc_Audio1[USB_AS_OUT_EP_DESCRIPTOR_OFFSET_MAXPACKETSIZE] = ((get_usb_to_device_bit_res() >> 3) * MAX_PACKET_SIZE_MULT_OUT_FS) & 0xff; //max packet size
cfgDesc_Audio1[USB_AS_OUT_EP_DESCRIPTOR_OFFSET_MAXPACKETSIZE + 1] = (((get_usb_to_device_bit_res() >> 3) * MAX_PACKET_SIZE_MULT_OUT_FS) & 0xff00) >> 8; //max packet size
cfgDesc_Audio1[USB_AS_OUT_EP_DESCRIPTOR_OFFSET_MAXPACKETSIZE] = ((get_usb_to_device_bit_res() >> 3) * MAX_PACKET_SIZE_MULT_OUT_FS) & 0xff; //max packet size
cfgDesc_Audio1[USB_AS_OUT_EP_DESCRIPTOR_OFFSET_MAXPACKETSIZE + 1] = (((get_usb_to_device_bit_res() >> 3) * MAX_PACKET_SIZE_MULT_OUT_FS) & 0xff00) >> 8; //max packet size
#endif // NUM_USB_CHAN_OUT
#endif
#endif // XUA_USB_DESCRIPTOR_OVERWRITE_RATE_RES
#if( 0 < HID_CONTROLS )
hidReportInit();
hidPrepareReportDescriptor();
size_t hidReportDescriptorLength = hidGetReportDescriptorLength();

View File

@@ -1,4 +1,4 @@
// Copyright 2011-2021 XMOS LIMITED.
// Copyright 2011-2022 XMOS LIMITED.
// This Software is subject to the terms of the XMOS Public Licence: Version 1.
/**
* @file xua_ep0_descriptors.h
@@ -1284,7 +1284,7 @@ USB_Config_Descriptor_Audio2_t cfgDesc_Audio2=
.bSourceID = FU_USBIN, /* 7 bSourceID Connect to analog input feature unit*/
#else
.bSourceID = ID_IT_USB,/* 7 bSourceID Connect to analog input term */
.bSourceID = ID_IT_AUD,/* 7 bSourceID Connect to analog input term */
#endif
.bCSourceID = ID_CLKSEL,
.bmControls = 0x0000,
@@ -2331,9 +2331,10 @@ const unsigned num_freqs_a1 = MAX(3, (0
#define CFG_TOTAL_LENGTH_A1 (18 + AC_TOTAL_LENGTH + (INPUT_INTERFACES_A1 * (49 + num_freqs_a1 * 3)) + (OUTPUT_INTERFACES_A1 * (49 + num_freqs_a1 * 3)) + CONTROL_INTERFACE_BYTES + DFU_INTERFACE_BYTES + HID_INTERFACE_BYTES)
#endif
#define INTERFACE_DESCRIPTOR_BYTES (9)
#ifdef XUA_USB_DESCRIPTOR_OVERWRITE_RATE_RES
#define AS_INTERFACE_BYTES (7)
#define INTERFACE_DESCRIPTOR_BYTES (9)
#define AS_FORMAT_TYPE_BYTES (17)
#define USB_AS_IN_INTERFACE_DESCRIPTOR_OFFSET_SUB_FRAME (18 + AC_TOTAL_LENGTH + (OUTPUT_INTERFACES_A1 * (49 + num_freqs_a1 * 3)) + (2*INTERFACE_DESCRIPTOR_BYTES) + (AS_INTERFACE_BYTES) + 5)
#define USB_AS_OUT_INTERFACE_DESCRIPTOR_OFFSET_SUB_FRAME (18 + AC_TOTAL_LENGTH + (2*INTERFACE_DESCRIPTOR_BYTES) + (AS_INTERFACE_BYTES) + 5)

View File

@@ -1,4 +1,4 @@
// Copyright 2011-2021 XMOS LIMITED.
// Copyright 2011-2022 XMOS LIMITED.
// This Software is subject to the terms of the XMOS Public Licence: Version 1.
/**
* @brief Implements relevant requests from the USB Audio 2.0 Specification
@@ -341,7 +341,7 @@ int AudioClassRequests_2(XUD_ep ep0_out, XUD_ep ep0_in, USB_SetupPacket_t &sp, c
setG_curSamFreqMultiplier(g_curSamFreq/(newMasterClock/512));
#endif
#if ADAT_RX
#if ADAT_RX
/* Configure ADAT SMUX based on sample rate */
outuint(c_clk_ctl, SET_SMUX);
if(g_curSamFreq < 88200)
@@ -1095,7 +1095,7 @@ int AudioEndpointRequests_1(XUD_ep ep0_out, XUD_ep ep0_in, USB_SetupPacket_t &sp
/* Check Control Selector */
unsigned short controlSelector = sp.wValue>>8;
if((result != XUD_GetBuffer(ep0_out, (buffer, unsigned char[]), length)) != XUD_RES_OKAY)
if((result = XUD_GetBuffer(ep0_out, (buffer, unsigned char[]), length)) != XUD_RES_OKAY)
{
return result;
}
@@ -1280,6 +1280,9 @@ XUD_Result_t AudioClassRequests_1(XUD_ep ep0_out, XUD_ep ep0_in, USB_SetupPacket
buffer[0] = (VOLUME_RES_MIXER & 0xff);
buffer[1] = (VOLUME_RES_MIXER >> 8);
return XUD_DoGetRequest(ep0_out, ep0_in, buffer, 2, sp.wLength);
default:
break;
}
#endif
return XUD_RES_ERR;

View File

@@ -134,7 +134,7 @@ on tile[AUDIO_IO_TILE] : buffered out port:32 p_bclk = PORT_I2S_BCLK;
on tile[AUDIO_IO_TILE] : in port p_mclk_in = PORT_MCLK_IN;
#if XUA_USB_EN
#if XUA_USB_EN
on tile[XUD_TILE] : in port p_for_mclk_count = PORT_MCLK_COUNT;
#endif
@@ -196,14 +196,6 @@ in port p_pdm_mclk = PORT_PDM_MCLK;
#endif
#endif
#if (defined(__XS2A__) && (ADAT_RX))
/* Cannot use default clock (CLKBLK_REF) for ADAT RX since it is tied to the
60MHz USB clock on XS2 processors. */
on tile[XUD_TILE] : clock clk_adat_rx = CLKBLK_ADAT_RX;
#endif
on tile[AUDIO_IO_TILE] : clock clk_audio_mclk = CLKBLK_MCLK; /* Master clock */
#if(AUDIO_IO_TILE != XUD_TILE) && XUA_USB_EN
@@ -214,15 +206,6 @@ on tile[XUD_TILE] : in port p_mclk_in_usb = PORT_MCLK_IN_USB;
on tile[AUDIO_IO_TILE] : clock clk_audio_bclk = CLKBLK_I2S_BIT; /* Bit clock */
/* L/G Series needs a port to use for USB reset */
#if ((defined(__XS2A__) || defined (__XS3A__)) && defined(PORT_USB_RESET))
/* This define is checked since it could be on a shift reg or similar */
on tile[XUD_TILE] : out port p_usb_rst = PORT_USB_RESET;
#else
#define p_usb_rst null
#endif
#ifdef IAP
/* I2C ports - in a struct for use with module_i2c_shared & module_i2c_simple/module_i2c_single_port */
#ifdef PORT_I2C
@@ -443,7 +426,7 @@ void SpdifTxWrapper(chanend c_spdif_tx)
}
#endif
void usb_audio_io(chanend ?c_aud_in, chanend ?c_adc,
void usb_audio_io(chanend ?c_aud_in,
#if (XUA_SPDIF_TX_EN) && (SPDIF_TX_TILE != AUDIO_IO_TILE)
chanend c_spdif_tx,
#endif
@@ -571,11 +554,6 @@ int main()
chan c_ea_data;
#endif
#endif
#ifdef SU1_ADC_ENABLE
chan c_adc;
#else
#define c_adc null
#endif
#ifdef MIXER
chan c_mix_ctl;
@@ -657,9 +635,9 @@ int main()
#endif /* XUA_USB_EN */
}
on tile[AUDIO_IO_TILE]:
on tile[AUDIO_IO_TILE]:
{
usb_audio_io(c_mix_out, c_adc
usb_audio_io(c_mix_out
#if (XUA_SPDIF_TX_EN) && (SPDIF_TX_TILE != AUDIO_IO_TILE)
, c_spdif_tx
#endif
@@ -725,11 +703,6 @@ int main()
{
set_thread_fast_mode_on();
#if defined(__XS2A__)
/* Can't use REF clock as this is usb clock */
set_port_clock(p_adat_rx, clk_adat_rx);
start_clock(clk_adat_rx);
#endif
while (1)
{
adatReceiver48000(p_adat_rx, c_adat_rx);
@@ -748,11 +721,11 @@ int main()
#endif
#ifndef PDM_RECORD
#if (XUA_NUM_PDM_MICS > 0)
#if (XUA_NUM_PDM_MICS > 0)
#if (PDM_TILE != AUDIO_IO_TILE)
/* PDM Mics running on a separate to AudioHub */
on stdcore[PDM_TILE]:
{
{
xua_pdm_mic_config(p_pdm_mclk, p_pdm_clk, p_pdm_mics, clk_pdm);
xua_pdm_mic(c_ds_output, p_pdm_mics);
}
@@ -765,11 +738,6 @@ int main()
#endif /*MIC_PROCESSING_USE_INTERFACE*/
#endif /*XUA_NUM_PDM_MICS > 0*/
#endif /*PDM_RECORD*/
#ifdef SU1_ADC_ENABLE
xs1_su_adc_service(c_adc);
#endif
}
return 0;

View File

@@ -1,13 +1,9 @@
// Copyright 2018-2021 XMOS LIMITED.
// This Software is subject to the terms of the XMOS Public Licence: Version 1.
//#include "devicedefines.h"
#define MAX_MIX_COUNT 8
#define MIX_INPUTS 18
#if defined(__XS2A__) || defined(__XS3A__)
#define DOMIX_TOP(i) \
.cc_top doMix##i.function,doMix##i; \
.align 4 ;\
@@ -50,52 +46,6 @@ doMix##i##: ;\
.size doMix##i, .-doMix##i; \
.cc_bottom doMix##i##.function;
#else
#define DOMIX_TOP(i) \
.cc_top doMix##i.function,doMix##i; \
.align 4 ;\
.globl doMix##i ;\
.type doMix##i, @function ;\
.globl doMix##i##.nstackwords ;\
.globl doMix##i##.maxthreads ; \
.globl doMix##i##.maxtimers ; \
.globl doMix##i##.maxchanends ; \
.globl doMix##i##.maxsync ;\
.linkset doMix##i##.locnoside, 1; \
.linkset doMix##i##.locnochandec, 1;\
.linkset doMix##i##.nstackwords, 0 ;\
.linkset doMix##i##.maxchanends, 0 ;\
.linkset doMix##i##.maxtimers, 0 ;\
.linkset doMix##i##.maxthreads, 1; \
doMix##i##: ;\
set cp, r0; \
set dp, r1; \
lsub r0, r1, r0, r0, r0;\
.label_##i##:
#define DOMIX_BOT(i) \
ldap r11, _dp; \
set dp, r11;\
ldap r11, _cp;\
set cp, r11;\
\
mov r0, r1;\
ldc r2, 0x19;\
sext r0, r2;\
eq r0, r0, r1;\
bf r0, .L20; \
\
shl r0, r1, 0x7;\
retsp 0x0;\
\
\
.size doMix##i, .-doMix##i; \
.cc_bottom doMix##i##.function;
#endif
#define N MIX_INPUTS
#define BODY(i) \
ldw r2,cp[i]; \
@@ -115,8 +65,6 @@ doMix##i##: ;\
retsp 0x0; \
#if(MAX_MIX_COUNT > 0)
DOMIX_TOP(0)
#include "repeat.h"

View File

@@ -1,7 +1,5 @@
// Copyright 2011-2021 XMOS LIMITED.
// Copyright 2011-2022 XMOS LIMITED.
// This Software is subject to the terms of the XMOS Public Licence: Version 1.
#include <xs1.h>
#include <print.h>
#include "xua.h"
@@ -15,7 +13,6 @@
/* FAST_MIXER has a bit of a nasty implentation but is more effcient */
#define FAST_MIXER 1
//#ifdef OUT_VOLUME_IN_MIXER
static unsigned int multOut_array[NUM_USB_CHAN_OUT + 1];
static xc_ptr multOut;
@@ -252,51 +249,53 @@ static inline void GetSamplesFromHost(chanend c)
#pragma unsafe arrays
static inline void GiveSamplesToDevice(chanend c, xc_ptr ptr, xc_ptr multOut)
{
{
#if(NUM_USB_CHAN_OUT == 0)
outuint(c, 0);
#else
#pragma loop unroll
for (int i=0; i<NUM_USB_CHAN_OUT; i++)
{
int sample, x;
for (int i=0; i<NUM_USB_CHAN_OUT; i++)
{
int sample, x;
#if defined(OUT_VOLUME_IN_MIXER) && defined(OUT_VOLUME_AFTER_MIX)
int mult;
int h;
unsigned l;
int mult;
int h;
unsigned l;
#endif
int index;
int index;
#if MAX_MIX_COUNT > 0
/* If mixer turned on sort out the channel mapping */
/* If mixer turned on sort out the channel mapping */
/* Read pointer to sample from the map */
read_via_xc_ptr_indexed(index, ptr, i);
/* Read pointer to sample from the map */
read_via_xc_ptr_indexed(index, ptr, i);
/* Read the actual sample value */
read_via_xc_ptr_indexed(sample, samples, index);
/* Read the actual sample value */
read_via_xc_ptr_indexed(sample, samples, index);
#else
unsafe
{
/* Read the actual sample value */
sample = ptr_samples[i];
}
unsafe
{
/* Read the actual sample value */
sample = ptr_samples[i];
}
#endif
#if defined(OUT_VOLUME_IN_MIXER) && defined(OUT_VOLUME_AFTER_MIX)
/* Do volume control processing */
/* Do volume control processing */
#warning OUT Vols in mixer, AFTER mix & map
read_via_xc_ptr_indexed(mult, multOut, i);
{h, l} = macs(mult, sample, 0, 0);
h<<=3; // Shift used to be done in audio thread but now done here incase of 32bit support
read_via_xc_ptr_indexed(mult, multOut, i);
{h, l} = macs(mult, sample, 0, 0);
h<<=3; // Shift used to be done in audio thread but now done here incase of 32bit support
#error
#if (STREAM_FORMAT_OUTPUT_RESOLUTION_32BIT_USED == 1)
h |= (l >>29)& 0x7; // Note: This step is not required if we assume sample depth is 24bit (rather than 32bit)
// Note: We need all 32bits for Native DSD
h |= (l >>29)& 0x7; // Note: This step is not required if we assume sample depth is 24bit (rather than 32bit)
// Note: We need all 32bits for Native DSD
#endif
outuint(c, h);
outuint(c, h);
#else
outuint(c, sample);
outuint(c, sample);
#endif
}
}
#endif
}
#pragma unsafe arrays
@@ -367,7 +366,7 @@ static void mixer1(chanend c_host, chanend c_mix_ctl, chanend c_mixer2)
/* Forward on Request for data to decouple thread */
outuint(c_host, request);
#if (MAX_MIX_COUNT > 0)
#if (MAX_MIX_COUNT > 0)
/* Sync */
outuint(c_mixer2, 0);
#endif
@@ -544,8 +543,8 @@ static void mixer1(chanend c_host, chanend c_mix_ctl, chanend c_mixer2)
/* Sync with mixer 2 (once it has swapped samples with audiohub) */
outuint(c_mixer2, 0);
inuint(c_mixer2);
/* Do the mixing */
/* Do the mixing */
#ifdef FAST_MIXER
mixed = doMix0(samples, mix_mult_slice(0));
#else
@@ -603,9 +602,6 @@ static void mixer1(chanend c_host, chanend c_mix_ctl, chanend c_mixer2)
}
#else /* IF MAX_MIX_COUNT > 0 */
/* No mixes, this thread runs on its own doing just volume */
#if(NUM_USB_CHAN_OUT == 0)
outuint(c_mixer2, 0);
#endif
GiveSamplesToDevice(c_mixer2, samples_to_device_map, multOut);
GetSamplesFromDevice(c_mixer2);
GetSamplesFromHost(c_host);
@@ -677,8 +673,8 @@ static void mixer2(chanend c_mixer1, chanend c_audio)
{
GiveSamplesToDevice(c_audio, samples_to_device_map, multOut);
GetSamplesFromDevice(c_audio);
/* Sync with mixer 1 (once it has swapped samples with the buffering sub-system) */
/* Sync with mixer 1 (once it has swapped samples with the buffering sub-system) */
inuint(c_mixer1);
outuint(c_mixer1, 0);
@@ -697,7 +693,7 @@ static void mixer2(chanend c_mixer1, chanend c_audio)
#endif
#endif
#if (MAX_FREQ > 96000)
/* Fewer mixes when running higher than 96kHz */
if (!mixer2_mix2_flag)

View File

@@ -22,7 +22,7 @@
#define MAX_DECIMATION_FACTOR (96000/(MIN_FREQ/AUD_TO_MICS_RATIO))
/* Build time sized microphone delay line */
#ifndef MIC_BUFFER_DEPTH
#ifndef MIC_BUFFER_DEPTH
#define MIC_BUFFER_DEPTH 1
#endif
@@ -229,7 +229,7 @@ void xua_pdm_mic_config(in port p_pdm_mclk, in port p_pdm_clk, buffered in port:
unsigned micDiv = MCLK_48/3072000;
configure_clock_src_divide(clk_pdm, p_pdm_mclk, micDiv/2);
configure_port_clock_output(p_pdm_clk, clk_pdm);
configure_in_port(p_pdm_mics, clk_pdm);
start_clock(clk_pdm);
@@ -243,7 +243,7 @@ void xua_pdm_mic(streaming chanend c_ds_output[2], buffered in port:32 p_pdm_mic
#else
#define c_4x_pdm_mic_1 null
#endif
par
{
mic_array_pdm_rx(p_pdm_mics, c_4x_pdm_mic_0, c_4x_pdm_mic_1);

View File

@@ -62,37 +62,12 @@ unsigned int divide, unsigned curSamFreq)
}
#endif
#if defined(__XS2A__) || defined(__XS3A__)
unsafe
{
/* Clock bitclock clock block from master clock pin (divided) */
configure_clock_src_divide(clk_audio_bclk, (port) p_mclk_in, (divide/2));
configure_port_clock_output(p_bclk, clk_audio_bclk);
}
#else
#error XS1 no longer supported in audio core
/* For a divide of one (i.e. bitclock == master-clock) BClk is set to clock_output mode.
* In this mode it outputs an edge clock on every tick of itsassociated clock_block.
*
* For all other divides, BClk is clocked by the master clock and data
* will be output to p_bclk to generate the bit clock.
*/
if (divide == 1) /* e.g. 176.4KHz from 11.2896 */
{
configure_port_clock_output(p_bclk, clk_audio_mclk);
/* Generate bit clock block straight from mclk */
configure_clock_src(clk_audio_bclk, p_mclk_in);
}
else
{
/* bit clock port from master clock clock-clock block */
configure_out_port_no_ready(p_bclk, clk_audio_mclk, 0);
/* Generate bit clock block from pin */
configure_clock_src(clk_audio_bclk, p_bclk);
}
#endif
if(!isnull(p_lrclk))
{

View File

@@ -22,7 +22,7 @@ static void reset_tile(unsigned const tileId)
read_sswitch_reg(tileId, 6, pllVal);
pllVal &= PLL_MASK;
write_sswitch_reg_no_ack(tileId, 6, pllVal);
}
}
/* Reboots XMOS device by writing to the PLL config register
* Note - resetting is per *node* not tile
@@ -38,18 +38,16 @@ void device_reboot(void)
/* Disconnect from bus */
unsigned data[] = {4};
write_periph_32(usb_tile, XS2_SU_PERIPH_USB_ID, XS1_GLX_PER_UIFM_FUNC_CONTROL_NUM, 1, data);
#elif defined(__XS3A__)
#warning Assuming that tile reset also resets USB in XS3 architectures
#endif
tileArrayLength = sizeof(tile)/sizeof(tileref);
/* Note - we could be in trouble if this doesn't return 0/1 since
/* Note - we could be in trouble if this doesn't return 0/1 since
* this code doesn't properly handle any network topology other than a
* simple line
* simple line
*/
/* Find tile index of the local tile ID */
for(int tileNum = 0; tileNum<tileArrayLength; tileNum++)
for(int tileNum = 0; tileNum<tileArrayLength; tileNum++)
{
if (get_tile_id(tile[tileNum]) == localTileId)
{

View File

@@ -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__ */

View File

@@ -11,11 +11,12 @@
#include "flash_interface.h"
#include "dfu_interface.h"
#if defined(__XS3A__)
#define FLAG_ADDRESS 0xfffcc
#elif defined(__XS2A__)
#if defined(__XS2A__)
/* Note range 0x7FFC8 - 0x7FFFF guarenteed to be untouched by tools */
#define FLAG_ADDRESS 0x7ffcc
#else
/* Note range 0xFFFC8 - 0xFFFFF guarenteed to be untouched by tools */
#define FLAG_ADDRESS 0xfffcc
#endif
/* Store Flag to fixed address */

View File

@@ -1,4 +1,4 @@
// Copyright 2019-2021 XMOS LIMITED.
// Copyright 2019-2022 XMOS LIMITED.
// This Software is subject to the terms of the XMOS Public Licence: Version 1.
#include <stdint.h>
#include <xs1.h>
@@ -7,38 +7,19 @@
#include "xud.h"
#include "xud_std_requests.h"
#include "xua_hid.h"
#include "xua_hid_report.h"
#define DEBUG_UNIT HID_XC
#define DEBUG_PRINT_ENABLE_HID_XC 0
#include "debug_print.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,47 +39,28 @@ 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 );
}
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 = ( 0U == hidGetReportPeriod( id ) || ( timeafter( hidGetNextReportTime( id ), currentTime )));
}
unsigned HidIsSetIdleSilenced( void )
{
unsigned isSilenced = s_hidIdleActive;
if( s_hidIdleActive ) {
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 )));
}
return isSilenced;
}
void HidSetChangePending( void )
{
unsafe {
*s_hidChangePendingPtr = 1;
}
return isSilenced;
}
/**
* \brief Calculate the timer value for sending the next HID Report.
*
* With regard to Section 7.2.4 Set_Idle Request of the USB Device Class Definition for Human
* Interface Devices (HID) Version 1.11, I've interpreted 'currently executing period' and
* 'current period' to mean the previously established Set Idle duration if one has been
* Interface Devices (HID) Version 1.11, 'currently executing period' and 'current period' have
* been interpreted to mean the previously established Set Idle duration if one has been
* established or the polling interval from the HID Report Descriptor if a Set Idle duration
* has not been established.
*
@@ -112,7 +74,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 */
@@ -171,6 +133,29 @@ static unsigned HidFindSetIdleActivationPoint( const unsigned currentPeriod, con
return result;
}
/**
* \brief Configure a hid report's next report time and idle status based on a setidle request
*
* \param[in] reportId -- The report ID to modify
* \param[in] reportDuration -- The duration of the setidle request
*
*/
static void HidUpdateReportPeriod( unsigned reportId, unsigned reportDuration ) {
unsigned currentPeriod = hidGetReportPeriod( reportId );
hidSetIdle( reportId, ( 0U == reportDuration ) || ( ENDPOINT_INT_INTERVAL_IN_HID < reportDuration ));
if( hidIsIdleActive( reportId )) {
unsigned reportTime = hidGetReportTime( reportId );
unsigned reportToSetIdleInterval = HidCalcReportToSetIdleInterval( reportTime );
unsigned nextReportTime = HidCalcNewReportTime( currentPeriod, reportTime, reportToSetIdleInterval, reportDuration * MS_IN_TICKS );
hidSetNextReportTime( reportId, nextReportTime );
currentPeriod = reportDuration * MS_IN_TICKS;
}
hidSetReportPeriod( reportId, currentPeriod );
}
/**
* \brief Process a Set Idle request
*
@@ -208,20 +193,24 @@ 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 ));
if( INTERFACE_NUMBER_HID == interfaceNum ) {
if( hidIsReportIdValid( reportId ) ) {
HidUpdateReportPeriod( reportId, 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 );
} else {
s_hidCurrentPeriod = ENDPOINT_INT_INTERVAL_IN_HID * MS_IN_TICKS;
s_hidIndefiniteDuration = 0U;
result = XUD_DoSetRequestStatus( c_ep0_in );
}
else if ( reportId == 0U ) {
// Wildcard request - set all report IDs to idle
unsigned startReportId = hidGetNextValidReportId(reportId);
result = XUD_DoSetRequestStatus( c_ep0_in );
reportId = startReportId;
do {
HidUpdateReportPeriod( reportId, duration );
reportId = hidGetNextValidReportId( reportId );
} while( reportId != startReportId);
result = XUD_DoSetRequestStatus( c_ep0_in );
}
}
return result;

View File

@@ -0,0 +1,858 @@
// Copyright 2021-2022 XMOS LIMITED.
// This Software is subject to the terms of the XMOS Public Licence: Version 1.
#include "xua_conf_full.h"
#if( 0 < HID_CONTROLS )
#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"
#include "swlock.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 ))
swlock_t hidStaticVarLock = SWLOCK_INITIAL_VALUE;
/*
* 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 );
unsigned hidIsReportIdInUse ( void ) {
return !hidIsReportIdValid(0U);
}
void hidCalcNextReportTime( const unsigned id )
{
swlock_acquire(&hidStaticVarLock);
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 ];
}
}
swlock_release(&hidStaticVarLock);
}
void hidCaptureReportTime( const unsigned id, const unsigned time )
{
swlock_acquire(&hidStaticVarLock);
for( size_t idx = 0U; idx < HID_REPORT_COUNT; ++idx ) {
if( id == hidGetElementReportId( hidReports[ idx ]->location )) {
s_hidReportTime[ idx ] = time;
}
}
swlock_release(&hidStaticVarLock);
}
void hidClearChangePending( const unsigned id )
{
swlock_acquire(&hidStaticVarLock);
for( size_t idx = 0U; idx < HID_REPORT_COUNT; ++idx) {
if(( id == 0U ) || ( id == hidGetElementReportId( hidReports[ idx ]->location ))) {
s_hidChangePending[ idx ] = 0U;
break;
}
}
swlock_release(&hidStaticVarLock);
}
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 ) {
swlock_acquire(&hidStaticVarLock);
unsigned retVal = 0U;
for ( size_t idx = 0U; idx < HID_REPORT_COUNT; ++idx ) {
if( id == hidGetElementReportId( hidReports[ idx ]->location )) {
retVal = s_hidNextReportTime[ idx ];
}
}
swlock_release(&hidStaticVarLock);
return retVal;
}
unsigned char* hidGetReportDescriptor( void )
{
unsigned char* retVal = NULL;
swlock_acquire(&hidStaticVarLock);
if( s_hidReportDescriptorPrepared ) {
retVal = s_hidReportDescriptor;
}
swlock_release(&hidStaticVarLock);
return retVal;
}
size_t hidGetReportDescriptorLength( void )
{
swlock_acquire(&hidStaticVarLock);
size_t retVal = ( s_hidReportDescriptorPrepared ) ? s_hidReportDescriptorLength : 0U;
swlock_release(&hidStaticVarLock);
return retVal;
}
unsigned hidGetReportIdLimit ( void ) {
unsigned retVal = 0U;
swlock_acquire(&hidStaticVarLock);
for( size_t idx = 0U; idx < HID_REPORT_COUNT; ++idx ) {
unsigned reportId = hidGetElementReportId( hidReports[ idx ]->location );
if( reportId >= retVal ) {
retVal = reportId + 1;
}
}
swlock_release(&hidStaticVarLock);
return retVal;
}
unsigned hidGetNextValidReportId ( unsigned idPrev ) {
size_t retIndex = 0;
swlock_acquire(&hidStaticVarLock);
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;
}
}
unsigned retVal = hidGetElementReportId( hidReports[ retIndex ]->location );
swlock_release(&hidStaticVarLock);
return retVal;
}
#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 ) {
swlock_acquire(&hidStaticVarLock);
USB_HID_Report_Element_t element = *hidConfigurableElements[ elementIdx ];
swlock_release(&hidStaticVarLock);
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 )
{
swlock_acquire(&hidStaticVarLock);
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 );
}
}
}
swlock_release(&hidStaticVarLock);
return retVal;
}
unsigned hidGetReportPeriod( const unsigned id )
{
swlock_acquire(&hidStaticVarLock);
unsigned retVal = 0U;
for( size_t idx = 0U; idx < HID_REPORT_COUNT; ++idx) {
if( id == hidGetElementReportId( hidReports[ idx ]->location )) {
retVal = s_hidCurrentPeriod[ idx ];
break;
}
}
swlock_release(&hidStaticVarLock);
return retVal;
}
unsigned hidGetReportTime( const unsigned id )
{
swlock_acquire(&hidStaticVarLock);
unsigned retVal = 0U;
for( size_t idx = 0U; idx < HID_REPORT_COUNT; ++idx ) {
if( id == hidGetElementReportId( hidReports[ idx ]->location )) {
retVal = s_hidReportTime[ idx ];
}
}
swlock_release(&hidStaticVarLock);
return retVal;
}
static unsigned hidGetUsagePage( const unsigned id )
{
unsigned retVal = 0U;
swlock_acquire(&hidStaticVarLock);
for( size_t idx = 0U; idx < HID_REPORT_COUNT; ++idx) {
if( id == hidGetElementReportId( hidReports[ idx ]->location )) {
retVal = hidReports[ idx ]->item.data[ 0 ];
break;
}
}
swlock_release(&hidStaticVarLock);
return retVal;
}
unsigned hidIsChangePending( const unsigned id )
{
unsigned retVal = 0U;
swlock_acquire(&hidStaticVarLock);
for( size_t idx = 0U; idx < HID_REPORT_COUNT; ++idx) {
if( id == hidGetElementReportId( hidReports[ idx ]->location )) {
retVal = ( s_hidChangePending[ idx ] != 0U );
break;
}
}
swlock_release(&hidStaticVarLock);
return retVal;
}
unsigned hidIsIdleActive( const unsigned id )
{
unsigned retVal = 0U;
swlock_acquire(&hidStaticVarLock);
for( size_t idx = 0U; idx < HID_REPORT_COUNT; ++idx) {
if( id == hidGetElementReportId( hidReports[ idx ]->location )) {
retVal = ( s_hidIdleActive[ idx ] != 0U );
break;
}
}
swlock_release(&hidStaticVarLock);
return retVal;
}
unsigned hidIsReportDescriptorPrepared( void )
{
swlock_acquire(&hidStaticVarLock);
unsigned retVal = s_hidReportDescriptorPrepared;
swlock_release(&hidStaticVarLock);
return retVal;
}
unsigned hidIsReportIdValid ( unsigned id ) {
size_t retVal = 0;
swlock_acquire(&hidStaticVarLock);
for( size_t idx = 0U; idx < HID_REPORT_COUNT; ++idx ) {
unsigned reportId = hidGetElementReportId( hidReports[ idx ]->location );
if( reportId == id ) {
retVal = 1;
break;
}
}
swlock_release(&hidStaticVarLock);
return retVal;
}
void hidPrepareReportDescriptor( void )
{
swlock_acquire(&hidStaticVarLock);
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;
}
swlock_release(&hidStaticVarLock);
}
void hidReportInit( void )
{
swlock_acquire(&hidStaticVarLock);
for( unsigned idx = 0U; idx < HID_REPORT_COUNT; ++idx ) {
s_hidCurrentPeriod[ idx ] = ENDPOINT_INT_INTERVAL_IN_HID * MS_IN_TICKS * HID_REPORT_COUNT;
}
memset( s_hidIdleActive, 0, sizeof( s_hidIdleActive ) );
memset( s_hidChangePending, 0, sizeof( s_hidChangePending ) );
swlock_release(&hidStaticVarLock);
}
void hidResetReportDescriptor( void )
{
swlock_acquire(&hidStaticVarLock);
s_hidReportDescriptorPrepared = 0U;
swlock_release(&hidStaticVarLock);
}
void hidSetChangePending( const unsigned id )
{
swlock_acquire(&hidStaticVarLock);
for( size_t idx = 0U; idx < HID_REPORT_COUNT; ++idx) {
if( id == hidGetElementReportId( hidReports[ idx ]->location )) {
s_hidChangePending[ idx ] = 1U;
break;
}
}
swlock_release(&hidStaticVarLock);
}
void hidSetIdle( const unsigned id, const unsigned state )
{
swlock_acquire(&hidStaticVarLock);
for( size_t idx = 0U; idx < HID_REPORT_COUNT; ++idx) {
if( id == hidGetElementReportId( hidReports[ idx ]->location )) {
s_hidIdleActive[ idx ] = ( state != 0U );
break;
}
}
swlock_release(&hidStaticVarLock);
}
void hidSetNextReportTime( const unsigned id, const unsigned time )
{
swlock_acquire(&hidStaticVarLock);
for( size_t idx = 0U; idx < HID_REPORT_COUNT; ++idx ) {
if( id == hidGetElementReportId( hidReports[ idx ]->location )) {
s_hidNextReportTime[ idx ] = time;
}
}
swlock_release(&hidStaticVarLock);
}
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 ) {
swlock_acquire(&hidStaticVarLock);
USB_HID_Report_Element_t element = *hidConfigurableElements[ elementIdx ];
swlock_release(&hidStaticVarLock);
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;
}
swlock_acquire(&hidStaticVarLock);
*hidConfigurableElements[ elementIdx ] = element;
swlock_release(&hidStaticVarLock);
retVal = HID_STATUS_GOOD;
break;
}
}
}
}
}
}
return retVal;
}
void hidSetReportPeriod( const unsigned id, const unsigned period )
{
swlock_acquire(&hidStaticVarLock);
for( size_t idx = 0U; idx < HID_REPORT_COUNT; ++idx) {
if( id == hidGetElementReportId( hidReports[ idx ]->location )) {
s_hidCurrentPeriod[ idx ] = period;
break;
}
}
swlock_release(&hidStaticVarLock);
}
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 );
}
}
#endif // ( 0 < HID_CONTROLS )

View File

@@ -1,272 +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 ];
}
*hidConfigurableItems[ itemIdx ] = item;
retVal = HID_STATUS_GOOD;
} else {
retVal = HID_STATUS_BAD_PAGE;
}
break;
}
}
}
}
return retVal;
}
static size_t hidTranslateItem( const USB_HID_Short_Item_t* inPtr, unsigned char** outPtrPtr )
{
size_t count = 0;
*(*outPtrPtr)++ = inPtr->header;
++count;
unsigned dataLength = hidGetItemSize( inPtr->header );
for( unsigned idx = 0; idx < dataLength; ++idx ) {
*(*outPtrPtr)++ = inPtr->data[ idx ];
++count;
}
return count;
}

View File

@@ -1,6 +1,12 @@
// Copyright 2019-2021 XMOS LIMITED.
// Copyright 2019-2022 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__

View File

@@ -0,0 +1,551 @@
// Copyright 2021-2022 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 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 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 (in the case that Report IDs are not in use),
* 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 hidClearChangePending( const unsigned id );
/**
* @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 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 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 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 (in the case that Report IDs are not in use),
* 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.
*
* \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.
* \retval False The given \a id does not have changed HID Report 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)
*
* \returns A Boolean indicating whether the HID Report for the given \a id is idle.
* \retval True The HID Report is idle.
* \retval False The HID Report is not idle.
*/
unsigned hidIsIdleActive( 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 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.
*
* @return Boolean
* @retval 1 Report IDs are in use
* @retval 0 Report IDs are not in use
*/
unsigned hidIsReportIdInUse ( void );
/**
* @brief Is the provided report ID valid for passing to other functions.
*
* e.g If Report IDs are not in use, then only 0 will return true.
* e.g If Report IDs are in use, then 0 will return false and the report IDs that
* are in use will return true when passed to this function.
*
* @param id The ID to check
* @return boolean
* @retval 0 The report ID is not valid, other functions may fail silently
* @retval 1 The report ID is valid and can be used as the argument to other functions
*/
unsigned hidIsReportIdValid ( 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 (in the case that Report IDs are not in use),
* 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_

View File

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

View 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_

View File

@@ -49,6 +49,7 @@ foreach( testsourcefile ${APP_SOURCES} )
"-fxscope"
"-target=XCORE-AI-EXPLORER"
"${CMAKE_CURRENT_SOURCE_DIR}/config.xscope"
"-DHID_CONTROLS=1"
"-DUNITY_SUPPORT_64"
"-DUNITY_INCLUDE_DOUBLE"
)
@@ -79,12 +80,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}

View File

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

View File

@@ -0,0 +1,296 @@
// 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 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 hidUsagePageGenericDesktop = {
.header = HID_REPORT_SET_HEADER(1, HID_REPORT_ITEM_TYPE_GLOBAL, HID_REPORT_ITEM_TAG_USAGE_PAGE),
.data = { USB_HID_USAGE_PAGE_ID_GENERIC_DESKTOP, 0x00 }};
static const USB_HID_Short_Item_t hidUsagePageConsumerControl = {
.header = HID_REPORT_SET_HEADER(1, HID_REPORT_ITEM_TYPE_GLOBAL, HID_REPORT_ITEM_TAG_USAGE_PAGE),
.data = { USB_HID_USAGE_PAGE_ID_CONSUMER, 0x00 }};
static const USB_HID_Short_Item_t hidUsagePageTelephony = {
.header = HID_REPORT_SET_HEADER(1, HID_REPORT_ITEM_TYPE_GLOBAL, HID_REPORT_ITEM_TAG_USAGE_PAGE),
.data = { USB_HID_USAGE_PAGE_ID_TELEPHONY_DEVICE, 0x00 }};
static const USB_HID_Short_Item_t hidUsageKeyboard = {
.header = HID_REPORT_SET_HEADER(1, HID_REPORT_ITEM_TYPE_LOCAL, HID_REPORT_ITEM_TAG_USAGE),
.data = { 0x06, 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 hidUsageTelephonyHeadset = {
.header = HID_REPORT_SET_HEADER(1, HID_REPORT_ITEM_TYPE_LOCAL, HID_REPORT_ITEM_TAG_USAGE),
.data = { 0x05, 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 )
};
/*
* Define configurable elements in the HID Report descriptor.
*/
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[] = {
&hidUsagePageGenericDesktop,
&hidUsageKeyboard,
&hidReportSize1,
&hidLogicalMinimum0,
&hidCollectionApplication, // Report 1
&hidReportId1,
&(hidReportKeyboard.item),
&hidLogicalMaximum1,
&hidReportCount1,
&(hidUsageReport1Byte0Bit0.item),
&hidInputDataVar,
&hidLogicalMaximum0,
&hidInputConstArray,
&hidLogicalMaximum1,
&(hidUsageReport1Byte0Bit2.item),
&hidInputDataVar,
&(hidUsageReport1Byte0Bit3.item),
&hidInputDataVar,
&hidLogicalMaximum0,
&hidReportCount4,
&hidInputConstArray,
&hidCollectionEnd,
&hidUsagePageConsumerControl,
&hidUsageConsumerControl,
&hidCollectionApplication, // 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,
&hidUsagePageTelephony,
&hidUsageTelephonyHeadset,
&hidCollectionApplication, // Report 3
&hidReportId3,
&(hidReportTelephony.item),
&(hidUsageReport3Byte0Bit0.item),
&hidInputDataVar,
&(hidUsageReport3Byte0Bit1.item),
&hidInputDataVar,
&hidLogicalMaximum0,
&hidReportCount6,
&hidInputConstArray,
&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__

View File

@@ -0,0 +1,887 @@
// Copyright 2021-2022 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 );
}
void test_is_report_id_valid( void ) {
unsigned isValid = 0;
unsigned reportId = 0;
isValid = hidIsReportIdValid( reportId );
TEST_ASSERT_EQUAL_UINT( 0, isValid );
reportId = 1;
isValid = hidIsReportIdValid( reportId );
TEST_ASSERT_EQUAL_UINT( 1, isValid );
reportId = 2;
isValid = hidIsReportIdValid( reportId );
TEST_ASSERT_EQUAL_UINT( 1, isValid );
reportId = 3;
isValid = hidIsReportIdValid( reportId );
TEST_ASSERT_EQUAL_UINT( 1, isValid );
reportId = 4;
isValid = hidIsReportIdValid( reportId );
TEST_ASSERT_EQUAL_UINT( 0, isValid );
}
// 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 reportId = 1;
unsigned reportId2 = 2;
unsigned setIdle = hidIsIdleActive( reportId );
TEST_ASSERT_EQUAL_UINT( 0, setIdle );
setIdle = hidIsIdleActive( reportId2 );
TEST_ASSERT_EQUAL_UINT( 0, setIdle );
hidSetIdle( reportId, 1 );
setIdle = hidIsIdleActive( reportId );
TEST_ASSERT_EQUAL_UINT( 1, setIdle );
setIdle = hidIsIdleActive( reportId2 );
TEST_ASSERT_EQUAL_UINT( 0, setIdle );
}
void test_set_all_idle( void )
{
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 );
for ( reportId = 1; reportId <= HID_REPORT_COUNT; ++reportId ) {
hidSetIdle( reportId, 1 );
setIdle = hidIsIdleActive( reportId );
TEST_ASSERT_EQUAL_UINT( 1, setIdle );
}
}
void test_change_pending( void )
{
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 );
hidSetChangePending( reportId );
changePending = hidIsChangePending( reportId );
TEST_ASSERT_EQUAL_UINT( 1, changePending );
changePending = hidIsChangePending( reportId2 );
TEST_ASSERT_EQUAL_UINT( 0, changePending );
}
void test_change_pending_all( void )
{
unsigned reportId = 1;
unsigned changePending = hidIsChangePending( reportId );
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 );
}
}
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 );
}

View 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__

View File

@@ -1,19 +1,26 @@
// Copyright 2021 XMOS LIMITED.
// Copyright 2021-2022 XMOS LIMITED.
// This Software is subject to the terms of the XMOS Public Licence: Version 1.
#include <stddef.h>
#include <stdio.h>
#include "xua_unit_tests.h"
#include "xua_hid_report_descriptor.h"
#include "hid_report_descriptor.h"
#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 )
static unsigned construct_usage_header( unsigned size )
{
@@ -29,26 +36,62 @@ 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 );
}
void test_is_report_id_valid( void ) {
unsigned isValid = 0;
unsigned reportId = 0;
isValid = hidIsReportIdValid( reportId );
TEST_ASSERT_EQUAL_UINT( 1, isValid );
reportId = 1;
isValid = hidIsReportIdValid( reportId );
TEST_ASSERT_EQUAL_UINT( 0, isValid );
}
// 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 );
}
@@ -69,16 +112,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 );
@@ -88,13 +138,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 );
@@ -104,13 +155,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 );
@@ -120,13 +172,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 );
@@ -136,13 +189,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 );
@@ -152,13 +206,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 );
@@ -169,226 +224,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();
@@ -397,13 +471,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();
@@ -411,8 +486,9 @@ void test_initial_modification_with_subsequent_preparation( void )
TEST_ASSERT_NOT_NULL( reportDescPtr );
}
void test_initial_modification_with_subsequent_verification( 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;
@@ -424,15 +500,62 @@ void test_initial_modification_with_subsequent_verification( 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( get_page, set_page );
TEST_ASSERT_EQUAL_UINT( get_header, set_header );
TEST_ASSERT_EQUAL_UINT( get_data[ 0 ], set_data[ 0 ]);
TEST_ASSERT_EQUAL_UINT( get_data[ 1 ], set_data[ 1 ]);
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 = 0;
const unsigned bit = MIN_VALID_BIT;
const unsigned byte = MIN_VALID_BYTE;
{
unsigned char get_data[ HID_REPORT_ITEM_MAX_SIZE ] = { 0xFF, 0xFF };
unsigned char get_header = 0xFF;
unsigned char get_page = 0xFF;
const unsigned char set_data[ 2 ] = {( AL_CONTROL_PANEL & 0x00FF ), (( AL_CONTROL_PANEL & 0xFF00 ) >> 8 )};
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( 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 ] = { LOUDNESS_CONTROL };
const unsigned char set_header = construct_usage_header( sizeof set_data / sizeof( unsigned char ));
const unsigned char set_page = CONSUMER_CONTROL_PAGE;
unsigned setRetVal = hidSetReportItem( 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
}
}
void test_modification_without_subsequent_preparation( void )
@@ -441,6 +564,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 };
@@ -448,7 +572,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();
@@ -461,6 +585,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 };
@@ -468,10 +593,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);
}

View File

@@ -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',
@@ -221,6 +230,7 @@ def build(bld):
makefile_opts['XCC_FLAGS'] = ['-O2',
'-g',
'-Wall',
'-DHID_CONTROLS=1',
'-DUNITY_SUPPORT_64',
'-DUNITY_INCLUDE_DOUBLE',
'-DXUD_CORE_CLOCK=600',

120
xpd.xml
View File

@@ -1,120 +0,0 @@
<?xml version="1.0" ?>
<xpd>
<components>
<component description = "module_dfu" type = "demoCode" scope = "General Use" path = "module_dfu" local = "false" id = "module_dfu" name = "module_dfu">
<board>XMOS USB Audio Reference Designes</board>
<keyword>DFU</keyword>
</component>
<component description = "queue" type = "demoCode" scope = "General Use" path = "module_queue" local = "false" id = "module_queue" name = "Queuing Module For USB Audio Framework">
<board></board>
<keyword>UAC2</keyword>
</component>
<component description = "Core USB Audio Module" type = "demoCode" scope = "General Use" path = "module_usb_audio" local = "false" id = "module_usb_audio" name = "USB AUDIO MODULE">
<board>XR-USB-AUDIO-20-MC</board>
<keyword>USB Audio UAC2</keyword>
</component>
<component description = "MIDI" type = "demoCode" scope = "General Use" path = "module_usb_midi" local = "false" id = "module_usb_midi" name = "MIDI Module for USB Audio Framework">
<board></board>
<componentDependency version = "7.4.1">module_queue</componentDependency>
<keyword>MIDI</keyword>
</component>
</components>
<description>USB Audio Shared Components. For use in the XMOS USB Audio Refererence Designs.</description>
<docdir>module_dfu/doc</docdir>
<git_export>False</git_export>
<location>git://git/apps/sc_usb_audio</location>
<name>USB Audio Shared Components</name>
<maintainer>xross</maintainer>
<partnumber>XM-004719-DH</partnumber>
<release parenthash = "98b3bdba959bbaff0eba0e73f3b05d6adea82bbd" version = "1.0.0rc0" githash = "543155aaefc8f2b0109393c543429edd16eefa8c"></release>
<release parenthash = "45f920c8adaad076c5e5f391094950a7de2fe8bb" version = "6.3.3alpha0" githash = "d07ec8f9a2f7fabbedd041c9a92c848de583c5b7"></release>
<release parenthash = "cfe9f508f1f10d5d3a5bbfca96fb9e018c85e2f5" version = "6.3.3alpha1" githash = "5fb9a989355e40e709166629e1233ace1a0391ff"></release>
<release parenthash = "055f05bfab5a4c31a7a32fc9a9acade5b747888c" version = "6.3.3alpha2" githash = "e4fd029d3de7bb3c33f80b6ffd94004d9a49d6a8"></release>
<release parenthash = "6dffaa379b87011dd364aaaebbcf58f08e156fe1" version = "6.3.3alpha3" githash = "2b536a00da240d713f77114da393e6baa2857521"></release>
<release parenthash = "62fc22ffc5ca39a5917277fcb97b8d3b7f05b311" version = "6.3.3alpha4" githash = "4c4cf162049902f3e532eaae88d48eff196981a2"></release>
<release parenthash = "b2660cf04e4705b99d027061d7576afc03d7124c" version = "6.3.3alpha5" githash = "104c70b4021d9176f8d1ff7b27741efa63f0ca7d"></release>
<release parenthash = "e90ed6b9ec4c366520bbc7546f463bd003f30c59" version = "6.4.0beta0" githash = "95a7caf8beb8afb74abe3323267710c0678dd32b"></release>
<release parenthash = "90eacf1170afb807c0541704fb94acb722215255" version = "6.4.0beta1" githash = "92087a2d40da2276c06dffd2b616532e65ea002d"></release>
<release parenthash = "fe3b0251da73729f957b1a5a766fe60b494d717a" version = "6.4.0beta2" githash = "432d39434a59418ef3449ae02005bf12e8f6fc61"></release>
<release parenthash = "bbd02f157fba840d918838a4922ca5b1fa4cae21" version = "6.4.0beta3" githash = "c6ed243a82555bd3e2825dad48266e3a307db716"></release>
<release parenthash = "486a19f54934e9eaa6662f316a4913b9af5db43b" version = "6.4.0beta4" githash = "80817b73ccbefa48819c70ec46b997af27de2ff7"></release>
<release parenthash = "bee14703105874475756abeaefe2fbfc42f6b035" version = "6.5.0beta0" githash = "9c5e0a1dd8b18cad1b7394260d67bcfc5b290834"></release>
<release parenthash = "0e120103c1b48d237420a462b68207fbd146acfa" version = "6.5.0beta1" githash = "1e31c9e51847fad9950d03d80dba86a9a8505bee"></release>
<release parenthash = "acd4fb35da412a9fbba8776d32a6a7d6fe57d9b4" version = "6.5.0beta2" githash = "8a6be40889401c5fc5815f3075185819a21cf871"></release>
<release parenthash = "64f42250848119c3ffddf41021a1a8edf6ab30f3" version = "6.5.1beta0" githash = "1488353b8d72e4dc0ed1b7975ec7df2460864fd9"></release>
<release parenthash = "125d4e6eb199947ef868f22c6f4b9b280b69722c" version = "6.5.1beta1" githash = "092569f76b23ea361a311acade971db1235c7e33"></release>
<release parenthash = "18073920cb2d1d6ca3ea0dfe6e8c65c98acab368" version = "6.5.1beta2" githash = "ae3db9b98d84a2dd2a00ef144e1434602c005fb0"></release>
<release parenthash = "8966f5db59939aa6373c85162e868462e9afc3fd" version = "6.5.1beta3" githash = "ff4cd847811d541fd2cd80508a9ecf07047fa6da"></release>
<release parenthash = "8f3067dcaaa34bd8fc0d3f64d2894c49b4efe056" version = "6.5.1beta4" githash = "d974daec508348baff08f5b51b5966b773f0a7b6"></release>
<release parenthash = "6a0449e56872d96d13c33ffc39888bea0cd52cad" version = "6.5.1rc0" githash = "dcfc791b3e9f3bee50fab2cd7c5070ed24a1c3da"></release>
<release parenthash = "16149f4746d69fdc7b811f4fc36bcea310d5375b" version = "6.5.1rc1" githash = "ed6bb50d26c3b588fa14ab4aac15a5204527954c"></release>
<release parenthash = "ba1d9ffac27c667cae836824dee94d98bd5c6496" version = "6.5.1rc2" githash = "2bd20a2097ffdd029148cc3fd53cc05d6fcadc94"></release>
<release parenthash = "6a3ec894175598c0efd7827590963bd63b0fd738" version = "6.5.1rc3" githash = "4044db7a28f55da1c7997c9994c08f7100f41091"></release>
<release parenthash = "2fe1d3cbf25c7cedf614d8cb84d4ce60cc6fda10" version = "6.5.1rc4" githash = "92918706a3c2212335bd8d34b5b8c905884bf6f1"></release>
<release parenthash = "24ddedc6927fe3f8dc081df71c01805a4a4e0792" version = "6.6.0beta0" githash = "555e001e071008d804f7a8d03f1837b0b810c074"></release>
<release parenthash = "ccf7c66588501a090ab25003f3d646b22c03b243" version = "6.6.0beta1" githash = "91c7bcff7a403fc9638bd05fcb4b63f75b7eccca"></release>
<release parenthash = "91c7bcff7a403fc9638bd05fcb4b63f75b7eccca" version = "6.6.0rc0" githash = "3a340d50732b31012b412d35598bbf311df2b914"></release>
<release parenthash = "d7f0cdd4be780869137968f00f1d2a46663a1f33" version = "6.6.0rc1" githash = "a714e668020fe14128b213eae7ea3290d4ddf28a"></release>
<release parenthash = "192b263d764650b2b498157b192dbda8882aba99" version = "6.6.0rc2" githash = "74d448097f79524c97fc2967bb227264a39be016"></release>
<release parenthash = "9be1ef8d706be7027c3712a2fef15144767dfe55" version = "6.6.1rc0" githash = "6456645f423546b708db53aa5979967b3c8019aa"></release>
<release parenthash = "7c17932c58c8e1d32a9002fe635672b95fff259d" version = "6.6.1rc1" githash = "9ce2f74146e6be516ed19cc767a03e52a6eb31a2"></release>
<release parenthash = "f2b688b4cb1ff723c322ddea30ee4608bd1edb4e" version = "6.6.2rc0" githash = "2a11db1e567ccbd8a6c3da10c4a85262c1f31e1b"></release>
<release parenthash = "1677eb49b0fec05c231727d6938643e0e7f07a10" version = "6.7.0alpha0" githash = "eea9122373f95302c67ce82749cb10ae8167ef83"></release>
<release parenthash = "3a67e1ce52406dd1af8600a483b038e745f1f33a" version = "6.8.0alpha0" githash = "abd65222735d714aa4ca759f39811d41d10421da"></release>
<release parenthash = "54c26602b86acb9dee6d18e6795a25da60300b96" version = "6.8.0alpha1" githash = "2f51ee286c387631e23258d5a1f702c7da754da3"></release>
<release parenthash = "49cb1290c9aa58823ac893cef97d46b4f95799c5" version = "6.8.0alpha2" githash = "ae85f31e22e8651950b619b2930f39791b31f9f2"></release>
<release parenthash = "085c444f40fd6189021b7d0bd5f131d40c0143e2" version = "6.9.0alpha0" githash = "b8819146cffb531fe9d044a78cce000da6d9c50c"></release>
<release parenthash = "75d5b0d4574c1766113ed3781b6218a75188da94" version = "6.10.0alpha0" githash = "8f9c2b960bd0fd6b7567d51d232c13b40619b0bc"></release>
<release parenthash = "d8939e38f70969a8312e27ac966f7a9ffe3267ee" version = "6.10.0alpha1" githash = "876e5a26068056a2cc2d52a6b543ce1f80a33e2e"></release>
<release parenthash = "30f610d185606bd17061581debb6693369fcbb05" version = "6.10.0alpha2" githash = "517fe9667c43f2c5fe0d8e5dae06be716342a16a"></release>
<release parenthash = "38958db165ea44a8db74abd0cf294fcb466e5172" version = "6.11.0alpha0" githash = "af925d59b69833c0ec8d970b667b4164833e5d4c"></release>
<release parenthash = "a4af4fd0f27b117df1f6e7ff6a10299f2ea91349" version = "6.11.0alpha1" githash = "bed9f5314a0f7f2c952da24bd6efa18931b12b93"></release>
<release parenthash = "66ce8f8a6e982c3de563205d12e0ed10725ef8c3" version = "6.11.0alpha2" githash = "7f8c3c687022e4664ba8f7d455ffcef8656911c0"></release>
<release parenthash = "6eaa986eb9b385a4be9de719fd906daa8b36a6bf" version = "6.11.1beta0" githash = "fa12263ac6248aa95abcdb11eaa5d6b09cffff7f"></release>
<release parenthash = "8335ef56cdc879e7e84a338534e10091b86b1e5a" version = "6.11.1beta1" githash = "3e61cee71c4aaa845908d5d9dfb9257a1000215d"></release>
<release parenthash = "214c5c4f4287b2e0f78a397d5ae9edeaceefa3b2" version = "6.11.1beta2" githash = "1e963e8bc5e02fc4a03cc1b4059533a7734417e9"></release>
<release parenthash = "575ee95714761eef35b2b59db4d09fe0bb311827" version = "6.11.2rc0" githash = "5bf4f147b1442ab7c682bb39cf9a159fe3770bf2"></release>
<release parenthash = "67b217f48f3e37fc9c185f126d0ce78e1892203d" version = "6.11.2rc1" githash = "46faa608ccdc0b44eb00425d2eb381cc8920504b"></release>
<release parenthash = "5eec2dd557d7d6c7e76643ad083879a24791e832" version = "6.11.2rc2" githash = "e1726efd172f52fe17e87687a59beeb0cc5dbd50"></release>
<release parenthash = "2f528c3e59378b6c9dc95ff5dbd73a6944b417ca" version = "6.11.3rc0" githash = "f4d02b8fd8ced64c28977ba38175cc5d633e4ddf"></release>
<release parenthash = "0c8cdd64a03f75d2c050ccadbb1bd8983534c7f7" version = "6.12.0alpha0" githash = "53c92345fc33bbdf6e8c2c42383755b4fb32350d"></release>
<release parenthash = "3087293667911378dda568b8d6ce05473780cf41" version = "6.12.0alpha1" githash = "e193478f759ec597725daa58df48d40b816f60b0"></release>
<release parenthash = "9be2eece00752df43d0d9ff3edf169407df30a72" version = "6.12.1alpha0" githash = "1d624b9a1f9cbbf262024abfc74c8dd8a0a16522"></release>
<release parenthash = "cdc2d74016f26492cf444a6f14ee82e104275874" version = "6.12.2rc0" githash = "e0e70d46060cabfc333ed08ccccb5dee565d1db2"></release>
<release parenthash = "53f819e748d25fdfd698303a48a7bfc51da77842" version = "6.12.2rc1" githash = "27e68d821d55560ac9d7b8878f2d77636864be1c"></release>
<release parenthash = "a09ba027a29767686091dfda3c390431cac8cdca" version = "6.12.2rc2" githash = "346f5a704f1130274b88cf742de73239e54b3c7d"></release>
<release parenthash = "cb6b3d3df25f5ee04577b9163f5ff2b7521919b3" version = "6.12.2rc3" githash = "d43c17a5c81724f880a001701669c5a00808a4e0"></release>
<release parenthash = "3b7f63844d1ef9363d4ab23fc9b028eb7bd94f31" version = "6.12.2rc4" githash = "7bf28f0367a76070bffa1b45fd7420e3e10a0b0d"></release>
<release parenthash = "c385fc2e1506b63b2a2440855a3b9d2503c76fa7" version = "6.12.3rc0" githash = "0b2696742e992a8031eeedb5226c1570705eedb1"></release>
<release parenthash = "ee6fa86c6c20d12c1fac1db24c3c8136e69dd892" version = "6.12.3rc1" githash = "47db9e113163d14946cf7c6165687f1888f20806"></release>
<release parenthash = "4d61773cf3919dd973d149c1ad2fa78d8f0502fe" version = "6.12.3rc2" githash = "c42d93f6a7975e7065a4edb5b86ac07baedf33c1"></release>
<release parenthash = "2b8419d7fb9e95d87484ff96f6a4024b7fadbf85" version = "6.12.3rc3" githash = "85383c7463baada50b9ee80706508a58d5e511c5"></release>
<release parenthash = "381e480cbc7385d32a5f003517ce8608e653c270" version = "6.12.4rc0" githash = "31b6b1f7f41584707a0ed761f03b80c28669af10"></release>
<release parenthash = "f7af9f6132d619d7858ab16c728309f013f8472c" version = "6.12.4rc1" githash = "7f644a433a6ad3a2e323e4ae42ad0bfe7487090f"></release>
<release parenthash = "ace38607b0adc325167d1eddab8c425e721451f1" version = "6.12.5rc0" githash = "23758e74f2ce9970b113e05084453c9596450622"></release>
<release parenthash = "9344178fcc4dc9da49e08ae049dd3a933b8202a8" version = "6.13.0beta0" githash = "c53447546e337a40da0bc64238d80666b35b7336"></release>
<release parenthash = "c53447546e337a40da0bc64238d80666b35b7336" version = "6.13.0beta1" githash = "2ae88301eb9f57f0556fad66e5350ef6b5c9a18d"></release>
<release parenthash = "b279a2ec4c2c8f3dad6624e5c55e2d487be202a8" version = "6.13.0beta2" githash = "55f20f68aef5887daab829d3bea5eb6d5fadecab"></release>
<release parenthash = "176cbeae28523b682ccdd7d92246edea0346634f" version = "6.14.0beta0" githash = "71dc9002456c5cdb6ae4a37887abaa8c3d08b5db"></release>
<release parenthash = "348fead68f7eec1c26df13241c0f96397cff2c08" version = "6.14.0beta1" githash = "caed924d76ce9cd4e9c4febe9bd1ef7b598a04ee"></release>
<release parenthash = "cfeb352d625de3d9e4208f8a32ed7b6c8974b024" version = "6.14.0beta2" githash = "216e8e3eee733c93d288826745850efbb3ebc4aa"></release>
<release parenthash = "929437e7df13732b917c4bedc8f74166840c08b7" version = "6.14.1beta0" githash = "977044168b6ad1c24c666c4cdc535967e2a74c71"></release>
<release parenthash = "95f44bf396ad9db3a98ed44811ebb3eda567b66e" version = "6.15.1rc0" githash = "577d68a08b45d6ef32d07fedfdb0d030daa2278c"></release>
<release parenthash = "0ed22a04170f3b17dc5d471b6f5a2fb68ed71f4f" version = "6.15.1rc1" githash = "b24377ad993cec6ddfbccc867618fbb8812e466f"></release>
<release parenthash = "136edf6bf7393d30e1f85197b72585c22611d94f" version = "6.15.2rc0" githash = "ef12c7afda6d448e22b7eb53c21d23e986db7b0d"></release>
<release parenthash = "d0929ae0676896b94a119e4b7c44ffadec1471d8" version = "6.16.0alpha0" githash = "5f2fec1d2ab32999c69536635f21ca42312dc267"></release>
<release parenthash = "60b6ca27825c4ab385fb945acf23089a4240a5ba" version = "6.18.0alpha0" githash = "37855df2f1b9a0c32d8c37e9c98853df4740e446"></release>
<release parenthash = "f770595930dac7e19fce394908a5817c34a79cda" version = "6.18.1alpha0" githash = "084863d720a4175b7248d68edb13f0d853321142"></release>
<release parenthash = "c3cae7fe525f1470ffae49e1f0955324924a1947" version = "6.19.0alpha0" githash = "e7c954ba63f496c41cbbd90bfcb7b9c3f14ee79c"></release>
<release parenthash = "13f5bb313d5e6e4f8c40342137e9c18ebc6d8d3f" version = "7.4.0rc0" githash = "ffb8baba208cbf71248bb265d2599c20b76325b5"></release>
<release parenthash = "25653fc08079eea48e63e440237db0359c9aa439" version = "7.4.1rc0" githash = "da927ba01ed5b970b1a7fd710249c44bc0adc7e8"></release>
<release parenthash = "cce4104b3a7d3465722cd4d7580b4d7293e6248c" version = "7.4.1rc1"></release>
<subpartnumber>XM-004720-SM</subpartnumber>
<vendor>XMOS</vendor>
<version_defines>
<version_define name = "BCD_DEVICE_J" format = "%MAJOR%"></version_define>
<version_define name = "BCD_DEVICE_M" format = "%MINOR%"></version_define>
<version_define name = "BCD_DEVICE_N" format = "%POINT%"></version_define>
</version_defines>
<xpd_version>1.0</xpd_version>
</xpd>