USB device stack

Dependents:   MATSU-bed_blinky MATSU-bed_detection

Fork of USBDevice by mbed official

Committer:
mbed_official
Date:
Thu Apr 16 11:00:20 2015 +0100
Revision:
48:03f8e580579a
Parent:
47:a0cd9646ecd1
Child:
50:a3c50882f2c5
Synchronized with git revision 1b9e8d686fd7448739e56182eb1f7cc0634667b5

Full URL: https://github.com/mbedmicro/mbed/commit/1b9e8d686fd7448739e56182eb1f7cc0634667b5/

Add SysEx to USBMIDI device

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
samux 1:80ab0d068708 23 USBMIDI::USBMIDI(uint16_t vendor_id, uint16_t product_id, uint16_t product_release): USBDevice(vendor_id, product_id, product_release) {
samux 1:80ab0d068708 24 midi_evt = NULL;
samux 1:80ab0d068708 25 USBDevice::connect();
samux 1:80ab0d068708 26 }
samux 1:80ab0d068708 27
mbed_official 48:03f8e580579a 28 // write plain MIDIMessage that will be converted to USBMidi event packet
samux 1:80ab0d068708 29 void USBMIDI::write(MIDIMessage m) {
mbed_official 48:03f8e580579a 30 // first byte keeped for retro-compatibility
mbed_official 48:03f8e580579a 31 for(int p=1; p < m.length; p+=3) {
mbed_official 48:03f8e580579a 32 uint8_t buf[4];
mbed_official 48:03f8e580579a 33 // Midi message to USBMidi event packet
mbed_official 48:03f8e580579a 34 buf[0]=m.data[1] >> 4;
mbed_official 48:03f8e580579a 35 // SysEx
mbed_official 48:03f8e580579a 36 if(buf[0] == 0xF) {
mbed_official 48:03f8e580579a 37 if((m.length - p) > 3) {
mbed_official 48:03f8e580579a 38 // SysEx start or continue
mbed_official 48:03f8e580579a 39 buf[0]=0x4;
mbed_official 48:03f8e580579a 40 } else {
mbed_official 48:03f8e580579a 41 switch(m.length - p) {
mbed_official 48:03f8e580579a 42 case 1:
mbed_official 48:03f8e580579a 43 // SysEx end with one byte
mbed_official 48:03f8e580579a 44 buf[0]=0x5;
mbed_official 48:03f8e580579a 45 break;
mbed_official 48:03f8e580579a 46 case 2:
mbed_official 48:03f8e580579a 47 // SysEx end with two bytes
mbed_official 48:03f8e580579a 48 buf[0]=0x6;
mbed_official 48:03f8e580579a 49 break;
mbed_official 48:03f8e580579a 50 case 3:
mbed_official 48:03f8e580579a 51 // SysEx end with three bytes
mbed_official 48:03f8e580579a 52 buf[0]=0x7;
mbed_official 48:03f8e580579a 53 break;
mbed_official 48:03f8e580579a 54 }
mbed_official 48:03f8e580579a 55 }
mbed_official 48:03f8e580579a 56 }
mbed_official 48:03f8e580579a 57 buf[1]=m.data[p];
mbed_official 48:03f8e580579a 58
mbed_official 48:03f8e580579a 59 if(p+1 < m.length)
mbed_official 48:03f8e580579a 60 buf[2]=m.data[p+1];
mbed_official 48:03f8e580579a 61 else
mbed_official 48:03f8e580579a 62 buf[2]=0;
mbed_official 48:03f8e580579a 63
mbed_official 48:03f8e580579a 64 if(p+2 < m.length)
mbed_official 48:03f8e580579a 65 buf[3]=m.data[p+2];
mbed_official 48:03f8e580579a 66 else
mbed_official 48:03f8e580579a 67 buf[3]=0;
mbed_official 48:03f8e580579a 68
mbed_official 48:03f8e580579a 69 USBDevice::write(EPBULK_IN, buf, 4, MAX_PACKET_SIZE_EPBULK);
mbed_official 48:03f8e580579a 70 }
samux 1:80ab0d068708 71 }
samux 1:80ab0d068708 72
samux 1:80ab0d068708 73
samux 1:80ab0d068708 74 void USBMIDI::attach(void (*fptr)(MIDIMessage)) {
samux 1:80ab0d068708 75 midi_evt = fptr;
samux 1:80ab0d068708 76 }
samux 1:80ab0d068708 77
mbed_official 47:a0cd9646ecd1 78 bool USBMIDI::EPBULK_OUT_callback() {
samux 1:80ab0d068708 79 uint8_t buf[64];
samux 1:80ab0d068708 80 uint32_t len;
samux 1:80ab0d068708 81 readEP(EPBULK_OUT, buf, &len, 64);
samux 1:80ab0d068708 82
samux 1:80ab0d068708 83 if (midi_evt != NULL) {
mbed_official 48:03f8e580579a 84 for (uint32_t i=0; i<len; i+=4) {
mbed_official 48:03f8e580579a 85 uint8_t data_read;
mbed_official 48:03f8e580579a 86 data_end=true;
mbed_official 48:03f8e580579a 87 switch(buf[i]) {
mbed_official 48:03f8e580579a 88 case 0x2:
mbed_official 48:03f8e580579a 89 // Two-bytes System Common Message - undefined in USBMidi 1.0
mbed_official 48:03f8e580579a 90 data_read=2;
mbed_official 48:03f8e580579a 91 break;
mbed_official 48:03f8e580579a 92 case 0x4:
mbed_official 48:03f8e580579a 93 // SysEx start or continue
mbed_official 48:03f8e580579a 94 data_end=false;
mbed_official 48:03f8e580579a 95 data_read=3;
mbed_official 48:03f8e580579a 96 break;
mbed_official 48:03f8e580579a 97 case 0x5:
mbed_official 48:03f8e580579a 98 // Single-byte System Common Message or SysEx end with one byte
mbed_official 48:03f8e580579a 99 data_read=1;
mbed_official 48:03f8e580579a 100 break;
mbed_official 48:03f8e580579a 101 case 0x6:
mbed_official 48:03f8e580579a 102 // SysEx end with two bytes
mbed_official 48:03f8e580579a 103 data_read=2;
mbed_official 48:03f8e580579a 104 break;
mbed_official 48:03f8e580579a 105 case 0xC:
mbed_official 48:03f8e580579a 106 // Program change
mbed_official 48:03f8e580579a 107 data_read=2;
mbed_official 48:03f8e580579a 108 break;
mbed_official 48:03f8e580579a 109 case 0xD:
mbed_official 48:03f8e580579a 110 // Channel pressure
mbed_official 48:03f8e580579a 111 data_read=2;
mbed_official 48:03f8e580579a 112 break;
mbed_official 48:03f8e580579a 113 case 0xF:
mbed_official 48:03f8e580579a 114 // Single byte
mbed_official 48:03f8e580579a 115 data_read=1;
mbed_official 48:03f8e580579a 116 break;
mbed_official 48:03f8e580579a 117 default:
mbed_official 48:03f8e580579a 118 // Others three-bytes messages
mbed_official 48:03f8e580579a 119 data_read=3;
mbed_official 48:03f8e580579a 120 break;
mbed_official 48:03f8e580579a 121 }
mbed_official 48:03f8e580579a 122
mbed_official 48:03f8e580579a 123 for(uint8_t j=1;j<data_read+1;j++) {
mbed_official 48:03f8e580579a 124 data[cur_data]=buf[i+j];
mbed_official 48:03f8e580579a 125 cur_data++;
mbed_official 48:03f8e580579a 126 }
mbed_official 48:03f8e580579a 127
mbed_official 48:03f8e580579a 128 if(data_end) {
mbed_official 48:03f8e580579a 129 midi_evt(MIDIMessage(data,cur_data));
mbed_official 48:03f8e580579a 130 cur_data=0;
mbed_official 48:03f8e580579a 131 }
mbed_official 48:03f8e580579a 132 }
samux 1:80ab0d068708 133 }
samux 1:80ab0d068708 134
samux 1:80ab0d068708 135 // We reactivate the endpoint to receive next characters
samux 1:80ab0d068708 136 readStart(EPBULK_OUT, MAX_PACKET_SIZE_EPBULK);
samux 1:80ab0d068708 137 return true;
samux 1:80ab0d068708 138 }
samux 1:80ab0d068708 139
samux 1:80ab0d068708 140 // Called in ISR context
samux 1:80ab0d068708 141 // Set configuration. Return false if the
samux 1:80ab0d068708 142 // configuration is not supported.
samux 1:80ab0d068708 143 bool USBMIDI::USBCallback_setConfiguration(uint8_t configuration) {
samux 1:80ab0d068708 144 if (configuration != DEFAULT_CONFIGURATION) {
samux 1:80ab0d068708 145 return false;
samux 1:80ab0d068708 146 }
samux 1:80ab0d068708 147
samux 1:80ab0d068708 148 // Configure endpoints > 0
samux 1:80ab0d068708 149 addEndpoint(EPBULK_IN, MAX_PACKET_SIZE_EPBULK);
samux 1:80ab0d068708 150 addEndpoint(EPBULK_OUT, MAX_PACKET_SIZE_EPBULK);
samux 1:80ab0d068708 151
samux 1:80ab0d068708 152 // We activate the endpoint to be able to receive data
samux 1:80ab0d068708 153 readStart(EPBULK_OUT, MAX_PACKET_SIZE_EPBULK);
samux 1:80ab0d068708 154 return true;
samux 1:80ab0d068708 155 }
samux 1:80ab0d068708 156
samux 1:80ab0d068708 157
samux 1:80ab0d068708 158 uint8_t * USBMIDI::stringIinterfaceDesc() {
samux 1:80ab0d068708 159 static uint8_t stringIinterfaceDescriptor[] = {
samux 1:80ab0d068708 160 0x0c, //bLength
samux 1:80ab0d068708 161 STRING_DESCRIPTOR, //bDescriptorType 0x03
samux 1:80ab0d068708 162 'A',0,'u',0,'d',0,'i',0,'o',0 //bString iInterface - Audio
samux 1:80ab0d068708 163 };
samux 1:80ab0d068708 164 return stringIinterfaceDescriptor;
samux 1:80ab0d068708 165 }
samux 1:80ab0d068708 166
samux 1:80ab0d068708 167 uint8_t * USBMIDI::stringIproductDesc() {
samux 1:80ab0d068708 168 static uint8_t stringIproductDescriptor[] = {
samux 1:80ab0d068708 169 0x16, //bLength
samux 1:80ab0d068708 170 STRING_DESCRIPTOR, //bDescriptorType 0x03
samux 1:80ab0d068708 171 '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 172 };
samux 1:80ab0d068708 173 return stringIproductDescriptor;
samux 1:80ab0d068708 174 }
samux 1:80ab0d068708 175
samux 1:80ab0d068708 176
samux 1:80ab0d068708 177 uint8_t * USBMIDI::configurationDesc() {
samux 1:80ab0d068708 178 static uint8_t configDescriptor[] = {
samux 1:80ab0d068708 179 // configuration descriptor
samux 1:80ab0d068708 180 0x09, 0x02, 0x65, 0x00, 0x02, 0x01, 0x00, 0xc0, 0x50,
samux 1:80ab0d068708 181
samux 1:80ab0d068708 182 // The Audio Interface Collection
samux 1:80ab0d068708 183 0x09, 0x04, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, // Standard AC Interface Descriptor
samux 1:80ab0d068708 184 0x09, 0x24, 0x01, 0x00, 0x01, 0x09, 0x00, 0x01, 0x01, // Class-specific AC Interface Descriptor
samux 1:80ab0d068708 185 0x09, 0x04, 0x01, 0x00, 0x02, 0x01, 0x03, 0x00, 0x00, // MIDIStreaming Interface Descriptors
samux 1:80ab0d068708 186 0x07, 0x24, 0x01, 0x00, 0x01, 0x41, 0x00, // Class-Specific MS Interface Header Descriptor
samux 1:80ab0d068708 187
samux 1:80ab0d068708 188 // MIDI IN JACKS
samux 1:80ab0d068708 189 0x06, 0x24, 0x02, 0x01, 0x01, 0x00,
samux 1:80ab0d068708 190 0x06, 0x24, 0x02, 0x02, 0x02, 0x00,
samux 1:80ab0d068708 191
samux 1:80ab0d068708 192 // MIDI OUT JACKS
samux 1:80ab0d068708 193 0x09, 0x24, 0x03, 0x01, 0x03, 0x01, 0x02, 0x01, 0x00,
samux 1:80ab0d068708 194 0x09, 0x24, 0x03, 0x02, 0x06, 0x01, 0x01, 0x01, 0x00,
samux 1:80ab0d068708 195
samux 1:80ab0d068708 196 // OUT endpoint descriptor
samux 1:80ab0d068708 197 0x09, 0x05, 0x02, 0x02, 0x40, 0x00, 0x00, 0x00, 0x00,
samux 1:80ab0d068708 198 0x05, 0x25, 0x01, 0x01, 0x01,
samux 1:80ab0d068708 199
samux 1:80ab0d068708 200 // IN endpoint descriptor
samux 1:80ab0d068708 201 0x09, 0x05, 0x82, 0x02, 0x40, 0x00, 0x00, 0x00, 0x00,
samux 1:80ab0d068708 202 0x05, 0x25, 0x01, 0x01, 0x03,
samux 1:80ab0d068708 203 };
samux 1:80ab0d068708 204 return configDescriptor;
samux 1:80ab0d068708 205 }