Fork of the official USBDevice library

Fork of USBDevice by mbed official

Committer:
screamer
Date:
Fri Apr 28 17:01:10 2017 +0000
Branch:
device-files
Revision:
76:f0fd8d911b24
Parent:
73:8d28a0cb7b43
Changed the layout of USBDevice implementation for various targets to match mbed-os/targets. This also reduces the amount of files being compiled as USBDevice code for other targets is not compiled.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
screamer 73:8d28a0cb7b43 1 /* Copyright (c) 2010-2011 mbed.org, MIT License
screamer 73:8d28a0cb7b43 2 *
screamer 73:8d28a0cb7b43 3 * Permission is hereby granted, free of charge, to any person obtaining a copy of this software
screamer 73:8d28a0cb7b43 4 * and associated documentation files (the "Software"), to deal in the Software without
screamer 73:8d28a0cb7b43 5 * restriction, including without limitation the rights to use, copy, modify, merge, publish,
screamer 73:8d28a0cb7b43 6 * distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the
screamer 73:8d28a0cb7b43 7 * Software is furnished to do so, subject to the following conditions:
screamer 73:8d28a0cb7b43 8 *
screamer 73:8d28a0cb7b43 9 * The above copyright notice and this permission notice shall be included in all copies or
screamer 73:8d28a0cb7b43 10 * substantial portions of the Software.
screamer 73:8d28a0cb7b43 11 *
screamer 73:8d28a0cb7b43 12 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
screamer 73:8d28a0cb7b43 13 * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
screamer 73:8d28a0cb7b43 14 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
screamer 73:8d28a0cb7b43 15 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
screamer 73:8d28a0cb7b43 16 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
screamer 73:8d28a0cb7b43 17 */
screamer 73:8d28a0cb7b43 18
screamer 73:8d28a0cb7b43 19 #include "stdint.h"
screamer 73:8d28a0cb7b43 20 #include "USBMIDI.h"
screamer 73:8d28a0cb7b43 21
screamer 73:8d28a0cb7b43 22
screamer 73:8d28a0cb7b43 23 USBMIDI::USBMIDI(uint16_t vendor_id, uint16_t product_id, uint16_t product_release)
screamer 73:8d28a0cb7b43 24 : USBDevice(vendor_id, product_id, product_release), cur_data(0), data_end(true)
screamer 73:8d28a0cb7b43 25 {
screamer 73:8d28a0cb7b43 26 midi_evt = NULL;
screamer 73:8d28a0cb7b43 27 USBDevice::connect();
screamer 73:8d28a0cb7b43 28 }
screamer 73:8d28a0cb7b43 29
screamer 73:8d28a0cb7b43 30 // write plain MIDIMessage that will be converted to USBMidi event packet
screamer 73:8d28a0cb7b43 31 void USBMIDI::write(MIDIMessage m) {
screamer 73:8d28a0cb7b43 32 // first byte keeped for retro-compatibility
screamer 73:8d28a0cb7b43 33 for(int p=1; p < m.length; p+=3) {
screamer 73:8d28a0cb7b43 34 uint8_t buf[4];
screamer 73:8d28a0cb7b43 35 // Midi message to USBMidi event packet
screamer 73:8d28a0cb7b43 36 buf[0]=m.data[1] >> 4;
screamer 73:8d28a0cb7b43 37 // SysEx
screamer 73:8d28a0cb7b43 38 if(buf[0] == 0xF) {
screamer 73:8d28a0cb7b43 39 if((m.length - p) > 3) {
screamer 73:8d28a0cb7b43 40 // SysEx start or continue
screamer 73:8d28a0cb7b43 41 buf[0]=0x4;
screamer 73:8d28a0cb7b43 42 } else {
screamer 73:8d28a0cb7b43 43 switch(m.length - p) {
screamer 73:8d28a0cb7b43 44 case 1:
screamer 73:8d28a0cb7b43 45 // SysEx end with one byte
screamer 73:8d28a0cb7b43 46 buf[0]=0x5;
screamer 73:8d28a0cb7b43 47 break;
screamer 73:8d28a0cb7b43 48 case 2:
screamer 73:8d28a0cb7b43 49 // SysEx end with two bytes
screamer 73:8d28a0cb7b43 50 buf[0]=0x6;
screamer 73:8d28a0cb7b43 51 break;
screamer 73:8d28a0cb7b43 52 case 3:
screamer 73:8d28a0cb7b43 53 // SysEx end with three bytes
screamer 73:8d28a0cb7b43 54 buf[0]=0x7;
screamer 73:8d28a0cb7b43 55 break;
screamer 73:8d28a0cb7b43 56 }
screamer 73:8d28a0cb7b43 57 }
screamer 73:8d28a0cb7b43 58 }
screamer 73:8d28a0cb7b43 59 buf[1]=m.data[p];
screamer 73:8d28a0cb7b43 60
screamer 73:8d28a0cb7b43 61 if(p+1 < m.length)
screamer 73:8d28a0cb7b43 62 buf[2]=m.data[p+1];
screamer 73:8d28a0cb7b43 63 else
screamer 73:8d28a0cb7b43 64 buf[2]=0;
screamer 73:8d28a0cb7b43 65
screamer 73:8d28a0cb7b43 66 if(p+2 < m.length)
screamer 73:8d28a0cb7b43 67 buf[3]=m.data[p+2];
screamer 73:8d28a0cb7b43 68 else
screamer 73:8d28a0cb7b43 69 buf[3]=0;
screamer 73:8d28a0cb7b43 70
screamer 73:8d28a0cb7b43 71 USBDevice::write(EPBULK_IN, buf, 4, MAX_PACKET_SIZE_EPBULK);
screamer 73:8d28a0cb7b43 72 }
screamer 73:8d28a0cb7b43 73 }
screamer 73:8d28a0cb7b43 74
screamer 73:8d28a0cb7b43 75
screamer 73:8d28a0cb7b43 76 void USBMIDI::attach(void (*fptr)(MIDIMessage)) {
screamer 73:8d28a0cb7b43 77 midi_evt = fptr;
screamer 73:8d28a0cb7b43 78 }
screamer 73:8d28a0cb7b43 79
screamer 73:8d28a0cb7b43 80 bool USBMIDI::EPBULK_OUT_callback() {
screamer 73:8d28a0cb7b43 81 uint8_t buf[64];
screamer 73:8d28a0cb7b43 82 uint32_t len;
screamer 73:8d28a0cb7b43 83 readEP(EPBULK_OUT, buf, &len, 64);
screamer 73:8d28a0cb7b43 84
screamer 73:8d28a0cb7b43 85 if (midi_evt != NULL) {
screamer 73:8d28a0cb7b43 86 for (uint32_t i=0; i<len; i+=4) {
screamer 73:8d28a0cb7b43 87 uint8_t data_read;
screamer 73:8d28a0cb7b43 88 data_end=true;
screamer 73:8d28a0cb7b43 89 switch(buf[i]) {
screamer 73:8d28a0cb7b43 90 case 0x2:
screamer 73:8d28a0cb7b43 91 // Two-bytes System Common Message - undefined in USBMidi 1.0
screamer 73:8d28a0cb7b43 92 data_read=2;
screamer 73:8d28a0cb7b43 93 break;
screamer 73:8d28a0cb7b43 94 case 0x4:
screamer 73:8d28a0cb7b43 95 // SysEx start or continue
screamer 73:8d28a0cb7b43 96 data_end=false;
screamer 73:8d28a0cb7b43 97 data_read=3;
screamer 73:8d28a0cb7b43 98 break;
screamer 73:8d28a0cb7b43 99 case 0x5:
screamer 73:8d28a0cb7b43 100 // Single-byte System Common Message or SysEx end with one byte
screamer 73:8d28a0cb7b43 101 data_read=1;
screamer 73:8d28a0cb7b43 102 break;
screamer 73:8d28a0cb7b43 103 case 0x6:
screamer 73:8d28a0cb7b43 104 // SysEx end with two bytes
screamer 73:8d28a0cb7b43 105 data_read=2;
screamer 73:8d28a0cb7b43 106 break;
screamer 73:8d28a0cb7b43 107 case 0xC:
screamer 73:8d28a0cb7b43 108 // Program change
screamer 73:8d28a0cb7b43 109 data_read=2;
screamer 73:8d28a0cb7b43 110 break;
screamer 73:8d28a0cb7b43 111 case 0xD:
screamer 73:8d28a0cb7b43 112 // Channel pressure
screamer 73:8d28a0cb7b43 113 data_read=2;
screamer 73:8d28a0cb7b43 114 break;
screamer 73:8d28a0cb7b43 115 case 0xF:
screamer 73:8d28a0cb7b43 116 // Single byte
screamer 73:8d28a0cb7b43 117 data_read=1;
screamer 73:8d28a0cb7b43 118 break;
screamer 73:8d28a0cb7b43 119 default:
screamer 73:8d28a0cb7b43 120 // Others three-bytes messages
screamer 73:8d28a0cb7b43 121 data_read=3;
screamer 73:8d28a0cb7b43 122 break;
screamer 73:8d28a0cb7b43 123 }
screamer 73:8d28a0cb7b43 124
screamer 73:8d28a0cb7b43 125 for(uint8_t j=1;j<data_read+1;j++) {
screamer 73:8d28a0cb7b43 126 data[cur_data]=buf[i+j];
screamer 73:8d28a0cb7b43 127 cur_data++;
screamer 73:8d28a0cb7b43 128 }
screamer 73:8d28a0cb7b43 129
screamer 73:8d28a0cb7b43 130 if(data_end) {
screamer 73:8d28a0cb7b43 131 midi_evt(MIDIMessage(data,cur_data));
screamer 73:8d28a0cb7b43 132 cur_data=0;
screamer 73:8d28a0cb7b43 133 }
screamer 73:8d28a0cb7b43 134 }
screamer 73:8d28a0cb7b43 135 }
screamer 73:8d28a0cb7b43 136
screamer 73:8d28a0cb7b43 137 // We reactivate the endpoint to receive next characters
screamer 73:8d28a0cb7b43 138 readStart(EPBULK_OUT, MAX_PACKET_SIZE_EPBULK);
screamer 73:8d28a0cb7b43 139 return true;
screamer 73:8d28a0cb7b43 140 }
screamer 73:8d28a0cb7b43 141
screamer 73:8d28a0cb7b43 142 // Called in ISR context
screamer 73:8d28a0cb7b43 143 // Set configuration. Return false if the
screamer 73:8d28a0cb7b43 144 // configuration is not supported.
screamer 73:8d28a0cb7b43 145 bool USBMIDI::USBCallback_setConfiguration(uint8_t configuration) {
screamer 73:8d28a0cb7b43 146 if (configuration != DEFAULT_CONFIGURATION) {
screamer 73:8d28a0cb7b43 147 return false;
screamer 73:8d28a0cb7b43 148 }
screamer 73:8d28a0cb7b43 149
screamer 73:8d28a0cb7b43 150 // Configure endpoints > 0
screamer 73:8d28a0cb7b43 151 addEndpoint(EPBULK_IN, MAX_PACKET_SIZE_EPBULK);
screamer 73:8d28a0cb7b43 152 addEndpoint(EPBULK_OUT, MAX_PACKET_SIZE_EPBULK);
screamer 73:8d28a0cb7b43 153
screamer 73:8d28a0cb7b43 154 // We activate the endpoint to be able to receive data
screamer 73:8d28a0cb7b43 155 readStart(EPBULK_OUT, MAX_PACKET_SIZE_EPBULK);
screamer 73:8d28a0cb7b43 156 return true;
screamer 73:8d28a0cb7b43 157 }
screamer 73:8d28a0cb7b43 158
screamer 73:8d28a0cb7b43 159
screamer 73:8d28a0cb7b43 160 uint8_t * USBMIDI::stringIinterfaceDesc() {
screamer 73:8d28a0cb7b43 161 static uint8_t stringIinterfaceDescriptor[] = {
screamer 73:8d28a0cb7b43 162 0x0c, //bLength
screamer 73:8d28a0cb7b43 163 STRING_DESCRIPTOR, //bDescriptorType 0x03
screamer 73:8d28a0cb7b43 164 'A',0,'u',0,'d',0,'i',0,'o',0 //bString iInterface - Audio
screamer 73:8d28a0cb7b43 165 };
screamer 73:8d28a0cb7b43 166 return stringIinterfaceDescriptor;
screamer 73:8d28a0cb7b43 167 }
screamer 73:8d28a0cb7b43 168
screamer 73:8d28a0cb7b43 169 uint8_t * USBMIDI::stringIproductDesc() {
screamer 73:8d28a0cb7b43 170 static uint8_t stringIproductDescriptor[] = {
screamer 73:8d28a0cb7b43 171 0x16, //bLength
screamer 73:8d28a0cb7b43 172 STRING_DESCRIPTOR, //bDescriptorType 0x03
screamer 73:8d28a0cb7b43 173 'M',0,'b',0,'e',0,'d',0,' ',0,'A',0,'u',0,'d',0,'i',0,'o',0 //bString iProduct - Mbed Audio
screamer 73:8d28a0cb7b43 174 };
screamer 73:8d28a0cb7b43 175 return stringIproductDescriptor;
screamer 73:8d28a0cb7b43 176 }
screamer 73:8d28a0cb7b43 177
screamer 73:8d28a0cb7b43 178
screamer 73:8d28a0cb7b43 179 uint8_t * USBMIDI::configurationDesc() {
screamer 73:8d28a0cb7b43 180 static uint8_t configDescriptor[] = {
screamer 73:8d28a0cb7b43 181 // configuration descriptor
screamer 73:8d28a0cb7b43 182 0x09, 0x02, 0x65, 0x00, 0x02, 0x01, 0x00, 0xc0, 0x50,
screamer 73:8d28a0cb7b43 183
screamer 73:8d28a0cb7b43 184 // The Audio Interface Collection
screamer 73:8d28a0cb7b43 185 0x09, 0x04, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, // Standard AC Interface Descriptor
screamer 73:8d28a0cb7b43 186 0x09, 0x24, 0x01, 0x00, 0x01, 0x09, 0x00, 0x01, 0x01, // Class-specific AC Interface Descriptor
screamer 73:8d28a0cb7b43 187 0x09, 0x04, 0x01, 0x00, 0x02, 0x01, 0x03, 0x00, 0x00, // MIDIStreaming Interface Descriptors
screamer 73:8d28a0cb7b43 188 0x07, 0x24, 0x01, 0x00, 0x01, 0x41, 0x00, // Class-Specific MS Interface Header Descriptor
screamer 73:8d28a0cb7b43 189
screamer 73:8d28a0cb7b43 190 // MIDI IN JACKS
screamer 73:8d28a0cb7b43 191 0x06, 0x24, 0x02, 0x01, 0x01, 0x00,
screamer 73:8d28a0cb7b43 192 0x06, 0x24, 0x02, 0x02, 0x02, 0x00,
screamer 73:8d28a0cb7b43 193
screamer 73:8d28a0cb7b43 194 // MIDI OUT JACKS
screamer 73:8d28a0cb7b43 195 0x09, 0x24, 0x03, 0x01, 0x03, 0x01, 0x02, 0x01, 0x00,
screamer 73:8d28a0cb7b43 196 0x09, 0x24, 0x03, 0x02, 0x06, 0x01, 0x01, 0x01, 0x00,
screamer 73:8d28a0cb7b43 197
screamer 73:8d28a0cb7b43 198 // OUT endpoint descriptor
screamer 73:8d28a0cb7b43 199 0x09, 0x05, 0x02, 0x02, 0x40, 0x00, 0x00, 0x00, 0x00,
screamer 73:8d28a0cb7b43 200 0x05, 0x25, 0x01, 0x01, 0x01,
screamer 73:8d28a0cb7b43 201
screamer 73:8d28a0cb7b43 202 // IN endpoint descriptor
screamer 73:8d28a0cb7b43 203 0x09, 0x05, 0x82, 0x02, 0x40, 0x00, 0x00, 0x00, 0x00,
screamer 73:8d28a0cb7b43 204 0x05, 0x25, 0x01, 0x01, 0x03,
screamer 73:8d28a0cb7b43 205 };
screamer 73:8d28a0cb7b43 206 return configDescriptor;
screamer 73:8d28a0cb7b43 207 }