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 Sep 17 14:29:11 2014 +0000
Revision:
23:9c1d09c6a2b6
Parent:
22:81d8c59d1070
Child:
24:5281ea9f6e68
revert rev20

Who changed what in which revision?

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