diff --git a/lib_xua/src/core/buffer/ep/ep_buffer.xc b/lib_xua/src/core/buffer/ep/ep_buffer.xc index eb6b373a..2802ff15 100644 --- a/lib_xua/src/core/buffer/ep/ep_buffer.xc +++ b/lib_xua/src/core/buffer/ep/ep_buffer.xc @@ -373,7 +373,7 @@ void XUA_Buffer_Ep(register chanend c_aud_out, #if( 0 < HID_CONTROLS ) { - int hidDataLength = hidGetReportLength(); + int hidDataLength = hidGetReportLength(0); // TODO Replace argument with HID Report ID XUD_SetReady_In(ep_hid, g_hidData, hidDataLength); } #endif @@ -889,8 +889,8 @@ void XUA_Buffer_Ep(register chanend c_aud_out, /* HID Report Data */ case XUD_SetData_Select(c_hid, ep_hid, result): { - int hidDataLength = hidGetReportLength(); - UserHIDGetData(g_hidData); + int hidDataLength = hidGetReportLength(0); // TODO Replace argument with HID Report ID + UserHIDGetData(0, g_hidData); // TODO Replace 1st argument with HID Report ID XUD_SetReady_In(ep_hid, g_hidData, hidDataLength); } break; diff --git a/lib_xua/src/core/user/hid/user_hid.h b/lib_xua/src/core/user/hid/user_hid.h index 3fcb52ee..6010af85 100644 --- a/lib_xua/src/core/user/hid/user_hid.h +++ b/lib_xua/src/core/user/hid/user_hid.h @@ -1,19 +1,31 @@ // 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__ /** * \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, + * - the location within the HID Report for the event, 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; @@ -22,15 +34,27 @@ typedef struct hidEvent_t { #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) + * \param[out] hidData The HID data */ -void UserHIDGetData( unsigned char hidData[ HID_MAX_DATA_BYTES ]); +void UserHIDGetData( const unsigned id, unsigned char hidData[ HID_MAX_DATA_BYTES ]); + +/** + * \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 UserHIDGetReportIdLimit ( void ); /** * \brief Initialize HID processing @@ -40,9 +64,10 @@ 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. + * \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 @@ -50,5 +75,17 @@ void UserHIDInit( void ); */ unsigned UserHIDRecordEvent( const hidEvent_t hidEvent[], const unsigned hidEventCnt ); +/** + * \brief Indicate if a HID Report ID has new data to report + * + * \param[in] id A HID Report ID (see 5.6, 6.2.2.7, 8.1 and 8.2) + * + * \returns A Boolean flag indicating the status of the operation + * \retval False The given \a id either does not have new data to report or lies + * outside the range of supported HID Report identifiers + * \retval True The given \a id has new data to report to the USB Host + */ +unsigned UserHIDReportChanged( const unsigned id ); + #endif /* ( 0 < HID_CONTROLS ) */ #endif /* __USER_HID_H__ */ diff --git a/lib_xua/src/hid/hid_report_descriptor.c b/lib_xua/src/hid/hid_report_descriptor.c index 1b899aaf..a9b6088e 100644 --- a/lib_xua/src/hid/hid_report_descriptor.c +++ b/lib_xua/src/hid/hid_report_descriptor.c @@ -77,11 +77,11 @@ static unsigned hidGetItemType( const unsigned char header ); * * Parameters: * - * @param[in] byte The byte location in the HID Report + * @param[in] id The HID Report ID for the Usage Page * - * @return The USB HID Usage Page code or zero if the \a byte parameter is out-of-range + * @return The USB HID Usage Page code or zero if the \a id parameter is out-of-range */ -static unsigned hidGetUsagePage( const unsigned byte ); +static unsigned hidGetUsagePage( const unsigned id ); /** * @brief Translate an Item from the \c USB_HID_Short_Item format to raw bytes @@ -147,6 +147,7 @@ size_t hidGetReportDescriptorLength( void ) #define HID_CONFIGURABLE_ITEM_COUNT ( sizeof hidConfigurableItems / sizeof ( USB_HID_Short_Item_t* )) unsigned hidGetReportItem( + const unsigned id, const unsigned byte, const unsigned bit, unsigned char* const page, @@ -175,15 +176,21 @@ unsigned hidGetReportItem( return retVal; } -size_t hidGetReportLength( void ) +size_t hidGetReportLength( const unsigned id ) { size_t retVal = ( hidReportDescriptorPrepared ) ? HID_REPORT_LENGTH : 0; return retVal; } -static unsigned hidGetUsagePage( const unsigned byte ) +static unsigned hidGetUsagePage( const unsigned id ) { - unsigned retVal = ( byte < HID_REPORT_LENGTH ) ? hidUsagePages[ byte ]->data[ 0 ] : 0; + unsigned retVal = 0U; + for( unsigned idx = 0; idx < 1; ++idx) { // TODO Fix the upper limit! + if( id == hidUsagePages[ idx ]->id ) { + retVal = hidUsagePages[ idx ]->data[ 0 ]; + break; + } + } return retVal; } @@ -206,6 +213,7 @@ void hidResetReportDescriptor( void ) } unsigned hidSetReportItem( + const unsigned id, const unsigned byte, const unsigned bit, const unsigned char page, diff --git a/lib_xua/src/hid/xua_hid_report_descriptor.h b/lib_xua/src/hid/xua_hid_report_descriptor.h index dc8878ae..00128407 100644 --- a/lib_xua/src/hid/xua_hid_report_descriptor.h +++ b/lib_xua/src/hid/xua_hid_report_descriptor.h @@ -40,9 +40,10 @@ #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 ) +#define HID_STATUS_BAD_ID ( 2 ) +#define HID_STATUS_BAD_LOCATION ( 3 ) +#define HID_STATUS_BAD_PAGE ( 4 ) +#define HID_STATUS_IN_USE ( 5 ) /** * @brief USB HID Report Descriptor. Short Item @@ -57,6 +58,8 @@ * 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) */ @@ -64,6 +67,7 @@ typedef struct { unsigned char header; unsigned char data[ HID_REPORT_ITEM_MAX_SIZE ]; + unsigned char id; unsigned char location; } USB_HID_Short_Item_t; @@ -100,6 +104,7 @@ size_t hidGetReportDescriptorLength( void ); * * Parameters: * + * @param[in] id The identifier for the HID Report (see 5.6, 6.2.2.7, 8.1 and 8.2) * @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) @@ -108,13 +113,26 @@ size_t hidGetReportDescriptorLength( void ); * * @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 byte, const unsigned bit, unsigned char* unsafe const page, unsigned char* unsafe const header, unsigned char* unsafe const data); +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 byte, const unsigned bit, unsigned char* const page, unsigned char* const header, unsigned char data[]); +unsigned hidGetReportItem( + const unsigned id, + const unsigned byte, + const unsigned bit, + unsigned char* const page, + unsigned char* const header, + unsigned char data[]); #endif /** @@ -122,11 +140,16 @@ unsigned hidGetReportItem( const unsigned byte, const unsigned bit, unsigned cha * * 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(). + * 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) * * @return The length of the Report in bytes */ -size_t hidGetReportLength( void ); +size_t hidGetReportLength( const unsigned id ); /** * @brief Prepare the USB HID Report descriptor @@ -154,6 +177,7 @@ void hidResetReportDescriptor( void ); * * Parameters: * + * @param[in] id The identifier for the HID Report (see 5.6, 6.2.2.7, 8.1 and 8.2) * @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) @@ -164,12 +188,19 @@ void hidResetReportDescriptor( void ); * @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 byte, const unsigned bit, const unsigned char page, const unsigned char header, const unsigned char data[]); +unsigned hidSetReportItem( + const unsigned id, + const unsigned byte, + const unsigned bit, + const unsigned char page, + const unsigned char header, + const unsigned char data[]); #endif // _HID_REPORT_DESCRIPTOR_