Library to use Arduino USB host shield on mbed

Dependents:   USBHOST_PS5

ArduinoのUSB Host Shield 2.0をmbedで使えるようにしたライブラリです。
大体のコードがArduinoからそのまま移植可能です。

Arduino UNOやMega用のホストシールド以外にもミニサイズのホストシールドでも使用可能です https://os.mbed.com/media/uploads/kotakku/dffgfddswa.png

シールドについて

3.3VのI/O用にシールドの改造が必要になりますがネット上に記事がたくさんあるのでそちらを参考にしてください

接続例

https://os.mbed.com/media/uploads/kotakku/esgsvfvhjrekldkcjxvb.png

使い方

Arduinoのコードと違うのはUSBのインスタンスの宣言部分のみです。
ピンを自分で指定できるようにしたので使いやすくなりました。

仕様

  • Arduinoのmillis関数、micros関数の移植のために内部でTimerクラスを使用しています。

main.cpp

#include "mbed.h"
#include <PS3BT.h>
#include <usbhub.h>

Serial pc(USBTX, USBRX, 115200);

//Nucleo f303k8用
USB Usb(A6, A5, A4, A3, A2); // mosi, miso, sclk, ssel, intr
BTD Btd(&Usb);
PS3BT PS3(&Btd);

int main()
{
    bool printAngle = false;

    if (Usb.Init() == -1)
    {
        pc.printf("\r\nOSC did not start");
        while (1); // Halt
    }
    pc.printf("\r\nPS3 USB Library Started");

    while (1)
    {
        Usb.Task();
        
        if (PS3.PS3Connected || PS3.PS3NavigationConnected) {
            if (PS3.getAnalogHat(LeftHatX) > 137 || PS3.getAnalogHat(LeftHatX) < 117 || PS3.getAnalogHat(LeftHatY) > 137 || PS3.getAnalogHat(LeftHatY) < 117 || PS3.getAnalogHat(RightHatX) > 137 || PS3.getAnalogHat(RightHatX) < 117 || PS3.getAnalogHat(RightHatY) > 137 || PS3.getAnalogHat(RightHatY) < 117)
            {
                pc.printf("\r\nLeftHatX: %d", PS3.getAnalogHat(LeftHatX));
                pc.printf("\tLeftHatY: %d", PS3.getAnalogHat(LeftHatY));
                if (PS3.PS3Connected)
                { // The Navigation controller only have one joystick
                    pc.printf("\tRightHatX: %d", PS3.getAnalogHat(RightHatX));
                    pc.printf("\tRightHatY: %d", PS3.getAnalogHat(RightHatY));
                }
            }
            // Analog button values can be read from almost all buttons
            if (PS3.getAnalogButton(L2) || PS3.getAnalogButton(R2))
            {
                pc.printf("\r\nL2: %d", PS3.getAnalogButton(L2));
                if (!PS3.PS3NavigationConnected)
                {
                    pc.printf("\tR2: %d", PS3.getAnalogButton(R2));
                }
            }
            if (PS3.getButtonClick(PS))
            {
                PS3.disconnect();
                pc.printf("\r\nPS");
            }
    
            if (PS3.getButtonClick(TRIANGLE))
                pc.printf("\r\nTriangle");
            if (PS3.getButtonClick(CIRCLE))
                pc.printf("\r\nCircle");
            if (PS3.getButtonClick(CROSS))
                pc.printf("\r\nCross");
            if (PS3.getButtonClick(SQUARE))
                pc.printf("\r\nSquare");
    
            if (PS3.getButtonClick(UP))
            {
                pc.printf("\r\nUp");
                PS3.setLedOff();
                PS3.setLedOn(CONTROLLER_LED4);
            }
            if (PS3.getButtonClick(RIGHT))
            {
                pc.printf("\r\nRight");
                PS3.setLedOff();
                PS3.setLedOn(CONTROLLER_LED1);
            }
            if (PS3.getButtonClick(DOWN))
            {
                pc.printf("\r\nDown");
                PS3.setLedOff();
                PS3.setLedOn(CONTROLLER_LED2);
            }
            if (PS3.getButtonClick(LEFT))
            {
                pc.printf("\r\nLeft");
                PS3.setLedOff();
                PS3.setLedOn(CONTROLLER_LED3);
            }
    
            if (PS3.getButtonClick(L1))
                pc.printf("\r\nL1");
            if (PS3.getButtonClick(L3))
                pc.printf("\r\nL3");
            if (PS3.getButtonClick(R1))
                pc.printf("\r\nR1");
            if (PS3.getButtonClick(R3))
                pc.printf("\r\nR3");
    
            if (PS3.getButtonClick(SELECT))
            {
                pc.printf("\r\nSelect - ");
                PS3.printStatusString();
            }
            if (PS3.getButtonClick(START))
            {
                pc.printf("\r\nStart");
                printAngle = !printAngle;
            }
            if (printAngle)
            {
                pc.printf("\r\nPitch: %.3lf", PS3.getAngle(Pitch));
                pc.printf("\tRoll: %.3lf", PS3.getAngle(Roll));
            }
        }
        else
        {
            pc.printf("not connect\n");
        }
    }
}
Committer:
robo_ichinoseki_a
Date:
Sat May 02 05:56:48 2020 +0000
Revision:
1:da31140f2a1c
Parent:
0:b1ce54272580
update

Who changed what in which revision?

