A library to send and receive MIDI messages over USB using the default USB-MIDI drivers on Win/Mac
Dependents: USBMIDI_HelloWorld USBMIDI_DrumExample USBMIDI_MonoSynth MIDI_Interface_ver_1 ... more
usbdevice.c
00001 /* @license The MIT License 00002 * Copyright (c) 2011 mux, simon 00003 * 00004 * Permission is hereby granted, free of charge, to any person obtaining a copy 00005 * of this software and associated documentation files (the "Software"), to deal 00006 * in the Software without restriction, including without limitation the rights 00007 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 00008 * copies of the Software, and to permit persons to whom the Software is 00009 * furnished to do so, subject to the following conditions: 00010 * 00011 * The above copyright notice and this permission notice shall be included in 00012 * all copies or substantial portions of the Software. 00013 * 00014 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 00015 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 00016 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 00017 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 00018 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 00019 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 00020 * THE SOFTWARE. 00021 */ 00022 00023 #include "usbcore.h" 00024 #include "mbed.h" 00025 00026 #define STANDARD_DEVICE_REQUEST (0x00) 00027 #define STANDARD_INTERFACE_REQUEST (0x01) 00028 #define STANDARD_ENDPOINT_REQUEST (0x02) 00029 #define CLASS_DEVICE_REQUEST (0x20) 00030 #define CLASS_INTERFACE_REQUEST (0x21) 00031 #define CLASS_ENDPOINT_REQUEST (0x22) 00032 #define VENDOR_DEVICE_REQUEST (0x40) 00033 #define VENDOR_INTERFACE_REQUEST (0x41) 00034 #define VENDOR_ENDPOINT_REQUEST (0x42) 00035 #define GET_STATUS (0x00) 00036 #define CLEAR_FEATURE (0x01) 00037 #define SET_FEATURE (0x03) 00038 #define SET_ADDRESS (0x05) 00039 #define GET_DESCRIPTOR (0x06) 00040 #define SET_DESCRIPTOR (0x07) 00041 #define GET_CONFIGURATION (0x08) 00042 #define SET_CONFIGURATION (0x09) 00043 #define DEVICE_DESCRIPTOR (0x01) 00044 #define CONFIG_DESCRIPTOR (0x02) 00045 #define STRING_DESCRIPTOR (0x03) 00046 #define INTERFACE_DESCRIPTOR (0x04) 00047 #define ENDPOINT_DESCRIPTOR (0x05) 00048 #define QUALIFIER_DESCRIPTOR (0x06) 00049 #define unpack(x) (x & 0xFF),((x >> 8) & 0xFF) 00050 00051 // setup packet 00052 struct { 00053 uint8_t bmRequestType; 00054 uint8_t bRequest; 00055 uint16_t wValue; 00056 uint16_t wIndex; 00057 uint16_t wLength; 00058 } __attribute__((packed)) setup = {0}; 00059 00060 // data packet 00061 struct { 00062 uint8_t *data; 00063 uint8_t size; 00064 uint8_t sent; 00065 } transfer = {0}; 00066 00067 uint8_t device_descriptor[] = { 00068 0x12, // Descriptor size in bytes (12h) 00069 DEVICE_DESCRIPTOR, // The constant DEVICE (01h) 00070 unpack(0x0200), // US2B specification release number (BCD) 00071 0x00, // Class code 00072 0x00, // Subclass code 00073 0x00, // Protocol Code 00074 MAX_EP0_PSIZE, // Maximum packet size for endpoint zero 00075 unpack(0x0763), // Vendor ID 00076 unpack(0x0198), // Product ID 00077 unpack(0x0001), // Device release number (BCD) 00078 0x00, // Index of string descriptor for the manufacturer 00079 0x00, // Index of string descriptor for the product 00080 0x00, // Index of string descriptor for the serial number 00081 0x01, // Number of possible configurations 00082 }; 00083 00084 uint8_t config_descriptor[]={ 00085 0x09, 0x02, 0x65, 0x00, 0x02, 0x01, 0x00, 0xc0, 0x50, // configuration descriptor 00086 // The Audio Interface Collection 00087 0x09, 0x04, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, // Standard AC Interface Descriptor 00088 0x09, 0x24, 0x01, 0x00, 0x01, 0x09, 0x00, 0x01, 0x01, // Class-specific AC Interface Descriptor 00089 0x09, 0x04, 0x01, 0x00, 0x02, 0x01, 0x03, 0x00, 0x00, // MIDIStreaming Interface Descriptors 00090 0x07, 0x24, 0x01, 0x00, 0x01, 0x41, 0x00, // Class-Specific MS Interface Header Descriptor 00091 00092 // MIDI IN JACKS 00093 0x06, 0x24, 0x02, 0x01, 0x01, 0x00, 00094 0x06, 0x24, 0x02, 0x02, 0x02, 0x00, 00095 00096 // MIDI OUT JACKS 00097 0x09, 0x24, 0x03, 0x01, 0x03, 0x01, 0x02, 0x01, 0x00, 00098 0x09, 0x24, 0x03, 0x02, 0x06, 0x01, 0x01, 0x01, 0x00, 00099 00100 // OUT endpoint descriptor 00101 0x09, 0x05, 0x02, 0x02, 0x40, 0x00, 0x00, 0x00, 0x00, 00102 0x05, 0x25, 0x01, 0x01, 0x01, 00103 00104 // IN endpoint descriptor 00105 0x09, 0x05, 0x82, 0x02, 0x40, 0x00, 0x00, 0x00, 0x00, 00106 0x05, 0x25, 0x01, 0x01, 0x03, 00107 }; 00108 00109 void ep0_in(); 00110 00111 void data_in_stage(uint8_t *desc, uint8_t length) { 00112 transfer.sent = 0; 00113 transfer.data = desc; 00114 transfer.size = length; 00115 ep0_in(); 00116 } 00117 00118 void status_in_stage() { 00119 ep_write(EP1, 0, 0); // ZLEP for status stage 00120 } 00121 00122 void ep0_setup() { 00123 ep_read(EP0,(uint8_t*) &setup); 00124 00125 switch (setup.bmRequestType & 0x7f) { // mask direction 00126 case STANDARD_DEVICE_REQUEST: 00127 switch (setup.bRequest) { 00128 case GET_DESCRIPTOR: 00129 switch ((setup.wValue>>8)) { 00130 case DEVICE_DESCRIPTOR: // device descriptor request 00131 case QUALIFIER_DESCRIPTOR: // device qualifier descriptor 00132 data_in_stage(device_descriptor, sizeof(device_descriptor)); 00133 break; 00134 case CONFIG_DESCRIPTOR: // configuration descriptor 00135 data_in_stage(config_descriptor, setup.wLength); 00136 break; 00137 case STRING_DESCRIPTOR: 00138 break; 00139 default: 00140 break; 00141 } 00142 break; 00143 case SET_ADDRESS: 00144 usb_set_address((uint8_t) (setup.wValue & 0xFF)); 00145 status_in_stage(); 00146 break; 00147 case SET_CONFIGURATION: 00148 if (!setup.wValue) { 00149 break; 00150 } 00151 ep_realize(EP4, MAX_EPn_PSIZE); 00152 ep_realize(EP5, MAX_EPn_PSIZE); 00153 status_in_stage(); 00154 usb_configure(1); 00155 break; 00156 default: 00157 break; 00158 } 00159 break; 00160 default: 00161 break; 00162 } 00163 } 00164 00165 void ep0_in() { 00166 if ((setup.bmRequestType & 0x80) && transfer.size) { // device to host 00167 if (transfer.size > MAX_EP0_PSIZE) { 00168 transfer.sent = MAX_EP0_PSIZE; 00169 } else { 00170 transfer.sent = transfer.size; 00171 } 00172 ep_write(EP1, transfer.data, transfer.sent); 00173 transfer.data += transfer.sent; 00174 transfer.size -= transfer.sent; 00175 } 00176 } 00177 00178 void ep0_out() { 00179 uint8_t buf[64]; 00180 ep_read(EP0, buf); 00181 }
Generated on Tue Jul 12 2022 16:19:58 by 1.7.2