USB device stack

Fork of USBDevice by mbed official

Committer:
KillingJacky
Date:
Wed Nov 04 10:00:54 2015 +0000
Revision:
59:addb0b0c2f90
Parent:
50:a3c50882f2c5
init commit

Who changed what in which revision?

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