UserRevisionLine numberNew contents of line
kotakku 0:b1ce54272580 1 /*
kotakku 0:b1ce54272580 2 *******************************************************************************
kotakku 0:b1ce54272580 3 * USB-MIDI class driver for USB Host Shield 2.0 Library
kotakku 0:b1ce54272580 4 * Copyright (c) 2012-2018 Yuuichi Akagawa
kotakku 0:b1ce54272580 5 *
kotakku 0:b1ce54272580 6 * Idea from LPK25 USB-MIDI to Serial MIDI converter
kotakku 0:b1ce54272580 7 * by Collin Cunningham - makezine.com, narbotic.com
kotakku 0:b1ce54272580 8 *
kotakku 0:b1ce54272580 9 * for use with USB Host Shield 2.0 from Circuitsathome.com
kotakku 0:b1ce54272580 10 * https://github.com/felis/USB_Host_Shield_2.0
kotakku 0:b1ce54272580 11 *******************************************************************************
kotakku 0:b1ce54272580 12 * This program is free software; you can redistribute it and/or modify
kotakku 0:b1ce54272580 13 * it under the terms of the GNU General Public License as published by
kotakku 0:b1ce54272580 14 * the Free Software Foundation; either version 2 of the License, or
kotakku 0:b1ce54272580 15 * (at your option) any later version.
kotakku 0:b1ce54272580 16 *
kotakku 0:b1ce54272580 17 * This program is distributed in the hope that it will be useful,
kotakku 0:b1ce54272580 18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
kotakku 0:b1ce54272580 19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
kotakku 0:b1ce54272580 20 * GNU General Public License for more details.
kotakku 0:b1ce54272580 21 *
kotakku 0:b1ce54272580 22 * You should have received a copy of the GNU General Public License
kotakku 0:b1ce54272580 23 * along with this program. If not, see <http://www.gnu.org/licenses/>
kotakku 0:b1ce54272580 24 *******************************************************************************
kotakku 0:b1ce54272580 25 */
kotakku 0:b1ce54272580 26
kotakku 0:b1ce54272580 27 #include "usbh_midi.h"
kotakku 0:b1ce54272580 28 //////////////////////////
kotakku 0:b1ce54272580 29 // MIDI MESAGES
kotakku 0:b1ce54272580 30 // midi.org/techspecs/
kotakku 0:b1ce54272580 31 //////////////////////////
kotakku 0:b1ce54272580 32 // STATUS BYTES
kotakku 0:b1ce54272580 33 // 0x8n == noteOff
kotakku 0:b1ce54272580 34 // 0x9n == noteOn
kotakku 0:b1ce54272580 35 // 0xAn == afterTouch
kotakku 0:b1ce54272580 36 // 0xBn == controlChange
kotakku 0:b1ce54272580 37 // n == Channel(0x0-0xf)
kotakku 0:b1ce54272580 38 //////////////////////////
kotakku 0:b1ce54272580 39 //DATA BYTE 1
kotakku 0:b1ce54272580 40 // note# == (0-127)
kotakku 0:b1ce54272580 41 // or
kotakku 0:b1ce54272580 42 // control# == (0-119)
kotakku 0:b1ce54272580 43 //////////////////////////
kotakku 0:b1ce54272580 44 // DATA BYTE 2
kotakku 0:b1ce54272580 45 // velocity == (0-127)
kotakku 0:b1ce54272580 46 // or
kotakku 0:b1ce54272580 47 // controlVal == (0-127)
kotakku 0:b1ce54272580 48 ///////////////////////////////////////////////////////////////////////////////
kotakku 0:b1ce54272580 49 // USB-MIDI Event Packets
kotakku 0:b1ce54272580 50 // usb.org - Universal Serial Bus Device Class Definition for MIDI Devices 1.0
kotakku 0:b1ce54272580 51 ///////////////////////////////////////////////////////////////////////////////
kotakku 0:b1ce54272580 52 //+-------------+-------------+-------------+-------------+
kotakku 0:b1ce54272580 53 //| Byte 0 | Byte 1 | Byte 2 | Byte 3 |
kotakku 0:b1ce54272580 54 //+------+------+-------------+-------------+-------------+
kotakku 0:b1ce54272580 55 //|Cable | Code | | | |
kotakku 0:b1ce54272580 56 //|Number|Index | MIDI_0 | MIDI_1 | MIDI_2 |
kotakku 0:b1ce54272580 57 //| |Number| | | |
kotakku 0:b1ce54272580 58 //|(4bit)|(4bit)| (8bit) | (8bit) | (8bit) |
kotakku 0:b1ce54272580 59 //+------+------+-------------+-------------+-------------+
kotakku 0:b1ce54272580 60 // CN == 0x0-0xf
kotakku 0:b1ce54272580 61 //+-----+-----------+-------------------------------------------------------------------
kotakku 0:b1ce54272580 62 //| CIN |MIDI_x size|Description
kotakku 0:b1ce54272580 63 //+-----+-----------+-------------------------------------------------------------------
kotakku 0:b1ce54272580 64 //| 0x0 | 1, 2 or 3 |Miscellaneous function codes. Reserved for future extensions.
kotakku 0:b1ce54272580 65 //| 0x1 | 1, 2 or 3 |Cable events. Reserved for future expansion.
kotakku 0:b1ce54272580 66 //| 0x2 | 2 |Two-byte System Common messages like MTC, SongSelect, etc.
kotakku 0:b1ce54272580 67 //| 0x3 | 3 |Three-byte System Common messages like SPP, etc.
kotakku 0:b1ce54272580 68 //| 0x4 | 3 |SysEx starts or continues
kotakku 0:b1ce54272580 69 //| 0x5 | 1 |Single-byte System Common Message or SysEx ends with following single byte.
kotakku 0:b1ce54272580 70 //| 0x6 | 2 |SysEx ends with following two bytes.
kotakku 0:b1ce54272580 71 //| 0x7 | 3 |SysEx ends with following three bytes.
kotakku 0:b1ce54272580 72 //| 0x8 | 3 |Note-off
kotakku 0:b1ce54272580 73 //| 0x9 | 3 |Note-on
kotakku 0:b1ce54272580 74 //| 0xA | 3 |Poly-KeyPress
kotakku 0:b1ce54272580 75 //| 0xB | 3 |Control Change
kotakku 0:b1ce54272580 76 //| 0xC | 2 |Program Change
kotakku 0:b1ce54272580 77 //| 0xD | 2 |Channel Pressure
kotakku 0:b1ce54272580 78 //| 0xE | 3 |PitchBend Change
kotakku 0:b1ce54272580 79 //| 0xF | 1 |Single Byte
kotakku 0:b1ce54272580 80 //+-----+-----------+-------------------------------------------------------------------
kotakku 0:b1ce54272580 81
kotakku 0:b1ce54272580 82 const uint8_t USBH_MIDI::epDataInIndex = 1;
kotakku 0:b1ce54272580 83 const uint8_t USBH_MIDI::epDataOutIndex = 2;
kotakku 0:b1ce54272580 84 const uint8_t USBH_MIDI::epDataInIndexVSP = 3;
kotakku 0:b1ce54272580 85 const uint8_t USBH_MIDI::epDataOutIndexVSP = 4;
kotakku 0:b1ce54272580 86
kotakku 0:b1ce54272580 87 USBH_MIDI::USBH_MIDI(USB *p) :
kotakku 0:b1ce54272580 88 pUsb(p),
kotakku 0:b1ce54272580 89 bAddress(0),
kotakku 0:b1ce54272580 90 bNumEP(1),
kotakku 0:b1ce54272580 91 bPollEnable(false),
kotakku 0:b1ce54272580 92 isMidiFound(false),
kotakku 0:b1ce54272580 93 readPtr(0) {
kotakku 0:b1ce54272580 94 // initialize endpoint data structures
kotakku 0:b1ce54272580 95 for(uint8_t i=0; i<MIDI_MAX_ENDPOINTS; i++) {
kotakku 0:b1ce54272580 96 epInfo[i].epAddr = 0;
kotakku 0:b1ce54272580 97 epInfo[i].maxPktSize = (i) ? 0 : 8;
kotakku 0:b1ce54272580 98 epInfo[i].bmNakPower = (i) ? USB_NAK_NOWAIT : USB_NAK_MAX_POWER;
kotakku 0:b1ce54272580 99
kotakku 0:b1ce54272580 100 }
kotakku 0:b1ce54272580 101 // register in USB subsystem
kotakku 0:b1ce54272580 102 if (pUsb) {
kotakku 0:b1ce54272580 103 pUsb->RegisterDeviceClass(this);
kotakku 0:b1ce54272580 104 }
kotakku 0:b1ce54272580 105 }
kotakku 0:b1ce54272580 106
kotakku 0:b1ce54272580 107 /* Connection initialization of an MIDI Device */
kotakku 0:b1ce54272580 108 uint8_t USBH_MIDI::Init(uint8_t parent, uint8_t port, bool lowspeed)
kotakku 0:b1ce54272580 109 {
kotakku 0:b1ce54272580 110 uint8_t buf[sizeof (USB_DEVICE_DESCRIPTOR)];
kotakku 0:b1ce54272580 111 USB_DEVICE_DESCRIPTOR * udd = reinterpret_cast<USB_DEVICE_DESCRIPTOR*>(buf);
kotakku 0:b1ce54272580 112 uint8_t rcode;
kotakku 0:b1ce54272580 113 UsbDevice *p = NULL;
kotakku 0:b1ce54272580 114 EpInfo *oldep_ptr = NULL;
kotakku 0:b1ce54272580 115 uint8_t num_of_conf; // number of configurations
kotakku 0:b1ce54272580 116
kotakku 0:b1ce54272580 117 USBTRACE("\rMIDI Init\r\n");
kotakku 0:b1ce54272580 118
kotakku 0:b1ce54272580 119 //for reconnect
kotakku 0:b1ce54272580 120 for(uint8_t i=epDataInIndex; i<=epDataOutIndex; i++) {
kotakku 0:b1ce54272580 121 epInfo[i].epAddr = (i==epDataInIndex) ? 0x81 : 0x01;
kotakku 0:b1ce54272580 122 epInfo[i].maxPktSize = 0;
kotakku 0:b1ce54272580 123 epInfo[i].bmSndToggle = 0;
kotakku 0:b1ce54272580 124 epInfo[i].bmRcvToggle = 0;
kotakku 0:b1ce54272580 125 }
kotakku 0:b1ce54272580 126
kotakku 0:b1ce54272580 127 // get memory address of USB device address pool
kotakku 0:b1ce54272580 128 AddressPool &addrPool = pUsb->GetAddressPool();
kotakku 0:b1ce54272580 129
kotakku 0:b1ce54272580 130 // check if address has already been assigned to an instance
kotakku 0:b1ce54272580 131 if (bAddress) {
kotakku 0:b1ce54272580 132 return USB_ERROR_CLASS_INSTANCE_ALREADY_IN_USE;
kotakku 0:b1ce54272580 133 }
kotakku 0:b1ce54272580 134 // Get pointer to pseudo device with address 0 assigned
kotakku 0:b1ce54272580 135 p = addrPool.GetUsbDevicePtr(bAddress);
kotakku 0:b1ce54272580 136 if (!p) {
kotakku 0:b1ce54272580 137 return USB_ERROR_ADDRESS_NOT_FOUND_IN_POOL;
kotakku 0:b1ce54272580 138 }
kotakku 0:b1ce54272580 139 if (!p->epinfo) {
kotakku 0:b1ce54272580 140 return USB_ERROR_EPINFO_IS_NULL;
kotakku 0:b1ce54272580 141 }
kotakku 0:b1ce54272580 142
kotakku 0:b1ce54272580 143 // Save old pointer to EP_RECORD of address 0
kotakku 0:b1ce54272580 144 oldep_ptr = p->epinfo;
kotakku 0:b1ce54272580 145
kotakku 0:b1ce54272580 146 // Temporary assign new pointer to epInfo to p->epinfo in order to avoid toggle inconsistence
kotakku 0:b1ce54272580 147 p->epinfo = epInfo;
kotakku 0:b1ce54272580 148 p->lowspeed = lowspeed;
kotakku 0:b1ce54272580 149
kotakku 0:b1ce54272580 150 // Get device descriptor
kotakku 0:b1ce54272580 151 rcode = pUsb->getDevDescr( 0, 0, sizeof(USB_DEVICE_DESCRIPTOR), (uint8_t*)buf );
kotakku 0:b1ce54272580 152 vid = udd->idVendor;
kotakku 0:b1ce54272580 153 pid = udd->idProduct;
kotakku 0:b1ce54272580 154 // Restore p->epinfo
kotakku 0:b1ce54272580 155 p->epinfo = oldep_ptr;
kotakku 0:b1ce54272580 156
kotakku 0:b1ce54272580 157 if( rcode ){
kotakku 0:b1ce54272580 158 goto FailGetDevDescr;
kotakku 0:b1ce54272580 159 }
kotakku 0:b1ce54272580 160
kotakku 0:b1ce54272580 161 // Allocate new address according to device class
kotakku 0:b1ce54272580 162 bAddress = addrPool.AllocAddress(parent, false, port);
kotakku 0:b1ce54272580 163 if (!bAddress) {
kotakku 0:b1ce54272580 164 return USB_ERROR_OUT_OF_ADDRESS_SPACE_IN_POOL;
kotakku 0:b1ce54272580 165 }
kotakku 0:b1ce54272580 166
kotakku 0:b1ce54272580 167 // Extract Max Packet Size from device descriptor
kotakku 0:b1ce54272580 168 epInfo[0].maxPktSize = udd->bMaxPacketSize0;
kotakku 0:b1ce54272580 169
kotakku 0:b1ce54272580 170 // Assign new address to the device
kotakku 0:b1ce54272580 171 rcode = pUsb->setAddr( 0, 0, bAddress );
kotakku 0:b1ce54272580 172 if (rcode) {
kotakku 0:b1ce54272580 173 p->lowspeed = false;
kotakku 0:b1ce54272580 174 addrPool.FreeAddress(bAddress);
kotakku 0:b1ce54272580 175 bAddress = 0;
kotakku 0:b1ce54272580 176 return rcode;
kotakku 0:b1ce54272580 177 }//if (rcode...
kotakku 0:b1ce54272580 178 USBTRACE2("Addr:", bAddress);
kotakku 0:b1ce54272580 179
kotakku 0:b1ce54272580 180 p->lowspeed = false;
kotakku 0:b1ce54272580 181
kotakku 0:b1ce54272580 182 //get pointer to assigned address record
kotakku 0:b1ce54272580 183 p = addrPool.GetUsbDevicePtr(bAddress);
kotakku 0:b1ce54272580 184 if (!p) {
kotakku 0:b1ce54272580 185 return USB_ERROR_ADDRESS_NOT_FOUND_IN_POOL;
kotakku 0:b1ce54272580 186 }
kotakku 0:b1ce54272580 187 p->lowspeed = lowspeed;
kotakku 0:b1ce54272580 188
kotakku 0:b1ce54272580 189 num_of_conf = udd->bNumConfigurations;
kotakku 0:b1ce54272580 190
kotakku 0:b1ce54272580 191 // Assign epInfo to epinfo pointer
kotakku 0:b1ce54272580 192 rcode = pUsb->setEpInfoEntry(bAddress, 1, epInfo);
kotakku 0:b1ce54272580 193 if (rcode) {
kotakku 0:b1ce54272580 194 USBTRACE("setEpInfoEntry failed");
kotakku 0:b1ce54272580 195 goto FailSetDevTblEntry;
kotakku 0:b1ce54272580 196 }
kotakku 0:b1ce54272580 197
kotakku 0:b1ce54272580 198 USBTRACE("VID:"), D_PrintHex(vid, 0x80);
kotakku 0:b1ce54272580 199 USBTRACE(" PID:"), D_PrintHex(pid, 0x80);
kotakku 0:b1ce54272580 200 USBTRACE2(" #Conf:", num_of_conf);
kotakku 0:b1ce54272580 201
kotakku 0:b1ce54272580 202 //Setup for well known vendor/device specific configuration
kotakku 0:b1ce54272580 203 bTransferTypeMask = bmUSB_TRANSFER_TYPE;
kotakku 0:b1ce54272580 204 setupDeviceSpecific();
kotakku 0:b1ce54272580 205
kotakku 0:b1ce54272580 206 isMidiFound = false;
kotakku 0:b1ce54272580 207 for (uint8_t i=0; i<num_of_conf; i++) {
kotakku 0:b1ce54272580 208 rcode = parseConfigDescr(bAddress, i);
kotakku 0:b1ce54272580 209 if( rcode )
kotakku 0:b1ce54272580 210 goto FailGetConfDescr;
kotakku 0:b1ce54272580 211 if (bNumEP > 1)
kotakku 0:b1ce54272580 212 break;
kotakku 0:b1ce54272580 213 } // for
kotakku 0:b1ce54272580 214
kotakku 0:b1ce54272580 215 USBTRACE2("\r\nNumEP:", bNumEP);
kotakku 0:b1ce54272580 216
kotakku 0:b1ce54272580 217 if( bNumEP < 2 ){ //Device not found.
kotakku 0:b1ce54272580 218 rcode = 0xff;
kotakku 0:b1ce54272580 219 goto FailGetConfDescr;
kotakku 0:b1ce54272580 220 }
kotakku 0:b1ce54272580 221
kotakku 0:b1ce54272580 222 if( !isMidiFound ){ //MIDI Device not found. Try last Bulk transfer device
kotakku 0:b1ce54272580 223 USBTRACE("MIDI not found. Attempts bulk device\r\n");
kotakku 0:b1ce54272580 224 epInfo[epDataInIndex].epAddr = epInfo[epDataInIndexVSP].epAddr;
kotakku 0:b1ce54272580 225 epInfo[epDataInIndex].maxPktSize = epInfo[epDataInIndexVSP].maxPktSize;
kotakku 0:b1ce54272580 226 epInfo[epDataOutIndex].epAddr = epInfo[epDataOutIndexVSP].epAddr;
kotakku 0:b1ce54272580 227 epInfo[epDataOutIndex].maxPktSize = epInfo[epDataOutIndexVSP].maxPktSize;
kotakku 0:b1ce54272580 228 }
kotakku 0:b1ce54272580 229
kotakku 0:b1ce54272580 230 // Assign epInfo to epinfo pointer
kotakku 0:b1ce54272580 231 rcode = pUsb->setEpInfoEntry(bAddress, 3, epInfo);
kotakku 0:b1ce54272580 232 USBTRACE2("Conf:", bConfNum);
kotakku 0:b1ce54272580 233 USBTRACE2("EPin :", (uint8_t)(epInfo[epDataInIndex].epAddr + 0x80));
kotakku 0:b1ce54272580 234 USBTRACE2("EPout:", epInfo[epDataOutIndex].epAddr);
kotakku 0:b1ce54272580 235
kotakku 0:b1ce54272580 236 // Set Configuration Value
kotakku 0:b1ce54272580 237 rcode = pUsb->setConf(bAddress, 0, bConfNum);
kotakku 0:b1ce54272580 238 if (rcode) {
kotakku 0:b1ce54272580 239 goto FailSetConfDescr;
kotakku 0:b1ce54272580 240 }
kotakku 0:b1ce54272580 241 bPollEnable = true;
kotakku 0:b1ce54272580 242 USBTRACE("Init done.\r\n");
kotakku 0:b1ce54272580 243 return 0;
kotakku 0:b1ce54272580 244 FailGetDevDescr:
kotakku 0:b1ce54272580 245 FailSetDevTblEntry:
kotakku 0:b1ce54272580 246 FailGetConfDescr:
kotakku 0:b1ce54272580 247 FailSetConfDescr:
kotakku 0:b1ce54272580 248 Release();
kotakku 0:b1ce54272580 249 return rcode;
kotakku 0:b1ce54272580 250 }
kotakku 0:b1ce54272580 251
kotakku 0:b1ce54272580 252 /* get and parse config descriptor */
kotakku 0:b1ce54272580 253 uint8_t USBH_MIDI::parseConfigDescr( uint8_t addr, uint8_t conf )
kotakku 0:b1ce54272580 254 {
kotakku 0:b1ce54272580 255 uint8_t buf[ DESC_BUFF_SIZE ];
kotakku 0:b1ce54272580 256 uint8_t* buf_ptr = buf;
kotakku 0:b1ce54272580 257 uint8_t rcode;
kotakku 0:b1ce54272580 258 uint8_t descr_length;
kotakku 0:b1ce54272580 259 uint8_t descr_type;
kotakku 0:b1ce54272580 260 uint16_t total_length;
kotakku 0:b1ce54272580 261 USB_ENDPOINT_DESCRIPTOR *epDesc;
kotakku 0:b1ce54272580 262 bool isMidi = false;
kotakku 0:b1ce54272580 263
kotakku 0:b1ce54272580 264 // get configuration descriptor (get descriptor size only)
kotakku 0:b1ce54272580 265 rcode = pUsb->getConfDescr( addr, 0, 4, conf, buf );
kotakku 0:b1ce54272580 266 if( rcode ){
kotakku 0:b1ce54272580 267 return rcode;
kotakku 0:b1ce54272580 268 }
kotakku 0:b1ce54272580 269 total_length = buf[2] | ((int)buf[3] << 8);
kotakku 0:b1ce54272580 270 if( total_length > DESC_BUFF_SIZE ) { //check if total length is larger than buffer
kotakku 0:b1ce54272580 271 total_length = DESC_BUFF_SIZE;
kotakku 0:b1ce54272580 272 }
kotakku 0:b1ce54272580 273
kotakku 0:b1ce54272580 274 // get configuration descriptor (all)
kotakku 0:b1ce54272580 275 rcode = pUsb->getConfDescr( addr, 0, total_length, conf, buf ); //get the whole descriptor
kotakku 0:b1ce54272580 276 if( rcode ){
kotakku 0:b1ce54272580 277 return rcode;
kotakku 0:b1ce54272580 278 }
kotakku 0:b1ce54272580 279
kotakku 0:b1ce54272580 280 //parsing descriptors
kotakku 0:b1ce54272580 281 while( buf_ptr < buf + total_length ) {
kotakku 0:b1ce54272580 282 descr_length = *( buf_ptr );
kotakku 0:b1ce54272580 283 descr_type = *( buf_ptr + 1 );
kotakku 0:b1ce54272580 284 switch( descr_type ) {
kotakku 0:b1ce54272580 285 case USB_DESCRIPTOR_CONFIGURATION :
kotakku 0:b1ce54272580 286 bConfNum = buf_ptr[5];
kotakku 0:b1ce54272580 287 break;
kotakku 0:b1ce54272580 288 case USB_DESCRIPTOR_INTERFACE :
kotakku 0:b1ce54272580 289 USBTRACE("\r\nConf:"), D_PrintHex(bConfNum, 0x80);
kotakku 0:b1ce54272580 290 USBTRACE(" Int:"), D_PrintHex(buf_ptr[2], 0x80);
kotakku 0:b1ce54272580 291 USBTRACE(" Alt:"), D_PrintHex(buf_ptr[3], 0x80);
kotakku 0:b1ce54272580 292 USBTRACE(" EPs:"), D_PrintHex(buf_ptr[4], 0x80);
kotakku 0:b1ce54272580 293 USBTRACE(" IntCl:"), D_PrintHex(buf_ptr[5], 0x80);
kotakku 0:b1ce54272580 294 USBTRACE(" IntSubCl:"), D_PrintHex(buf_ptr[6], 0x80);
kotakku 0:b1ce54272580 295 USBTRACE("\r\n");
kotakku 0:b1ce54272580 296
kotakku 0:b1ce54272580 297 if( buf_ptr[5] == USB_CLASS_AUDIO && buf_ptr[6] == USB_SUBCLASS_MIDISTREAMING ) { //p[5]; bInterfaceClass = 1(Audio), p[6]; bInterfaceSubClass = 3(MIDI Streaming)
kotakku 0:b1ce54272580 298 isMidiFound = true; //MIDI device found.
kotakku 0:b1ce54272580 299 isMidi = true;
kotakku 0:b1ce54272580 300 USBTRACE("MIDI Device\r\n");
kotakku 0:b1ce54272580 301 }else{
kotakku 0:b1ce54272580 302 isMidi = false;
kotakku 0:b1ce54272580 303 USBTRACE("No MIDI Device\r\n");
kotakku 0:b1ce54272580 304 }
kotakku 0:b1ce54272580 305 break;
kotakku 0:b1ce54272580 306 case USB_DESCRIPTOR_ENDPOINT :
kotakku 0:b1ce54272580 307 epDesc = (USB_ENDPOINT_DESCRIPTOR *)buf_ptr;
kotakku 0:b1ce54272580 308 USBTRACE("-EPAddr:"), D_PrintHex(epDesc->bEndpointAddress, 0x80);
kotakku 0:b1ce54272580 309 USBTRACE(" bmAttr:"), D_PrintHex(epDesc->bmAttributes, 0x80);
kotakku 0:b1ce54272580 310 USBTRACE2(" MaxPktSz:", (uint8_t)epDesc->wMaxPacketSize);
kotakku 0:b1ce54272580 311 if ((epDesc->bmAttributes & bTransferTypeMask) == USB_TRANSFER_TYPE_BULK) {//bulk
kotakku 0:b1ce54272580 312 uint8_t index;
kotakku 0:b1ce54272580 313 if( isMidi )
kotakku 0:b1ce54272580 314 index = ((epDesc->bEndpointAddress & 0x80) == 0x80) ? epDataInIndex : epDataOutIndex;
kotakku 0:b1ce54272580 315 else
kotakku 0:b1ce54272580 316 index = ((epDesc->bEndpointAddress & 0x80) == 0x80) ? epDataInIndexVSP : epDataOutIndexVSP;
kotakku 0:b1ce54272580 317 epInfo[index].epAddr = (epDesc->bEndpointAddress & 0x0F);
kotakku 0:b1ce54272580 318 epInfo[index].maxPktSize = (uint8_t)epDesc->wMaxPacketSize;
kotakku 0:b1ce54272580 319 bNumEP ++;
kotakku 0:b1ce54272580 320 #ifdef DEBUG_USB_HOST
kotakku 0:b1ce54272580 321 PrintEndpointDescriptor(epDesc);
kotakku 0:b1ce54272580 322 #endif
kotakku 0:b1ce54272580 323 }
kotakku 0:b1ce54272580 324 break;
kotakku 0:b1ce54272580 325 default:
kotakku 0:b1ce54272580 326 break;
kotakku 0:b1ce54272580 327 }//switch( descr_type
kotakku 0:b1ce54272580 328 buf_ptr += descr_length; //advance buffer pointer
kotakku 0:b1ce54272580 329 }//while( buf_ptr <=...
kotakku 0:b1ce54272580 330 return 0;
kotakku 0:b1ce54272580 331 }
kotakku 0:b1ce54272580 332
kotakku 0:b1ce54272580 333 /* Performs a cleanup after failed Init() attempt */
kotakku 0:b1ce54272580 334 uint8_t USBH_MIDI::Release()
kotakku 0:b1ce54272580 335 {
kotakku 0:b1ce54272580 336 pUsb->GetAddressPool().FreeAddress(bAddress);
kotakku 0:b1ce54272580 337 bNumEP = 1; //must have to be reset to 1
kotakku 0:b1ce54272580 338 bAddress = 0;
kotakku 0:b1ce54272580 339 bPollEnable = false;
kotakku 0:b1ce54272580 340 readPtr = 0;
kotakku 0:b1ce54272580 341 return 0;
kotakku 0:b1ce54272580 342 }
kotakku 0:b1ce54272580 343
kotakku 0:b1ce54272580 344 /* Setup for well known vendor/device specific configuration */
kotakku 0:b1ce54272580 345 void USBH_MIDI::setupDeviceSpecific()
kotakku 0:b1ce54272580 346 {
kotakku 0:b1ce54272580 347 // Novation
kotakku 0:b1ce54272580 348 if( vid == 0x1235 ) {
kotakku 0:b1ce54272580 349 // LaunchPad's endpoint attirbute is interrupt (0x20:S, 0x36:Mini, 0x51:Pro, 0x69:MK2, 0x7b:Launchkey25 MK2)
kotakku 0:b1ce54272580 350 if(pid == 0x20 || pid == 0x36 || pid == 0x51 || pid == 0x69 || pid == 0x7b ) {
kotakku 0:b1ce54272580 351 bTransferTypeMask = 2;
kotakku 0:b1ce54272580 352 }
kotakku 0:b1ce54272580 353 }
kotakku 0:b1ce54272580 354 }
kotakku 0:b1ce54272580 355
kotakku 0:b1ce54272580 356 /* Receive data from MIDI device */
kotakku 0:b1ce54272580 357 uint8_t USBH_MIDI::RecvData(uint16_t *bytes_rcvd, uint8_t *dataptr)
kotakku 0:b1ce54272580 358 {
kotakku 0:b1ce54272580 359 *bytes_rcvd = (uint16_t)epInfo[epDataInIndex].maxPktSize;
kotakku 0:b1ce54272580 360 uint8_t r = pUsb->inTransfer(bAddress, epInfo[epDataInIndex].epAddr, bytes_rcvd, dataptr);
kotakku 0:b1ce54272580 361
kotakku 0:b1ce54272580 362 if( *bytes_rcvd < (MIDI_EVENT_PACKET_SIZE-4)){
kotakku 0:b1ce54272580 363 dataptr[*bytes_rcvd] = '\0';
kotakku 0:b1ce54272580 364 dataptr[(*bytes_rcvd)+1] = '\0';
kotakku 0:b1ce54272580 365 }
kotakku 0:b1ce54272580 366 return r;
kotakku 0:b1ce54272580 367 }
kotakku 0:b1ce54272580 368
kotakku 0:b1ce54272580 369 /* Receive data from MIDI device */
kotakku 0:b1ce54272580 370 uint8_t USBH_MIDI::RecvData(uint8_t *outBuf, bool isRaw)
kotakku 0:b1ce54272580 371 {
kotakku 0:b1ce54272580 372 uint8_t rcode = 0; //return code
kotakku 0:b1ce54272580 373 uint16_t rcvd;
kotakku 0:b1ce54272580 374
kotakku 0:b1ce54272580 375 if( bPollEnable == false ) return 0;
kotakku 0:b1ce54272580 376
kotakku 0:b1ce54272580 377 //Checking unprocessed message in buffer.
kotakku 0:b1ce54272580 378 if( readPtr != 0 && readPtr < MIDI_EVENT_PACKET_SIZE ){
kotakku 0:b1ce54272580 379 if(recvBuf[readPtr] == 0 && recvBuf[readPtr+1] == 0) {
kotakku 0:b1ce54272580 380 //no unprocessed message left in the buffer.
kotakku 0:b1ce54272580 381 }else{
kotakku 0:b1ce54272580 382 goto RecvData_return_from_buffer;
kotakku 0:b1ce54272580 383 }
kotakku 0:b1ce54272580 384 }
kotakku 0:b1ce54272580 385
kotakku 0:b1ce54272580 386 readPtr = 0;
kotakku 0:b1ce54272580 387 rcode = RecvData( &rcvd, recvBuf);
kotakku 0:b1ce54272580 388 if( rcode != 0 ) {
kotakku 0:b1ce54272580 389 return 0;
kotakku 0:b1ce54272580 390 }
kotakku 0:b1ce54272580 391
kotakku 0:b1ce54272580 392 //if all data is zero, no valid data received.
kotakku 0:b1ce54272580 393 if( recvBuf[0] == 0 && recvBuf[1] == 0 && recvBuf[2] == 0 && recvBuf[3] == 0 ) {
kotakku 0:b1ce54272580 394 return 0;
kotakku 0:b1ce54272580 395 }
kotakku 0:b1ce54272580 396
kotakku 0:b1ce54272580 397 RecvData_return_from_buffer:
kotakku 0:b1ce54272580 398 uint8_t m;
kotakku 0:b1ce54272580 399 uint8_t cin = recvBuf[readPtr];
kotakku 0:b1ce54272580 400 if( isRaw == true ) {
kotakku 0:b1ce54272580 401 *(outBuf++) = cin;
kotakku 0:b1ce54272580 402 }
kotakku 0:b1ce54272580 403 readPtr++;
kotakku 0:b1ce54272580 404 *(outBuf++) = m = recvBuf[readPtr++];
kotakku 0:b1ce54272580 405 *(outBuf++) = recvBuf[readPtr++];
kotakku 0:b1ce54272580 406 *(outBuf++) = recvBuf[readPtr++];
kotakku 0:b1ce54272580 407 return lookupMsgSize(m, cin);
kotakku 0:b1ce54272580 408 }
kotakku 0:b1ce54272580 409
kotakku 0:b1ce54272580 410 /* Receive raw data from MIDI device */
kotakku 0:b1ce54272580 411 uint8_t USBH_MIDI::RecvRawData(uint8_t *outBuf)
kotakku 0:b1ce54272580 412 {
kotakku 0:b1ce54272580 413 return RecvData(outBuf, true);
kotakku 0:b1ce54272580 414 }
kotakku 0:b1ce54272580 415
kotakku 0:b1ce54272580 416 /* Send data to MIDI device */
kotakku 0:b1ce54272580 417 uint8_t USBH_MIDI::SendData(uint8_t *dataptr, uint8_t nCable)
kotakku 0:b1ce54272580 418 {
kotakku 0:b1ce54272580 419 uint8_t buf[4];
kotakku 0:b1ce54272580 420 uint8_t msg;
kotakku 0:b1ce54272580 421
kotakku 0:b1ce54272580 422 msg = dataptr[0];
kotakku 0:b1ce54272580 423 // SysEx long message ?
kotakku 0:b1ce54272580 424 if( msg == 0xf0 )
kotakku 0:b1ce54272580 425 {
kotakku 0:b1ce54272580 426 return SendSysEx(dataptr, countSysExDataSize(dataptr), nCable);
kotakku 0:b1ce54272580 427 }
kotakku 0:b1ce54272580 428
kotakku 0:b1ce54272580 429 buf[0] = (nCable << 4) | (msg >> 4);
kotakku 0:b1ce54272580 430 if( msg < 0xf0 ) msg = msg & 0xf0;
kotakku 0:b1ce54272580 431
kotakku 0:b1ce54272580 432
kotakku 0:b1ce54272580 433 //Building USB-MIDI Event Packets
kotakku 0:b1ce54272580 434 buf[1] = dataptr[0];
kotakku 0:b1ce54272580 435 buf[2] = dataptr[1];
kotakku 0:b1ce54272580 436 buf[3] = dataptr[2];
kotakku 0:b1ce54272580 437
kotakku 0:b1ce54272580 438 switch(lookupMsgSize(msg)) {
kotakku 0:b1ce54272580 439 //3 bytes message
kotakku 0:b1ce54272580 440 case 3 :
kotakku 0:b1ce54272580 441 if(msg == 0xf2) {//system common message(SPP)
kotakku 0:b1ce54272580 442 buf[0] = (nCable << 4) | 3;
kotakku 0:b1ce54272580 443 }
kotakku 0:b1ce54272580 444 break;
kotakku 0:b1ce54272580 445
kotakku 0:b1ce54272580 446 //2 bytes message
kotakku 0:b1ce54272580 447 case 2 :
kotakku 0:b1ce54272580 448 if(msg == 0xf1 || msg == 0xf3) {//system common message(MTC/SongSelect)
kotakku 0:b1ce54272580 449 buf[0] = (nCable << 4) | 2;
kotakku 0:b1ce54272580 450 }
kotakku 0:b1ce54272580 451 buf[3] = 0;
kotakku 0:b1ce54272580 452 break;
kotakku 0:b1ce54272580 453
kotakku 0:b1ce54272580 454 //1 byte message
kotakku 0:b1ce54272580 455 case 1 :
kotakku 0:b1ce54272580 456 default :
kotakku 0:b1ce54272580 457 buf[2] = 0;
kotakku 0:b1ce54272580 458 buf[3] = 0;
kotakku 0:b1ce54272580 459 break;
kotakku 0:b1ce54272580 460 }
kotakku 0:b1ce54272580 461 return pUsb->outTransfer(bAddress, epInfo[epDataOutIndex].epAddr, 4, buf);
kotakku 0:b1ce54272580 462 }
kotakku 0:b1ce54272580 463
kotakku 0:b1ce54272580 464 #ifdef DEBUG_USB_HOST
kotakku 0:b1ce54272580 465 void USBH_MIDI::PrintEndpointDescriptor( const USB_ENDPOINT_DESCRIPTOR* ep_ptr )
kotakku 0:b1ce54272580 466 {
kotakku 0:b1ce54272580 467 USBTRACE("Endpoint descriptor:\r\n");
kotakku 0:b1ce54272580 468 USBTRACE2(" Length:\t", ep_ptr->bLength);
kotakku 0:b1ce54272580 469 USBTRACE2(" Type:\t\t", ep_ptr->bDescriptorType);
kotakku 0:b1ce54272580 470 USBTRACE2(" Address:\t", ep_ptr->bEndpointAddress);
kotakku 0:b1ce54272580 471 USBTRACE2(" Attributes:\t", ep_ptr->bmAttributes);
kotakku 0:b1ce54272580 472 USBTRACE2(" MaxPktSize:\t", ep_ptr->wMaxPacketSize);
kotakku 0:b1ce54272580 473 USBTRACE2(" Poll Intrv:\t", ep_ptr->bInterval);
kotakku 0:b1ce54272580 474 }
kotakku 0:b1ce54272580 475 #endif
kotakku 0:b1ce54272580 476
kotakku 0:b1ce54272580 477 /* look up a MIDI message size from spec */
kotakku 0:b1ce54272580 478 /*Return */
kotakku 0:b1ce54272580 479 /* 0 : undefined message */
kotakku 0:b1ce54272580 480 /* 0<: Vaild message size(1-3) */
kotakku 0:b1ce54272580 481 uint8_t USBH_MIDI::lookupMsgSize(uint8_t midiMsg, uint8_t cin)
kotakku 0:b1ce54272580 482 {
kotakku 0:b1ce54272580 483 uint8_t msgSize = 0;
kotakku 0:b1ce54272580 484
kotakku 0:b1ce54272580 485 //SysEx message?
kotakku 0:b1ce54272580 486 cin = cin & 0x0f;
kotakku 0:b1ce54272580 487 if( (cin & 0xc) == 4 ) {
kotakku 0:b1ce54272580 488 if( cin == 4 || cin == 7 ) return 3;
kotakku 0:b1ce54272580 489 if( cin == 6 ) return 2;
kotakku 0:b1ce54272580 490 if( cin == 5 ) return 1;
kotakku 0:b1ce54272580 491 }
kotakku 0:b1ce54272580 492
kotakku 0:b1ce54272580 493 if( midiMsg < 0xf0 ) midiMsg &= 0xf0;
kotakku 0:b1ce54272580 494 switch(midiMsg) {
kotakku 0:b1ce54272580 495 //3 bytes messages
kotakku 0:b1ce54272580 496 case 0xf2 : //system common message(SPP)
kotakku 0:b1ce54272580 497 case 0x80 : //Note off
kotakku 0:b1ce54272580 498 case 0x90 : //Note on
kotakku 0:b1ce54272580 499 case 0xa0 : //Poly KeyPress
kotakku 0:b1ce54272580 500 case 0xb0 : //Control Change
kotakku 0:b1ce54272580 501 case 0xe0 : //PitchBend Change
kotakku 0:b1ce54272580 502 msgSize = 3;
kotakku 0:b1ce54272580 503 break;
kotakku 0:b1ce54272580 504
kotakku 0:b1ce54272580 505 //2 bytes messages
kotakku 0:b1ce54272580 506 case 0xf1 : //system common message(MTC)
kotakku 0:b1ce54272580 507 case 0xf3 : //system common message(SongSelect)
kotakku 0:b1ce54272580 508 case 0xc0 : //Program Change
kotakku 0:b1ce54272580 509 case 0xd0 : //Channel Pressure
kotakku 0:b1ce54272580 510 msgSize = 2;
kotakku 0:b1ce54272580 511 break;
kotakku 0:b1ce54272580 512
kotakku 0:b1ce54272580 513 //1 byte messages
kotakku 0:b1ce54272580 514 case 0xf8 : //system realtime message
kotakku 0:b1ce54272580 515 case 0xf9 : //system realtime message
kotakku 0:b1ce54272580 516 case 0xfa : //system realtime message
kotakku 0:b1ce54272580 517 case 0xfb : //system realtime message
kotakku 0:b1ce54272580 518 case 0xfc : //system realtime message
kotakku 0:b1ce54272580 519 case 0xfe : //system realtime message
kotakku 0:b1ce54272580 520 case 0xff : //system realtime message
kotakku 0:b1ce54272580 521 msgSize = 1;
kotakku 0:b1ce54272580 522 break;
kotakku 0:b1ce54272580 523
kotakku 0:b1ce54272580 524 //undefine messages
kotakku 0:b1ce54272580 525 default :
kotakku 0:b1ce54272580 526 break;
kotakku 0:b1ce54272580 527 }
kotakku 0:b1ce54272580 528 return msgSize;
kotakku 0:b1ce54272580 529 }
kotakku 0:b1ce54272580 530
kotakku 0:b1ce54272580 531 /* SysEx data size counter */
kotakku 0:b1ce54272580 532 uint16_t USBH_MIDI::countSysExDataSize(uint8_t *dataptr)
kotakku 0:b1ce54272580 533 {
kotakku 0:b1ce54272580 534 uint16_t c = 1;
kotakku 0:b1ce54272580 535
kotakku 0:b1ce54272580 536 if( *dataptr != 0xf0 ){ //not SysEx
kotakku 0:b1ce54272580 537 return 0;
kotakku 0:b1ce54272580 538 }
kotakku 0:b1ce54272580 539
kotakku 0:b1ce54272580 540 //Search terminator(0xf7)
kotakku 0:b1ce54272580 541 while(*dataptr != 0xf7)
kotakku 0:b1ce54272580 542 {
kotakku 0:b1ce54272580 543 dataptr++;
kotakku 0:b1ce54272580 544 c++;
kotakku 0:b1ce54272580 545
kotakku 0:b1ce54272580 546 //Limiter (default: 256 bytes)
kotakku 0:b1ce54272580 547 if(c > MIDI_MAX_SYSEX_SIZE){
kotakku 0:b1ce54272580 548 c = 0;
kotakku 0:b1ce54272580 549 break;
kotakku 0:b1ce54272580 550 }
kotakku 0:b1ce54272580 551 }
kotakku 0:b1ce54272580 552 return c;
kotakku 0:b1ce54272580 553 }
kotakku 0:b1ce54272580 554
kotakku 0:b1ce54272580 555 /* Send SysEx message to MIDI device */
kotakku 0:b1ce54272580 556 uint8_t USBH_MIDI::SendSysEx(uint8_t *dataptr, uint16_t datasize, uint8_t nCable)
kotakku 0:b1ce54272580 557 {
kotakku 0:b1ce54272580 558 uint8_t buf[MIDI_EVENT_PACKET_SIZE];
kotakku 0:b1ce54272580 559 uint8_t rc = 0;
kotakku 0:b1ce54272580 560 uint16_t n = datasize;
kotakku 0:b1ce54272580 561 uint16_t pktSize = (n*10/3+7)/10*4; //Calculate total USB MIDI packet size
kotakku 0:b1ce54272580 562 uint8_t wptr = 0;
kotakku 0:b1ce54272580 563 uint8_t maxpkt = epInfo[epDataInIndex].maxPktSize;
kotakku 0:b1ce54272580 564
kotakku 0:b1ce54272580 565 if( maxpkt > MIDI_EVENT_PACKET_SIZE ) maxpkt = MIDI_EVENT_PACKET_SIZE;
kotakku 0:b1ce54272580 566
kotakku 0:b1ce54272580 567 USBTRACE("SendSysEx:\r\t");
kotakku 0:b1ce54272580 568 USBTRACE2(" Length:\t", datasize);
kotakku 0:b1ce54272580 569 USBTRACE2(" Total pktSize:\t", pktSize);
kotakku 0:b1ce54272580 570
kotakku 0:b1ce54272580 571 while(n > 0) {
kotakku 0:b1ce54272580 572 //Byte 0
kotakku 0:b1ce54272580 573 buf[wptr] = (nCable << 4) | 0x4; //x4 SysEx starts or continues
kotakku 0:b1ce54272580 574
kotakku 0:b1ce54272580 575 switch ( n ) {
kotakku 0:b1ce54272580 576 case 1 :
kotakku 0:b1ce54272580 577 buf[wptr++] = (nCable << 4) | 0x5; //x5 SysEx ends with following single byte.
kotakku 0:b1ce54272580 578 buf[wptr++] = *(dataptr++);
kotakku 0:b1ce54272580 579 buf[wptr++] = 0x00;
kotakku 0:b1ce54272580 580 buf[wptr++] = 0x00;
kotakku 0:b1ce54272580 581 n = n - 1;
kotakku 0:b1ce54272580 582 break;
kotakku 0:b1ce54272580 583 case 2 :
kotakku 0:b1ce54272580 584 buf[wptr++] = (nCable << 4) | 0x6; //x6 SysEx ends with following two bytes.
kotakku 0:b1ce54272580 585 buf[wptr++] = *(dataptr++);
kotakku 0:b1ce54272580 586 buf[wptr++] = *(dataptr++);
kotakku 0:b1ce54272580 587 buf[wptr++] = 0x00;
kotakku 0:b1ce54272580 588 n = n - 2;
kotakku 0:b1ce54272580 589 break;
kotakku 0:b1ce54272580 590 case 3 :
kotakku 0:b1ce54272580 591 buf[wptr] = (nCable << 4) | 0x7; //x7 SysEx ends with following three bytes.
kotakku 0:b1ce54272580 592 default :
kotakku 0:b1ce54272580 593 wptr++;
kotakku 0:b1ce54272580 594 buf[wptr++] = *(dataptr++);
kotakku 0:b1ce54272580 595 buf[wptr++] = *(dataptr++);
kotakku 0:b1ce54272580 596 buf[wptr++] = *(dataptr++);
kotakku 0:b1ce54272580 597 n = n - 3;
kotakku 0:b1ce54272580 598 break;
kotakku 0:b1ce54272580 599 }
kotakku 0:b1ce54272580 600
kotakku 0:b1ce54272580 601 if( wptr >= maxpkt || n == 0 ){ //Reach a maxPktSize or data end.
kotakku 0:b1ce54272580 602 USBTRACE2(" wptr:\t", wptr);
kotakku 0:b1ce54272580 603 if( (rc = pUsb->outTransfer(bAddress, epInfo[epDataOutIndex].epAddr, wptr, buf)) != 0 ){
kotakku 0:b1ce54272580 604 break;
kotakku 0:b1ce54272580 605 }
kotakku 0:b1ce54272580 606 wptr = 0; //rewind data pointer
kotakku 0:b1ce54272580 607 }
kotakku 0:b1ce54272580 608 }
kotakku 0:b1ce54272580 609 return(rc);
kotakku 0:b1ce54272580 610 }
kotakku 0:b1ce54272580 611
kotakku 0:b1ce54272580 612 /* Send raw data to MIDI device */
kotakku 0:b1ce54272580 613 uint8_t USBH_MIDI::SendRawData(uint16_t bytes_send, uint8_t *dataptr)
kotakku 0:b1ce54272580 614 {
kotakku 0:b1ce54272580 615 return pUsb->outTransfer(bAddress, epInfo[epDataOutIndex].epAddr, bytes_send, dataptr);
kotakku 0:b1ce54272580 616
kotakku 0:b1ce54272580 617 }
kotakku 0:b1ce54272580 618
kotakku 0:b1ce54272580 619 uint8_t USBH_MIDI::extractSysExData(uint8_t *p, uint8_t *buf)
kotakku 0:b1ce54272580 620 {
kotakku 0:b1ce54272580 621 uint8_t rc = 0;
kotakku 0:b1ce54272580 622 uint8_t cin = *(p) & 0x0f;
kotakku 0:b1ce54272580 623
kotakku 0:b1ce54272580 624 //SysEx message?
kotakku 0:b1ce54272580 625 if( (cin & 0xc) != 4 ) return rc;
kotakku 0:b1ce54272580 626
kotakku 0:b1ce54272580 627 switch(cin) {
kotakku 0:b1ce54272580 628 case 4:
kotakku 0:b1ce54272580 629 case 7:
kotakku 0:b1ce54272580 630 *buf++ = *(p+1);
kotakku 0:b1ce54272580 631 *buf++ = *(p+2);
kotakku 0:b1ce54272580 632 *buf++ = *(p+3);
kotakku 0:b1ce54272580 633 rc = 3;
kotakku 0:b1ce54272580 634 break;
kotakku 0:b1ce54272580 635 case 6:
kotakku 0:b1ce54272580 636 *buf++ = *(p+1);
kotakku 0:b1ce54272580 637 *buf++ = *(p+2);
kotakku 0:b1ce54272580 638 rc = 2;
kotakku 0:b1ce54272580 639 break;
kotakku 0:b1ce54272580 640 case 5:
kotakku 0:b1ce54272580 641 *buf++ = *(p+1);
kotakku 0:b1ce54272580 642 rc = 1;
kotakku 0:b1ce54272580 643 break;
kotakku 0:b1ce54272580 644 default:
kotakku 0:b1ce54272580 645 break;
kotakku 0:b1ce54272580 646 }
kotakku 0:b1ce54272580 647 return(rc);
kotakku 0:b1ce54272580 648 }
kotakku 0:b1ce54272580 649