ST/USBHOST forked to add another HID handler for raw keyboard data to get more detail not available with current handlers (all pressed keys, all releases, and periodic updates)

Dependents:   C64-stm429_discovery

Committer:
davervw
Date:
Mon Apr 13 05:25:10 2020 +0000
Revision:
7:9dc1cb9d5e12
Parent:
1:ab240722d7ef
Added handler to USBHostHID/USBHostKeyboard.cpp:;    void (*onKeyData)(uint8_t len, uint8_t* data);; so can get raw keyboard data for all keys simultaneously pressed, and all releases and periodic data

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
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 27 USBHostMIDI::USBHostMIDI() {
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 28 host = USBHost::getHostInst();
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 29 size_bulk_in = 0;
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 30 size_bulk_out = 0;
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 31 init();
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 32 }
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 33
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 34 void USBHostMIDI::init() {
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 35 dev = NULL;
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 36 bulk_in = NULL;
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 37 bulk_out = NULL;
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 38 dev_connected = false;
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 39 midi_intf = -1;
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 40 midi_device_found = false;
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 41 sysExBufferPos = 0;
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 42 }
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 43
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 44 bool USBHostMIDI::connected() {
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 45 return dev_connected;
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 46 }
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 47
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 48 bool USBHostMIDI::connect() {
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 49 if (dev_connected) {
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 50 return true;
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 51 }
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 52
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 53 for (uint8_t i = 0; i < MAX_DEVICE_CONNECTED; i++) {
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 54 if ((dev = host->getDevice(i)) != NULL) {
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 55
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 56 USB_DBG("Trying to connect MIDI device\r\n");
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 57
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 58 if (host->enumerate(dev, this)) {
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 59 break;
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 60 }
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 61
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 62 if (midi_device_found) {
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 63 bulk_in = dev->getEndpoint(midi_intf, BULK_ENDPOINT, IN);
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 64 bulk_out = dev->getEndpoint(midi_intf, BULK_ENDPOINT, OUT);
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 65
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 66 if (!bulk_in || !bulk_out) {
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 67 break;
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 68 }
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 69
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 70 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 71 dev->setName("MIDI", midi_intf);
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 72 host->registerDriver(dev, midi_intf, this, &USBHostMIDI::init);
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 73
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 74 size_bulk_in = bulk_in->getSize();
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 75 size_bulk_out = bulk_out->getSize();
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 76
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 77 bulk_in->attach(this, &USBHostMIDI::rxHandler);
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 78
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 79 host->bulkRead(dev, bulk_in, buf, size_bulk_in, false);
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 80 dev_connected = true;
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 81 return true;
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 82 }
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 83 }
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 84 }
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 85
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 86 init();
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 87 return false;
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 88 }
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 89
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 90 void USBHostMIDI::rxHandler() {
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 91 uint8_t *midi;
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 92 if (bulk_in) {
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 93 int length = bulk_in->getLengthTransferred();
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 94 if (bulk_in->getState() == USB_TYPE_IDLE || bulk_in->getState() == USB_TYPE_FREE) {
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 95 // MIDI event handling
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 96 for (int i = 0; i < length; i += 4) {
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 97 if (i + 4 > length) {
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 98 // length shortage, ignored.
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 99 break;
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 100 }
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 101
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 102 // read each four bytes
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 103 midi = &buf[i];
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 104 // process MIDI message
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 105 // switch by code index number
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 106 switch (midi[0] & 0xf) {
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 107 case 0: // miscellaneous function codes
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 108 miscellaneousFunctionCode(midi[1], midi[2], midi[3]);
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 109 break;
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 110 case 1: // cable events
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 111 cableEvent(midi[1], midi[2], midi[3]);
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 112 break;
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 113 case 2: // two bytes system common messages
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 114 systemCommonTwoBytes(midi[1], midi[2]);
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 115 break;
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 116 case 3: // three bytes system common messages
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 117 systemCommonThreeBytes(midi[1], midi[2], midi[3]);
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 118 break;
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 119 case 4: // SysEx starts or continues
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 120 sysExBuffer[sysExBufferPos++] = midi[1];
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 121 if (sysExBufferPos >= 64) {
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 122 systemExclusive(sysExBuffer, sysExBufferPos, true);
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 123 sysExBufferPos = 0;
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 124 }
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 125 sysExBuffer[sysExBufferPos++] = midi[2];
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 126 if (sysExBufferPos >= 64) {
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 127 systemExclusive(sysExBuffer, sysExBufferPos, true);
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 128 sysExBufferPos = 0;
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 129 }
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 130 sysExBuffer[sysExBufferPos++] = midi[3];
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 131 // SysEx continues. don't send
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 132 break;
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 133 case 5: // SysEx ends with single byte
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 134 sysExBuffer[sysExBufferPos++] = midi[1];
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 135 systemExclusive(sysExBuffer, sysExBufferPos, false);
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 136 sysExBufferPos = 0;
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 137 break;
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 138 case 6: // SysEx ends with two bytes
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 139 sysExBuffer[sysExBufferPos++] = midi[1];
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 140 if (sysExBufferPos >= 64) {
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 141 systemExclusive(sysExBuffer, sysExBufferPos, true);
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 142 sysExBufferPos = 0;
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 143 }
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 144 sysExBuffer[sysExBufferPos++] = midi[2];
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 145 systemExclusive(sysExBuffer, sysExBufferPos, false);
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 146 sysExBufferPos = 0;
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 147 break;
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 148 case 7: // SysEx ends with three bytes
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 149 sysExBuffer[sysExBufferPos++] = midi[1];
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 150 if (sysExBufferPos >= 64) {
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 151 systemExclusive(sysExBuffer, sysExBufferPos, true);
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 152 sysExBufferPos = 0;
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 153 }
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 154 sysExBuffer[sysExBufferPos++] = midi[2];
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 155 if (sysExBufferPos >= 64) {
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 156 systemExclusive(sysExBuffer, sysExBufferPos, true);
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 157 sysExBufferPos = 0;
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 158 }
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 159 sysExBuffer[sysExBufferPos++] = midi[3];
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 160 systemExclusive(sysExBuffer, sysExBufferPos, false);
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 161 sysExBufferPos = 0;
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 162 break;
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 163 case 8:
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 164 noteOff(midi[1] & 0xf, midi[2], midi[3]);
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 165 break;
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 166 case 9:
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 167 if (midi[3]) {
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 168 noteOn(midi[1] & 0xf, midi[2], midi[3]);
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 169 } else {
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 170 noteOff(midi[1] & 0xf, midi[2], midi[3]);
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 171 }
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 172 break;
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 173 case 10:
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 174 polyKeyPress(midi[1] & 0xf, midi[2], midi[3]);
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 175 break;
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 176 case 11:
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 177 controlChange(midi[1] & 0xf, midi[2], midi[3]);
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 178 break;
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 179 case 12:
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 180 programChange(midi[1] & 0xf, midi[2]);
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 181 break;
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 182 case 13:
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 183 channelPressure(midi[1] & 0xf, midi[2]);
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 184 break;
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 185 case 14:
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 186 pitchBend(midi[1] & 0xf, midi[2] | (midi[3] << 7));
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 187 break;
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 188 case 15:
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 189 singleByte(midi[1]);
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 190 break;
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 191 }
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 192 }
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 193
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 194 // read another message
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 195 host->bulkRead(dev, bulk_in, buf, size_bulk_in, false);
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 196 }
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 197 }
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 198 }
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 199
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 200 bool USBHostMIDI::sendMidiBuffer(uint8_t data0, uint8_t data1, uint8_t data2, uint8_t data3) {
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 201 if (bulk_out) {
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 202 uint8_t midi[4];
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 203
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 204 midi[0] = data0;
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 205 midi[1] = data1;
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 206 midi[2] = data2;
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 207 midi[3] = data3;
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 208 if (host->bulkWrite(dev, bulk_out, (uint8_t *)midi, 4) == USB_TYPE_OK) {
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 209 return true;
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 210 }
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 211 }
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 212 return false;
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 213 }
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 214
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 215 bool USBHostMIDI::sendMiscellaneousFunctionCode(uint8_t data1, uint8_t data2, uint8_t data3) {
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 216 return sendMidiBuffer(0, data1, data2, data3);
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 217 }
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 218
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 219 bool USBHostMIDI::sendCableEvent(uint8_t data1, uint8_t data2, uint8_t data3) {
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 220 return sendMidiBuffer(1, data1, data2, data3);
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 221 }
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 222
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 223 bool USBHostMIDI::sendSystemCommmonTwoBytes(uint8_t data1, uint8_t data2) {
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 224 return sendMidiBuffer(2, data1, data2, 0);
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 225 }
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 226
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 227 bool USBHostMIDI::sendSystemCommmonThreeBytes(uint8_t data1, uint8_t data2, uint8_t data3) {
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 228 return sendMidiBuffer(3, data1, data2, 0);
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 229 }
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 230
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 231 bool USBHostMIDI::sendSystemExclusive(uint8_t *buffer, int length) {
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 232 uint8_t midi[64];
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 233 int midiLength;
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 234 int midiPos;
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 235 if (bulk_out) {
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 236 for (int i = 0; i < length; i += 48) {
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 237 if (i + 48 >= length) {
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 238 // contains last data
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 239 midiLength = (((length - i) + 2) / 3) * 4;
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 240 for (int pos = i; pos < length; pos += 3) {
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 241 midiPos = (pos + 2) / 3 * 4;
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 242 if (pos + 3 >= length) {
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 243 // last data
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 244 switch (pos % 3) {
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 245 case 0:
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 246 midi[midiPos ] = 7;
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 247 midi[midiPos + 1] = buffer[pos ];
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 248 midi[midiPos + 2] = buffer[pos + 1];
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 249 midi[midiPos + 3] = buffer[pos + 2];
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 250 break;
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 251 case 1:
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 252 midi[midiPos ] = 5;
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 253 midi[midiPos + 1] = buffer[pos ];
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 254 midi[midiPos + 2] = 0;
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 255 midi[midiPos + 3] = 0;
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 256 break;
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 257 case 2:
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 258 midi[midiPos ] = 6;
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 259 midi[midiPos + 1] = buffer[pos ];
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 260 midi[midiPos + 2] = buffer[pos + 1];
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 261 midi[midiPos + 3] = 0;
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 262 break;
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 263 }
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 264 } else {
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 265 // has more data
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 266 midi[midiPos ] = 4;
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 267 midi[midiPos + 1] = buffer[pos ];
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 268 midi[midiPos + 2] = buffer[pos + 1];
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 269 midi[midiPos + 3] = buffer[pos + 2];
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 270 }
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 271 }
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 272 } else {
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 273 // has more data
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 274 midiLength = 64;
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 275 for (int pos = i; pos < length; pos += 3) {
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 276 midiPos = (pos + 2) / 3 * 4;
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 277 midi[midiPos ] = 4;
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 278 midi[midiPos + 1] = buffer[pos ];
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 279 midi[midiPos + 2] = buffer[pos + 1];
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 280 midi[midiPos + 3] = buffer[pos + 2];
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 281 }
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 282 }
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 283
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 284 if (host->bulkWrite(dev, bulk_out, (uint8_t *)midi, midiLength) != USB_TYPE_OK) {
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 285 return false;
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 286 }
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 287 }
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 288 return true;
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 289 }
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 290 return false;
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 291 }
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 292
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 293 bool USBHostMIDI::sendNoteOff(uint8_t channel, uint8_t note, uint8_t velocity) {
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 294 return sendMidiBuffer(8, channel & 0xf | 0x80, note & 0x7f, velocity & 0x7f);
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 295 }
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 296
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 297 bool USBHostMIDI::sendNoteOn(uint8_t channel, uint8_t note, uint8_t velocity) {
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 298 return sendMidiBuffer(9, channel & 0xf | 0x90, note & 0x7f, velocity & 0x7f);
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 299 }
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 300
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 301 bool USBHostMIDI::sendPolyKeyPress(uint8_t channel, uint8_t note, uint8_t pressure) {
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 302 return sendMidiBuffer(10, channel & 0xf | 0xa0, note & 0x7f, pressure & 0x7f);
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 303 }
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 304
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 305 bool USBHostMIDI::sendControlChange(uint8_t channel, uint8_t key, uint8_t value) {
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 306 return sendMidiBuffer(11, channel & 0xf | 0xb0, key & 0x7f, value & 0x7f);
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 307 }
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 308
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 309 bool USBHostMIDI::sendProgramChange(uint8_t channel, uint8_t program) {
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 310 return sendMidiBuffer(12, channel & 0xf | 0xc0, program & 0x7f, 0);
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 311 }
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 312
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 313 bool USBHostMIDI::sendChannelPressure(uint8_t channel, uint8_t pressure) {
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 314 return sendMidiBuffer(13, channel & 0xf | 0xd0, pressure & 0x7f, 0);
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 315 }
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 316
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 317 bool USBHostMIDI::sendPitchBend(uint8_t channel, uint16_t value) {
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 318 return sendMidiBuffer(14, channel & 0xf | 0xe0, value & 0x7f, (value >> 7) & 0x7f);
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 319 }
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 320
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 321 bool USBHostMIDI::sendSingleByte(uint8_t data) {
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 322 return sendMidiBuffer(15, data, 0, 0);
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 323 }
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 324
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 325 /*virtual*/ void USBHostMIDI::setVidPid(uint16_t vid, uint16_t pid)
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 326 {
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 327 // we don't check VID/PID for this driver
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 328 }
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 329
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 330 /*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 331 {
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 332 // USB MIDI class/subclass
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 333 if ((midi_intf == -1) &&
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 334 (intf_class == AUDIO_CLASS) &&
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 335 (intf_subclass == 0x03)) {
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 336 midi_intf = intf_nb;
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 337 return true;
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 338 }
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 339
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 340 // vendor specific device
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 341 if ((midi_intf == -1) &&
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 342 (intf_class == 0xff) &&
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 343 (intf_subclass == 0x03)) {
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 344 midi_intf = intf_nb;
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
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 348 return false;
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 349 }
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 350
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 351 /*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 352 {
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 353 if (intf_nb == midi_intf) {
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 354 if (type == BULK_ENDPOINT) {
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 355 midi_device_found = true;
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 356 return true;
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 357 }
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 358 }
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 359 return false;
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 360 }
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 361
frq08711@LMECWL0871.LME.ST.COM 1:ab240722d7ef 362 #endif