forked from PAWPAW-Mirror/lib_xua
Merge pull request #103 from mbanth/feature/pendragon
Feature/pendragon
This commit is contained in:
1
.gitignore
vendored
1
.gitignore
vendored
@@ -27,3 +27,4 @@ _build*
|
||||
build/
|
||||
.build*
|
||||
*.pyc
|
||||
xscope.xmt
|
||||
|
||||
@@ -1,6 +1,13 @@
|
||||
lib_xua Change Log
|
||||
==================
|
||||
|
||||
0.3.0
|
||||
-----
|
||||
|
||||
* ADDED: UAC1 HID support with simulated Voice Command detection reported
|
||||
every 10 seconds
|
||||
* ADDED: Support for USB HID Set Idle request
|
||||
|
||||
0.2.1
|
||||
-----
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright (c) 2011-2018, XMOS Ltd, All rights reserved
|
||||
// Copyright (c) 2011-2019, XMOS Ltd, All rights reserved
|
||||
#ifndef __XUA_BUFFER_H__
|
||||
#define __XUA_BUFFER_H__
|
||||
|
||||
@@ -58,7 +58,7 @@ void XUA_Buffer(
|
||||
chanend c_sof,
|
||||
chanend c_aud_ctl,
|
||||
in port p_off_mclk
|
||||
#ifdef HID_CONTROLS
|
||||
#if( 0 < HID_CONTROLS )
|
||||
, chanend c_hid
|
||||
#endif
|
||||
, chanend c_aud
|
||||
@@ -97,7 +97,7 @@ void XUA_Buffer_Ep(chanend c_aud_out,
|
||||
chanend c_sof,
|
||||
chanend c_aud_ctl,
|
||||
in port p_off_mclk
|
||||
#ifdef HID_CONTROLS
|
||||
#if( 0 < HID_CONTROLS )
|
||||
, chanend c_hid
|
||||
#endif
|
||||
#ifdef CHAN_BUFF_CTRL
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright (c) 2011-2018, XMOS Ltd, All rights reserved
|
||||
// Copyright (c) 2011-2019, XMOS Ltd, All rights reserved
|
||||
/*
|
||||
* @brief Defines relating to device configuration and customisation of lib_xua
|
||||
* @author Ross Owen, XMOS Limited
|
||||
@@ -425,10 +425,6 @@
|
||||
#define HID_CONTROLS (0)
|
||||
#endif
|
||||
|
||||
#if defined(HID_CONTROLS) && (HID_CONTROLS == 0)
|
||||
#undef HID_CONTROLS
|
||||
#endif
|
||||
|
||||
/* @brief Defines whether XMOS device runs as master (i.e. drives LR and Bit clocks)
|
||||
*
|
||||
* 0: XMOS is I2S master. 1: CODEC is I2s master.
|
||||
@@ -1158,6 +1154,10 @@
|
||||
#endif
|
||||
|
||||
|
||||
#if (defined(UAC_FORCE_FEEDBACK_EP) && UAC_FORCE_FEEDBACK_EP == 0)
|
||||
#undef UAC_FORCE_FEEDBACK_EP
|
||||
#endif
|
||||
|
||||
#ifndef __ASSEMBLER__
|
||||
/* Endpoint addresses enums */
|
||||
enum USBEndpointNumber_In
|
||||
@@ -1173,7 +1173,7 @@ enum USBEndpointNumber_In
|
||||
#ifdef MIDI
|
||||
ENDPOINT_NUMBER_IN_MIDI,
|
||||
#endif
|
||||
#ifdef HID_CONTROLS
|
||||
#if( 0 < HID_CONTROLS )
|
||||
ENDPOINT_NUMBER_IN_HID,
|
||||
#endif
|
||||
#ifdef IAP
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
VERSION = 0.2.1
|
||||
VERSION = 0.3.0
|
||||
|
||||
DEPENDENT_MODULES = lib_logging(>=3.0.0) \
|
||||
lib_xassert(>=4.0.0) \
|
||||
@@ -43,6 +43,7 @@ INCLUDE_DIRS = $(EXPORT_INCLUDE_DIRS) \
|
||||
src/core/support/powersave \
|
||||
src/core/user \
|
||||
src/core/user/audiostream \
|
||||
src/core/user/hid \
|
||||
src/core/user/hostactive \
|
||||
src/midi
|
||||
|
||||
@@ -61,6 +62,7 @@ SOURCE_DIRS = src/core \
|
||||
src/core/user/hostactive \
|
||||
src/core/xuduser \
|
||||
src/dfu \
|
||||
src/hid \
|
||||
src/midi
|
||||
|
||||
EXCLUDE_FILES += descriptors_2.rst
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright (c) 2011-2018, XMOS Ltd, All rights reserved
|
||||
// Copyright (c) 2011-2019, XMOS Ltd, All rights reserved
|
||||
#include "xua.h"
|
||||
|
||||
#if XUA_USB_EN
|
||||
@@ -12,7 +12,7 @@
|
||||
#include "usbaudio20.h" /* Defines from the USB Audio 2.0 Specifications */
|
||||
#endif
|
||||
|
||||
#ifdef HID_CONTROLS
|
||||
#if( 0 < HID_CONTROLS )
|
||||
#include "user_hid.h"
|
||||
#endif
|
||||
#define MAX(x,y) ((x)>(y) ? (x) : (y))
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright (c) 2011-2018, XMOS Ltd, All rights reserved
|
||||
// Copyright (c) 2011-2019, XMOS Ltd, All rights reserved
|
||||
#include "xua.h"
|
||||
#if XUA_USB_EN
|
||||
#include <xs1.h>
|
||||
@@ -19,7 +19,7 @@
|
||||
#include "xud.h"
|
||||
#include "testct_byref.h"
|
||||
|
||||
#ifdef HID_CONTROLS
|
||||
#if( 0 < HID_CONTROLS )
|
||||
#include "user_hid.h"
|
||||
unsigned char g_hidData[1] = {0};
|
||||
#endif
|
||||
@@ -120,7 +120,7 @@ void XUA_Buffer(
|
||||
chanend c_sof,
|
||||
chanend c_aud_ctl,
|
||||
in port p_off_mclk
|
||||
#ifdef HID_CONTROLS
|
||||
#if( 0 < HID_CONTROLS )
|
||||
, chanend c_hid
|
||||
#endif
|
||||
, chanend c_aud
|
||||
@@ -164,7 +164,7 @@ void XUA_Buffer(
|
||||
c_clk_int,
|
||||
#endif
|
||||
c_sof, c_aud_ctl, p_off_mclk
|
||||
#ifdef HID_CONTROLS
|
||||
#if( 0 < HID_CONTROLS )
|
||||
, c_hid
|
||||
#endif
|
||||
#ifdef CHAN_BUFF_CTRL
|
||||
@@ -223,7 +223,7 @@ void XUA_Buffer_Ep(register chanend c_aud_out,
|
||||
chanend c_sof,
|
||||
chanend c_aud_ctl,
|
||||
in port p_off_mclk
|
||||
#ifdef HID_CONTROLS
|
||||
#if( 0 < HID_CONTROLS )
|
||||
, chanend c_hid
|
||||
#endif
|
||||
#ifdef CHAN_BUFF_CTRL
|
||||
@@ -260,7 +260,7 @@ void XUA_Buffer_Ep(register chanend c_aud_out,
|
||||
XUD_ep ep_int = XUD_InitEp(c_ep_int);
|
||||
#endif
|
||||
|
||||
#ifdef HID_CONTROLS
|
||||
#if( 0 < HID_CONTROLS )
|
||||
XUD_ep ep_hid = XUD_InitEp(c_hid);
|
||||
#endif
|
||||
unsigned u_tmp;
|
||||
@@ -364,7 +364,7 @@ void XUA_Buffer_Ep(register chanend c_aud_out,
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef HID_CONTROLS
|
||||
#if( 0 < HID_CONTROLS )
|
||||
XUD_SetReady_In(ep_hid, g_hidData, 1);
|
||||
#endif
|
||||
|
||||
@@ -875,12 +875,12 @@ void XUA_Buffer_Ep(register chanend c_aud_out,
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef HID_CONTROLS
|
||||
#if( 0 < HID_CONTROLS )
|
||||
/* HID Report Data */
|
||||
case XUD_SetData_Select(c_hid, ep_hid, result):
|
||||
{
|
||||
g_hidData[0]=0;
|
||||
UserReadHIDButtons(g_hidData);
|
||||
UserReadHIDData(g_hidData);
|
||||
XUD_SetReady_In(ep_hid, g_hidData, 1);
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -1,8 +1,13 @@
|
||||
// Copyright (c) 2015-2018, XMOS Ltd, All rights reserved
|
||||
// Copyright (c) 2015-2019, XMOS Ltd, All rights reserved
|
||||
|
||||
#ifndef __DESCRIPTOR_DEFS_H__
|
||||
#define __DESCRIPTOR_DEFS_H__
|
||||
|
||||
/*
|
||||
Include xua.h to pick up the #defines of NUM_USB_CHAN_IN and NUM_USB_CHAN_OUT.
|
||||
*/
|
||||
#include "xua.h"
|
||||
|
||||
#if (NUM_USB_CHAN_IN > 0) && (NUM_USB_CHAN_OUT > 0)
|
||||
#define AUDIO_INTERFACE_COUNT 3
|
||||
#elif (NUM_USB_CHAN_IN > 0) || (NUM_USB_CHAN_OUT > 0)
|
||||
@@ -54,10 +59,14 @@ enum USBInterfaceNumber
|
||||
INTERFACE_NUMBER_IAP_EA_NATIVE_TRANS,
|
||||
#endif
|
||||
#endif
|
||||
#if defined(HID_CONTROLS) && (HID_CONTROLS != 0)
|
||||
#if( 0 < HID_CONTROLS )
|
||||
INTERFACE_NUMBER_HID,
|
||||
#endif
|
||||
INTERFACE_COUNT /* End marker */
|
||||
};
|
||||
|
||||
#if( 0 < HID_CONTROLS )
|
||||
#define ENDPOINT_INT_INTERVAL_IN_HID 0x08
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -561,27 +561,24 @@ unsigned char devQualDesc_Null[] =
|
||||
#define MIXER_LENGTH (0)
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef HID_CONTROLS
|
||||
unsigned char hidReportDescriptor[] =
|
||||
#if( 0 < HID_CONTROLS )
|
||||
unsigned char hidReportDescriptor[] = /* Voice Command usage as per request #HUTRR45 */
|
||||
{
|
||||
0x05, 0x0c, /* Usage Page (Consumer Device) */
|
||||
0x09, 0x01, /* Usage (Consumer Control) */
|
||||
0xa1, 0x01, /* Collection (Application) */
|
||||
0x15, 0x00, /* Logical Minimum (0) */
|
||||
0x25, 0x01, /* Logical Maximum (1) */
|
||||
0x09, 0xb0, /* Usage (Play) */
|
||||
0x09, 0xb5, /* Usage (Scan Next Track) */
|
||||
0x09, 0xb6, /* Usage (Scan Previous Track) */
|
||||
0x09, 0xe9, /* Usage (Volume Up) */
|
||||
0x09, 0xea, /* Usage (Volume Down) */
|
||||
0x09, 0xe2, /* Usage (Mute) */
|
||||
0x75, 0x01, /* Report Size (1) */
|
||||
0x95, 0x06, /* Report Count (6) */
|
||||
0x81, 0x02, /* Input (Data, Var, Abs) */
|
||||
0x95, 0x02, /* Report Count (2) */
|
||||
0x81, 0x01, /* Input (Cnst, Ary, Abs) */
|
||||
0xc0 /* End collection */
|
||||
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) */
|
||||
0xa1, 0x01, /* Collection (Application) */
|
||||
0x0a, 0x00, 0x02, /* Usage (Generic GUI Application Controls) */
|
||||
0xa1, 0x02, /* Collection (Logical) */
|
||||
0x0a, 0x21, 0x02, /* Usage (AC Search) */
|
||||
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) */
|
||||
0xc0 /* End collection (Application) */
|
||||
};
|
||||
#endif
|
||||
|
||||
@@ -784,7 +781,7 @@ typedef struct
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef HID_CONTROLS
|
||||
#if( 0 < HID_CONTROLS )
|
||||
USB_Descriptor_Interface_t HID_Interface;
|
||||
unsigned char hidDesc[9]; //TODO ideally we would have a struct for this.
|
||||
USB_Descriptor_Endpoint_t HID_In_Endpoint;
|
||||
@@ -1099,7 +1096,7 @@ USB_Config_Descriptor_Audio2_t cfgDesc_Audio2=
|
||||
},
|
||||
0, /* 60 iFeature */
|
||||
},
|
||||
#endif
|
||||
#endif /* (OUTPUT_VOLUME_CONTROL == 1) */
|
||||
|
||||
/* Output Terminal Descriptor (Audio) */
|
||||
.Audio_Out_OutputTerminal =
|
||||
@@ -1119,7 +1116,7 @@ USB_Config_Descriptor_Audio2_t cfgDesc_Audio2=
|
||||
0x0000, /* 9 bmControls */
|
||||
0, /* 11 iTerminal */
|
||||
},
|
||||
#endif
|
||||
#endif /* (NUM_USB_CHAN_OUT > 0) */
|
||||
|
||||
|
||||
|
||||
@@ -1274,7 +1271,7 @@ USB_Config_Descriptor_Audio2_t cfgDesc_Audio2=
|
||||
},
|
||||
0, /* 60 iFeature */
|
||||
},
|
||||
#endif
|
||||
#endif /* (INPUT_VOLUME_CONTROL == 1) */
|
||||
|
||||
.Audio_In_OutputTerminal =
|
||||
{
|
||||
@@ -1295,7 +1292,7 @@ USB_Config_Descriptor_Audio2_t cfgDesc_Audio2=
|
||||
.bmControls = 0x0000,
|
||||
.iTerminal = offsetof(StringDescTable_t, usbOutputTermStr_Audio2)/sizeof(char *)
|
||||
},
|
||||
#endif
|
||||
#endif /* (NUM_USB_CHAN_IN > 0) */
|
||||
|
||||
#if defined(MIXER) && (MAX_MIX_COUNT > 0)
|
||||
/* Extension Unit Descriptor (4.7.2.12) */
|
||||
@@ -1389,7 +1386,7 @@ USB_Config_Descriptor_Audio2_t cfgDesc_Audio2=
|
||||
0x00, /* bmControls */
|
||||
0 /* Mixer unit string descriptor index */
|
||||
},
|
||||
#endif
|
||||
#endif /* defined(MIXER) && (MAX_MIX_COUNT > 0) */
|
||||
|
||||
#if (SPDIF_RX) || (ADAT_RX)
|
||||
/* Standard AS Interrupt Endpoint Descriptor (4.8.2.1): */
|
||||
@@ -1586,7 +1583,7 @@ USB_Config_Descriptor_Audio2_t cfgDesc_Audio2=
|
||||
4, /* 6 bInterval. Only values <= 1 frame (4) supported by MS */
|
||||
},
|
||||
#endif
|
||||
#endif
|
||||
#endif /* OUTPUT_FORMAT_COUNT > 1 */
|
||||
#if (OUTPUT_FORMAT_COUNT > 2)
|
||||
/* Standard AS Interface Descriptor (4.9.1) (Alt) */
|
||||
.Audio_Out_StreamInterface_Alt3 =
|
||||
@@ -1831,7 +1828,7 @@ USB_Config_Descriptor_Audio2_t cfgDesc_Audio2=
|
||||
.bLockDelayUnits = 0x02,
|
||||
.wLockDelay = 0x0008,
|
||||
},
|
||||
#endif
|
||||
#endif /* (INPUT_FORMAT_COUNT > 1) */
|
||||
#if (INPUT_FORMAT_COUNT > 2)
|
||||
/* Alternative 3 */
|
||||
/* Standard AS Interface Descriptor (4.9.1) (Alt) */
|
||||
@@ -1904,7 +1901,7 @@ USB_Config_Descriptor_Audio2_t cfgDesc_Audio2=
|
||||
.bLockDelayUnits = 0x02,
|
||||
.wLockDelay = 0x0008,
|
||||
},
|
||||
#endif
|
||||
#endif /* (INPUT_FORMAT_COUNT > 2) */
|
||||
|
||||
#endif /* #if(NUM_USB_CHAN_IN > 0) */
|
||||
#ifdef MIDI
|
||||
@@ -2060,7 +2057,7 @@ USB_Config_Descriptor_Audio2_t cfgDesc_Audio2=
|
||||
0x10, /* 7 bcdDFUVersion */
|
||||
0x01}, /* 7 bcdDFUVersion */
|
||||
#endif
|
||||
#endif
|
||||
#endif /* (XUA_DFU_EN == 1) */
|
||||
|
||||
#ifdef IAP
|
||||
/* Interface descriptor */
|
||||
@@ -2169,7 +2166,7 @@ USB_Config_Descriptor_Audio2_t cfgDesc_Audio2=
|
||||
#endif
|
||||
#endif /* IAP */
|
||||
|
||||
#ifdef HID_CONTROLS
|
||||
#if( 0 < HID_CONTROLS )
|
||||
.HID_Interface =
|
||||
{
|
||||
9, /* 0 bLength : Size of descriptor in Bytes */
|
||||
@@ -2203,22 +2200,22 @@ USB_Config_Descriptor_Audio2_t cfgDesc_Audio2=
|
||||
ENDPOINT_ADDRESS_IN_HID, /* 2 bEndpointAddress */
|
||||
3, /* 3 bmAttributes (INTERRUPT) */
|
||||
64, /* 4 wMaxPacketSize */
|
||||
8, /* 6 bInterval */
|
||||
ENDPOINT_INT_INTERVAL_IN_HID, /* 6 bInterval */
|
||||
}
|
||||
#endif
|
||||
|
||||
};
|
||||
#endif
|
||||
#endif /* (AUDIO_CLASS == 2) */
|
||||
|
||||
#ifdef HID_CONTROLS
|
||||
#if( 0 < HID_CONTROLS )
|
||||
unsigned char hidDescriptor[] =
|
||||
{
|
||||
9, /* 0 bLength : Size of descriptor in Bytes */
|
||||
0x09, /* 0 bLength : Size of descriptor in Bytes */
|
||||
0x21, /* 1 bDescriptorType (HID) */
|
||||
0x10, /* 2 bcdHID */
|
||||
0x01, /* 3 bcdHID */
|
||||
0, /* 4 bCountryCode */
|
||||
1, /* 5 bNumDescriptors */
|
||||
0x00, /* 4 bCountryCode */
|
||||
0x01, /* 5 bNumDescriptors */
|
||||
0x22, /* 6 bDescriptorType[0] (Report) */
|
||||
sizeof(hidReportDescriptor) & 0xff, /* 7 wDescriptorLength[0] */
|
||||
sizeof(hidReportDescriptor) >> 8, /* 8 wDescriptorLength[0] */
|
||||
@@ -2325,18 +2322,13 @@ const unsigned num_freqs_a1 = MAX(3, (0
|
||||
#define DFU_INTERFACES_A1 0
|
||||
#endif
|
||||
|
||||
/* Total number of bytes returned for the class-specific AudioControl interface descriptor.
|
||||
* Includes the combined length of this descriptor header and all Unit and Terminal descriptors
|
||||
* For us this is IT -> FU -> OT * 2 and a header */
|
||||
#define AC_TOTAL_LENGTH (AC_LENGTH + \
|
||||
(INPUT_INTERFACES_A1 * (12 + ( (8 + NUM_USB_CHAN_IN_FS) * INPUT_VOLUME_CONTROL) + 9)) +\
|
||||
(OUTPUT_INTERFACES_A1 * (12 + ( (8 + NUM_USB_CHAN_OUT_FS) * OUTPUT_VOLUME_CONTROL) + 9)))
|
||||
|
||||
#define STREAMING_INTERFACES (INPUT_INTERFACES_A1 + OUTPUT_INTERFACES_A1)
|
||||
|
||||
//#if (NUM_USB_CHAN_IN == 0) || defined(UAC_FORCE_FEEDBACK_EP)
|
||||
//#define CFG_TOTAL_LENGTH_A1 (18 + AC_TOTAL_LENGTH + (INPUT_INTERFACES_A1 * (49 + num_freqs_a1 * 3)) + (OUTPUT_INTERFACES_A1 * (58 + num_freqs_a1 * 3)) + CONTROL_INTERFACE_BYTES + DFU_INTERFACE_BYTES)
|
||||
//#endif
|
||||
#if( 0 < HID_CONTROLS )
|
||||
#define HID_INTERFACE_BYTES ( 9 + 9 + 7 )
|
||||
#define HID_INTERFACES_A1 1
|
||||
#else
|
||||
#define HID_INTERFACE_BYTES 0
|
||||
#define HID_INTERFACES_A1 0
|
||||
#endif
|
||||
|
||||
/* Total number of bytes returned for the class-specific AudioControl interface descriptor.
|
||||
* Includes the combined length of this descriptor header and all Unit and Terminal descriptors
|
||||
@@ -2349,12 +2341,12 @@ const unsigned num_freqs_a1 = MAX(3, (0
|
||||
|
||||
/* Number of interfaces for Audio 1.0 (+1 for control ) */
|
||||
/* Note, this is different that INTERFACE_COUNT since we dont support items such as MIDI, iAP etc in UAC1 mode */
|
||||
#define NUM_INTERFACES_A1 (1+INPUT_INTERFACES_A1 + OUTPUT_INTERFACES_A1+NUM_CONTROL_USB_INTERFACES+DFU_INTERFACES_A1)
|
||||
#define NUM_INTERFACES_A1 (1 + INPUT_INTERFACES_A1 + OUTPUT_INTERFACES_A1 + NUM_CONTROL_USB_INTERFACES + DFU_INTERFACES_A1 + HID_INTERFACES_A1)
|
||||
|
||||
#if (NUM_USB_CHAN_IN == 0) || defined(UAC_FORCE_FEEDBACK_EP)
|
||||
#define CFG_TOTAL_LENGTH_A1 (18 + AC_TOTAL_LENGTH + (INPUT_INTERFACES_A1 * (49 + num_freqs_a1 * 3)) + (OUTPUT_INTERFACES_A1 * (58 + num_freqs_a1 * 3)) + CONTROL_INTERFACE_BYTES + DFU_INTERFACE_BYTES)
|
||||
#define CFG_TOTAL_LENGTH_A1 (18 + AC_TOTAL_LENGTH + (INPUT_INTERFACES_A1 * (49 + num_freqs_a1 * 3)) + (OUTPUT_INTERFACES_A1 * (58 + num_freqs_a1 * 3)) + CONTROL_INTERFACE_BYTES + DFU_INTERFACE_BYTES + HID_INTERFACE_BYTES)
|
||||
#else
|
||||
#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)
|
||||
#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 CHARIFY_SR(x) (x & 0xff),((x & 0xff00)>> 8),((x & 0xff0000)>> 16)
|
||||
@@ -2856,6 +2848,39 @@ unsigned char cfgDesc_Audio1[] =
|
||||
offsetof(StringDescTable_t, ctrlStr)/sizeof(char *), /* 8 iInterface */
|
||||
#endif
|
||||
|
||||
#if( 0 < HID_CONTROLS )
|
||||
/* HID interface descriptor */
|
||||
0x09, /* 0 bLength : Size of descriptor in Bytes */
|
||||
0x04, /* 1 bDescriptorType (Interface: 0x04)*/
|
||||
INTERFACE_NUMBER_HID, /* 2 bInterfaceNumber : Number of interface */
|
||||
0x00, /* 3 bAlternateSetting : Value used alternate interfaces using SetInterface Request */
|
||||
0x01, /* 4: bNumEndpoints : Number of endpoitns for this interface (excluding 0) */
|
||||
0x03, /* 5: bInterfaceClass */
|
||||
0x00, /* 6: bInterfaceSubClass - no boot device */
|
||||
0x00, /* 7: bInterfaceProtocol*/
|
||||
0x00, /* 8 iInterface */
|
||||
|
||||
/* HID descriptor */
|
||||
0x09, /* 0 bLength : Size of descriptor in Bytes */
|
||||
0x21, /* 1 bDescriptorType (HID) */
|
||||
0x10, /* 2 bcdHID */
|
||||
0x01, /* 3 bcdHID */
|
||||
0x00, /* 4 bCountryCode */
|
||||
0x01, /* 5 bNumDescriptors */
|
||||
0x22, /* 6 bDescriptorType[0] (Report) */
|
||||
0x1E, /* 7 wDescriptorLength[0] */
|
||||
0x00, /* 8 wDescriptorLength[0] */
|
||||
|
||||
/* HID Endpoint descriptor (IN) */
|
||||
0x07, /* 0 bLength */
|
||||
0x05, /* 1 bDescriptorType */
|
||||
ENDPOINT_ADDRESS_IN_HID, /* 2 bEndpointAddress */
|
||||
0x03, /* 3 bmAttributes (INTERRUPT) */
|
||||
0x40, /* 4 wMaxPacketSize */
|
||||
0x00, /* 5 wMaxPacketSize */
|
||||
ENDPOINT_INT_INTERVAL_IN_HID, /* 6 bInterval */
|
||||
#endif
|
||||
|
||||
};
|
||||
#endif
|
||||
#endif
|
||||
|
||||
@@ -5,13 +5,13 @@
|
||||
|
||||
#include <xccompat.h>
|
||||
|
||||
int AudioClassRequests_2(XUD_ep ep0_out, XUD_ep ep0_in, REFERENCE_PARAM(USB_SetupPacket_t, sp), chanend c_audioControl,
|
||||
int AudioClassRequests_2(XUD_ep ep0_out, XUD_ep ep0_in, REFERENCE_PARAM(USB_SetupPacket_t, sp), NULLABLE_RESOURCE(chanend, c_audioControl),
|
||||
NULLABLE_RESOURCE(chanend, c_mix_ctl), NULLABLE_RESOURCE(chanend, c_clk_ctl));
|
||||
|
||||
XUD_Result_t AudioClassRequests_1(XUD_ep ep0_out, XUD_ep ep0_in, REFERENCE_PARAM(USB_SetupPacket_t, sp), chanend c_audioControl,
|
||||
XUD_Result_t AudioClassRequests_1(XUD_ep ep0_out, XUD_ep ep0_in, REFERENCE_PARAM(USB_SetupPacket_t, sp), NULLABLE_RESOURCE(chanend, c_audioControl),
|
||||
NULLABLE_RESOURCE(chanend, c_mix_ctl), NULLABLE_RESOURCE(chanend, c_clk_ctl));
|
||||
|
||||
int AudioEndpointRequests_1(XUD_ep ep0_out, XUD_ep ep0_in, REFERENCE_PARAM(USB_SetupPacket_t, sp), chanend c_audioControl,
|
||||
int AudioEndpointRequests_1(XUD_ep ep0_out, XUD_ep ep0_in, REFERENCE_PARAM(USB_SetupPacket_t, sp), NULLABLE_RESOURCE(chanend, c_audioControl),
|
||||
NULLABLE_RESOURCE(chanend, c_mix_ctl), NULLABLE_RESOURCE(chanend, c_clk_ctl));
|
||||
|
||||
|
||||
|
||||
@@ -273,7 +273,7 @@ static void updateVol(int unitID, int channel, chanend ?c_mix_ctl)
|
||||
* XUD_RES_RST for device reset
|
||||
* else XUD_RES_ERR
|
||||
*/
|
||||
int AudioClassRequests_2(XUD_ep ep0_out, XUD_ep ep0_in, USB_SetupPacket_t &sp, chanend c_audioControl, chanend ?c_mix_ctl, chanend ?c_clk_ctl
|
||||
int AudioClassRequests_2(XUD_ep ep0_out, XUD_ep ep0_in, USB_SetupPacket_t &sp, chanend ?c_audioControl, chanend ?c_mix_ctl, chanend ?c_clk_ctl
|
||||
)
|
||||
{
|
||||
unsigned int buffer[32];
|
||||
@@ -1071,7 +1071,7 @@ int AudioClassRequests_2(XUD_ep ep0_out, XUD_ep ep0_in, USB_SetupPacket_t &sp, c
|
||||
|
||||
#if (AUDIO_CLASS_FALLBACK != 0) || (AUDIO_CLASS == 1)
|
||||
|
||||
int AudioEndpointRequests_1(XUD_ep ep0_out, XUD_ep ep0_in, USB_SetupPacket_t &sp, chanend c_audioControl, chanend ?c_mix_ctl, chanend ?c_clk_ctl)
|
||||
int AudioEndpointRequests_1(XUD_ep ep0_out, XUD_ep ep0_in, USB_SetupPacket_t &sp, chanend ?c_audioControl, chanend ?c_mix_ctl, chanend ?c_clk_ctl)
|
||||
{
|
||||
/* At this point we know:
|
||||
* bmRequestType.Recipient = Endpoint
|
||||
@@ -1159,7 +1159,7 @@ int AudioEndpointRequests_1(XUD_ep ep0_out, XUD_ep ep0_in, USB_SetupPacket_t &sp
|
||||
|
||||
|
||||
/* Handles the Audio Class 1.0 specific requests */
|
||||
XUD_Result_t AudioClassRequests_1(XUD_ep ep0_out, XUD_ep ep0_in, USB_SetupPacket_t &sp, chanend c_audioControl, chanend ?c_mix_ctl, chanend ?c_clk_ctl
|
||||
XUD_Result_t AudioClassRequests_1(XUD_ep ep0_out, XUD_ep ep0_in, USB_SetupPacket_t &sp, chanend ?c_audioControl, chanend ?c_mix_ctl, chanend ?c_clk_ctl
|
||||
)
|
||||
{
|
||||
#if (OUTPUT_VOLUME_CONTROL == 1) || (INPUT_VOLUME_CONTROL == 1)
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright (c) 2012-2018, XMOS Ltd, All rights reserved
|
||||
// Copyright (c) 2012-2019, XMOS Ltd, All rights reserved
|
||||
|
||||
#include "xua.h" /* Device specific defines */
|
||||
#ifndef EXCLUDE_USB_AUDIO_MAIN
|
||||
@@ -259,7 +259,7 @@ XUD_EpType epTypeTableIn[ENDPOINT_COUNT_IN] = { XUD_EPTYPE_CTL | XUD_STATUS_ENAB
|
||||
#ifdef MIDI
|
||||
XUD_EPTYPE_BUL,
|
||||
#endif
|
||||
#ifdef HID_CONTROLS
|
||||
#if( 0 < HID_CONTROLS )
|
||||
XUD_EPTYPE_INT,
|
||||
#endif
|
||||
#ifdef IAP
|
||||
@@ -400,7 +400,7 @@ VENDOR_REQUESTS_PARAMS_DEC_
|
||||
c_clk_int,
|
||||
#endif
|
||||
c_sof, c_aud_ctl, p_for_mclk_count
|
||||
#ifdef HID_CONTROLS
|
||||
#if( 0 < HID_CONTROLS )
|
||||
, c_xud_in[ENDPOINT_NUMBER_IN_HID]
|
||||
#endif
|
||||
#ifdef CHAN_BUFF_CTRL
|
||||
|
||||
19
lib_xua/src/core/user/hid/user_hid.h
Normal file
19
lib_xua/src/core/user/hid/user_hid.h
Normal file
@@ -0,0 +1,19 @@
|
||||
// Copyright (c) 2013-2019, XMOS Ltd, All rights reserved
|
||||
|
||||
/* 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
|
||||
|
||||
#define HID_DATA_SIZE 1
|
||||
|
||||
#if( 0 < HID_CONTROLS )
|
||||
|
||||
void UserInitHIDData( void );
|
||||
void UserReadHIDData( unsigned char hidData[ HID_DATA_SIZE ]);
|
||||
void UserSetHIDData( const unsigned hidData );
|
||||
|
||||
#endif /* ( 0 < HID_CONTROLS ) */
|
||||
@@ -1,13 +0,0 @@
|
||||
// Copyright (c) 2013-2018, XMOS Ltd, All rights reserved
|
||||
|
||||
|
||||
/* 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
|
||||
|
||||
void UserReadHIDButtons(unsigned char hidData[]);
|
||||
|
||||
222
lib_xua/src/hid/hid.xc
Normal file
222
lib_xua/src/hid/hid.xc
Normal file
@@ -0,0 +1,222 @@
|
||||
// Copyright (c) 2019, XMOS Ltd, All rights reserved
|
||||
#include <xs1.h>
|
||||
#include "descriptor_defs.h"
|
||||
#include "hid.h"
|
||||
#include "xud.h"
|
||||
#include "xud_std_requests.h"
|
||||
#include "xua_hid.h"
|
||||
|
||||
#if( 0 < HID_CONTROLS )
|
||||
#define MS_IN_TICKS 100000U
|
||||
|
||||
static unsigned s_hidIdleActive = 0U;
|
||||
static unsigned s_hidCurrentPeriod = ENDPOINT_INT_INTERVAL_IN_HID * MS_IN_TICKS;
|
||||
static unsigned s_hidIndefiniteDuration = 0U;
|
||||
static unsigned s_hidNextReportTime = 0U;
|
||||
static unsigned s_hidReportTime = 0U;
|
||||
|
||||
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,
|
||||
USB_SetupPacket_t &sp )
|
||||
{
|
||||
XUD_Result_t result = XUD_RES_ERR;
|
||||
|
||||
switch ( sp.bRequest ) {
|
||||
case HID_SET_IDLE:
|
||||
result = HidProcessSetIdleRequest( c_ep0_out, c_ep0_in, sp );
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
unsigned HidIsSetIdleSilenced( void )
|
||||
{
|
||||
unsigned isSilenced = s_hidIdleActive;
|
||||
|
||||
if( s_hidIdleActive ) {
|
||||
unsigned currentTime;
|
||||
asm volatile( "gettime %0" : "=r" ( currentTime )); // Use inline assembly to access the time without creating a side-effect
|
||||
isSilenced = ( s_hidIndefiniteDuration || ( timeafter( s_hidNextReportTime, currentTime )));
|
||||
}
|
||||
|
||||
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
|
||||
* established or the polling interval from the HID Report Descriptor if a Set Idle duration
|
||||
* has not been established.
|
||||
*
|
||||
* \param[in] currentPeriod -- The duration of the current period in timer ticks
|
||||
* \param[in] reportTime -- The time at which the last HID Report was sent
|
||||
* \param[in] reportToSetIdleInterval -- The time interval between receiving the Set Idle Request
|
||||
* and sending the most recent HID Report
|
||||
* \param[in] newPeriod -- The new period value in timer ticks
|
||||
*
|
||||
* \return The time at which the next HID Report should be sent
|
||||
*/
|
||||
static unsigned HidCalcNewReportTime( const unsigned currentPeriod, const unsigned reportTime, const unsigned reportToSetIdleInterval, const unsigned newPeriod )
|
||||
{
|
||||
unsigned nextReportTime = 0;
|
||||
|
||||
if( HidFindSetIdleActivationPoint( currentPeriod, reportToSetIdleInterval )) {
|
||||
/* Activate immediately after sending the next HID Report */
|
||||
nextReportTime = reportTime + currentPeriod;
|
||||
} else {
|
||||
/* Activate immediately after sending the most recent HID Report */
|
||||
nextReportTime = reportTime + newPeriod;
|
||||
}
|
||||
|
||||
return nextReportTime;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Calculate the time interval between the most recent HID Report and a subsequent Set Idle Request
|
||||
*
|
||||
* \warning For this function to produce an accurate interval measument, it must be called without delay
|
||||
* upon receiving a Set Idle Request from the USB Host.
|
||||
*
|
||||
* \param[in] reportTime -- The time at which the last HID Report was sent
|
||||
*
|
||||
* \return The time interval between receiving the Set Idle Request and sending the most recent HID Report
|
||||
*/
|
||||
static unsigned HidCalcReportToSetIdleInterval( const unsigned reportTime )
|
||||
{
|
||||
timer tmr;
|
||||
unsigned setIdleTime;
|
||||
|
||||
tmr :> setIdleTime;
|
||||
unsigned result = HidTimeDiff( reportTime, setIdleTime );
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Indicate if activation of the Set Idle Request happens at the previous or next HID Report
|
||||
*
|
||||
* Section 7.2.4 Set_Idle Request of the USB Device Class Definition for Human Interface
|
||||
* Devices (HID) Version 1.11 makes two statements about the activation point for starting the
|
||||
* duration of the request:
|
||||
* - 'A new request will be executed as if it were issued immediately after the last report, if
|
||||
* the new request is received at least 4 milliseconds before the end of the currently executing
|
||||
* period.'
|
||||
* - 'If the new request is received within 4 milliseconds of the end of the current period, then
|
||||
* the new request will have no effect until after the report.'
|
||||
*
|
||||
* \param[in] currentPeriod -- The duration of the current period
|
||||
* \param[in] timeWithinPeriod -- The current point in time relative to the current period
|
||||
*
|
||||
* \return A Boolean indicating where the activation of the Set Idle Request Duration occurs.
|
||||
* \retval 1 -- Activate immediately after the next HID Report
|
||||
* \retval 0 -- Activate immediately after the previous HID Report
|
||||
*/
|
||||
static unsigned HidFindSetIdleActivationPoint( const unsigned currentPeriod, const unsigned timeWithinPeriod )
|
||||
{
|
||||
unsigned result = (( currentPeriod - timeWithinPeriod ) < ( 4U * MS_IN_TICKS )) ? 1 : 0;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Process a Set Idle request
|
||||
*
|
||||
* \param[in] c_ep0_out -- the channel that carries data from Endpoint 0
|
||||
* \param[in] c_ep0_in -- the channel that carries data for Endpoint 0
|
||||
* \param[in] sp -- a structure containing the Set Idle data
|
||||
*
|
||||
* \return An XUD status value
|
||||
*/
|
||||
static XUD_Result_t HidProcessSetIdleRequest( XUD_ep c_ep0_out, XUD_ep c_ep0_in, USB_SetupPacket_t &sp )
|
||||
{
|
||||
XUD_Result_t result = XUD_RES_ERR;
|
||||
|
||||
/*
|
||||
The Set Idle request wValue field contains two sub-fields:
|
||||
- Duration in the MSB; and
|
||||
- Report ID in the LSB.
|
||||
|
||||
The Duration field specifies how long the USB Device responds with NAK provided the HID data hasn't changed.
|
||||
Zero means indefinitely.
|
||||
The value is in units of 4ms.
|
||||
|
||||
The Report ID identifies the HID report that the USB Host wishes to silence.
|
||||
|
||||
The Set Idle request xIndex field contains the interface number.
|
||||
*/
|
||||
uint16_t duration = ( sp.wValue & 0xFF00 ) >> 6; // Transform from units of 4ms into units of 1ms.
|
||||
uint8_t reportId = sp.wValue & 0x00FF;
|
||||
uint16_t interfaceNum = sp.wIndex;
|
||||
|
||||
/*
|
||||
As long as our HID Report Descriptor does not include a Report ID, any Report ID value other than zero
|
||||
indicates an error by the USB Host (see xua_ep0_descriptors.h for the definition of the HID
|
||||
Report Descriptor).
|
||||
|
||||
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( 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 );
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Calculate the difference between two points in time
|
||||
*
|
||||
* This function calculates the difference between two two points in time.
|
||||
* It always returns a positive value even if the timer used to obtain the two
|
||||
* time measurements has wrapped around.
|
||||
*
|
||||
* \warning If time values have been obtained from a timer that has wrapped
|
||||
* more than once in between the two measurements, this function returns an
|
||||
* incorrect value.
|
||||
*
|
||||
* \param[in] earlierTime -- A value from a timer
|
||||
* \param[in] laterTime -- A value from a timer taken after \a earlierTime
|
||||
*
|
||||
* \return The interval between the two points in time
|
||||
*/
|
||||
static unsigned HidTimeDiff( const unsigned earlierTime, const unsigned laterTime )
|
||||
{
|
||||
return ( earlierTime < laterTime ) ? laterTime - earlierTime : UINT_MAX - earlierTime + laterTime;
|
||||
}
|
||||
|
||||
#endif /* ( 0 < HID_CONTROLS ) */
|
||||
55
lib_xua/src/hid/xua_hid.h
Normal file
55
lib_xua/src/hid/xua_hid.h
Normal file
@@ -0,0 +1,55 @@
|
||||
// Copyright (c) 2019, XMOS Ltd, All rights reserved
|
||||
#include <xs1.h>
|
||||
#include <xccompat.h>
|
||||
#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 Indicate whether to send a HID Report based on elapsed time.
|
||||
*
|
||||
* 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 monitors the passage of time and reports to the caller
|
||||
* whether or not the time to send the next periodic HID Report has
|
||||
* elapsed.
|
||||
*
|
||||
* \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 );
|
||||
Reference in New Issue
Block a user