Added hid controls

This commit is contained in:
Ross Owen
2012-04-10 15:18:13 +01:00
parent ac0fa94bc7
commit b900002f84
8 changed files with 239 additions and 36 deletions

View File

@@ -38,6 +38,10 @@
#undef IAP
#endif
#if defined(HID_CONTROLS) && (HID_CONTROLS == 0)
#undef HID_CONTROLS
#endif
#if defined(MIDI) && (MIDI == 0)
#undef MIDI
#endif
@@ -181,11 +185,17 @@
#define OUTPUT_INTERFACES (0)
#endif
#define NUM_EP_OUT_AUD (OUTPUT_INTERFACES)
#define NUM_EP_IN_AUD (OUTPUT_INTERFACES + INPUT_INTERFACES)
#if defined(MIDI)
#define MIDI_INTERFACES (2)
#define NUM_EP_OUT_MIDI (1)
#define NUM_EP_IN_MIDI (1)
#else
#define MIDI_INTERFACES (0)
#define NUM_EP_OUT_MIDI (0)
#define NUM_EP_IN_MIDI (0)
#endif
#if defined(IAP)
@@ -194,6 +204,56 @@
#define IAP_INTERFACES (0)
#endif
#if defined(HID_CONTROLS)
#define HID_INTERFACES (1)
#else
#define HID_INTERFACES (0)
#endif
#define NUM_EP_OUT_IAP (IAP_INTERFACES)
#define NUM_EP_IN_IAP (IAP_INTERFACES * 2)
#define NUM_EP_OUT_HID (0)
#define NUM_EP_IN_HID (HID_INTERFACES)
/* Define for number of audio interfaces (+1 for mandatory control interface) */
#define AUDIO_INTERFACES (INPUT_INTERFACES + OUTPUT_INTERFACES + 1)
/* Interface number defines */
#define INTERFACE_NUM_IAP (INPUT_INTERFACES+OUTPUT_INTERFACES+MIDI_INTERFACES+DFU_INTERFACES+1)
#define INTERFACE_NUM_HID (INPUT_INTERFACES+OUTPUT_INTERFACES+MIDI_INTERFACES+DFU_INTERFACES+IAP_INTERFACES+1)
/* Endpoint Number Defines */
#define EP_NUM_IN_FB (1) /* Always 1 */
#define EP_NUM_IN_AUD (2) /* Always 2 */
#define EP_NUM_IN_AUD_INT (3) /* Audio interrupt/status EP */
#define EP_NUM_IN_MIDI ((EP_NUM_IN_AUD_INT + 1))
#define EP_NUM_IN_HID ((EP_NUM_IN_AUD_INT + NUM_EP_IN_MIDI + 1))
#define EP_NUM_IN_IAP ((EP_NUM_IN_AUD_INT + NUM_EP_IN_MIDI + NUM_EP_IN_HID + 1)) /* iAP Bulk */
#define EP_NUM_IN_IAP_INT ((EP_NUM_IN_AUD_INT + NUM_EP_IN_MIDI + NUM_EP_IN_HID + 2)) /* iAP interrupt */
#define EP_NUM_OUT_AUD 1 /* Always 1 */
#define EP_NUM_OUT_MIDI 2 /* Always 2 */
#define EP_NUM_OUT_IAP 3 /* Always 3 */
/* Endpoint Address Defines */
#define EP_ADR_IN_FB (EP_NUM_IN_FB | 0x80)
#define EP_ADR_IN_AUD (EP_NUM_IN_AUD | 0x80)
#define EP_ADR_IN_AUD_INT (EP_NUM_IN_AUD_INT | 0x80)
#define EP_ADR_IN_MIDI (EP_NUM_IN_MIDI | 0x80)
#define EP_ADR_IN_HID (EP_NUM_IN_HID | 0x80)
#define EP_ADR_IN_IAP (EP_NUM_IN_IAP | 0x80)
#define EP_ADR_IN_IAP_INT (EP_NUM_IAP_INT | 0x80)
#define EP_ADR_OUT_AUD EP_NUM_OUT_AUD
#define EP_ADR_OUT_MIDI EP_NUM_OUT_MIDI
#define EP_ADR_OUT_IAP EP_NUM_OUT_IAP
/* Endpoint count totals */
#define NUM_EP_OUT (1 + NUM_EP_OUT_AUD + NUM_EP_OUT_MIDI + NUM_EP_OUT_IAP) /* +1 due to EP0 */
#define NUM_EP_IN (2 + NUM_EP_IN_AUD + NUM_EP_IN_MIDI + NUM_EP_IN_IAP + NUM_EP_IN_HID) /* +1 due to EP0 and Int EP */
#define AUDIO_STOP_FOR_DFU (0x12345678)
#define AUDIO_START_FROM_DFU (0x87654321)
#define AUDIO_REBOOT_FROM_DFU (0xa5a5a5a5)
@@ -201,8 +261,8 @@
#define MAX_VOL (0x20000000)
#define NUM_EP_OUT 4 /* Max number of device endpoints used */
#define NUM_EP_IN 7
/* Length of clock unit/clock-selector units */
#if defined(SPDIF_RX) && defined(ADAT_RX)
#define NUM_CLOCKS 3
@@ -214,7 +274,7 @@
/* Total number of USB interfaces this device implements (+1 for required control interface) */
#define NUM_INTERFACES INPUT_INTERFACES + OUTPUT_INTERFACES + DFU_INTERFACES + MIDI_INTERFACES + IAP_INTERFACES + 1
#define NUM_INTERFACES INPUT_INTERFACES + OUTPUT_INTERFACES + DFU_INTERFACES + MIDI_INTERFACES + IAP_INTERFACES + 1 + HID_INTERFACES
/* Audio Unit ID defines */
#define FU_USBIN 11 /* Feature Unit: USB Audio device -> host */
#define FU_USBOUT 10 /* Feature Unit: USB Audio host -> device*/

