diff --git a/CHANGELOG.rst b/CHANGELOG.rst index d8b82f4a..f2aa6a1e 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -11,6 +11,15 @@ lib_xua Change Log 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 + customer + * CHANGE: 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 + detection as AC Stop 0.2.1 ----- diff --git a/LICENSE.txt b/LICENSE.txt index 19f8e7cc..d4acef94 100644 --- a/LICENSE.txt +++ b/LICENSE.txt @@ -1,6 +1,6 @@ Software Release License Agreement -Copyright (c) 2011-2019, XMOS, All rights reserved. +Copyright (c) 2011-2020, XMOS, All rights reserved. BY ACCESSING, USING, INSTALLING OR DOWNLOADING THE XMOS SOFTWARE, YOU AGREE TO BE BOUND BY THE FOLLOWING TERMS. IF YOU DO NOT AGREE TO THESE, DO NOT ATTEMPT TO DOWNLOAD, ACCESS OR USE THE XMOS Software. diff --git a/lib_xua/LICENSE.txt b/lib_xua/LICENSE.txt index 3932a9ae..7f5e44ce 100644 --- a/lib_xua/LICENSE.txt +++ b/lib_xua/LICENSE.txt @@ -1,6 +1,6 @@ Software Release License Agreement -Copyright (c) 2017-2019, XMOS, All rights reserved. +Copyright (c) 2017-2020, XMOS, All rights reserved. BY ACCESSING, USING, INSTALLING OR DOWNLOADING THE XMOS SOFTWARE, YOU AGREE TO BE BOUND BY THE FOLLOWING TERMS. IF YOU DO NOT AGREE TO THESE, DO NOT ATTEMPT TO DOWNLOAD, ACCESS OR USE THE XMOS Software. diff --git a/lib_xua/api/xua_conf_default.h b/lib_xua/api/xua_conf_default.h index a1d700f3..6255221e 100644 --- a/lib_xua/api/xua_conf_default.h +++ b/lib_xua/api/xua_conf_default.h @@ -1,4 +1,4 @@ -// Copyright (c) 2011-2019, XMOS Ltd, All rights reserved +// Copyright (c) 2011-2020, XMOS Ltd, All rights reserved /* * @brief Defines relating to device configuration and customisation of lib_xua * @author Ross Owen, XMOS Limited @@ -1473,6 +1473,12 @@ enum USBEndpointNumber_Out #error Bad DEFAULT_MCLK_FREQ #endif +/* DFU functional descriptor wDetachTimeOut field (milliseconds) + * Time for device to wait for bus reset after DETACH request before reverting to idle state */ +#ifndef DFU_DETACH_TIME_OUT +#define DFU_DETACH_TIME_OUT 250 +#endif + #if ((MCLK_441 % MIN_FREQ) == 0) #define MIN_FREQ_44 MIN_FREQ #define MIN_FREQ_48 ((48000 * 512)/((44100 * 512)/MIN_FREQ)) @@ -1494,4 +1500,3 @@ enum USBEndpointNumber_Out #if (CODEC_MASTER == 1) && (DSD_CHANS_DAC != 0) #error CODEC_MASTER with DSD is currently unsupported #endif - diff --git a/lib_xua/src/core/buffer/ep/ep_buffer.xc b/lib_xua/src/core/buffer/ep/ep_buffer.xc index 45e08da3..ae58ef83 100644 --- a/lib_xua/src/core/buffer/ep/ep_buffer.xc +++ b/lib_xua/src/core/buffer/ep/ep_buffer.xc @@ -1,4 +1,4 @@ -// Copyright (c) 2011-2019, XMOS Ltd, All rights reserved +// Copyright (c) 2011-2020, XMOS Ltd, All rights reserved #include "xua.h" #if XUA_USB_EN #include @@ -21,7 +21,7 @@ #if( 0 < HID_CONTROLS ) #include "user_hid.h" -unsigned char g_hidData[1] = {0}; +unsigned char g_hidData[HID_DATA_BYTES] = {0}; #endif void GetADCCounts(unsigned samFreq, int &min, int &mid, int &max); @@ -880,7 +880,7 @@ void XUA_Buffer_Ep(register chanend c_aud_out, case XUD_SetData_Select(c_hid, ep_hid, result): { g_hidData[0]=0; - UserReadHIDData(g_hidData); + UserHIDGetData(g_hidData); XUD_SetReady_In(ep_hid, g_hidData, 1); } break; diff --git a/lib_xua/src/core/endpoint0/xua_ep0_descriptors.h b/lib_xua/src/core/endpoint0/xua_ep0_descriptors.h index 42f26651..dd284b0a 100644 --- a/lib_xua/src/core/endpoint0/xua_ep0_descriptors.h +++ b/lib_xua/src/core/endpoint0/xua_ep0_descriptors.h @@ -1,4 +1,4 @@ -// Copyright (c) 2011-2019, XMOS Ltd, All rights reserved +// Copyright (c) 2011-2020, XMOS Ltd, All rights reserved /** * @file xua_ep0_descriptors.h * @brief Device Descriptors @@ -566,20 +566,26 @@ unsigned char devQualDesc_Null[] = #if( 0 < HID_CONTROLS ) unsigned char hidReportDescriptor[] = /* Voice Command usage as per request #HUTRR45 */ { - 0x15, 0x01, /* Logical Minimum (1) */ - 0x25, 0x01, /* Logical Maximum (1) */ - 0x75, 0x01, /* Report Size (1) */ - 0x05, 0x0c, /* Usage Page (Consumer Device) */ - 0x09, 0x01, /* Usage (Consumer Control) */ + 0x05, 0x01, /* Usage Page (Generic Desktop) */ + 0x09, 0x06, /* Usage (Keyboard) */ 0xa1, 0x01, /* Collection (Application) */ - 0x0a, 0x00, 0x02, /* Usage (Generic GUI Application Controls) */ - 0xa1, 0x02, /* Collection (Logical) */ - 0x0a, 0x21, 0x02, /* Usage (AC Search) */ + 0x75, 0x01, /* Report Size (1) */ + 0x95, 0x04, /* Report Count (4) */ + 0x15, 0x00, /* Logical Minimum (0) */ + 0x25, 0x00, /* Logical Maximum (0) */ + 0x81, 0x01, /* Input (Cnst, Ary, Abs, No Wrap, Lin, Pref, No Nul) */ 0x95, 0x01, /* Report Count (1) */ - 0x81, 0x40, /* Input (Data, Ary, Abs, Nul) */ - 0x95, 0x07, /* Report Count (7) */ - 0x81, 0x01, /* Input (Cnst, Ary, Abs) */ - 0xc0, /* End collection (Logical) */ + 0x25, 0x01, /* Logical Maximum (1) */ + 0x05, 0x0C, /* Usage Page (Consumer) */ + 0x0a, 0x21, 0x02, /* Usage (AC Search) */ + 0x81, 0x02, /* Input (Data, Var, Abs, No Wrap, Lin, Pref, No Nul) */ + 0x0a, 0x26, 0x02, /* Usage (AC Stop) */ + 0x81, 0x02, /* Input (Data, Var, Abs, No Wrap, Lin, Pref, No Nul) */ + 0x95, 0x02, /* Report Count (2) */ + 0x05, 0x07, /* Usage Page (Key Codes) */ + 0x19, 0x72, /* Usage Minimum (Keyboard F23) */ + 0x29, 0x73, /* Usage Maximum (Keyboard F24) */ + 0x81, 0x02, /* Input (Data, Var, Abs, No Wrap, Lin, Pref, No Nul) */ 0xc0 /* End collection (Application) */ }; #endif @@ -2064,8 +2070,8 @@ USB_Config_Descriptor_Audio2_t cfgDesc_Audio2= 0x09, /* 0 Size */ 0x21, /* 1 bDescriptorType : DFU FUNCTIONAL */ 0x07, /* 2 bmAttributes */ - 0xFA, /* 3 wDetachTimeOut */ - 0x00, /* 4 wDetachTimeOut */ + DFU_DETACH_TIME_OUT & 0xFF, /* 3 wDetachTimeOut */ + (DFU_DETACH_TIME_OUT >> 8) & 0xFF, /* 4 wDetachTimeOut */ 0x40, /* 5 wTransferSize */ 0x00, /* 6 wTransferSize */ 0x10, /* 7 bcdDFUVersion */ @@ -2692,7 +2698,7 @@ unsigned char cfgDesc_Audio1[] = (FS_STREAM_FORMAT_OUTPUT_1_MAXPACKETSIZE&0xff), /* 4 wMaxPacketSize (Typically 294 bytes)*/ (FS_STREAM_FORMAT_OUTPUT_1_MAXPACKETSIZE&0xff00)>>8, /* 5 wMaxPacketSize */ 0x01, /* bInterval */ - 0x00, /* bRefresh */ + 0x00, /* bRefresh */ #if (NUM_USB_CHAN_IN == 0) || defined(UAC_FORCE_FEEDBACK_EP) ENDPOINT_ADDRESS_IN_FEEDBACK, /* bSynchAdddress - address of EP used to communicate sync info */ #else /* Bi-directional in/out device */ @@ -3004,8 +3010,8 @@ unsigned char cfgDesc_Audio1[] = 0x09, /* 0 Size */ 0x21, /* 1 bDescriptorType : DFU FUNCTIONAL */ 0x07, /* 2 bmAttributes */ - 0xFA, /* 3 wDetachTimeOut */ - 0x00, /* 4 wDetachTimeOut */ + DFU_DETACH_TIME_OUT & 0xFF, /* 3 wDetachTimeOut */ + (DFU_DETACH_TIME_OUT >> 8) & 0xFF, /* 4 wDetachTimeOut */ 0x40, /* 5 wTransferSize */ 0x00, /* 6 wTransferSize */ 0x10, /* 7 bcdDFUVersion */ @@ -3045,7 +3051,7 @@ unsigned char cfgDesc_Audio1[] = 0x00, /* 4 bCountryCode */ 0x01, /* 5 bNumDescriptors */ 0x22, /* 6 bDescriptorType[0] (Report) */ - 0x1E, /* 7 wDescriptorLength[0] */ + 0x2B, /* 7 wDescriptorLength[0] */ 0x00, /* 8 wDescriptorLength[0] */ /* HID Endpoint descriptor (IN) */ diff --git a/lib_xua/src/core/user/hid/user_hid.h b/lib_xua/src/core/user/hid/user_hid.h index 7d67b00c..91b32290 100644 --- a/lib_xua/src/core/user/hid/user_hid.h +++ b/lib_xua/src/core/user/hid/user_hid.h @@ -1,23 +1,85 @@ -// Copyright (c) 2013-2019, XMOS Ltd, All rights reserved +// Copyright (c) 2013-2020, XMOS Ltd, All rights reserved #ifndef __USER_HID_H__ #define __USER_HID_H__ -/* These defines relate to the HID report desc - do not mod */ -#define HID_CONTROL_PLAYPAUSE_SHIFT 0x00 -#define HID_CONTROL_NEXT_SHIFT 0x01 -#define HID_CONTROL_PREV_SHIFT 0x02 -#define HID_CONTROL_VOLUP_SHIFT 0x03 -#define HID_CONTROL_VOLDN_SHIFT 0x04 -#define HID_CONTROL_MUTE_SHIFT 0x05 +/** + * \brief HID event identifiers + * + * This enumeration defines a constant value for each HID event. + * It defines one value for each of the four GPI pins supported in the standard voice products. + * It defines a further 28 values for generic events. + */ +typedef enum hidEventId_t { + HID_EVENT_ID_GPI0 = 0, + HID_EVENT_ID_GPI1, + HID_EVENT_ID_GPI2, + HID_EVENT_ID_GPI3, + HID_EVENT_ID_EVT0, + HID_EVENT_ID_EVT1, + HID_EVENT_ID_EVT2, + HID_EVENT_ID_EVT3, + HID_EVENT_ID_EVT4, + HID_EVENT_ID_EVT5, + HID_EVENT_ID_EVT6, + HID_EVENT_ID_EVT7, + HID_EVENT_ID_EVT8, + HID_EVENT_ID_EVT9, + HID_EVENT_ID_EVT10, + HID_EVENT_ID_EVT11, + HID_EVENT_ID_EVT12, + HID_EVENT_ID_EVT13, + HID_EVENT_ID_EVT14, + HID_EVENT_ID_EVT15, + HID_EVENT_ID_EVT16, + HID_EVENT_ID_EVT17, + HID_EVENT_ID_EVT18, + HID_EVENT_ID_EVT19, + HID_EVENT_ID_EVT20, + HID_EVENT_ID_EVT21, + HID_EVENT_ID_EVT22, + HID_EVENT_ID_EVT23, + HID_EVENT_ID_EVT24, + HID_EVENT_ID_EVT25, + HID_EVENT_ID_EVT26, + HID_EVENT_ID_EVT27, + HID_EVENT_ID_INVALID = 0xffffffff, +} hidEventId_t; -#define HID_DATA_SIZE 1 +#define HID_DATA_BYTES 4 #if( 0 < HID_CONTROLS ) -void UserInitHIDData( void ); -void UserReadHIDData( unsigned char hidData[ HID_DATA_SIZE ]); -void UserSetHIDData( const unsigned hidData ); +/** + * \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 + */ +void UserHIDGetData( unsigned char hidData[ HID_DATA_BYTES ]); + +/** + * \brief Initialize HID processing + */ +void UserHIDInit( void ); + +/** + * \brief Record that a HID event has occurred + * + * \param{in} hidEventId The identifier of an event which has occurred + * \param{in} hidEventData A list of data associated with the event + * \param{in} hidEventDataSize The length of the event data list + * + * \note At present, this function only takes a single element of event data, i.e. + * hidEventDataSize must equal 1. + * + * \note At present, this function treats the event data as a Boolean flag. + * Zero means False; all other values mean True. + */ +void UserHIDRecordEvent( const hidEventId_t hidEventId, const int * hidEventData, const unsigned hidEventDataSize ); #endif /* ( 0 < HID_CONTROLS ) */ #endif /* __USER_HID_H__ */ diff --git a/lib_xua/src/hid/hid.xc b/lib_xua/src/hid/hid.xc index 854b78d3..906fd1ec 100644 --- a/lib_xua/src/hid/hid.xc +++ b/lib_xua/src/hid/hid.xc @@ -9,12 +9,17 @@ #if( 0 < HID_CONTROLS ) #define MS_IN_TICKS 100000U -static unsigned s_hidIdleActive = 0U; +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 ); @@ -51,6 +56,18 @@ XUD_Result_t HidInterfaceClassRequests( return result; } +void HidClearChangePending( void ) +{ + unsafe { + *s_hidChangePendingPtr = 0U; + } +} + +unsigned HidIsChangePending( void ) +{ + return( s_hidChangePending != 0 ); +} + unsigned HidIsSetIdleSilenced( void ) { unsigned isSilenced = s_hidIdleActive; @@ -67,6 +84,13 @@ unsigned HidIsSetIdleSilenced( void ) return isSilenced; } +void HidSetChangePending( void ) +{ + unsafe { + *s_hidChangePendingPtr = 1; + } +} + /** * \brief Calculate the timer value for sending the next HID Report. * diff --git a/lib_xua/src/hid/xua_hid.h b/lib_xua/src/hid/xua_hid.h index 63469054..9e620788 100644 --- a/lib_xua/src/hid/xua_hid.h +++ b/lib_xua/src/hid/xua_hid.h @@ -40,6 +40,17 @@ XUD_Result_t HidInterfaceClassRequests( 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. * @@ -58,4 +69,9 @@ XUD_Result_t HidInterfaceClassRequests( */ unsigned HidIsSetIdleSilenced( void ); +/** + * \brief Register that a change to the HID Report data has been received. + */ +void HidSetChangePending( void ); + #endif // __XUA_HID_H__