Merge pull request #368 from YuuichiAkagawa/pr_usbh_midi_040

Update MIDI driver v0.4.0
This commit is contained in:
Kristian Sloth Lauszus 2018-03-24 18:27:17 +01:00 committed by GitHub
commit 208a0a75cf
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
7 changed files with 45 additions and 85 deletions

View file

@ -24,14 +24,11 @@ USB Usb;
USBH_MIDI Midi(&Usb); USBH_MIDI Midi(&Usb);
void MIDI_poll(); void MIDI_poll();
void doDelay(uint32_t t1, uint32_t t2, uint32_t delayTime);
boolean bFirst;
uint16_t pid, vid; uint16_t pid, vid;
void setup() void setup()
{ {
bFirst = true;
vid = pid = 0; vid = pid = 0;
Serial.begin(115200); Serial.begin(115200);
@ -45,12 +42,9 @@ void loop()
{ {
Usb.Task(); Usb.Task();
//uint32_t t1 = (uint32_t)micros(); //uint32_t t1 = (uint32_t)micros();
if ( Usb.getUsbTaskState() == USB_STATE_RUNNING ) if ( Midi ) {
{
MIDI_poll(); MIDI_poll();
} }
//delay(1ms)
//doDelay(t1, (uint32_t)micros(), 1000);
} }
// Poll USB MIDI Controler and send to serial MIDI // Poll USB MIDI Controler and send to serial MIDI
@ -60,11 +54,11 @@ void MIDI_poll()
uint8_t bufMidi[64]; uint8_t bufMidi[64];
uint16_t rcvd; uint16_t rcvd;
if (Midi.vid != vid || Midi.pid != pid) { if (Midi.idVendor() != vid || Midi.idProduct() != pid) {
sprintf(buf, "VID:%04X, PID:%04X", Midi.vid, Midi.pid); vid = Midi.idVendor();
pid = Midi.idProduct();
sprintf(buf, "VID:%04X, PID:%04X", vid, pid);
Serial.println(buf); Serial.println(buf);
vid = Midi.vid;
pid = Midi.pid;
} }
if (Midi.RecvData( &rcvd, bufMidi) == 0 ) { if (Midi.RecvData( &rcvd, bufMidi) == 0 ) {
uint32_t time = (uint32_t)millis(); uint32_t time = (uint32_t)millis();
@ -79,19 +73,3 @@ void MIDI_poll()
Serial.println(""); Serial.println("");
} }
} }
// Delay time (max 16383 us)
void doDelay(uint32_t t1, uint32_t t2, uint32_t delayTime)
{
uint32_t t3;
if ( t1 > t2 ) {
t3 = (0xFFFFFFFF - t1 + t2);
} else {
t3 = t2 - t1;
}
if ( t3 < delayTime ) {
delayMicroseconds(delayTime - t3);
}
}

View file

