My Fork of F401RE-USBHost. Add USBHostMIDI functions (originaled by Kaoru Shoji http://mbed.org/users/kshoji/code/USBHostMIDI/)

Dependencies:   FATFileSystem

Dependents:   F401RE-USBHostMIDI_RecieveExample

Fork of F401RE-USBHost by Norimasa Okamoto

Committer:
hsgw
Date:
Wed Jun 25 20:48:01 2014 +0000
Revision:
18:bac56d0365e1
Child:
22:81d8c59d1070
Add USBHostMIDI(porting https://mbed.org/users/kshoji/code/USBHostMIDI/)

Who changed what in which revision?

UserRevisionLine numberNew contents of line
hsgw 18:bac56d0365e1 1 /* USBHostMidi library
hsgw 18:bac56d0365e1 2 * Originaled by k.shoji
hsgw 18:bac56d0365e1 3 * porting by Takuya Urakawa
hsgw 18:bac56d0365e1 4 */
hsgw 18:bac56d0365e1 5
hsgw 18:bac56d0365e1 6 /* mbed USBHost Library
hsgw 18:bac56d0365e1 7 * Copyright (c) 2006-2013 ARM Limited
hsgw 18:bac56d0365e1 8 *
hsgw 18:bac56d0365e1 9 * Licensed under the Apache License, Version 2.0 (the "License");
hsgw 18:bac56d0365e1 10 * you may not use this file except in compliance with the License.
hsgw 18:bac56d0365e1 11 * You may obtain a copy of the License at
hsgw 18:bac56d0365e1 12 *
hsgw 18:bac56d0365e1 13 * http://www.apache.org/licenses/LICENSE-2.0
hsgw 18:bac56d0365e1 14 *
hsgw 18:bac56d0365e1 15 * Unless required by applicable law or agreed to in writing, software
hsgw 18:bac56d0365e1 16 * distributed under the License is distributed on an "AS IS" BASIS,
hsgw 18:bac56d0365e1 17 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
hsgw 18:bac56d0365e1 18 * See the License for the specific language governing permissions and
hsgw 18:bac56d0365e1 19 * limitations under the License.
hsgw 18:bac56d0365e1 20 */
hsgw 18:bac56d0365e1 21
hsgw 18:bac56d0365e1 22 #include "USBHostMIDI.h"
hsgw 18:bac56d0365e1 23
hsgw 18:bac56d0365e1 24 #if USBHOST_MIDI
hsgw 18:bac56d0365e1 25
hsgw 18:bac56d0365e1 26 #include "dbg.h"
hsgw 18:bac56d0365e1 27
hsgw 18:bac56d0365e1 28 #define SET_LINE_CODING 0x20
hsgw 18:bac56d0365e1 29
hsgw 18:bac56d0365e1 30 USBHostMIDI::USBHostMIDI(): circ_buf() {
hsgw 18:bac56d0365e1 31 host = USBHost::getHostInst();
hsgw 18:bac56d0365e1 32 size_bulk_in = 0;
hsgw 18:bac56d0365e1 33 size_bulk_out = 0;
hsgw 18:bac56d0365e1 34 init();
hsgw 18:bac56d0365e1 35 }
hsgw 18:bac56d0365e1 36
hsgw 18:bac56d0365e1 37 void USBHostMIDI::init() {
hsgw 18:bac56d0365e1 38 dev = NULL;
hsgw 18:bac56d0365e1 39 bulk_in = NULL;
hsgw 18:bac56d0365e1 40 bulk_out = NULL;
hsgw 18:bac56d0365e1 41 dev_connected = false;
hsgw 18:bac56d0365e1 42 midi_intf = -1;
hsgw 18:bac56d0365e1 43 midi_device_found = false;
hsgw 18:bac56d0365e1 44 circ_buf.flush();
hsgw 18:bac56d0365e1 45 }
hsgw 18:bac56d0365e1 46
hsgw 18:bac56d0365e1 47 bool USBHostMIDI::connected()
hsgw 18:bac56d0365e1 48 {
hsgw 18:bac56d0365e1 49 return dev_connected;
hsgw 18:bac56d0365e1 50 }
hsgw 18:bac56d0365e1 51
hsgw 18:bac56d0365e1 52 bool USBHostMIDI::connect() {
hsgw 18:bac56d0365e1 53
hsgw 18:bac56d0365e1 54 if (dev_connected) {
hsgw 18:bac56d0365e1 55 return true;
hsgw 18:bac56d0365e1 56 }
hsgw 18:bac56d0365e1 57 for (uint8_t i = 0; i < MAX_DEVICE_CONNECTED; i++) {
hsgw 18:bac56d0365e1 58 if ((dev = host->getDevice(i)) != NULL) {
hsgw 18:bac56d0365e1 59
hsgw 18:bac56d0365e1 60 USB_DBG("Trying to connect MIDI device\r\n");
hsgw 18:bac56d0365e1 61
hsgw 18:bac56d0365e1 62 if(host->enumerate(dev, this))
hsgw 18:bac56d0365e1 63 break;
hsgw 18:bac56d0365e1 64
hsgw 18:bac56d0365e1 65 if (midi_device_found) {
hsgw 18:bac56d0365e1 66 bulk_in = dev->getEndpoint(midi_intf, BULK_ENDPOINT, IN);
hsgw 18:bac56d0365e1 67 bulk_out = dev->getEndpoint(midi_intf, BULK_ENDPOINT, OUT);
hsgw 18:bac56d0365e1 68
hsgw 18:bac56d0365e1 69 if (!bulk_in || !bulk_out)
hsgw 18:bac56d0365e1 70 break;
hsgw 18:bac56d0365e1 71
hsgw 18:bac56d0365e1 72 USB_INFO("New MIDI device: VID:%04x PID:%04x [dev: %p - intf: %d]", dev->getVid(), dev->getPid(), dev, midi_intf);
hsgw 18:bac56d0365e1 73 dev->setName("MIDI", midi_intf);
hsgw 18:bac56d0365e1 74 host->registerDriver(dev, midi_intf, this, &USBHostMIDI::init);
hsgw 18:bac56d0365e1 75
hsgw 18:bac56d0365e1 76 size_bulk_in = bulk_in->getSize();
hsgw 18:bac56d0365e1 77 size_bulk_out = bulk_out->getSize();
hsgw 18:bac56d0365e1 78
hsgw 18:bac56d0365e1 79 bulk_in->attach(this, &USBHostMIDI::rxHandler);
hsgw 18:bac56d0365e1 80
hsgw 18:bac56d0365e1 81 host->bulkRead(dev, bulk_in, buf, size_bulk_in, false);
hsgw 18:bac56d0365e1 82 dev_connected = true;
hsgw 18:bac56d0365e1 83 return true;
hsgw 18:bac56d0365e1 84 }
hsgw 18:bac56d0365e1 85 }
hsgw 18:bac56d0365e1 86 }
hsgw 18:bac56d0365e1 87 init();
hsgw 18:bac56d0365e1 88 return false;
hsgw 18:bac56d0365e1 89 }
hsgw 18:bac56d0365e1 90
hsgw 18:bac56d0365e1 91 void USBHostMIDI::rxHandler() {
hsgw 18:bac56d0365e1 92 uint8_t pos = 0;
hsgw 18:bac56d0365e1 93 uint8_t midi[4];
hsgw 18:bac56d0365e1 94 if (bulk_in) {
hsgw 18:bac56d0365e1 95 int len = bulk_in->getLengthTransferred();
hsgw 18:bac56d0365e1 96 if (bulk_in->getState() == USB_TYPE_IDLE || bulk_in->getState() == USB_TYPE_FREE) {
hsgw 18:bac56d0365e1 97 for (int i = 0; i < len; i++) {
hsgw 18:bac56d0365e1 98 circ_buf.queue(buf[i]);
hsgw 18:bac56d0365e1 99 }
hsgw 18:bac56d0365e1 100
hsgw 18:bac56d0365e1 101 // MIDI event handling
hsgw 18:bac56d0365e1 102 while (!circ_buf.isEmpty()) {
hsgw 18:bac56d0365e1 103 // read each four bytes
hsgw 18:bac56d0365e1 104 circ_buf.dequeue(&midi[pos++]);
hsgw 18:bac56d0365e1 105 if (pos == 4) {
hsgw 18:bac56d0365e1 106 pos = 0;
hsgw 18:bac56d0365e1 107
hsgw 18:bac56d0365e1 108 // process MIDI message
hsgw 18:bac56d0365e1 109 // switch by code index number
hsgw 18:bac56d0365e1 110 switch (midi[0] & 0xf) {
hsgw 18:bac56d0365e1 111 case 8:
hsgw 18:bac56d0365e1 112 noteOff(midi[1] & 0xf, midi[2], midi[3]);
hsgw 18:bac56d0365e1 113 break;
hsgw 18:bac56d0365e1 114 case 9:
hsgw 18:bac56d0365e1 115 if (midi[3]) {
hsgw 18:bac56d0365e1 116 noteOn(midi[1] & 0xf, midi[2], midi[3]);
hsgw 18:bac56d0365e1 117 } else {
hsgw 18:bac56d0365e1 118 noteOff(midi[1] & 0xf, midi[2], midi[3]);
hsgw 18:bac56d0365e1 119 }
hsgw 18:bac56d0365e1 120 break;
hsgw 18:bac56d0365e1 121 case 11:
hsgw 18:bac56d0365e1 122 controlChange(midi[1] & 0xf, midi[2], midi[3]);
hsgw 18:bac56d0365e1 123 break;
hsgw 18:bac56d0365e1 124 case 12:
hsgw 18:bac56d0365e1 125 programChange(midi[1] & 0xf, midi[2]);
hsgw 18:bac56d0365e1 126 break;
hsgw 18:bac56d0365e1 127 case 14:
hsgw 18:bac56d0365e1 128 pitchBend(midi[1] & 0xf, midi[2] | (midi[3] << 7));
hsgw 18:bac56d0365e1 129 break;
hsgw 18:bac56d0365e1 130 default:
hsgw 18:bac56d0365e1 131 break;
hsgw 18:bac56d0365e1 132 }
hsgw 18:bac56d0365e1 133 }
hsgw 18:bac56d0365e1 134 }
hsgw 18:bac56d0365e1 135
hsgw 18:bac56d0365e1 136 host->bulkRead(dev, bulk_in, buf, size_bulk_in, false);
hsgw 18:bac56d0365e1 137 }
hsgw 18:bac56d0365e1 138 }
hsgw 18:bac56d0365e1 139 }
hsgw 18:bac56d0365e1 140
hsgw 18:bac56d0365e1 141 int USBHostMIDI::sendNoteOn(unsigned char channel, unsigned char note, unsigned char velocity) {
hsgw 18:bac56d0365e1 142 uint8_t midi[4];
hsgw 18:bac56d0365e1 143
hsgw 18:bac56d0365e1 144 if (bulk_out) {
hsgw 18:bac56d0365e1 145 midi[0] = 9;
hsgw 18:bac56d0365e1 146 midi[1] = channel & 0xf;
hsgw 18:bac56d0365e1 147 midi[2] = note & 0x7f;
hsgw 18:bac56d0365e1 148 midi[3] = velocity & 0x7f;
hsgw 18:bac56d0365e1 149 if (host->bulkWrite(dev, bulk_out, (uint8_t *)midi, 4) == USB_TYPE_OK) {
hsgw 18:bac56d0365e1 150 return 1;
hsgw 18:bac56d0365e1 151 }
hsgw 18:bac56d0365e1 152 }
hsgw 18:bac56d0365e1 153 return -1;
hsgw 18:bac56d0365e1 154 }
hsgw 18:bac56d0365e1 155
hsgw 18:bac56d0365e1 156 int USBHostMIDI::sendNoteOff(unsigned char channel, unsigned char note, unsigned char velocity) {
hsgw 18:bac56d0365e1 157 uint8_t midi[4];
hsgw 18:bac56d0365e1 158
hsgw 18:bac56d0365e1 159 if (bulk_out) {
hsgw 18:bac56d0365e1 160 midi[0] = 8;
hsgw 18:bac56d0365e1 161 midi[1] = channel & 0xf;
hsgw 18:bac56d0365e1 162 midi[2] = note & 0x7f;
hsgw 18:bac56d0365e1 163 midi[3] = velocity & 0x7f;
hsgw 18:bac56d0365e1 164 if (host->bulkWrite(dev, bulk_out, (uint8_t *)midi, 4) == USB_TYPE_OK) {
hsgw 18:bac56d0365e1 165 return 1;
hsgw 18:bac56d0365e1 166 }
hsgw 18:bac56d0365e1 167 }
hsgw 18:bac56d0365e1 168 return -1;
hsgw 18:bac56d0365e1 169 }
hsgw 18:bac56d0365e1 170
hsgw 18:bac56d0365e1 171 int USBHostMIDI::sendControlChange(unsigned char channel, unsigned char key, unsigned char value) {
hsgw 18:bac56d0365e1 172 uint8_t midi[4];
hsgw 18:bac56d0365e1 173
hsgw 18:bac56d0365e1 174 if (bulk_out) {
hsgw 18:bac56d0365e1 175 midi[0] = 11;
hsgw 18:bac56d0365e1 176 midi[1] = channel & 0xf;
hsgw 18:bac56d0365e1 177 midi[2] = key & 0x7f;
hsgw 18:bac56d0365e1 178 midi[3] = value & 0x7f;
hsgw 18:bac56d0365e1 179 if (host->bulkWrite(dev, bulk_out, (uint8_t *)midi, 4) == USB_TYPE_OK) {
hsgw 18:bac56d0365e1 180 return 1;
hsgw 18:bac56d0365e1 181 }
hsgw 18:bac56d0365e1 182 }
hsgw 18:bac56d0365e1 183 return -1;
hsgw 18:bac56d0365e1 184 }
hsgw 18:bac56d0365e1 185
hsgw 18:bac56d0365e1 186 int USBHostMIDI::sendProgramChange(unsigned char channel, unsigned char program) {
hsgw 18:bac56d0365e1 187 uint8_t midi[4];
hsgw 18:bac56d0365e1 188
hsgw 18:bac56d0365e1 189 if (bulk_out) {
hsgw 18:bac56d0365e1 190 midi[0] = 12;
hsgw 18:bac56d0365e1 191 midi[1] = channel & 0xf;
hsgw 18:bac56d0365e1 192 midi[2] = program & 0x7f;
hsgw 18:bac56d0365e1 193 midi[3] = 0;
hsgw 18:bac56d0365e1 194 if (host->bulkWrite(dev, bulk_out, (uint8_t *)midi, 4) == USB_TYPE_OK) {
hsgw 18:bac56d0365e1 195 return 1;
hsgw 18:bac56d0365e1 196 }
hsgw 18:bac56d0365e1 197 }
hsgw 18:bac56d0365e1 198 return -1;
hsgw 18:bac56d0365e1 199 }
hsgw 18:bac56d0365e1 200
hsgw 18:bac56d0365e1 201 int USBHostMIDI::sendPitchBend(unsigned char channel, unsigned int value) {
hsgw 18:bac56d0365e1 202 uint8_t midi[4];
hsgw 18:bac56d0365e1 203
hsgw 18:bac56d0365e1 204 if (bulk_out) {
hsgw 18:bac56d0365e1 205 midi[0] = 14;
hsgw 18:bac56d0365e1 206 midi[1] = channel & 0xf;
hsgw 18:bac56d0365e1 207 midi[2] = value & 0x7f;
hsgw 18:bac56d0365e1 208 midi[3] = (value >> 7) & 0x7f;
hsgw 18:bac56d0365e1 209 if (host->bulkWrite(dev, bulk_out, (uint8_t *)midi, 4) == USB_TYPE_OK) {
hsgw 18:bac56d0365e1 210 return 1;
hsgw 18:bac56d0365e1 211 }
hsgw 18:bac56d0365e1 212 }
hsgw 18:bac56d0365e1 213 return -1;
hsgw 18:bac56d0365e1 214 }
hsgw 18:bac56d0365e1 215
hsgw 18:bac56d0365e1 216 void USBHostMIDI::poll()
hsgw 18:bac56d0365e1 217 {
hsgw 18:bac56d0365e1 218 host->poll();
hsgw 18:bac56d0365e1 219 }
hsgw 18:bac56d0365e1 220
hsgw 18:bac56d0365e1 221 /*virtual*/ void USBHostMIDI::setVidPid(uint16_t vid, uint16_t pid)
hsgw 18:bac56d0365e1 222 {
hsgw 18:bac56d0365e1 223 // we don't check VID/PID for this driver
hsgw 18:bac56d0365e1 224 }
hsgw 18:bac56d0365e1 225
hsgw 18:bac56d0365e1 226 /*virtual*/ bool USBHostMIDI::parseInterface(uint8_t intf_nb, uint8_t intf_class, uint8_t intf_subclass, uint8_t intf_protocol) //Must return true if the interface should be parsed
hsgw 18:bac56d0365e1 227 {
hsgw 18:bac56d0365e1 228 // USB MIDI class/subclass
hsgw 18:bac56d0365e1 229 if ((midi_intf == -1) &&
hsgw 18:bac56d0365e1 230 (intf_class == AUDIO_CLASS) &&
hsgw 18:bac56d0365e1 231 (intf_subclass == 0x03)) {
hsgw 18:bac56d0365e1 232 midi_intf = intf_nb;
hsgw 18:bac56d0365e1 233 return true;
hsgw 18:bac56d0365e1 234 }
hsgw 18:bac56d0365e1 235
hsgw 18:bac56d0365e1 236 // vendor specific device
hsgw 18:bac56d0365e1 237 if ((midi_intf == -1) &&
hsgw 18:bac56d0365e1 238 (intf_class == 0xff) &&
hsgw 18:bac56d0365e1 239 (intf_subclass == 0x03)) {
hsgw 18:bac56d0365e1 240 midi_intf = intf_nb;
hsgw 18:bac56d0365e1 241 return true;
hsgw 18:bac56d0365e1 242 }
hsgw 18:bac56d0365e1 243
hsgw 18:bac56d0365e1 244 return false;
hsgw 18:bac56d0365e1 245 }
hsgw 18:bac56d0365e1 246
hsgw 18:bac56d0365e1 247 /*virtual*/ bool USBHostMIDI::useEndpoint(uint8_t intf_nb, ENDPOINT_TYPE type, ENDPOINT_DIRECTION dir) //Must return true if the endpoint will be used
hsgw 18:bac56d0365e1 248 {
hsgw 18:bac56d0365e1 249 if (intf_nb == midi_intf) {
hsgw 18:bac56d0365e1 250 if (type == BULK_ENDPOINT) {
hsgw 18:bac56d0365e1 251 midi_device_found = true;
hsgw 18:bac56d0365e1 252 return true;
hsgw 18:bac56d0365e1 253 }
hsgw 18:bac56d0365e1 254 }
hsgw 18:bac56d0365e1 255 return false;
hsgw 18:bac56d0365e1 256 }
hsgw 18:bac56d0365e1 257
hsgw 18:bac56d0365e1 258 #endif