Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Fork of USBMIDI by
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 23:30:37 by