View File

@@ -5,6 +5,8 @@
* @version 1.4
*/
#ifndef _DEVICE_DESCRIPTORS_2_
#define _DEVICE_DESCRIPTORS_2_
@@ -260,11 +262,32 @@ unsigned char devQualDesc_Null[] =
#define IAP_INTERFACE_STRING_INDEX (MIXER_STRING_INDEX)
#endif
/* Total length of config descriptor */
#define CFG_TOTAL_LENGTH_A2 (7 + 26 + (INPUT_INTERFACES * 55) + (OUTPUT_INTERFACES * 62) + (MIDI_LENGTH) + (DFU_INTERFACES * 18) + TLEN_AC + (MIXER_LENGTH) + IAP_LENGTH + INPUT_ALT_LENGTH + OUTPUT_ALT_LENGTH)
#ifdef HID_CONTROLS
unsigned char hidReportDescriptor[] = {
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/Pause) */
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 */
};
#endif
/* Define for number of audio interfaces (+1 for mandatory control interface) */
#define AUDIO_INTERFACES (INPUT_INTERFACES + OUTPUT_INTERFACES + 1)
#define HID_LENGTH (25*HID_INTERFACES)
/* Total length of config descriptor */
#define CFG_TOTAL_LENGTH_A2 (7 + 26 + (INPUT_INTERFACES * 55) + (OUTPUT_INTERFACES * 62) + (MIDI_LENGTH) + (DFU_INTERFACES * 18) + TLEN_AC + (MIXER_LENGTH) + IAP_LENGTH + INPUT_ALT_LENGTH + OUTPUT_ALT_LENGTH + HID_LENGTH)
/* Configuration Descriptor for Audio 2.0 (HS) operation */
unsigned char cfgDesc_Audio2[] =
@@ -738,7 +761,7 @@ unsigned char cfgDesc_Audio2[] =
/* Standard AS Interrupt Endpoint Descriptor (4.8.2.1): */
0x07, /* 0 bLength: 7 */
0x05, /* 1 bDescriptorType: ENDPOINT */
0x84, /* 2 bEndpointAddress (D7: 0:out, 1:in) */
EP_ADR_IN_AUD_INT, /* 2 bEndpointAddress (D7: 0:out, 1:in) */
3, /* 3 bmAttributes (bitmap) */
6,0, /* 4 wMaxPacketSize */
8, /* 6 bInterval */
@@ -1120,7 +1143,7 @@ unsigned char cfgDesc_Audio2[] =
/* Table B-11: MIDI Adapter Standard Bulk OUT Endpoint Descriptor */
0x09, /* 0 bLength : Size of this descriptor, in bytes. (field size 1 bytes) */
0x05, /* 1 bDescriptorType : ENDPOINT descriptor. (field size 1 bytes) */
0x02, /* 2 bEndpointAddress : OUT Endpoint 3. (field size 1 bytes) */
EP_ADR_OUT_MIDI, /* 2 bEndpointAddress : OUT Endpoint 3. (field size 1 bytes) */
0x02, /* 3 bmAttributes : Bulk, not shared. (field size 1 bytes) */
0x00, /* 4 wMaxPacketSize : 64 bytes per packet. (field size 2 bytes) - has to be 0x200 for compliance*/
0x02, /* 5 wMaxPacketSize */
@@ -1138,7 +1161,7 @@ unsigned char cfgDesc_Audio2[] =
/* Table B-13: MIDI Adapter Standard Bulk IN Endpoint Descriptor */
0x09, /* 0 bLength : Size of this descriptor, in bytes. (field size 1 bytes) */
0x05, /* 1 bDescriptorType : ENDPOINT descriptor. (field size 1 bytes) */
0x83, /* 2 bEndpointAddress : IN Endpoint 3. (field size 1 bytes) */
EP_ADR_IN_MIDI, /* 2 bEndpointAddress : IN Endpoint 3. (field size 1 bytes) */
0x02, /* 3 bmAttributes : Bulk, not shared. (field size 1 bytes) */
0x00, /* 4 wMaxPacketSize : 64 bytes per packet. (field size 2 bytes) - has to be 0x200 for compliance*/
0x02, /* 5 wMaxPacketSize */
@@ -1229,10 +1252,56 @@ unsigned char cfgDesc_Audio2[] =
0x40, /* 4 wMaxPacketSize : 64 bytes per packet. (field size 2 bytes) - has to be 0x40 for compliance*/
0x00, /* 5 wMaxPacketSize */
0x08, /* 6 bInterval : (2^(bInterval-1))/8 ms. Must be between 4 and 32ms (field size 1 bytes) */
#endif
#ifdef HID_CONTROLS
/* HID */
/* Interface descriptor details */
9, /* 0 bLength : Size of descriptor in Bytes */
4, /* 1 bDescriptorType (Interface: 0x04)*/
INTERFACE_NUM_HID, /* 2 bInterfacecNumber : Number of interface */
0, /* 3 bAlternateSetting : Value used alternate interfaces using SetInterface Request */
1, /* 4: bNumEndpoints : Number of endpoitns for this interface (excluding 0) */
3, /* 5: bInterfaceClass */
0, /* 6: bInterfaceSubClass - no boot device */
0, /* 7: bInterfaceProtocol*/
0, /* 8 iInterface */
/* The device implements HID Descriptor: */
9, /* 0 bLength : Size of descriptor in Bytes */
0x21, /* 1 bDescriptorType (HID) */
0x10, /* 2 bcdHID */
0x01, /* 3 bcdHID */
0, /* 4 bCountryCode */
1, /* 5 bNumDescriptors */
0x22, /* 6 bDescriptorType[0] (Report) */
sizeof(hidReportDescriptor) & 0xff, /* 7 wDescriptorLength[0] */
sizeof(hidReportDescriptor) >> 8, /* 8 wDescriptorLength[0] */
/* Endpoint descriptor (IN) */
0x7, /* 0 bLength */
5, /* 1 bDescriptorType */
EP_ADR_IN_HID, /* 2 bEndpointAddress */
3, /* 3 bmAttributes (INTERRUPT) */
64, /* 4 wMaxPacketSize */
0, /* 5 wMaxPacketSize */
8, /* 6 bInterval */
#endif
};
#define APPEND_VENDOR_STR(x) VENDOR_STR#x
/* String table */

