USB device stack
Dependents: blinky_max32630fthr FTHR_USB_serial FTHR_OLED HSP_RPC_GUI_3_0_1 ... more
Fork of USBDevice by
USBMIDI.cpp
00001 /* Copyright (c) 2010-2011 mbed.org, MIT License 00002 * 00003 * Permission is hereby granted, free of charge, to any person obtaining a copy of this software 00004 * and associated documentation files (the "Software"), to deal in the Software without 00005 * restriction, including without limitation the rights to use, copy, modify, merge, publish, 00006 * distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the 00007 * Software is furnished to do so, subject to the following conditions: 00008 * 00009 * The above copyright notice and this permission notice shall be included in all copies or 00010 * substantial portions of the Software. 00011 * 00012 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING 00013 * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 00014 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, 00015 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 00016 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 00017 */ 00018 00019 #include "stdint.h" 00020 #include "USBMIDI.h" 00021 00022 00023 USBMIDI::USBMIDI(uint16_t vendor_id, uint16_t product_id, uint16_t product_release) 00024 : USBDevice(vendor_id, product_id, product_release), cur_data(0), data_end(true) 00025 { 00026 midi_evt = NULL; 00027 USBDevice::connect(); 00028 } 00029 00030 // write plain MIDIMessage that will be converted to USBMidi event packet 00031 void USBMIDI::write(MIDIMessage m) { 00032 // first byte keeped for retro-compatibility 00033 for(int p=1; p < m.length; p+=3) { 00034 uint8_t buf[4]; 00035 // Midi message to USBMidi event packet 00036 buf[0]=m.data[1] >> 4; 00037 // SysEx 00038 if(buf[0] == 0xF) { 00039 if((m.length - p) > 3) { 00040 // SysEx start or continue 00041 buf[0]=0x4; 00042 } else { 00043 switch(m.length - p) { 00044 case 1: 00045 // SysEx end with one byte 00046 buf[0]=0x5; 00047 break; 00048 case 2: 00049 // SysEx end with two bytes 00050 buf[0]=0x6; 00051 break; 00052 case 3: 00053 // SysEx end with three bytes 00054 buf[0]=0x7; 00055 break; 00056 } 00057 } 00058 } 00059 buf[1]=m.data[p]; 00060 00061 if(p+1 < m.length) 00062 buf[2]=m.data[p+1]; 00063 else 00064 buf[2]=0; 00065 00066 if(p+2 < m.length) 00067 buf[3]=m.data[p+2]; 00068 else 00069 buf[3]=0; 00070 00071 USBDevice::write(EPBULK_IN, buf, 4, MAX_PACKET_SIZE_EPBULK); 00072 } 00073 } 00074 00075 00076 void USBMIDI::attach(void (*fptr)(MIDIMessage)) { 00077 midi_evt = fptr; 00078 } 00079 00080 bool USBMIDI::EPBULK_OUT_callback() { 00081 uint8_t buf[64]; 00082 uint32_t len; 00083 readEP(EPBULK_OUT, buf, &len, 64); 00084 00085 if (midi_evt != NULL) { 00086 for (uint32_t i=0; i<len; i+=4) { 00087 uint8_t data_read; 00088 data_end=true; 00089 switch(buf[i]) { 00090 case 0x2: 00091 // Two-bytes System Common Message - undefined in USBMidi 1.0 00092 data_read=2; 00093 break; 00094 case 0x4: 00095 // SysEx start or continue 00096 data_end=false; 00097 data_read=3; 00098 break; 00099 case 0x5: 00100 // Single-byte System Common Message or SysEx end with one byte 00101 data_read=1; 00102 break; 00103 case 0x6: 00104 // SysEx end with two bytes 00105 data_read=2; 00106 break; 00107 case 0xC: 00108 // Program change 00109 data_read=2; 00110 break; 00111 case 0xD: 00112 // Channel pressure 00113 data_read=2; 00114 break; 00115 case 0xF: 00116 // Single byte 00117 data_read=1; 00118 break; 00119 default: 00120 // Others three-bytes messages 00121 data_read=3; 00122 break; 00123 } 00124 00125 for(uint8_t j=1;j<data_read+1;j++) { 00126 data[cur_data]=buf[i+j]; 00127 cur_data++; 00128 } 00129 00130 if(data_end) { 00131 midi_evt(MIDIMessage(data,cur_data)); 00132 cur_data=0; 00133 } 00134 } 00135 } 00136 00137 // We reactivate the endpoint to receive next characters 00138 readStart(EPBULK_OUT, MAX_PACKET_SIZE_EPBULK); 00139 return true; 00140 } 00141 00142 // Called in ISR context 00143 // Set configuration. Return false if the 00144 // configuration is not supported. 00145 bool USBMIDI::USBCallback_setConfiguration(uint8_t configuration) { 00146 if (configuration != DEFAULT_CONFIGURATION) { 00147 return false; 00148 } 00149 00150 // Configure endpoints > 0 00151 addEndpoint(EPBULK_IN, MAX_PACKET_SIZE_EPBULK); 00152 addEndpoint(EPBULK_OUT, MAX_PACKET_SIZE_EPBULK); 00153 00154 // We activate the endpoint to be able to receive data 00155 readStart(EPBULK_OUT, MAX_PACKET_SIZE_EPBULK); 00156 return true; 00157 } 00158 00159 00160 uint8_t * USBMIDI::stringIinterfaceDesc() { 00161 static uint8_t stringIinterfaceDescriptor[] = { 00162 0x0c, //bLength 00163 STRING_DESCRIPTOR, //bDescriptorType 0x03 00164 'A',0,'u',0,'d',0,'i',0,'o',0 //bString iInterface - Audio 00165 }; 00166 return stringIinterfaceDescriptor; 00167 } 00168 00169 uint8_t * USBMIDI::stringIproductDesc() { 00170 static uint8_t stringIproductDescriptor[] = { 00171 0x16, //bLength 00172 STRING_DESCRIPTOR, //bDescriptorType 0x03 00173 'M',0,'b',0,'e',0,'d',0,' ',0,'A',0,'u',0,'d',0,'i',0,'o',0 //bString iProduct - Mbed Audio 00174 }; 00175 return stringIproductDescriptor; 00176 } 00177 00178 00179 uint8_t * USBMIDI::configurationDesc() { 00180 static uint8_t configDescriptor[] = { 00181 // configuration descriptor 00182 0x09, 0x02, 0x65, 0x00, 0x02, 0x01, 0x00, 0xc0, 0x50, 00183 00184 // The Audio Interface Collection 00185 0x09, 0x04, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, // Standard AC Interface Descriptor 00186 0x09, 0x24, 0x01, 0x00, 0x01, 0x09, 0x00, 0x01, 0x01, // Class-specific AC Interface Descriptor 00187 0x09, 0x04, 0x01, 0x00, 0x02, 0x01, 0x03, 0x00, 0x00, // MIDIStreaming Interface Descriptors 00188 0x07, 0x24, 0x01, 0x00, 0x01, 0x41, 0x00, // Class-Specific MS Interface Header Descriptor 00189 00190 // MIDI IN JACKS 00191 0x06, 0x24, 0x02, 0x01, 0x01, 0x00, 00192 0x06, 0x24, 0x02, 0x02, 0x02, 0x00, 00193 00194 // MIDI OUT JACKS 00195 0x09, 0x24, 0x03, 0x01, 0x03, 0x01, 0x02, 0x01, 0x00, 00196 0x09, 0x24, 0x03, 0x02, 0x06, 0x01, 0x01, 0x01, 0x00, 00197 00198 // OUT endpoint descriptor 00199 0x09, 0x05, 0x02, 0x02, 0x40, 0x00, 0x00, 0x00, 0x00, 00200 0x05, 0x25, 0x01, 0x01, 0x01, 00201 00202 // IN endpoint descriptor 00203 0x09, 0x05, 0x82, 0x02, 0x40, 0x00, 0x00, 0x00, 0x00, 00204 0x05, 0x25, 0x01, 0x01, 0x03, 00205 }; 00206 return configDescriptor; 00207 }
Generated on Wed Jul 13 2022 12:44:03 by 1.7.2