diff --git a/module_usb_aud_shared/devicedefines.h b/module_usb_aud_shared/devicedefines.h index 3cca2435..07c63c06 100644 --- a/module_usb_aud_shared/devicedefines.h +++ b/module_usb_aud_shared/devicedefines.h @@ -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*/ diff --git a/module_usb_aud_shared/endpoint0/descriptors_2.h b/module_usb_aud_shared/endpoint0/descriptors_2.h index 24cb8042..f81c0b24 100644 --- a/module_usb_aud_shared/endpoint0/descriptors_2.h +++ b/module_usb_aud_shared/endpoint0/descriptors_2.h @@ -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 */ diff --git a/module_usb_aud_shared/endpoint0/endpoint0.xc b/module_usb_aud_shared/endpoint0/endpoint0.xc index f0c29c6d..3f2cfef7 100755 --- a/module_usb_aud_shared/endpoint0/endpoint0.xc +++ b/module_usb_aud_shared/endpoint0/endpoint0.xc @@ -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; diff --git a/module_usb_aud_shared/iic/iic.h b/module_usb_aud_shared/iic/iic.h index 8e9ccda0..f9052049 100755 --- a/module_usb_aud_shared/iic/iic.h +++ b/module_usb_aud_shared/iic/iic.h @@ -3,7 +3,7 @@ #include -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__ diff --git a/module_usb_aud_shared/usb_buffer/decouple.xc b/module_usb_aud_shared/usb_buffer/decouple.xc index a17946a5..155a57cd 100644 --- a/module_usb_aud_shared/usb_buffer/decouple.xc +++ b/module_usb_aud_shared/usb_buffer/decouple.xc @@ -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) { diff --git a/module_usb_aud_shared/usb_buffer/usb_buffer.h b/module_usb_aud_shared/usb_buffer/usb_buffer.h index 76448b17..02670090 100644 --- a/module_usb_aud_shared/usb_buffer/usb_buffer.h +++ b/module_usb_aud_shared/usb_buffer/usb_buffer.h @@ -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 diff --git a/module_usb_aud_shared/usb_buffer/usb_buffer.xc b/module_usb_aud_shared/usb_buffer/usb_buffer.xc index 562c1234..eccb4f6b 100644 --- a/module_usb_aud_shared/usb_buffer/usb_buffer.xc +++ b/module_usb_aud_shared/usb_buffer/usb_buffer.xc @@ -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 + } } diff --git a/module_usb_midi/src/usb_midi.xc b/module_usb_midi/src/usb_midi.xc index a80443ac..f43acc0e 100644 --- a/module_usb_midi/src/usb_midi.xc +++ b/module_usb_midi/src/usb_midi.xc @@ -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< 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)<>= 1; if (symbol == 0)