View File

@@ -20,6 +20,9 @@
#include "vendorrequests.h"
#include "dfu_types.h"
#include "xc_ptr.h"
#ifdef HID_CONTROLS
#include "hid.h"
#endif
/* Windows does not have a built in DFU driver (windows will prompt), so warn that DFU will not be functional in Audio 1.0 mode.Udi
* Of course, OSX is unaffected.
@@ -524,14 +527,30 @@ void Endpoint0( chanend c_ep0_out, chanend c_ep0_in, chanend c_audioControl,
retVal = XUD_DoGetRequest(ep0_out, ep0_in, buffer, 1, sp.wLength);
break;
#ifdef HID_CONTROLS
case GET_DESCRIPTOR:
if(sp.wIndex == INTERFACE_NUM_HID)
{
switch (sp.wValue>>8)
{
case REPORT:
/* Return HID report descriptor */
retVal = XUD_DoGetRequest(ep0_out, ep0_in, hidReportDescriptor,
min(sizeof(hidReportDescriptor),sp.wLength), sp.wLength);
break;
}
}
break;
#endif
default:
printstr("Unknown Standard Interface Request: ");
printhexln(sp.bRequest);
printhexln(sp.bmRequestType.Type);
printhexln(sp.bmRequestType.Recipient);
printhexln(sp.bmRequestType.Recipient | (sp.bmRequestType.Type << 5));
//printstr("Unknown Standard Interface Request: ");
//printhexln(sp.bRequest);
//printhexln(sp.bmRequestType.Type);
//printhexln(sp.bmRequestType.Recipient);
//printhexln(sp.bmRequestType.Recipient | (sp.bmRequestType.Type << 5));
break;
}
break;

