uint16_t AudioInputUSB::incoming_count; | uint16_t AudioInputUSB::incoming_count; | ||||
uint8_t AudioInputUSB::receive_flag; | uint8_t AudioInputUSB::receive_flag; | ||||
struct usb_audio_features_struct AudioInputUSB::features = {0,0,FEATURE_MAX_VOLUME}; | |||||
#define DMABUFATTR __attribute__ ((section(".dmabuffers"), aligned (4))) | #define DMABUFATTR __attribute__ ((section(".dmabuffers"), aligned (4))) | ||||
uint16_t usb_audio_receive_buffer[AUDIO_RX_SIZE/2] DMABUFATTR; | uint16_t usb_audio_receive_buffer[AUDIO_RX_SIZE/2] DMABUFATTR; | ||||
uint32_t usb_audio_sync_feedback DMABUFATTR; | uint32_t usb_audio_sync_feedback DMABUFATTR; | ||||
return target * 4; | return target * 4; | ||||
} | } | ||||
int usb_audio_get_feature(void *stp, uint8_t *data, uint32_t *datalen) | |||||
{ | |||||
struct setup_struct setup = *((struct setup_struct *)stp); | |||||
if (setup.bmRequestType==0xA1) { // should check bRequest, bChannel, and UnitID | |||||
if (setup.bCS==0x01) { // mute | |||||
data[0] = AudioInputUSB::features.mute; // 1=mute, 0=unmute | |||||
*datalen = 1; | |||||
return 1; | |||||
} | |||||
else if (setup.bCS==0x02) { // volume | |||||
if (setup.bRequest==0x81) { // GET_CURR | |||||
data[0] = AudioInputUSB::features.volume & 0xFF; | |||||
data[1] = (AudioInputUSB::features.volume>>8) & 0xFF; | |||||
} | |||||
else if (setup.bRequest==0x82) { // GET_MIN | |||||
//serial_print("vol get_min\n"); | |||||
data[0] = 0; // min level is 0 | |||||
data[1] = 0; | |||||
} | |||||
else if (setup.bRequest==0x83) { // GET_MAX | |||||
data[0] = FEATURE_MAX_VOLUME & 0xFF; // max level, for range of 0 to MAX | |||||
data[1] = (FEATURE_MAX_VOLUME>>8) & 0x0F; | |||||
} | |||||
else if (setup.bRequest==0x84) { // GET_RES | |||||
data[0] = 1; // increment vol by by 1 | |||||
data[1] = 0; | |||||
} | |||||
else { // pass over SET_MEM, etc. | |||||
return 0; | |||||
} | |||||
*datalen = 2; | |||||
return 1; | |||||
} | |||||
} | |||||
return 0; | |||||
} | |||||
int usb_audio_set_feature(void *stp, uint8_t *buf) | |||||
{ | |||||
struct setup_struct setup = *((struct setup_struct *)stp); | |||||
if (setup.bmRequestType==0x21) { // should check bRequest, bChannel and UnitID | |||||
if (setup.bCS==0x01) { // mute | |||||
if (setup.bRequest==0x01) { // SET_CUR | |||||
AudioInputUSB::features.mute = buf[0]; // 1=mute,0=unmute | |||||
AudioInputUSB::features.change = 1; | |||||
return 1; | |||||
} | |||||
} | |||||
else if (setup.bCS==0x02) { // volume | |||||
if (setup.bRequest==0x01) { // SET_CUR | |||||
AudioInputUSB::features.volume = buf[0] + (buf[1]<<8); | |||||
AudioInputUSB::features.change = 1; | |||||
return 1; | |||||
} | |||||
} | |||||
} | |||||
return 0; | |||||
} | |||||
#endif // F_CPU | #endif // F_CPU | ||||
#endif // AUDIO_INTERFACE | #endif // AUDIO_INTERFACE |
#include "usb_desc.h" | #include "usb_desc.h" | ||||
#ifdef AUDIO_INTERFACE | #ifdef AUDIO_INTERFACE | ||||
#define FEATURE_MAX_VOLUME 0xFFF // volume accepted from 0 to 0xFFF | |||||
#ifdef __cplusplus | #ifdef __cplusplus | ||||
extern "C" { | extern "C" { | ||||
#endif | #endif | ||||
extern uint16_t usb_audio_transmit_buffer[]; | extern uint16_t usb_audio_transmit_buffer[]; | ||||
extern void usb_audio_receive_callback(unsigned int len); | extern void usb_audio_receive_callback(unsigned int len); | ||||
extern unsigned int usb_audio_transmit_callback(void); | extern unsigned int usb_audio_transmit_callback(void); | ||||
int usb_audio_set_feature(void *stp, uint8_t *buf); | |||||
int usb_audio_get_feature(void *stp, uint8_t *data, uint32_t *datalen); | |||||
extern uint32_t usb_audio_sync_feedback; | extern uint32_t usb_audio_sync_feedback; | ||||
extern uint8_t usb_audio_receive_setting; | extern uint8_t usb_audio_receive_setting; | ||||
extern uint8_t usb_audio_transmit_setting; | extern uint8_t usb_audio_transmit_setting; | ||||
#ifdef __cplusplus | #ifdef __cplusplus | ||||
} | } | ||||
// setup struct definition could be moved from usb_dev.c to usb_dev.h so we can reuse | |||||
// it instead of redefining it here | |||||
struct setup_struct { | |||||
union { | |||||
struct { | |||||
uint8_t bmRequestType; | |||||
uint8_t bRequest; | |||||
union { | |||||
struct { | |||||
uint8_t bChannel; // 0=main, 1=left, 2=right | |||||
uint8_t bCS; // Control Selector | |||||
}; | |||||
uint16_t wValue; | |||||
}; | |||||
union { | |||||
struct { | |||||
uint8_t bIfEp; // type of entity | |||||
uint8_t bEntityId; // UnitID, TerminalID, etc. | |||||
}; | |||||
uint16_t wIndex; | |||||
}; | |||||
uint16_t wLength; | |||||
}; | |||||
}; | |||||
}; | |||||
// audio features supported | |||||
struct usb_audio_features_struct { | |||||
int change; // set to 1 when any value is changed | |||||
int mute; // 1=mute, 0=unmute | |||||
int volume; // volume from 0 to FEATURE_MAX_VOLUME, maybe should be float from 0.0 to 1.0 | |||||
}; | |||||
#include "AudioStream.h" | #include "AudioStream.h" | ||||
class AudioInputUSB : public AudioStream | class AudioInputUSB : public AudioStream | ||||
virtual void update(void); | virtual void update(void); | ||||
void begin(void); | void begin(void); | ||||
friend void usb_audio_receive_callback(unsigned int len); | friend void usb_audio_receive_callback(unsigned int len); | ||||
friend int usb_audio_set_feature(void *stp, uint8_t *buf); | |||||
friend int usb_audio_get_feature(void *stp, uint8_t *data, uint32_t *datalen); | |||||
static struct usb_audio_features_struct features; | |||||
private: | private: | ||||
static bool update_responsibility; | static bool update_responsibility; | ||||
static audio_block_t *incoming_left; | static audio_block_t *incoming_left; |
}; | }; | ||||
#endif | #endif | ||||
#ifdef MULTITOUCH_INTERFACE | |||||
// https://forum.pjrc.com/threads/32331-USB-HID-Touchscreen-support-needed | |||||
// https://msdn.microsoft.com/en-us/library/windows/hardware/jj151563%28v=vs.85%29.aspx | |||||
// https://msdn.microsoft.com/en-us/library/windows/hardware/jj151565%28v=vs.85%29.aspx | |||||
// https://msdn.microsoft.com/en-us/library/windows/hardware/ff553734%28v=vs.85%29.aspx | |||||
// https://msdn.microsoft.com/en-us/library/windows/hardware/jj151564%28v=vs.85%29.aspx | |||||
// download.microsoft.com/download/a/d/f/adf1347d-08dc-41a4-9084-623b1194d4b2/digitizerdrvs_touch.docx | |||||
static uint8_t multitouch_report_desc[] = { | |||||
0x05, 0x0D, // Usage Page (Digitizer) | |||||
0x09, 0x04, // Usage (Touch Screen) | |||||
0xa1, 0x01, // Collection (Application) | |||||
0x09, 0x22, // Usage (Finger) | |||||
0xA1, 0x02, // Collection (Logical) | |||||
0x09, 0x42, // Usage (Tip Switch) | |||||
0x15, 0x00, // Logical Minimum (0) | |||||
0x25, 0x01, // Logical Maximum (1) | |||||
0x75, 0x01, // Report Size (1) | |||||
0x95, 0x01, // Report Count (1) | |||||
0x81, 0x02, // Input (variable,absolute) | |||||
0x09, 0x30, // Usage (Pressure) | |||||
0x25, 0x7F, // Logical Maximum (127) | |||||
0x75, 0x07, // Report Size (7) | |||||
0x95, 0x01, // Report Count (1) | |||||
0x81, 0x02, // Input (variable,absolute) | |||||
0x09, 0x51, // Usage (Contact Identifier) | |||||
0x26, 0xFF, 0x00, // Logical Maximum (255) | |||||
0x75, 0x08, // Report Size (8) | |||||
0x95, 0x02, // Report Count (1) | |||||
0x81, 0x02, // Input (variable,absolute) | |||||
0x05, 0x01, // Usage Page (Generic Desktop) | |||||
0x09, 0x30, // Usage (X) | |||||
0x09, 0x31, // Usage (Y) | |||||
0x26, 0xFF, 0x7F, // Logical Maximum (32767) | |||||
0x65, 0x00, // Unit (None) <-- probably needs real units? | |||||
0x75, 0x10, // Report Size (16) | |||||
0x95, 0x01, // Report Count (2) | |||||
0x81, 0x02, // Input (variable,absolute) | |||||
0xC0, // End Collection | |||||
0x05, 0x0D, // Usage Page (Digitizer) | |||||
0x27, 0xFF, 0xFF, 0, 0, // Logical Maximum (65535) | |||||
0x75, 0x10, // Report Size (16) | |||||
0x95, 0x01, // Report Count (1) | |||||
0x09, 0x56, // Usage (Scan Time) | |||||
0x81, 0x02, // Input (variable,absolute) | |||||
0x09, 0x54, // Usage (Contact Count) | |||||
0x25, 0x0A, // Logical Maximum (10) | |||||
0x75, 0x08, // Report Size (8) | |||||
0x95, 0x01, // Report Count (1) | |||||
0x81, 0x02, // Input (variable,absolute) | |||||
0x05, 0x0D, // Usage Page (Digitizers) | |||||
0x09, 0x55, // Usage (Contact Count Maximum) | |||||
0x25, 0x0A, // Logical Maximum (10) | |||||
0x75, 0x08, // Report Size (8) | |||||
0x95, 0x01, // Report Count (1) | |||||
0xB1, 0x02, // Feature (variable,absolute) | |||||
0xC0 // End Collection | |||||
}; | |||||
#endif | |||||
#ifdef SEREMU_INTERFACE | #ifdef SEREMU_INTERFACE | ||||
static uint8_t seremu_report_desc[] = { | static uint8_t seremu_report_desc[] = { | ||||
0x06, 0xC9, 0xFF, // Usage Page 0xFFC9 (vendor defined) | 0x06, 0xC9, 0xFF, // Usage Page 0xFFC9 (vendor defined) | ||||
#define AUDIO_INTERFACE_DESC_POS KEYMEDIA_INTERFACE_DESC_POS+KEYMEDIA_INTERFACE_DESC_SIZE | #define AUDIO_INTERFACE_DESC_POS KEYMEDIA_INTERFACE_DESC_POS+KEYMEDIA_INTERFACE_DESC_SIZE | ||||
#ifdef AUDIO_INTERFACE | #ifdef AUDIO_INTERFACE | ||||
#define AUDIO_INTERFACE_DESC_SIZE 9+10+12+9+12+9 + 9+9+7+11+9+7 + 9+9+7+11+9+7+9 | |||||
#define AUDIO_INTERFACE_DESC_SIZE 9+10+12+9+12+10+9 + 9+9+7+11+9+7 + 9+9+7+11+9+7+9 | |||||
#else | #else | ||||
#define AUDIO_INTERFACE_DESC_SIZE 0 | #define AUDIO_INTERFACE_DESC_SIZE 0 | ||||
#endif | #endif | ||||
#define CONFIG_DESC_SIZE AUDIO_INTERFACE_DESC_POS+AUDIO_INTERFACE_DESC_SIZE | |||||
#define MULTITOUCH_INTERFACE_DESC_POS AUDIO_INTERFACE_DESC_POS+AUDIO_INTERFACE_DESC_SIZE | |||||
#ifdef MULTITOUCH_INTERFACE | |||||
#define MULTITOUCH_INTERFACE_DESC_SIZE 9+9+7 | |||||
#define MULTITOUCH_HID_DESC_OFFSET MULTITOUCH_INTERFACE_DESC_POS+9 | |||||
#else | |||||
#define MULTITOUCH_INTERFACE_DESC_SIZE 0 | |||||
#endif | |||||
#define CONFIG_DESC_SIZE MULTITOUCH_INTERFACE_DESC_POS+MULTITOUCH_INTERFACE_DESC_SIZE | |||||
0x24, // bDescriptorType, 0x24 = CS_INTERFACE | 0x24, // bDescriptorType, 0x24 = CS_INTERFACE | ||||
0x01, // bDescriptorSubtype, 1 = HEADER | 0x01, // bDescriptorSubtype, 1 = HEADER | ||||
0x00, 0x01, // bcdADC (version 1.0) | 0x00, 0x01, // bcdADC (version 1.0) | ||||
LSB(52), MSB(52), // wTotalLength | |||||
LSB(62), MSB(62), // wTotalLength | |||||
2, // bInCollection | 2, // bInCollection | ||||
AUDIO_INTERFACE+1, // baInterfaceNr(1) - Transmit to PC | AUDIO_INTERFACE+1, // baInterfaceNr(1) - Transmit to PC | ||||
AUDIO_INTERFACE+2, // baInterfaceNr(2) - Receive from PC | AUDIO_INTERFACE+2, // baInterfaceNr(2) - Receive from PC | ||||
0x03, 0x00, // wChannelConfig, 0x0003 = Left & Right Front | 0x03, 0x00, // wChannelConfig, 0x0003 = Left & Right Front | ||||
0, // iChannelNames | 0, // iChannelNames | ||||
0, // iTerminal | 0, // iTerminal | ||||
// Volume feature descriptor | |||||
10, // bLength | |||||
0x24, // bDescriptorType = CS_INTERFACE | |||||
0x06, // bDescriptorSubType = FEATURE_UNIT | |||||
0x31, // bUnitID | |||||
0x03, // bSourceID (Input Terminal) | |||||
0x01, // bControlSize (each channel is 1 byte, 3 channels) | |||||
0x01, // bmaControls(0) Master: Mute | |||||
0x02, // bmaControls(1) Left: Volume | |||||
0x02, // bmaControls(2) Right: Volume | |||||
0x00, // iFeature | |||||
// Output Terminal Descriptor | // Output Terminal Descriptor | ||||
// USB DCD for Audio Devices 1.0, Table 4-4, page 40 | // USB DCD for Audio Devices 1.0, Table 4-4, page 40 | ||||
9, // bLength | 9, // bLength | ||||
//0x02, 0x03, // wTerminalType, 0x0302 = Headphones | //0x02, 0x03, // wTerminalType, 0x0302 = Headphones | ||||
0x02, 0x06, // wTerminalType, 0x0602 = Digital Audio | 0x02, 0x06, // wTerminalType, 0x0602 = Digital Audio | ||||
0, // bAssocTerminal, 0 = unidirectional | 0, // bAssocTerminal, 0 = unidirectional | ||||
3, // bCSourceID, connected to input terminal, ID=3 | |||||
0x31, // bCSourceID, connected to feature, ID=31 | |||||
0, // iTerminal | 0, // iTerminal | ||||
// Standard AS Interface Descriptor | // Standard AS Interface Descriptor | ||||
// USB DCD for Audio Devices 1.0, Section 4.5.1, Table 4-18, page 59 | // USB DCD for Audio Devices 1.0, Section 4.5.1, Table 4-18, page 59 | ||||
5, // bRefresh, 5 = 32ms | 5, // bRefresh, 5 = 32ms | ||||
0, // bSynchAddress | 0, // bSynchAddress | ||||
#endif | #endif | ||||
#ifdef MULTITOUCH_INTERFACE | |||||
// interface descriptor, USB spec 9.6.5, page 267-269, Table 9-12 | |||||
9, // bLength | |||||
4, // bDescriptorType | |||||
MULTITOUCH_INTERFACE, // bInterfaceNumber | |||||
0, // bAlternateSetting | |||||
1, // bNumEndpoints | |||||
0x03, // bInterfaceClass (0x03 = HID) | |||||
0x00, // bInterfaceSubClass | |||||
0x00, // bInterfaceProtocol | |||||
0, // iInterface | |||||
// HID interface descriptor, HID 1.11 spec, section 6.2.1 | |||||
9, // bLength | |||||
0x21, // bDescriptorType | |||||
0x11, 0x01, // bcdHID | |||||
0, // bCountryCode | |||||
1, // bNumDescriptors | |||||
0x22, // bDescriptorType | |||||
LSB(sizeof(multitouch_report_desc)), // wDescriptorLength | |||||
MSB(sizeof(multitouch_report_desc)), | |||||
// endpoint descriptor, USB spec 9.6.6, page 269-271, Table 9-13 | |||||
7, // bLength | |||||
5, // bDescriptorType | |||||
MULTITOUCH_ENDPOINT | 0x80, // bEndpointAddress | |||||
0x03, // bmAttributes (0x03=intr) | |||||
MULTITOUCH_SIZE, 0, // wMaxPacketSize | |||||
1, // bInterval | |||||
#endif // KEYMEDIA_INTERFACE | |||||
}; | }; | ||||
#ifdef KEYMEDIA_INTERFACE | #ifdef KEYMEDIA_INTERFACE | ||||
{0x2200, KEYMEDIA_INTERFACE, keymedia_report_desc, sizeof(keymedia_report_desc)}, | {0x2200, KEYMEDIA_INTERFACE, keymedia_report_desc, sizeof(keymedia_report_desc)}, | ||||
{0x2100, KEYMEDIA_INTERFACE, config_descriptor+KEYMEDIA_HID_DESC_OFFSET, 9}, | {0x2100, KEYMEDIA_INTERFACE, config_descriptor+KEYMEDIA_HID_DESC_OFFSET, 9}, | ||||
#endif | |||||
#ifdef MULTITOUCH_INTERFACE | |||||
{0x2200, MULTITOUCH_INTERFACE, multitouch_report_desc, sizeof(multitouch_report_desc)}, | |||||
{0x2100, MULTITOUCH_INTERFACE, config_descriptor+MULTITOUCH_HID_DESC_OFFSET, 9}, | |||||
#endif | #endif | ||||
{0x0300, 0x0000, (const uint8_t *)&string0, 0}, | {0x0300, 0x0000, (const uint8_t *)&string0, 0}, | ||||
{0x0301, 0x0409, (const uint8_t *)&usb_string_manufacturer_name, 0}, | {0x0301, 0x0409, (const uint8_t *)&usb_string_manufacturer_name, 0}, |
#define ENDPOINT3_CONFIG ENDPOINT_RECEIVE_ONLY | #define ENDPOINT3_CONFIG ENDPOINT_RECEIVE_ONLY | ||||
#define ENDPOINT4_CONFIG ENDPOINT_TRANSIMIT_ONLY | #define ENDPOINT4_CONFIG ENDPOINT_TRANSIMIT_ONLY | ||||
#elif defined(USB_KEYBOARDONLY) | |||||
#define VENDOR_ID 0x16C0 | |||||
#define PRODUCT_ID 0x0482 // TODO: unique | |||||
#define MANUFACTURER_NAME {'T','e','e','n','s','y','d','u','i','n','o'} | |||||
#define MANUFACTURER_NAME_LEN 11 | |||||
#define PRODUCT_NAME {'K','e','y','b','o','a','r','d'} | |||||
#define PRODUCT_NAME_LEN 8 | |||||
#define EP0_SIZE 64 | |||||
#define NUM_ENDPOINTS 4 | |||||
#define NUM_USB_BUFFERS 14 | |||||
#define NUM_INTERFACE 3 | |||||
#define SEREMU_INTERFACE 1 // Serial emulation | |||||
#define SEREMU_TX_ENDPOINT 1 | |||||
#define SEREMU_TX_SIZE 64 | |||||
#define SEREMU_TX_INTERVAL 1 | |||||
#define SEREMU_RX_ENDPOINT 2 | |||||
#define SEREMU_RX_SIZE 32 | |||||
#define SEREMU_RX_INTERVAL 2 | |||||
#define KEYBOARD_INTERFACE 0 // Keyboard | |||||
#define KEYBOARD_ENDPOINT 3 | |||||
#define KEYBOARD_SIZE 8 | |||||
#define KEYBOARD_INTERVAL 1 | |||||
#define KEYMEDIA_INTERFACE 2 // Keyboard Media Keys | |||||
#define KEYMEDIA_ENDPOINT 4 | |||||
#define KEYMEDIA_SIZE 8 | |||||
#define KEYMEDIA_INTERVAL 4 | |||||
#define ENDPOINT1_CONFIG ENDPOINT_TRANSIMIT_ONLY | |||||
#define ENDPOINT2_CONFIG ENDPOINT_RECEIVE_ONLY | |||||
#define ENDPOINT3_CONFIG ENDPOINT_TRANSIMIT_ONLY | |||||
#define ENDPOINT4_CONFIG ENDPOINT_TRANSIMIT_ONLY | |||||
#define ENDPOINT5_CONFIG ENDPOINT_TRANSIMIT_ONLY | |||||
#define ENDPOINT6_CONFIG ENDPOINT_TRANSIMIT_ONLY | |||||
#elif defined(USB_HID) | #elif defined(USB_HID) | ||||
#define VENDOR_ID 0x16C0 | #define VENDOR_ID 0x16C0 | ||||
#define PRODUCT_ID 0x0482 | #define PRODUCT_ID 0x0482 | ||||
#define ENDPOINT6_CONFIG ENDPOINT_TRANSIMIT_ONLY | #define ENDPOINT6_CONFIG ENDPOINT_TRANSIMIT_ONLY | ||||
#define ENDPOINT7_CONFIG ENDPOINT_TRANSIMIT_ONLY | #define ENDPOINT7_CONFIG ENDPOINT_TRANSIMIT_ONLY | ||||
#elif defined(USB_TOUCHSCREEN) | |||||
#define VENDOR_ID 0x16C0 | |||||
#define PRODUCT_ID 0x048B | |||||
#define MANUFACTURER_NAME {'T','e','e','n','s','y','d','u','i','n','o'} | |||||
#define MANUFACTURER_NAME_LEN 11 | |||||
#define PRODUCT_NAME {'K','e','y','b','o','a','r','d','/','T','o','u','c','h','s','c','r','e','e','n'} | |||||
#define PRODUCT_NAME_LEN 20 | |||||
#define EP0_SIZE 64 | |||||
#define NUM_ENDPOINTS 5 | |||||
#define NUM_USB_BUFFERS 15 | |||||
#define NUM_INTERFACE 4 | |||||
#define SEREMU_INTERFACE 1 // Serial emulation | |||||
#define SEREMU_TX_ENDPOINT 1 | |||||
#define SEREMU_TX_SIZE 64 | |||||
#define SEREMU_TX_INTERVAL 1 | |||||
#define SEREMU_RX_ENDPOINT 2 | |||||
#define SEREMU_RX_SIZE 32 | |||||
#define SEREMU_RX_INTERVAL 2 | |||||
#define KEYBOARD_INTERFACE 0 // Keyboard | |||||
#define KEYBOARD_ENDPOINT 3 | |||||
#define KEYBOARD_SIZE 8 | |||||
#define KEYBOARD_INTERVAL 1 | |||||
#define KEYMEDIA_INTERFACE 2 // Keyboard Media Keys | |||||
#define KEYMEDIA_ENDPOINT 4 | |||||
#define KEYMEDIA_SIZE 8 | |||||
#define KEYMEDIA_INTERVAL 4 | |||||
#define MULTITOUCH_INTERFACE 3 // Touchscreen | |||||
#define MULTITOUCH_ENDPOINT 5 | |||||
#define MULTITOUCH_SIZE 9 | |||||
#define MULTITOUCH_FINGERS 10 | |||||
#define ENDPOINT1_CONFIG ENDPOINT_TRANSIMIT_ONLY | |||||
#define ENDPOINT2_CONFIG ENDPOINT_RECEIVE_ONLY | |||||
#define ENDPOINT3_CONFIG ENDPOINT_TRANSIMIT_ONLY | |||||
#define ENDPOINT4_CONFIG ENDPOINT_TRANSIMIT_ONLY | |||||
#define ENDPOINT5_CONFIG ENDPOINT_TRANSIMIT_ONLY | |||||
#elif defined(USB_MIDI) | #elif defined(USB_MIDI) | ||||
#define VENDOR_ID 0x16C0 | #define VENDOR_ID 0x16C0 | ||||
#define PRODUCT_ID 0x0485 | #define PRODUCT_ID 0x0485 | ||||
#define ENDPOINT3_CONFIG ENDPOINT_TRANSIMIT_ONLY | #define ENDPOINT3_CONFIG ENDPOINT_TRANSIMIT_ONLY | ||||
#define ENDPOINT4_CONFIG ENDPOINT_RECEIVE_ONLY | #define ENDPOINT4_CONFIG ENDPOINT_RECEIVE_ONLY | ||||
#elif defined(USB_MIDI_SERIAL) | |||||
#define VENDOR_ID 0x16C0 | |||||
#define PRODUCT_ID 0x0485 // TODO: unique | |||||
#define MANUFACTURER_NAME {'T','e','e','n','s','y','d','u','i','n','o'} | |||||
#define MANUFACTURER_NAME_LEN 11 | |||||
#define PRODUCT_NAME {'T','e','e','n','s','y',' ','M','I','D','I'} | |||||
#define PRODUCT_NAME_LEN 11 | |||||
#define EP0_SIZE 64 | |||||
#define NUM_ENDPOINTS 5 | |||||
#define NUM_USB_BUFFERS 30 | |||||
#define NUM_INTERFACE 3 | |||||
#define CDC_IAD_DESCRIPTOR 1 | |||||
#define CDC_STATUS_INTERFACE 0 | |||||
#define CDC_DATA_INTERFACE 1 // Serial | |||||
#define CDC_ACM_ENDPOINT 1 | |||||
#define CDC_RX_ENDPOINT 2 | |||||
#define CDC_TX_ENDPOINT 3 | |||||
#define CDC_ACM_SIZE 16 | |||||
#define CDC_RX_SIZE 64 | |||||
#define CDC_TX_SIZE 64 | |||||
#define MIDI_INTERFACE 2 // MIDI | |||||
#define MIDI_TX_ENDPOINT 4 | |||||
#define MIDI_TX_SIZE 64 | |||||
#define MIDI_RX_ENDPOINT 5 | |||||
#define MIDI_RX_SIZE 64 | |||||
#define ENDPOINT1_CONFIG ENDPOINT_TRANSIMIT_ONLY | |||||
#define ENDPOINT2_CONFIG ENDPOINT_RECEIVE_ONLY | |||||
#define ENDPOINT3_CONFIG ENDPOINT_TRANSIMIT_ONLY | |||||
#define ENDPOINT4_CONFIG ENDPOINT_TRANSIMIT_ONLY | |||||
#define ENDPOINT5_CONFIG ENDPOINT_RECEIVE_ONLY | |||||
#elif defined(USB_RAWHID) | #elif defined(USB_RAWHID) | ||||
#define VENDOR_ID 0x16C0 | #define VENDOR_ID 0x16C0 | ||||
#define PRODUCT_ID 0x0486 | #define PRODUCT_ID 0x0486 | ||||
#elif defined(USB_AUDIO) | #elif defined(USB_AUDIO) | ||||
#define VENDOR_ID 0x16C0 | #define VENDOR_ID 0x16C0 | ||||
#define PRODUCT_ID 0x0485 // TODO: assign unique | |||||
#define PRODUCT_ID 0x048A | |||||
#define MANUFACTURER_NAME {'T','e','e','n','s','y','d','u','i','n','o'} | #define MANUFACTURER_NAME {'T','e','e','n','s','y','d','u','i','n','o'} | ||||
#define MANUFACTURER_NAME_LEN 11 | #define MANUFACTURER_NAME_LEN 11 | ||||
#define PRODUCT_NAME {'T','e','e','n','s','y',' ','A','u','d','i','o'} | #define PRODUCT_NAME {'T','e','e','n','s','y',' ','A','u','d','i','o'} | ||||
#define ENDPOINT4_CONFIG ENDPOINT_RECEIVE_ISOCHRONOUS | #define ENDPOINT4_CONFIG ENDPOINT_RECEIVE_ISOCHRONOUS | ||||
#define ENDPOINT5_CONFIG ENDPOINT_TRANSMIT_ISOCHRONOUS | #define ENDPOINT5_CONFIG ENDPOINT_TRANSMIT_ISOCHRONOUS | ||||
#elif defined(USB_MIDI_AUDIO_SERIAL) | |||||
#define VENDOR_ID 0x16C0 | |||||
#define PRODUCT_ID 0x0485 // TODO: unique | |||||
#define MANUFACTURER_NAME {'T','e','e','n','s','y','d','u','i','n','o'} | |||||
#define MANUFACTURER_NAME_LEN 11 | |||||
#define PRODUCT_NAME {'T','e','e','n','s','y',' ','M','I','D','I','/','A','u','d','i','o'} | |||||
#define PRODUCT_NAME_LEN 17 | |||||
#define EP0_SIZE 64 | |||||
#define NUM_ENDPOINTS 8 | |||||
#define NUM_USB_BUFFERS 30 | |||||
#define NUM_INTERFACE 6 | |||||
#define CDC_IAD_DESCRIPTOR 1 | |||||
#define CDC_STATUS_INTERFACE 0 | |||||
#define CDC_DATA_INTERFACE 1 // Serial | |||||
#define CDC_ACM_ENDPOINT 1 | |||||
#define CDC_RX_ENDPOINT 2 | |||||
#define CDC_TX_ENDPOINT 3 | |||||
#define CDC_ACM_SIZE 16 | |||||
#define CDC_RX_SIZE 64 | |||||
#define CDC_TX_SIZE 64 | |||||
#define MIDI_INTERFACE 2 // MIDI | |||||
#define MIDI_TX_ENDPOINT 4 | |||||
#define MIDI_TX_SIZE 64 | |||||
#define MIDI_RX_ENDPOINT 5 | |||||
#define MIDI_RX_SIZE 64 | |||||
#define AUDIO_INTERFACE 3 // Audio (uses 3 consecutive interfaces) | |||||
#define AUDIO_TX_ENDPOINT 6 | |||||
#define AUDIO_TX_SIZE 180 | |||||
#define AUDIO_RX_ENDPOINT 7 | |||||
#define AUDIO_RX_SIZE 180 | |||||
#define AUDIO_SYNC_ENDPOINT 8 | |||||
#define ENDPOINT1_CONFIG ENDPOINT_TRANSIMIT_ONLY | |||||
#define ENDPOINT2_CONFIG ENDPOINT_RECEIVE_ONLY | |||||
#define ENDPOINT3_CONFIG ENDPOINT_TRANSIMIT_ONLY | |||||
#define ENDPOINT4_CONFIG ENDPOINT_TRANSIMIT_ONLY | |||||
#define ENDPOINT5_CONFIG ENDPOINT_RECEIVE_ONLY | |||||
#define ENDPOINT6_CONFIG ENDPOINT_TRANSMIT_ISOCHRONOUS | |||||
#define ENDPOINT7_CONFIG ENDPOINT_RECEIVE_ISOCHRONOUS | |||||
#define ENDPOINT8_CONFIG ENDPOINT_TRANSMIT_ISOCHRONOUS | |||||
#endif | #endif | ||||
#ifdef USB_DESC_LIST_DEFINE | #ifdef USB_DESC_LIST_DEFINE |
return; | return; | ||||
} | } | ||||
break; | break; | ||||
case 0x0122: // SET_CUR (wValue=0, wIndex=interface, wLength=len) | |||||
case 0x0121: // SET FEATURE | |||||
case 0x0221: | |||||
case 0x0321: | |||||
case 0x0421: | |||||
// handle these on the next packet. See usb_audio_set_feature() | |||||
return; | return; | ||||
case 0x81A1: // GET FEATURE | |||||
case 0x82A1: | |||||
case 0x83A1: | |||||
case 0x84A1: | |||||
if (usb_audio_get_feature(&setup, reply_buffer, &datalen)) { | |||||
data = reply_buffer; | |||||
} | |||||
else { | |||||
endpoint0_stall(); | |||||
return; | |||||
} | |||||
break; | |||||
case 0x81A2: // GET_CUR (wValue=0, wIndex=interface, wLength=len) | case 0x81A2: // GET_CUR (wValue=0, wIndex=interface, wLength=len) | ||||
if (setup.wLength >= 3) { | if (setup.wLength >= 3) { | ||||
reply_buffer[0] = 44100 & 255; | reply_buffer[0] = 44100 & 255; | ||||
} | } | ||||
#endif | #endif | ||||
#ifdef AUDIO_INTERFACE | #ifdef AUDIO_INTERFACE | ||||
if (setup.wRequestAndType == 0x0122 /* SET_CUR */) { | |||||
// TODO: actually check data, do something with it? | |||||
if (usb_audio_set_feature(&setup, buf)) { | |||||
endpoint0_transmit(NULL, 0); | endpoint0_transmit(NULL, 0); | ||||
} | } | ||||
#endif | #endif |