Merge pull request #232 from YuuichiAkagawa/pr_usbh_midi_031

Update MIDI driver v0.3.1
This commit is contained in:
Kristian Sloth Lauszus 2016-04-27 22:34:10 +02:00
commit 2295571e2d
7 changed files with 252 additions and 93 deletions

View file

@ -320,8 +320,8 @@ HID devices are also supported by the library. However these require you to writ
The library support MIDI devices. The library support MIDI devices.
You can convert USB MIDI keyboard to legacy serial MIDI. You can convert USB MIDI keyboard to legacy serial MIDI.
* [USB_MIDI_converter.ino](USBH_MIDI/USB_MIDI_converter) * [USB_MIDI_converter.ino](examples/USBH_MIDI/USB_MIDI_converter/USB_MIDI_converter.ino)
* [USB_MIDI_converter_multi.ino](USBH_MIDI/USB_MIDI_converter_multi) * [USB_MIDI_converter_multi.ino](examples/USBH_MIDI/USB_MIDI_converter_multi/USB_MIDI_converter_multi.ino)
For information see the following page: <http://yuuichiakagawa.github.io/USBH_MIDI/>. For information see the following page: <http://yuuichiakagawa.github.io/USBH_MIDI/>.

View file

@ -64,7 +64,7 @@ void loop()
// Poll USB MIDI Controler and send to serial MIDI // Poll USB MIDI Controler and send to serial MIDI
void MIDI_poll() void MIDI_poll()
{ {
byte outBuf[ 3 ]; uint8_t outBuf[ 3 ];
uint8_t size; uint8_t size;
do { do {

View file

@ -66,7 +66,7 @@ void loop()
// Poll USB MIDI Controler and send to serial MIDI // Poll USB MIDI Controler and send to serial MIDI
void MIDI_poll() void MIDI_poll()
{ {
byte outBuf[ 3 ]; uint8_t outBuf[ 3 ];
uint8_t size; uint8_t size;
do { do {

View file

@ -40,15 +40,28 @@ MIDI_CREATE_DEFAULT_INSTANCE();
////////////////////////// //////////////////////////
USB Usb; USB Usb;
USBH_MIDI Midi(&Usb); USBH_MIDI Midi(&Usb);
void MIDI_poll(); void MIDI_poll();
void doDelay(unsigned long t1, unsigned long t2, unsigned long delayTime); void doDelay(unsigned long t1, unsigned long t2, unsigned long delayTime);
//If you want handle System Exclusive message, enable this #define otherwise comment out it.
#define USBH_MIDI_SYSEX_ENABLE
#ifdef USBH_MIDI_SYSEX_ENABLE
MidiSysEx sysExData;
//SysEx:
void handle_sysex( byte* sysexmsg, unsigned sizeofsysex) {
Midi.SendSysEx(sysexmsg, sizeofsysex);
}
#endif
void setup() void setup()
{ {
MIDI.begin(MIDI_CHANNEL_OMNI); MIDI.begin(MIDI_CHANNEL_OMNI);
#ifdef USBH_MIDI_SYSEX_ENABLE
MIDI.setHandleSystemExclusive(handle_sysex);
#endif
if (Usb.Init() == -1) { if (Usb.Init() == -1) {
while (1); //halt while (1); //halt
}//if (Usb.Init() == -1... }//if (Usb.Init() == -1...
@ -67,13 +80,17 @@ void loop()
MIDI_poll(); MIDI_poll();
if (MIDI.read()) { if (MIDI.read()) {
msg[0] = MIDI.getType(); msg[0] = MIDI.getType();
if ( msg[0] == 0xf0 ) { //SysEX switch (msg[0]) {
//TODO case midi::ActiveSensing :
//SysEx implementation is not yet. break;
} else { case midi::SystemExclusive :
msg[1] = MIDI.getData1(); //SysEx is handled by event.
msg[2] = MIDI.getData2(); break;
Midi.SendData(msg, 0); default :
msg[1] = MIDI.getData1();
msg[2] = MIDI.getData2();
Midi.SendData(msg, 0);
break;
} }
} }
} }
@ -84,13 +101,53 @@ void loop()
// Poll USB MIDI Controler and send to serial MIDI // Poll USB MIDI Controler and send to serial MIDI
void MIDI_poll() void MIDI_poll()
{ {
byte outBuf[ 3 ];
uint8_t size; uint8_t size;
#ifdef USBH_MIDI_SYSEX_ENABLE
uint8_t recvBuf[MIDI_EVENT_PACKET_SIZE];
uint8_t rcode = 0; //return code
uint16_t rcvd;
uint8_t readPtr = 0;
if ( (size = Midi.RecvData(outBuf)) > 0 ) { rcode = Midi.RecvData( &rcvd, recvBuf);
//MIDI Output
_MIDI_SERIAL_PORT.write(outBuf, size); //data check
if (rcode != 0) return;
if ( recvBuf[0] == 0 && recvBuf[1] == 0 && recvBuf[2] == 0 && recvBuf[3] == 0 ) {
return ;
} }
uint8_t *p = recvBuf;
while (readPtr < MIDI_EVENT_PACKET_SIZE) {
if (*p == 0 && *(p + 1) == 0) break; //data end
MidiSysEx::Status rc = sysExData.set(p);
switch (rc) {
case MidiSysEx::nonsysex : //No SysEx message send data to Serial MIDI
p++;
size = Midi.lookupMsgSize(*p);
_MIDI_SERIAL_PORT.write(p, size);
p += 3;
break;
case MidiSysEx::done : //SysEx end. send data to Serial MIDI
_MIDI_SERIAL_PORT.write(sysExData.get(), sysExData.getSize());
/* FALLTHROUGH */
case MidiSysEx::overflow : //SysEx buffer over. ignore and flush buffer.
sysExData.clear();
/* FALLTHROUGH */
default:
p += 4;
break;
}
readPtr += 4;
}
#else
uint8_t outBuf[ 3 ];
do {
if ( (size = Midi.RecvData(outBuf)) > 0 ) {
//MIDI Output
_MIDI_SERIAL_PORT.write(outBuf, size);
}
} while (size > 0);
#endif
} }
// Delay time (max 16383 us) // Delay time (max 16383 us)

View file

@ -61,7 +61,7 @@ void loop()
// Poll USB MIDI Controler // Poll USB MIDI Controler
void MIDI_poll() void MIDI_poll()
{ {
byte inBuf[ 3 ]; uint8_t inBuf[ 3 ];
//first call? //first call?
if (Midi.vid != vid || Midi.pid != pid) { if (Midi.vid != vid || Midi.pid != pid) {

218
usbh_midi.cpp Executable file → Normal file
View file

@ -116,11 +116,10 @@ uint8_t USBH_MIDI::Init(uint8_t parent, uint8_t port, bool lowspeed)
EpInfo *oldep_ptr = NULL; EpInfo *oldep_ptr = NULL;
uint8_t num_of_conf; // number of configurations uint8_t num_of_conf; // number of configurations
USBTRACE("\rMIDI Init\r\n");
// get memory address of USB device address pool // get memory address of USB device address pool
AddressPool &addrPool = pUsb->GetAddressPool(); AddressPool &addrPool = pUsb->GetAddressPool();
#ifdef DEBUG_USB_HOST
USBTRACE("\rMIDI Init\r\n");
#endif
// check if address has already been assigned to an instance // check if address has already been assigned to an instance
if (bAddress) { if (bAddress) {
return USB_ERROR_CLASS_INSTANCE_ALREADY_IN_USE; return USB_ERROR_CLASS_INSTANCE_ALREADY_IN_USE;
@ -169,9 +168,8 @@ uint8_t USBH_MIDI::Init(uint8_t parent, uint8_t port, bool lowspeed)
bAddress = 0; bAddress = 0;
return rcode; return rcode;
}//if (rcode... }//if (rcode...
#ifdef DEBUG_USB_HOST
USBTRACE2("Addr:", bAddress); USBTRACE2("Addr:", bAddress);
#endif
p->lowspeed = false; p->lowspeed = false;
//get pointer to assigned address record //get pointer to assigned address record
@ -186,27 +184,29 @@ uint8_t USBH_MIDI::Init(uint8_t parent, uint8_t port, bool lowspeed)
// Assign epInfo to epinfo pointer // Assign epInfo to epinfo pointer
rcode = pUsb->setEpInfoEntry(bAddress, 1, epInfo); rcode = pUsb->setEpInfoEntry(bAddress, 1, epInfo);
if (rcode) { if (rcode) {
#ifdef DEBUG_USB_HOST
USBTRACE("setEpInfoEntry failed"); USBTRACE("setEpInfoEntry failed");
#endif
goto FailSetDevTblEntry; goto FailSetDevTblEntry;
} }
#ifdef DEBUG_USB_HOST
USBTRACE2("NC:", num_of_conf); USBTRACE("VID:"), D_PrintHex(vid, 0x80);
#endif USBTRACE(" PID:"), D_PrintHex(pid, 0x80);
USBTRACE2(" #Conf:", num_of_conf);
for (uint8_t i=0; i<num_of_conf; i++) { for (uint8_t i=0; i<num_of_conf; i++) {
parseConfigDescr(bAddress, i); parseConfigDescr(bAddress, i);
if (bNumEP > 1) if (bNumEP > 1)
break; break;
} // for } // for
#ifdef DEBUG_USB_HOST
USBTRACE2("NumEP:", bNumEP); USBTRACE2("\r\nNumEP:", bNumEP);
#endif
if( bConfNum == 0 ){ //Device not found. if( bNumEP < 3 ){ //Device not found.
rcode = 0xff;
goto FailGetConfDescr; goto FailGetConfDescr;
} }
if( !isMidiFound ){ //MIDI Device not found. Try first Bulk transfer device if( !isMidiFound ){ //MIDI Device not found. Try last Bulk transfer device
USBTRACE("MIDI not found. Attempts bulk device\r\n");
epInfo[epDataInIndex].epAddr = epInfo[epDataInIndexVSP].epAddr; epInfo[epDataInIndex].epAddr = epInfo[epDataInIndexVSP].epAddr;
epInfo[epDataInIndex].maxPktSize = epInfo[epDataInIndexVSP].maxPktSize; epInfo[epDataInIndex].maxPktSize = epInfo[epDataInIndexVSP].maxPktSize;
epInfo[epDataOutIndex].epAddr = epInfo[epDataOutIndexVSP].epAddr; epInfo[epDataOutIndex].epAddr = epInfo[epDataOutIndexVSP].epAddr;
@ -215,18 +215,17 @@ uint8_t USBH_MIDI::Init(uint8_t parent, uint8_t port, bool lowspeed)
// Assign epInfo to epinfo pointer // Assign epInfo to epinfo pointer
rcode = pUsb->setEpInfoEntry(bAddress, bNumEP, epInfo); rcode = pUsb->setEpInfoEntry(bAddress, bNumEP, epInfo);
#ifdef DEBUG_USB_HOST
USBTRACE2("Conf:", bConfNum); USBTRACE2("Conf:", bConfNum);
#endif USBTRACE2("EPin :", (uint8_t)(epInfo[epDataInIndex].epAddr + 0x80));
USBTRACE2("EPout:", epInfo[epDataOutIndex].epAddr);
// Set Configuration Value // Set Configuration Value
rcode = pUsb->setConf(bAddress, 0, bConfNum); rcode = pUsb->setConf(bAddress, 0, bConfNum);
if (rcode) { if (rcode) {
goto FailSetConfDescr; goto FailSetConfDescr;
} }
#ifdef DEBUG_USB_HOST
USBTRACE("Init done.");
#endif
bPollEnable = true; bPollEnable = true;
USBTRACE("Init done.\r\n");
return 0; return 0;
FailGetDevDescr: FailGetDevDescr:
FailSetDevTblEntry: FailSetDevTblEntry:
@ -237,13 +236,13 @@ FailSetConfDescr:
} }
/* get and parse config descriptor */ /* get and parse config descriptor */
void USBH_MIDI::parseConfigDescr( byte addr, byte conf ) void USBH_MIDI::parseConfigDescr( uint8_t addr, uint8_t conf )
{ {
uint8_t buf[ DESC_BUFF_SIZE ]; uint8_t buf[ DESC_BUFF_SIZE ];
uint8_t* buf_ptr = buf; uint8_t* buf_ptr = buf;
byte rcode; uint8_t rcode;
byte descr_length; uint8_t descr_length;
byte descr_type; uint8_t descr_type;
unsigned int total_length; unsigned int total_length;
USB_ENDPOINT_DESCRIPTOR *epDesc; USB_ENDPOINT_DESCRIPTOR *epDesc;
boolean isMidi = false; boolean isMidi = false;
@ -273,18 +272,28 @@ void USBH_MIDI::parseConfigDescr( byte addr, byte conf )
bConfNum = buf_ptr[5]; bConfNum = buf_ptr[5];
break; break;
case USB_DESCRIPTOR_INTERFACE : case USB_DESCRIPTOR_INTERFACE :
USBTRACE("\r\nConf:"), D_PrintHex(bConfNum, 0x80);
USBTRACE(" Int:"), D_PrintHex(buf_ptr[2], 0x80);
USBTRACE(" Alt:"), D_PrintHex(buf_ptr[3], 0x80);
USBTRACE(" EPs:"), D_PrintHex(buf_ptr[4], 0x80);
USBTRACE(" IntCl:"), D_PrintHex(buf_ptr[5], 0x80);
USBTRACE(" IntSubCl:"), D_PrintHex(buf_ptr[6], 0x80);
USBTRACE("\r\n");
if( buf_ptr[5] == USB_CLASS_AUDIO && buf_ptr[6] == USB_SUBCLASS_MIDISTREAMING ) { //p[5]; bInterfaceClass = 1(Audio), p[6]; bInterfaceSubClass = 3(MIDI Streaming) if( buf_ptr[5] == USB_CLASS_AUDIO && buf_ptr[6] == USB_SUBCLASS_MIDISTREAMING ) { //p[5]; bInterfaceClass = 1(Audio), p[6]; bInterfaceSubClass = 3(MIDI Streaming)
isMidiFound = true; //MIDI device found. isMidiFound = true; //MIDI device found.
isMidi = true; isMidi = true;
USBTRACE("MIDI Device\r\n");
}else{ }else{
#ifdef DEBUG_USB_HOST
USBTRACE("No MIDI Device\n");
#endif
isMidi = false; isMidi = false;
USBTRACE("No MIDI Device\r\n");
} }
break; break;
case USB_DESCRIPTOR_ENDPOINT : case USB_DESCRIPTOR_ENDPOINT :
epDesc = (USB_ENDPOINT_DESCRIPTOR *)buf_ptr; epDesc = (USB_ENDPOINT_DESCRIPTOR *)buf_ptr;
USBTRACE("-EPAddr:"), D_PrintHex(epDesc->bEndpointAddress, 0x80);
USBTRACE(" bmAttr:"), D_PrintHex(epDesc->bmAttributes, 0x80);
USBTRACE2(" MaxPktSz:", (uint8_t)epDesc->wMaxPacketSize);
if ((epDesc->bmAttributes & 0x02) == 2) {//bulk if ((epDesc->bmAttributes & 0x02) == 2) {//bulk
uint8_t index; uint8_t index;
if( isMidi ) if( isMidi )
@ -333,7 +342,7 @@ uint8_t USBH_MIDI::RecvData(uint16_t *bytes_rcvd, uint8_t *dataptr)
/* Receive data from MIDI device */ /* Receive data from MIDI device */
uint8_t USBH_MIDI::RecvData(uint8_t *outBuf) uint8_t USBH_MIDI::RecvData(uint8_t *outBuf)
{ {
byte rcode = 0; //return code uint8_t rcode = 0; //return code
uint16_t rcvd; uint16_t rcvd;
if( bPollEnable == false ) return false; if( bPollEnable == false ) return false;
@ -370,10 +379,10 @@ RecvData_return_from_buffer:
} }
/* Send data to MIDI device */ /* Send data to MIDI device */
uint8_t USBH_MIDI::SendData(uint8_t *dataptr, byte nCable) uint8_t USBH_MIDI::SendData(uint8_t *dataptr, uint8_t nCable)
{ {
byte buf[4]; uint8_t buf[4];
byte msg; uint8_t msg;
msg = dataptr[0]; msg = dataptr[0];
// SysEx long message ? // SysEx long message ?
@ -407,7 +416,7 @@ uint8_t USBH_MIDI::SendData(uint8_t *dataptr, byte nCable)
buf[3] = 0; buf[3] = 0;
break; break;
//1 bytes message //1 byte message
case 1 : case 1 :
default : default :
buf[2] = 0; buf[2] = 0;
@ -420,20 +429,13 @@ uint8_t USBH_MIDI::SendData(uint8_t *dataptr, byte nCable)
#ifdef DEBUG_USB_HOST #ifdef DEBUG_USB_HOST
void USBH_MIDI::PrintEndpointDescriptor( const USB_ENDPOINT_DESCRIPTOR* ep_ptr ) void USBH_MIDI::PrintEndpointDescriptor( const USB_ENDPOINT_DESCRIPTOR* ep_ptr )
{ {
Notify(PSTR("Endpoint descriptor:"), 0x80); USBTRACE("Endpoint descriptor:\r\n");
Notify(PSTR("\r\nLength:\t\t"), 0x80); USBTRACE2(" Length:\t", ep_ptr->bLength);
PrintHex<uint8_t>(ep_ptr->bLength, 0x80); USBTRACE2(" Type:\t\t", ep_ptr->bDescriptorType);
Notify(PSTR("\r\nType:\t\t"), 0x80); USBTRACE2(" Address:\t", ep_ptr->bEndpointAddress);
PrintHex<uint8_t>(ep_ptr->bDescriptorType, 0x80); USBTRACE2(" Attributes:\t", ep_ptr->bmAttributes);
Notify(PSTR("\r\nAddress:\t"), 0x80); USBTRACE2(" MaxPktSize:\t", ep_ptr->wMaxPacketSize);
PrintHex<uint8_t>(ep_ptr->bEndpointAddress, 0x80); USBTRACE2(" Poll Intrv:\t", ep_ptr->bInterval);
Notify(PSTR("\r\nAttributes:\t"), 0x80);
PrintHex<uint8_t>(ep_ptr->bmAttributes, 0x80);
Notify(PSTR("\r\nMaxPktSize:\t"), 0x80);
PrintHex<uint16_t>(ep_ptr->wMaxPacketSize, 0x80);
Notify(PSTR("\r\nPoll Intrv:\t"), 0x80);
PrintHex<uint8_t>(ep_ptr->bInterval, 0x80);
Notify(PSTR("\r\n"), 0x80);
} }
#endif #endif
@ -465,7 +467,7 @@ uint8_t USBH_MIDI::lookupMsgSize(uint8_t midiMsg)
msgSize = 2; msgSize = 2;
break; break;
//1 bytes messages //1 byte messages
case 0xf8 : //system realtime message case 0xf8 : //system realtime message
case 0xf9 : //system realtime message case 0xf9 : //system realtime message
case 0xfa : //system realtime message case 0xfa : //system realtime message
@ -508,43 +510,121 @@ unsigned int USBH_MIDI::countSysExDataSize(uint8_t *dataptr)
} }
/* Send SysEx message to MIDI device */ /* Send SysEx message to MIDI device */
uint8_t USBH_MIDI::SendSysEx(uint8_t *dataptr, unsigned int datasize, byte nCable) uint8_t USBH_MIDI::SendSysEx(uint8_t *dataptr, unsigned int datasize, uint8_t nCable)
{ {
byte buf[4]; uint8_t buf[64];
uint8_t rc; uint8_t rc;
unsigned int n = datasize; unsigned int n = datasize;
unsigned int pktSize = (n*10/3+7)/10*4; //Calculate total USB MIDI packet size
uint8_t wptr = 0;
uint8_t maxpkt = epInfo[epDataInIndex].maxPktSize;
USBTRACE("SendSysEx:\r\t");
USBTRACE2(" Length:\t", datasize);
USBTRACE2(" Total pktSize:\t", pktSize);
while(n > 0) { while(n > 0) {
//Byte 0 //Byte 0
buf[0] = (nCable << 4) | 0x4; //x4 SysEx starts or continues buf[wptr] = (nCable << 4) | 0x4; //x4 SysEx starts or continues
switch ( n ) { switch ( n ) {
case 1 : case 1 :
buf[0] = (nCable << 4) | 0x5; //x5 SysEx ends with following single byte. buf[wptr++] = (nCable << 4) | 0x5; //x5 SysEx ends with following single byte.
buf[1] = *(dataptr++); buf[wptr++] = *(dataptr++);
buf[2] = 0x00; buf[wptr++] = 0x00;
buf[3] = 0x00; buf[wptr++] = 0x00;
n = n - 1; n = n - 1;
break; break;
case 2 : case 2 :
buf[0] = (nCable << 4) | 0x6; //x6 SysEx ends with following two bytes. buf[wptr++] = (nCable << 4) | 0x6; //x6 SysEx ends with following two bytes.
buf[1] = *(dataptr++); buf[wptr++] = *(dataptr++);
buf[2] = *(dataptr++); buf[wptr++] = *(dataptr++);
buf[3] = 0x00; buf[wptr++] = 0x00;
n = n - 2; n = n - 2;
break; break;
case 3 : case 3 :
buf[0] = (nCable << 4) | 0x7; //x7 SysEx ends with following three bytes. buf[wptr] = (nCable << 4) | 0x7; //x7 SysEx ends with following three bytes.
default : default :
buf[1] = *(dataptr++); wptr++;
buf[2] = *(dataptr++); buf[wptr++] = *(dataptr++);
buf[3] = *(dataptr++); buf[wptr++] = *(dataptr++);
buf[wptr++] = *(dataptr++);
n = n - 3; n = n - 3;
break; break;
} }
rc = pUsb->outTransfer(bAddress, epInfo[epDataOutIndex].epAddr, 4, buf);
if(rc != 0) if( wptr >= maxpkt || n == 0 ){ //Reach a maxPktSize or data end.
break; USBTRACE2(" wptr:\t", wptr);
if( (rc = pUsb->outTransfer(bAddress, epInfo[epDataOutIndex].epAddr, wptr, buf)) != 0 ){
break;
}
wptr = 0; //rewind data pointer
}
}
return(rc);
}
/* Send raw data to MIDI device */
uint8_t USBH_MIDI::SendRawData(uint16_t bytes_send, uint8_t *dataptr)
{
return pUsb->outTransfer(bAddress, epInfo[epDataOutIndex].epAddr, bytes_send, dataptr);
}
//
// System Exclusive packet data management class
//
MidiSysEx::MidiSysEx()
{
clear();
}
void MidiSysEx::clear()
{
pos = 0;
buf[0] = 0;
}
MidiSysEx::Status MidiSysEx::set(uint8_t *p)
{
MidiSysEx::Status rc = MidiSysEx::ok;
uint8_t cin = *(p) & 0x0f;
//SysEx message?
if( (cin & 0xc) != 4 ) return MidiSysEx::nonsysex;
switch(cin) {
case 4:
case 7:
if( pos+2 < MIDI_EVENT_PACKET_SIZE ) {
buf[pos++] = *(p+1);
buf[pos++] = *(p+2);
buf[pos++] = *(p+3);
}else{
rc = MidiSysEx::overflow;
}
break;
case 5:
if( pos+1 < MIDI_EVENT_PACKET_SIZE ) {
buf[pos++] = *(p+1);
buf[pos++] = *(p+2);
}else{
rc = MidiSysEx::overflow;
}
break;
case 6:
if( pos < MIDI_EVENT_PACKET_SIZE ) {
buf[pos++] = *(p+1);
}else{
rc = MidiSysEx::overflow;
}
break;
default:
break;
}
//SysEx end?
if((cin & 0x3) != 0) {
rc = MidiSysEx::done;
} }
return(rc); return(rc);
} }

34
usbh_midi.h Executable file → Normal file
View file

@ -26,6 +26,7 @@
#if !defined(_USBH_MIDI_H_) #if !defined(_USBH_MIDI_H_)
#define _USBH_MIDI_H_ #define _USBH_MIDI_H_
//#define DEBUG_USB_HOST
#include "Usb.h" #include "Usb.h"
#define MIDI_MAX_ENDPOINTS 5 //endpoint 0, bulk_IN(MIDI), bulk_OUT(MIDI), bulk_IN(VSP), bulk_OUT(VSP) #define MIDI_MAX_ENDPOINTS 5 //endpoint 0, bulk_IN(MIDI), bulk_OUT(MIDI), bulk_IN(VSP), bulk_OUT(VSP)
@ -36,9 +37,6 @@ class USBH_MIDI;
class USBH_MIDI : public USBDeviceConfig class USBH_MIDI : public USBDeviceConfig
{ {
private:
uint8_t lookupMsgSize(uint8_t midiMsg);
protected: protected:
static const uint8_t epDataInIndex; // DataIn endpoint index(MIDI) static const uint8_t epDataInIndex; // DataIn endpoint index(MIDI)
static const uint8_t epDataOutIndex; // DataOUT endpoint index(MIDI) static const uint8_t epDataOutIndex; // DataOUT endpoint index(MIDI)
@ -59,7 +57,7 @@ protected:
uint8_t recvBuf[MIDI_EVENT_PACKET_SIZE]; uint8_t recvBuf[MIDI_EVENT_PACKET_SIZE];
uint8_t readPtr; uint8_t readPtr;
void parseConfigDescr(byte addr, byte conf); void parseConfigDescr(uint8_t addr, uint8_t conf);
unsigned int countSysExDataSize(uint8_t *dataptr); unsigned int countSysExDataSize(uint8_t *dataptr);
#ifdef DEBUG_USB_HOST #ifdef DEBUG_USB_HOST
void PrintEndpointDescriptor( const USB_ENDPOINT_DESCRIPTOR* ep_ptr ); void PrintEndpointDescriptor( const USB_ENDPOINT_DESCRIPTOR* ep_ptr );
@ -70,8 +68,10 @@ public:
// Methods for recieving and sending data // Methods for recieving and sending data
uint8_t RecvData(uint16_t *bytes_rcvd, uint8_t *dataptr); uint8_t RecvData(uint16_t *bytes_rcvd, uint8_t *dataptr);
uint8_t RecvData(uint8_t *outBuf); uint8_t RecvData(uint8_t *outBuf);
uint8_t SendData(uint8_t *dataptr, byte nCable=0); uint8_t SendData(uint8_t *dataptr, uint8_t nCable=0);
uint8_t SendSysEx(uint8_t *dataptr, unsigned int datasize, byte nCable=0); uint8_t lookupMsgSize(uint8_t midiMsg);
uint8_t SendSysEx(uint8_t *dataptr, unsigned int datasize, uint8_t nCable=0);
uint8_t SendRawData(uint16_t bytes_send, uint8_t *dataptr);
// backward compatibility functions // backward compatibility functions
inline uint8_t RcvData(uint16_t *bytes_rcvd, uint8_t *dataptr){ return RecvData(bytes_rcvd, dataptr); }; inline uint8_t RcvData(uint16_t *bytes_rcvd, uint8_t *dataptr){ return RecvData(bytes_rcvd, dataptr); };
inline uint8_t RcvData(uint8_t *outBuf){ return RecvData(outBuf); }; inline uint8_t RcvData(uint8_t *outBuf){ return RecvData(outBuf); };
@ -82,4 +82,26 @@ public:
virtual uint8_t GetAddress() { return bAddress; }; virtual uint8_t GetAddress() { return bAddress; };
}; };
//
// System Exclusive packet data management class
//
class MidiSysEx {
private:
uint8_t pos;
uint8_t buf[MIDI_EVENT_PACKET_SIZE];
public:
typedef enum {
nonsysex = 0,
ok = 1,
done = 0xfe,
overflow = 0xff
} Status;
MidiSysEx();
void clear();
MidiSysEx::Status set(uint8_t *p);
inline uint8_t *get(){return buf;};
inline uint8_t getSize(){return pos;};
};
#endif //_USBH_MIDI_H_ #endif //_USBH_MIDI_H_