View File

@@ -3,7 +3,7 @@
#include <xccompat.h>
int iic_initialise(timer t, port p_scl, port p_sda);
//int iic_initialise(timer t, port p_scl, port p_sda);
// Write to IIC device
#if defined __XC__

View File

@@ -32,6 +32,9 @@
#include "clockcmds.h"
#include "xud.h"
#include "usb.h"
#ifdef HID_CONTROLS
#include "vendor_hid.h"
#endif
/* This function changes the buffer staged for an IN transaction.
* **It can only be used if you know that the IN transaction will not occur**
@@ -200,6 +203,13 @@ unsigned int g_iap_to_host_buffer_A[MAX_IAP_PACKET_SIZE/4+4];
unsigned int g_iap_to_host_buffer_B[MAX_IAP_PACKET_SIZE/4+4];
int g_iap_from_host_buffer[MAX_IAP_PACKET_SIZE/4+4];
unsigned g_zero_buffer[1];
#endif
#ifdef HID_CONTROLS
extern in port p_but;
unsigned char g_hidData[16] = {0};
unsigned char g_hidFlag = 0;
unsigned g_ep_hid = 0;
#endif
// shared global aud buffering variables
@@ -821,16 +831,32 @@ void decouple(chanend c_mix_out,
while(1)
{
int tmp;
if (!isnull(c_clk_int))
{
check_for_interrupt(c_clk_int);
check_for_interrupt(c_clk_int);
}
asm("#decouple-default");
/* Check for freq change or other update */
{
int tmp;
p_but :> tmp;
tmp = ~tmp;
tmp &=3;
g_hidData[0] = tmp;
#ifdef HID_CONTROLS
Vendor_ReadHIDButtons(g_hidData);
asm("ldaw %0, dp[g_hidData]":"=r"(tmp));
if(g_hidFlag==0)
{
XUD_SetReady_In(g_ep_hid, 0, tmp, 1);
g_hidFlag = 1;
}
#endif
asm("#decouple-default");
/* Check for freq change or other update */
GET_SHARED_GLOBAL(tmp, g_freqChange_flag);
if (tmp == SET_SAMPLE_FREQ)
{

View File

@@ -16,9 +16,11 @@
* \param c_aud_ctl Audio control channel connected to Endpoint0()
* \param p_off_mclk A port that is clocked of the MCLK input (not the MCLK input itself)
*/
void buffer(chanend c_aud_out, chanend c_aud_in, chanend c_aud_fb,
void buffer(chanend c_aud_out, chanend c_aud_in, chanend c_aud_fb,
#ifdef MIDI
chanend c_midi_from_host,
chanend c_midi_to_host,
#endif
#ifdef IAP
chanend c_iap_from_host,
chanend c_iap_to_host,
@@ -27,7 +29,9 @@ void buffer(chanend c_aud_out, chanend c_aud_in, chanend c_aud_fb,
chanend? c_int,
chanend c_sof,
chanend c_aud_ctl,
in port p_off_mclk);
in port p_off_mclk
#ifdef HID_CONTROLS
,chanend c_hid
#endif
);
#endif

View File

@@ -19,12 +19,10 @@
#include "xud.h"
#include "testct_byref.h"
//typedef unsigned int XUD_ep;
//int XUD_GetData_NoReq(chanend c, xc_ptr buffer);
//int XUD_SetData_NoReq(chanend c, xc_ptr buffer, unsigned datalength, unsigned startIndex);
XUD_ep XUD_Init_Ep(chanend c_ep);
inline void XUD_SetNotReady(XUD_ep e)
{
int chan_array_ptr;
@@ -73,9 +71,11 @@ extern unsigned g_numUsbChanIn;
* @param c_aud_fb chanend for feeback to xud
* @return void
*/
void buffer(register chanend c_aud_out, register chanend c_aud_in, chanend c_aud_fb,
void buffer(register chanend c_aud_out, register chanend c_aud_in, chanend c_aud_fb,
#ifdef MIDI
chanend c_midi_from_host,
chanend c_midi_to_host,
#endif
#ifdef IAP
chanend c_iap_from_host,
chanend c_iap_to_host,
@@ -84,6 +84,9 @@ void buffer(register chanend c_aud_out, register chanend c_aud_in, chanend c_aud
chanend ?c_int, chanend c_sof,
chanend c_aud_ctl,
in port p_off_mclk
#ifdef HID_CONTROLS
,chanend c_hid
#endif
)
{
XUD_ep ep_aud_out = XUD_Init_Ep(c_aud_out);
@@ -101,6 +104,10 @@ void buffer(register chanend c_aud_out, register chanend c_aud_in, chanend c_aud
#if defined(SPDIF_RX) || defined(ADAT_RX)
XUD_ep ep_int = XUD_Init_Ep(c_int);
#endif
#ifdef HID_CONTROLS
XUD_ep ep_hid = XUD_Init_Ep(c_hid);
#endif
unsigned datalength;
unsigned tmp;
@@ -149,6 +156,7 @@ void buffer(register chanend c_aud_out, register chanend c_aud_in, chanend c_aud
#endif
asm("stw %0, dp[aud_from_host_usb_ep]"::"r"(ep_aud_out));
asm("stw %0, dp[aud_to_host_usb_ep]"::"r"(ep_aud_in));
asm("stw %0, dp[g_ep_hid]"::"r"(ep_hid));
asm("stw %0, dp[buffer_aud_ctl_chan]"::"r"(c_aud_ctl));
/* Wait for USB connect then setup our first packet */
@@ -215,7 +223,6 @@ void buffer(register chanend c_aud_out, register chanend c_aud_in, chanend c_aud
(fb_clocks, unsigned[])[0] = 0;
{
int usb_speed;
int x;
@@ -661,6 +668,20 @@ void buffer(register chanend c_aud_out, register chanend c_aud_in, chanend c_aud
}
break;
#endif
#ifdef HID_CONTROLS
/* HID Report Data */
case inuint_byref(c_hid, tmp):
{
XUD_SetData_Inline(ep_hid, c_hid);
asm("stw %0, dp[g_hidFlag]" :: "r" (0) );
XUD_SetNotReady(ep_hid);
}
break;
#endif
}
}

View File

@@ -21,6 +21,10 @@ static unsigned makeSymbol(unsigned data)
#define RATE 31250
#ifndef MIDI_SHIFT_TX
#define MIDI_SHIFT_TX 0
#endif
static unsigned bit_time = XS1_TIMER_MHZ * 1000000 / (unsigned) RATE;
static unsigned bit_time_2 = (XS1_TIMER_MHZ * 1000000 / (unsigned) RATE) / 2;
@@ -133,7 +137,7 @@ void usb_midi(port ?p_midi_in, port ?p_midi_out,
#ifdef IAP
CoProcessorDisable();
#endif
p_midi_out <: 1; // Start with high bit.
p_midi_out <: 1 << MIDI_SHIFT_TX; // Start with high bit.
#ifdef IAP
CoProcessorEnable();
#endif
@@ -253,7 +257,7 @@ void usb_midi(port ?p_midi_in, port ?p_midi_out,
midi_send_ack(c_midi);
}
p_midi_out <: 1 @ txPT;
p_midi_out <: (1<<MIDI_SHIFT_TX) @ txPT;
// printstr("mout1\n");
t :> txT;
txT += bit_time;
@@ -265,7 +269,7 @@ void usb_midi(port ?p_midi_in, port ?p_midi_out,
// Mid-symbol
txT += bit_time; // Should this be after the output otherwise be double the length of the high before the start bit
txPT += bit_time;
p_midi_out @ txPT <: (symbol & 1);
p_midi_out @ txPT <: ((symbol & 1)<<MIDI_SHIFT_TX);
// printstr("mout2\n");
symbol >>= 1;
if (symbol == 0)