@ -51,8 +51,7 @@ void loop()
{ {
Usb.Task(); Usb.Task();
uint32_t t1 = (uint32_t)micros(); uint32_t t1 = (uint32_t)micros();
if ( Usb.getUsbTaskState() == USB_STATE_RUNNING ) if ( Midi ) {
{
MIDI_poll(); MIDI_poll();
} }
//delay(1ms) //delay(1ms)
@ -78,12 +77,7 @@ void doDelay(uint32_t t1, uint32_t t2, uint32_t delayTime)
{ {
uint32_t t3; uint32_t t3;
if ( t1 > t2 ) { t3 = t2 - t1;
t3 = (0xFFFFFFFF - t1 + t2);
} else {
t3 = t2 - t1;
}
if ( t3 < delayTime ) { if ( t3 < delayTime ) {
delayMicroseconds(delayTime - t3); delayMicroseconds(delayTime - t3);
} }

View file

@ -53,28 +53,24 @@ void loop()
{ {
Usb.Task(); Usb.Task();
uint32_t t1 = (uint32_t)micros(); uint32_t t1 = (uint32_t)micros();
if ( Usb.getUsbTaskState() == USB_STATE_RUNNING ) if ( Midi1 ) {
{ MIDI_poll(Midi1);
MIDI_poll(); }
if ( Midi2 ) {
MIDI_poll(Midi2);
} }
//delay(1ms) //delay(1ms)
doDelay(t1, (uint32_t)micros(), 1000); doDelay(t1, (uint32_t)micros(), 1000);
} }
// Poll USB MIDI Controler and send to serial MIDI // Poll USB MIDI Controler and send to serial MIDI
void MIDI_poll() void MIDI_poll(USBH_MIDI &Midi)
{ {
uint8_t outBuf[ 3 ]; uint8_t outBuf[ 3 ];
uint8_t size; uint8_t size;
do { do {
if ( (size = Midi1.RecvData(outBuf)) > 0 ) { if ( (size = Midi.RecvData(outBuf)) > 0 ) {
//MIDI Output
_MIDI_SERIAL_PORT.write(outBuf, size);
}
} while (size > 0);
do {
if ( (size = Midi2.RecvData(outBuf)) > 0 ) {
//MIDI Output //MIDI Output
_MIDI_SERIAL_PORT.write(outBuf, size); _MIDI_SERIAL_PORT.write(outBuf, size);
} }
@ -86,12 +82,7 @@ void doDelay(uint32_t t1, uint32_t t2, uint32_t delayTime)
{ {
uint32_t t3; uint32_t t3;
if ( t1 > t2 ) { t3 = t2 - t1;
t3 = (0xFFFFFFFF - t1 + t2);
} else {
t3 = t2 - t1;
}
if ( t3 < delayTime ) { if ( t3 < delayTime ) {
delayMicroseconds(delayTime - t3); delayMicroseconds(delayTime - t3);
} }

View file

@ -43,7 +43,6 @@ USB Usb;
USBH_MIDI Midi(&Usb); USBH_MIDI Midi(&Usb);
void MIDI_poll(); void MIDI_poll();
void doDelay(uint32_t t1, uint32_t t2, uint32_t delayTime);
//If you want handle System Exclusive message, enable this #define otherwise comment out it. //If you want handle System Exclusive message, enable this #define otherwise comment out it.
#define USBH_MIDI_SYSEX_ENABLE #define USBH_MIDI_SYSEX_ENABLE
@ -58,6 +57,7 @@ void handle_sysex( byte* sysexmsg, unsigned sizeofsysex) {
void setup() void setup()
{ {
MIDI.begin(MIDI_CHANNEL_OMNI); MIDI.begin(MIDI_CHANNEL_OMNI);
MIDI.turnThruOff();
#ifdef USBH_MIDI_SYSEX_ENABLE #ifdef USBH_MIDI_SYSEX_ENABLE
MIDI.setHandleSystemExclusive(handle_sysex); MIDI.setHandleSystemExclusive(handle_sysex);
#endif #endif
@ -72,9 +72,7 @@ void loop()
uint8_t msg[4]; uint8_t msg[4];
Usb.Task(); Usb.Task();
uint32_t t1 = (uint32_t)micros(); if ( Midi ) {
if ( Usb.getUsbTaskState() == USB_STATE_RUNNING )
{
MIDI_poll(); MIDI_poll();
if (MIDI.read()) { if (MIDI.read()) {
msg[0] = MIDI.getType(); msg[0] = MIDI.getType();
@ -92,8 +90,6 @@ void loop()
} }
} }
} }
//delay(1ms)
doDelay(t1, (uint32_t)micros(), 1000);
} }
// Poll USB MIDI Controler and send to serial MIDI // Poll USB MIDI Controler and send to serial MIDI
@ -141,19 +137,3 @@ void MIDI_poll()
} while (size > 0); } while (size > 0);
#endif #endif
} }
// Delay time (max 16383 us)
void doDelay(uint32_t t1, uint32_t t2, uint32_t delayTime)
{
uint32_t t3;
if ( t1 > t2 ) {
t3 = (0xFFFFFFFF - t1 + t2);
} else {
t3 = t2 - t1;
}
if ( t3 < delayTime ) {
delayMicroseconds(delayTime - t3);
}
}

View file

@ -48,8 +48,7 @@ void setup()
void loop() void loop()
{ {
Usb.Task(); Usb.Task();
if ( Usb.getUsbTaskState() == USB_STATE_RUNNING ) if( Midi ) {
{
MIDI_poll(); MIDI_poll();
noteOn(0x3f); noteOn(0x3f);
delay(400); delay(400);
@ -64,8 +63,8 @@ void MIDI_poll()
uint8_t inBuf[ 3 ]; uint8_t inBuf[ 3 ];
//first call? //first call?
if (Midi.vid != vid || Midi.pid != pid) { if (Midi.idVendor() != vid || Midi.idProduct() != pid) {
vid = Midi.vid; pid = Midi.pid; vid = Midi.idVendor(); pid = Midi.idProduct();
Midi.SendSysEx(exdata, sizeof(exdata)); Midi.SendSysEx(exdata, sizeof(exdata));
delay(500); delay(500);
} }

View file

@ -1,7 +1,7 @@
/* /*
******************************************************************************* *******************************************************************************
* USB-MIDI class driver for USB Host Shield 2.0 Library * USB-MIDI class driver for USB Host Shield 2.0 Library
* Copyright (c) 2012-2017 Yuuichi Akagawa * Copyright (c) 2012-2018 Yuuichi Akagawa
* *
* Idea from LPK25 USB-MIDI to Serial MIDI converter * Idea from LPK25 USB-MIDI to Serial MIDI converter
* by Collin Cunningham - makezine.com, narbotic.com * by Collin Cunningham - makezine.com, narbotic.com
@ -199,6 +199,10 @@ uint8_t USBH_MIDI::Init(uint8_t parent, uint8_t port, bool lowspeed)
USBTRACE(" PID:"), D_PrintHex(pid, 0x80); USBTRACE(" PID:"), D_PrintHex(pid, 0x80);
USBTRACE2(" #Conf:", num_of_conf); USBTRACE2(" #Conf:", num_of_conf);
//Setup for well known vendor/device specific configuration
bTransferTypeMask = bmUSB_TRANSFER_TYPE;
setupDeviceSpecific();
isMidiFound = false; isMidiFound = false;
for (uint8_t i=0; i<num_of_conf; i++) { for (uint8_t i=0; i<num_of_conf; i++) {
rcode = parseConfigDescr(bAddress, i); rcode = parseConfigDescr(bAddress, i);
@ -304,7 +308,7 @@ uint8_t USBH_MIDI::parseConfigDescr( uint8_t addr, uint8_t conf )
USBTRACE("-EPAddr:"), D_PrintHex(epDesc->bEndpointAddress, 0x80); USBTRACE("-EPAddr:"), D_PrintHex(epDesc->bEndpointAddress, 0x80);
USBTRACE(" bmAttr:"), D_PrintHex(epDesc->bmAttributes, 0x80); USBTRACE(" bmAttr:"), D_PrintHex(epDesc->bmAttributes, 0x80);
USBTRACE2(" MaxPktSz:", (uint8_t)epDesc->wMaxPacketSize); USBTRACE2(" MaxPktSz:", (uint8_t)epDesc->wMaxPacketSize);
if ((epDesc->bmAttributes & bmUSB_TRANSFER_TYPE) == USB_TRANSFER_TYPE_BULK) {//bulk if ((epDesc->bmAttributes & bTransferTypeMask) == USB_TRANSFER_TYPE_BULK) {//bulk
uint8_t index; uint8_t index;
if( isMidi ) if( isMidi )
index = ((epDesc->bEndpointAddress & 0x80) == 0x80) ? epDataInIndex : epDataOutIndex; index = ((epDesc->bEndpointAddress & 0x80) == 0x80) ? epDataInIndex : epDataOutIndex;
@ -337,6 +341,18 @@ uint8_t USBH_MIDI::Release()
return 0; return 0;
} }
/* Setup for well known vendor/device specific configuration */
void USBH_MIDI::setupDeviceSpecific()
{
// Novation
if( vid == 0x1235 ) {
// LaunchPad's endpoint attirbute is interrupt (0x20:S, 0x36:Mini, 0x51:Pro, 0x69:MK2)
if(pid == 0x20 || pid == 0x36 || pid == 0x51 || pid == 0x69 ) {
bTransferTypeMask = 2;
}
}
}
/* Receive data from MIDI device */ /* Receive data from MIDI device */
uint8_t USBH_MIDI::RecvData(uint16_t *bytes_rcvd, uint8_t *dataptr) uint8_t USBH_MIDI::RecvData(uint16_t *bytes_rcvd, uint8_t *dataptr)
{ {

View file

@ -1,7 +1,7 @@
/* /*
******************************************************************************* *******************************************************************************
* USB-MIDI class driver for USB Host Shield 2.0 Library * USB-MIDI class driver for USB Host Shield 2.0 Library
* Copyright (c) 2012-2017 Yuuichi Akagawa * Copyright (c) 2012-2018 Yuuichi Akagawa
* *
* Idea from LPK25 USB-MIDI to Serial MIDI converter * Idea from LPK25 USB-MIDI to Serial MIDI converter
* by Collin Cunningham - makezine.com, narbotic.com * by Collin Cunningham - makezine.com, narbotic.com
@ -50,8 +50,9 @@ protected:
uint8_t bConfNum; // configuration number uint8_t bConfNum; // configuration number
uint8_t bNumEP; // total number of EP in the configuration uint8_t bNumEP; // total number of EP in the configuration
bool bPollEnable; bool bPollEnable;
bool isMidiFound;
bool isMidiFound; uint16_t pid, vid; // ProductID, VendorID
uint8_t bTransferTypeMask;
/* Endpoint data structure */ /* Endpoint data structure */
EpInfo epInfo[MIDI_MAX_ENDPOINTS]; EpInfo epInfo[MIDI_MAX_ENDPOINTS];
/* MIDI Event packet buffer */ /* MIDI Event packet buffer */
@ -60,13 +61,14 @@ protected:
uint8_t parseConfigDescr(uint8_t addr, uint8_t conf); uint8_t parseConfigDescr(uint8_t addr, uint8_t conf);
uint16_t countSysExDataSize(uint8_t *dataptr); uint16_t countSysExDataSize(uint8_t *dataptr);
void setupDeviceSpecific();
#ifdef DEBUG_USB_HOST #ifdef DEBUG_USB_HOST
void PrintEndpointDescriptor( const USB_ENDPOINT_DESCRIPTOR* ep_ptr ); void PrintEndpointDescriptor( const USB_ENDPOINT_DESCRIPTOR* ep_ptr );
#endif #endif
public: public:
uint16_t pid, vid;
USBH_MIDI(USB *p); USBH_MIDI(USB *p);
operator bool() { return (pUsb->getUsbTaskState()==USB_STATE_RUNNING && isMidiFound); } // Misc functions
operator bool() { return (pUsb->getUsbTaskState()==USB_STATE_RUNNING); }
uint16_t idVendor() { return vid; } uint16_t idVendor() { return vid; }
uint16_t idProduct() { return pid; } uint16_t idProduct() { return pid; }
// Methods for recieving and sending data // Methods for recieving and sending data