mbed USBHostMIDI improved. function pointer initialization and null checking

Committer:
kazbo
Date:
Fri May 10 11:23:49 2019 +0000
Revision:
7:264794e7fed1
Parent:
1:ab240722d7ef
mbed USBHostMIDI improved. function pointer initialization and NULL checking;

Who changed what in which revision?

UserRevisionLine numberNew contents of line
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 1 /* Copyright (c) 2014 mbed.org, MIT License
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 2 *
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 3 * Permission is hereby granted, free of charge, to any person obtaining a copy of this software
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 4 * and associated documentation files (the "Software"), to deal in the Software without
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 5 * restriction, including without limitation the rights to use, copy, modify, merge, publish,
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 6 * distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 7 * Software is furnished to do so, subject to the following conditions:
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 8 *
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 9 * The above copyright notice and this permission notice shall be included in all copies or
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 10 * substantial portions of the Software.
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 11 *
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 12 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 13 * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 14 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 15 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 16 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 17 */
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 18
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 19 #include "USBHostMIDI.h"
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 20
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 21 #if USBHOST_MIDI
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 22
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 23 #include "dbg.h"
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 24
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 25 #define SET_LINE_CODING 0x20
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 26
kazbo 7:264794e7fed1 27 USBHostMIDI::USBHostMIDI() :
kazbo 7:264794e7fed1 28 miscellaneousFunctionCode(NULL),
kazbo 7:264794e7fed1 29 cableEvent(NULL),
kazbo 7:264794e7fed1 30 systemCommonTwoBytes(NULL),
kazbo 7:264794e7fed1 31 systemCommonThreeBytes(NULL),
kazbo 7:264794e7fed1 32 systemExclusive(NULL),
kazbo 7:264794e7fed1 33 noteOff(NULL),
kazbo 7:264794e7fed1 34 noteOn(NULL),
kazbo 7:264794e7fed1 35 polyKeyPress(NULL),
kazbo 7:264794e7fed1 36 controlChange(NULL),
kazbo 7:264794e7fed1 37 programChange(NULL),
kazbo 7:264794e7fed1 38 channelPressure(NULL),
kazbo 7:264794e7fed1 39 pitchBend(NULL),
kazbo 7:264794e7fed1 40 singleByte(NULL) {
kazbo 7:264794e7fed1 41 host = USBHost::getHostInst();
kazbo 7:264794e7fed1 42 size_bulk_in = 0;
kazbo 7:264794e7fed1 43 size_bulk_out = 0;
kazbo 7:264794e7fed1 44 init();
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 45 }
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 46
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 47 void USBHostMIDI::init() {
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 48 dev = NULL;
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 49 bulk_in = NULL;
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 50 bulk_out = NULL;
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 51 dev_connected = false;
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 52 midi_intf = -1;
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 53 midi_device_found = false;
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 54 sysExBufferPos = 0;
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 55 }
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 56
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 57 bool USBHostMIDI::connected() {
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 58 return dev_connected;
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 59 }
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 60
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 61 bool USBHostMIDI::connect() {
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 62 if (dev_connected) {
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 63 return true;
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 64 }
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 65
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 66 for (uint8_t i = 0; i < MAX_DEVICE_CONNECTED; i++) {
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 67 if ((dev = host->getDevice(i)) != NULL) {
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 68
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 69 USB_DBG("Trying to connect MIDI device\r\n");
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 70
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 71 if (host->enumerate(dev, this)) {
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 72 break;
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 73 }
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 74
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 75 if (midi_device_found) {
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 76 bulk_in = dev->getEndpoint(midi_intf, BULK_ENDPOINT, IN);
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 77 bulk_out = dev->getEndpoint(midi_intf, BULK_ENDPOINT, OUT);
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 78
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 79 if (!bulk_in || !bulk_out) {
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 80 break;
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 81 }
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 82
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 83 USB_INFO("New MIDI device: VID:%04x PID:%04x [dev: %p - intf: %d]", dev->getVid(), dev->getPid(), dev, midi_intf);
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 84 dev->setName("MIDI", midi_intf);
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 85 host->registerDriver(dev, midi_intf, this, &USBHostMIDI::init);
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 86
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 87 size_bulk_in = bulk_in->getSize();
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 88 size_bulk_out = bulk_out->getSize();
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 89
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 90 bulk_in->attach(this, &USBHostMIDI::rxHandler);
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 91
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 92 host->bulkRead(dev, bulk_in, buf, size_bulk_in, false);
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 93 dev_connected = true;
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 94 return true;
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 95 }
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 96 }
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 97 }
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 98
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 99 init();
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 100 return false;
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 101 }
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 102
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 103 void USBHostMIDI::rxHandler() {
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 104 uint8_t *midi;
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 105 if (bulk_in) {
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 106 int length = bulk_in->getLengthTransferred();
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 107 if (bulk_in->getState() == USB_TYPE_IDLE || bulk_in->getState() == USB_TYPE_FREE) {
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 108 // MIDI event handling
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 109 for (int i = 0; i < length; i += 4) {
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 110 if (i + 4 > length) {
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 111 // length shortage, ignored.
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 112 break;
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 113 }
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 114
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 115 // read each four bytes
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 116 midi = &buf[i];
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 117 // process MIDI message
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 118 // switch by code index number
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 119 switch (midi[0] & 0xf) {
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 120 case 0: // miscellaneous function codes
kazbo 7:264794e7fed1 121 if (miscellaneousFunctionCode) {
kazbo 7:264794e7fed1 122 miscellaneousFunctionCode(midi[1], midi[2], midi[3]);
kazbo 7:264794e7fed1 123 }
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 124 break;
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 125 case 1: // cable events
kazbo 7:264794e7fed1 126 if (cableEvent) {
kazbo 7:264794e7fed1 127 cableEvent(midi[1], midi[2], midi[3]);
kazbo 7:264794e7fed1 128 }
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 129 break;
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 130 case 2: // two bytes system common messages
kazbo 7:264794e7fed1 131 if (systemCommonTwoBytes) {
kazbo 7:264794e7fed1 132 systemCommonTwoBytes(midi[1], midi[2]);
kazbo 7:264794e7fed1 133 }
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 134 break;
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 135 case 3: // three bytes system common messages
kazbo 7:264794e7fed1 136 if (systemCommonThreeBytes) {
kazbo 7:264794e7fed1 137 systemCommonThreeBytes(midi[1], midi[2], midi[3]);
kazbo 7:264794e7fed1 138 }
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 139 break;
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 140 case 4: // SysEx starts or continues
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 141 sysExBuffer[sysExBufferPos++] = midi[1];
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 142 if (sysExBufferPos >= 64) {
kazbo 7:264794e7fed1 143 if (systemExclusive) {
kazbo 7:264794e7fed1 144 systemExclusive(sysExBuffer, sysExBufferPos, true);
kazbo 7:264794e7fed1 145 }
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 146 sysExBufferPos = 0;
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 147 }
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 148 sysExBuffer[sysExBufferPos++] = midi[2];
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 149 if (sysExBufferPos >= 64) {
kazbo 7:264794e7fed1 150 if (systemExclusive) {
kazbo 7:264794e7fed1 151 systemExclusive(sysExBuffer, sysExBufferPos, true);
kazbo 7:264794e7fed1 152 }
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 153 sysExBufferPos = 0;
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 154 }
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 155 sysExBuffer[sysExBufferPos++] = midi[3];
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 156 // SysEx continues. don't send
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 157 break;
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 158 case 5: // SysEx ends with single byte
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 159 sysExBuffer[sysExBufferPos++] = midi[1];
kazbo 7:264794e7fed1 160 if (systemExclusive) {
kazbo 7:264794e7fed1 161 systemExclusive(sysExBuffer, sysExBufferPos, false);
kazbo 7:264794e7fed1 162 }
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 163 sysExBufferPos = 0;
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 164 break;
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 165 case 6: // SysEx ends with two bytes
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 166 sysExBuffer[sysExBufferPos++] = midi[1];
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 167 if (sysExBufferPos >= 64) {
kazbo 7:264794e7fed1 168 if (systemExclusive) {
kazbo 7:264794e7fed1 169 systemExclusive(sysExBuffer, sysExBufferPos, true);
kazbo 7:264794e7fed1 170 }
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 171 sysExBufferPos = 0;
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 172 }
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 173 sysExBuffer[sysExBufferPos++] = midi[2];
kazbo 7:264794e7fed1 174
kazbo 7:264794e7fed1 175 if (systemExclusive) {
kazbo 7:264794e7fed1 176 systemExclusive(sysExBuffer, sysExBufferPos, false);
kazbo 7:264794e7fed1 177 }
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 178 sysExBufferPos = 0;
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 179 break;
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 180 case 7: // SysEx ends with three bytes
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 181 sysExBuffer[sysExBufferPos++] = midi[1];
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 182 if (sysExBufferPos >= 64) {
kazbo 7:264794e7fed1 183 if (systemExclusive) {
kazbo 7:264794e7fed1 184 systemExclusive(sysExBuffer, sysExBufferPos, true);
kazbo 7:264794e7fed1 185 }
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 186 sysExBufferPos = 0;
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 187 }
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 188 sysExBuffer[sysExBufferPos++] = midi[2];
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 189 if (sysExBufferPos >= 64) {
kazbo 7:264794e7fed1 190 if (systemExclusive) {
kazbo 7:264794e7fed1 191 systemExclusive(sysExBuffer, sysExBufferPos, true);
kazbo 7:264794e7fed1 192 }
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 193 sysExBufferPos = 0;
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 194 }
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 195 sysExBuffer[sysExBufferPos++] = midi[3];
kazbo 7:264794e7fed1 196
kazbo 7:264794e7fed1 197 if (systemExclusive) {
kazbo 7:264794e7fed1 198 systemExclusive(sysExBuffer, sysExBufferPos, false);
kazbo 7:264794e7fed1 199 }
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 200 sysExBufferPos = 0;
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 201 break;
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 202 case 8:
kazbo 7:264794e7fed1 203 if (noteOff) {
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 204 noteOff(midi[1] & 0xf, midi[2], midi[3]);
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 205 }
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 206 break;
kazbo 7:264794e7fed1 207 case 9:
kazbo 7:264794e7fed1 208 if (midi[3]) {
kazbo 7:264794e7fed1 209 if (noteOn) {
kazbo 7:264794e7fed1 210 noteOn(midi[1] & 0xf, midi[2], midi[3]);
kazbo 7:264794e7fed1 211 }
kazbo 7:264794e7fed1 212 } else {
kazbo 7:264794e7fed1 213 if (noteOff) {
kazbo 7:264794e7fed1 214 noteOff(midi[1] & 0xf, midi[2], midi[3]);
kazbo 7:264794e7fed1 215 }
kazbo 7:264794e7fed1 216 }
kazbo 7:264794e7fed1 217 break;
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 218 case 10:
kazbo 7:264794e7fed1 219 if (polyKeyPress) {
kazbo 7:264794e7fed1 220 polyKeyPress(midi[1] & 0xf, midi[2], midi[3]);
kazbo 7:264794e7fed1 221 }
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 222 break;
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 223 case 11:
kazbo 7:264794e7fed1 224 if (controlChange) {
kazbo 7:264794e7fed1 225 controlChange(midi[1] & 0xf, midi[2], midi[3]);
kazbo 7:264794e7fed1 226 }
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 227 break;
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 228 case 12:
kazbo 7:264794e7fed1 229 if (programChange) {
kazbo 7:264794e7fed1 230 programChange(midi[1] & 0xf, midi[2]);
kazbo 7:264794e7fed1 231 }
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 232 break;
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 233 case 13:
kazbo 7:264794e7fed1 234 if (channelPressure) {
kazbo 7:264794e7fed1 235 channelPressure(midi[1] & 0xf, midi[2]);
kazbo 7:264794e7fed1 236 }
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 237 break;
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 238 case 14:
kazbo 7:264794e7fed1 239 if (pitchBend) {
kazbo 7:264794e7fed1 240 pitchBend(midi[1] & 0xf, midi[2] | (midi[3] << 7));
kazbo 7:264794e7fed1 241 }
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 242 break;
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 243 case 15:
kazbo 7:264794e7fed1 244 if (singleByte) {
kazbo 7:264794e7fed1 245 singleByte(midi[1]);
kazbo 7:264794e7fed1 246 }
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 247 break;
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 248 }
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 249 }
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 250
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 251 // read another message
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 252 host->bulkRead(dev, bulk_in, buf, size_bulk_in, false);
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 253 }
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 254 }
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 255 }
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 256
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 257 bool USBHostMIDI::sendMidiBuffer(uint8_t data0, uint8_t data1, uint8_t data2, uint8_t data3) {
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 258 if (bulk_out) {
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 259 uint8_t midi[4];
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 260
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 261 midi[0] = data0;
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 262 midi[1] = data1;
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 263 midi[2] = data2;
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 264 midi[3] = data3;
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 265 if (host->bulkWrite(dev, bulk_out, (uint8_t *)midi, 4) == USB_TYPE_OK) {
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 266 return true;
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 267 }
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 268 }
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 269 return false;
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 270 }
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 271
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 272 bool USBHostMIDI::sendMiscellaneousFunctionCode(uint8_t data1, uint8_t data2, uint8_t data3) {
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 273 return sendMidiBuffer(0, data1, data2, data3);
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 274 }
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 275
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 276 bool USBHostMIDI::sendCableEvent(uint8_t data1, uint8_t data2, uint8_t data3) {
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 277 return sendMidiBuffer(1, data1, data2, data3);
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 278 }
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 279
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 280 bool USBHostMIDI::sendSystemCommmonTwoBytes(uint8_t data1, uint8_t data2) {
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 281 return sendMidiBuffer(2, data1, data2, 0);
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 282 }
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 283
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 284 bool USBHostMIDI::sendSystemCommmonThreeBytes(uint8_t data1, uint8_t data2, uint8_t data3) {
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 285 return sendMidiBuffer(3, data1, data2, 0);
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 286 }
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 287
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 288 bool USBHostMIDI::sendSystemExclusive(uint8_t *buffer, int length) {
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 289 uint8_t midi[64];
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 290 int midiLength;
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 291 int midiPos;
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 292 if (bulk_out) {
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 293 for (int i = 0; i < length; i += 48) {
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 294 if (i + 48 >= length) {
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 295 // contains last data
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 296 midiLength = (((length - i) + 2) / 3) * 4;
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 297 for (int pos = i; pos < length; pos += 3) {
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 298 midiPos = (pos + 2) / 3 * 4;
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 299 if (pos + 3 >= length) {
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 300 // last data
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 301 switch (pos % 3) {
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 302 case 0:
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 303 midi[midiPos ] = 7;
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 304 midi[midiPos + 1] = buffer[pos ];
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 305 midi[midiPos + 2] = buffer[pos + 1];
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 306 midi[midiPos + 3] = buffer[pos + 2];
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 307 break;
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 308 case 1:
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 309 midi[midiPos ] = 5;
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 310 midi[midiPos + 1] = buffer[pos ];
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 311 midi[midiPos + 2] = 0;
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 312 midi[midiPos + 3] = 0;
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 313 break;
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 314 case 2:
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 315 midi[midiPos ] = 6;
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 316 midi[midiPos + 1] = buffer[pos ];
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 317 midi[midiPos + 2] = buffer[pos + 1];
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 318 midi[midiPos + 3] = 0;
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 319 break;
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 320 }
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 321 } else {
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 322 // has more data
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 323 midi[midiPos ] = 4;
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 324 midi[midiPos + 1] = buffer[pos ];
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 325 midi[midiPos + 2] = buffer[pos + 1];
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 326 midi[midiPos + 3] = buffer[pos + 2];
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 327 }
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 328 }
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 329 } else {
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 330 // has more data
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 331 midiLength = 64;
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 332 for (int pos = i; pos < length; pos += 3) {
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 333 midiPos = (pos + 2) / 3 * 4;
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 334 midi[midiPos ] = 4;
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 335 midi[midiPos + 1] = buffer[pos ];
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 336 midi[midiPos + 2] = buffer[pos + 1];
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 337 midi[midiPos + 3] = buffer[pos + 2];
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 338 }
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 339 }
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 340
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 341 if (host->bulkWrite(dev, bulk_out, (uint8_t *)midi, midiLength) != USB_TYPE_OK) {
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 342 return false;
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 343 }
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 344 }
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 345 return true;
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 346 }
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 347 return false;
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 348 }
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 349
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 350 bool USBHostMIDI::sendNoteOff(uint8_t channel, uint8_t note, uint8_t velocity) {
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 351 return sendMidiBuffer(8, channel & 0xf | 0x80, note & 0x7f, velocity & 0x7f);
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 352 }
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 353
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 354 bool USBHostMIDI::sendNoteOn(uint8_t channel, uint8_t note, uint8_t velocity) {
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 355 return sendMidiBuffer(9, channel & 0xf | 0x90, note & 0x7f, velocity & 0x7f);
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 356 }
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 357
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 358 bool USBHostMIDI::sendPolyKeyPress(uint8_t channel, uint8_t note, uint8_t pressure) {
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 359 return sendMidiBuffer(10, channel & 0xf | 0xa0, note & 0x7f, pressure & 0x7f);
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 360 }
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 361
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 362 bool USBHostMIDI::sendControlChange(uint8_t channel, uint8_t key, uint8_t value) {
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 363 return sendMidiBuffer(11, channel & 0xf | 0xb0, key & 0x7f, value & 0x7f);
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 364 }
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 365
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 366 bool USBHostMIDI::sendProgramChange(uint8_t channel, uint8_t program) {
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 367 return sendMidiBuffer(12, channel & 0xf | 0xc0, program & 0x7f, 0);
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 368 }
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 369
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 370 bool USBHostMIDI::sendChannelPressure(uint8_t channel, uint8_t pressure) {
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 371 return sendMidiBuffer(13, channel & 0xf | 0xd0, pressure & 0x7f, 0);
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 372 }
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 373
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 374 bool USBHostMIDI::sendPitchBend(uint8_t channel, uint16_t value) {
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 375 return sendMidiBuffer(14, channel & 0xf | 0xe0, value & 0x7f, (value >> 7) & 0x7f);
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 376 }
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 377
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 378 bool USBHostMIDI::sendSingleByte(uint8_t data) {
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 379 return sendMidiBuffer(15, data, 0, 0);
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 380 }
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 381
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 382 /*virtual*/ void USBHostMIDI::setVidPid(uint16_t vid, uint16_t pid)
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 383 {
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 384 // we don't check VID/PID for this driver
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 385 }
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 386
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 387 /*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
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 388 {
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 389 // USB MIDI class/subclass
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 390 if ((midi_intf == -1) &&
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 391 (intf_class == AUDIO_CLASS) &&
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 392 (intf_subclass == 0x03)) {
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 393 midi_intf = intf_nb;
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 394 return true;
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 395 }
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 396
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 397 // vendor specific device
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 398 if ((midi_intf == -1) &&
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 399 (intf_class == 0xff) &&
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 400 (intf_subclass == 0x03)) {
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 401 midi_intf = intf_nb;
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 402 return true;
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 403 }
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 404
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 405 return false;
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 406 }
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 407
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 408 /*virtual*/ bool USBHostMIDI::useEndpoint(uint8_t intf_nb, ENDPOINT_TYPE type, ENDPOINT_DIRECTION dir) //Must return true if the endpoint will be used
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 409 {
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 410 if (intf_nb == midi_intf) {
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 411 if (type == BULK_ENDPOINT) {
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 412 midi_device_found = true;
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 413 return true;
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 414 }
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 415 }
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 416 return false;
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 417 }
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 418
kazbo 7:264794e7fed1 419 #endif