Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependents: STM32F103C8T6_WebUSBDFU STM32F103C8T6_USBDFU STM32F103C8T6_USBDFU dfu_usb_stm32f103
Fork of USBDevice_STM32F103 by
Revision 48:03f8e580579a, committed 2015-04-16
- Comitter:
- mbed_official
- Date:
- Thu Apr 16 11:00:20 2015 +0100
- Parent:
- 47:a0cd9646ecd1
- Child:
- 49:bee5808e91e3
- Commit message:
- Synchronized with git revision 1b9e8d686fd7448739e56182eb1f7cc0634667b5
Full URL: https://github.com/mbedmicro/mbed/commit/1b9e8d686fd7448739e56182eb1f7cc0634667b5/
Add SysEx to USBMIDI device
Changed in this revision
--- a/USBMIDI/MIDIMessage.h Wed Apr 08 07:46:23 2015 +0100
+++ b/USBMIDI/MIDIMessage.h Thu Apr 16 11:00:20 2015 +0100
@@ -21,6 +21,8 @@
#include "mbed.h"
+#define MAX_MIDI_MESSAGE_SIZE 256 // Max message size. SysEx can be up to 65536 but 256 should be fine for most usage
+
// MIDI Message Format
//
// [ msg(4) | channel(4) ] [ 0 | n(7) ] [ 0 | m(7) ]
@@ -49,6 +51,16 @@
data[i] = buf[i];
}
+ // New constructor, buf is a true MIDI message (not USBMidi message) and buf_len true message length.
+ MIDIMessage(uint8_t *buf, int buf_len) {
+ length=buf_len+1;
+ // first byte keeped for retro-compatibility
+ data[0]=0;
+
+ for (int i = 0; i < buf_len; i++)
+ data[i+1] = buf[i];
+ }
+
// create messages
/** Create a NoteOff message
@@ -162,6 +174,16 @@
return ControlChange(123, 0, channel);
}
+ /** Create a SysEx message
+ * @param data SysEx data (including 0xF0 .. 0xF7)
+ * @param len SysEx data length
+ * @returns A MIDIMessage
+ */
+ static MIDIMessage SysEx(uint8_t *data, int len) {
+ MIDIMessage msg=MIDIMessage(data,len);
+ return msg;
+ }
+
// decode messages
/** MIDI Message Types */
@@ -174,7 +196,8 @@
ProgramChangeType,
ChannelAftertouchType,
PitchWheelType,
- AllNotesOffType
+ AllNotesOffType,
+ SysExType
};
/** Read the message type
@@ -196,6 +219,7 @@
case 0xC: return ProgramChangeType;
case 0xD: return ChannelAftertouchType;
case 0xE: return PitchWheelType;
+ case 0xF: return SysExType;
default: return ErrorType;
}
}
@@ -245,7 +269,8 @@
return p - 8192; // 0 - 16383, 8192 is center
}
- uint8_t data[4];
+ uint8_t data[MAX_MIDI_MESSAGE_SIZE+1];
+ uint8_t length=4;
};
#endif
--- a/USBMIDI/USBMIDI.cpp Wed Apr 08 07:46:23 2015 +0100
+++ b/USBMIDI/USBMIDI.cpp Thu Apr 16 11:00:20 2015 +0100
@@ -25,8 +25,49 @@
USBDevice::connect();
}
+// write plain MIDIMessage that will be converted to USBMidi event packet
void USBMIDI::write(MIDIMessage m) {
- USBDevice::write(EPBULK_IN, m.data, 4, MAX_PACKET_SIZE_EPBULK);
+ // first byte keeped for retro-compatibility
+ for(int p=1; p < m.length; p+=3) {
+ uint8_t buf[4];
+ // Midi message to USBMidi event packet
+ buf[0]=m.data[1] >> 4;
+ // SysEx
+ if(buf[0] == 0xF) {
+ if((m.length - p) > 3) {
+ // SysEx start or continue
+ buf[0]=0x4;
+ } else {
+ switch(m.length - p) {
+ case 1:
+ // SysEx end with one byte
+ buf[0]=0x5;
+ break;
+ case 2:
+ // SysEx end with two bytes
+ buf[0]=0x6;
+ break;
+ case 3:
+ // SysEx end with three bytes
+ buf[0]=0x7;
+ break;
+ }
+ }
+ }
+ buf[1]=m.data[p];
+
+ if(p+1 < m.length)
+ buf[2]=m.data[p+1];
+ else
+ buf[2]=0;
+
+ if(p+2 < m.length)
+ buf[3]=m.data[p+2];
+ else
+ buf[3]=0;
+
+ USBDevice::write(EPBULK_IN, buf, 4, MAX_PACKET_SIZE_EPBULK);
+ }
}
@@ -34,16 +75,61 @@
midi_evt = fptr;
}
-
bool USBMIDI::EPBULK_OUT_callback() {
uint8_t buf[64];
uint32_t len;
readEP(EPBULK_OUT, buf, &len, 64);
if (midi_evt != NULL) {
- for (uint32_t i=0; i<len; i+=4) {
- midi_evt(MIDIMessage(buf+i));
- }
+ for (uint32_t i=0; i<len; i+=4) {
+ uint8_t data_read;
+ data_end=true;
+ switch(buf[i]) {
+ case 0x2:
+ // Two-bytes System Common Message - undefined in USBMidi 1.0
+ data_read=2;
+ break;
+ case 0x4:
+ // SysEx start or continue
+ data_end=false;
+ data_read=3;
+ break;
+ case 0x5:
+ // Single-byte System Common Message or SysEx end with one byte
+ data_read=1;
+ break;
+ case 0x6:
+ // SysEx end with two bytes
+ data_read=2;
+ break;
+ case 0xC:
+ // Program change
+ data_read=2;
+ break;
+ case 0xD:
+ // Channel pressure
+ data_read=2;
+ break;
+ case 0xF:
+ // Single byte
+ data_read=1;
+ break;
+ default:
+ // Others three-bytes messages
+ data_read=3;
+ break;
+ }
+
+ for(uint8_t j=1;j<data_read+1;j++) {
+ data[cur_data]=buf[i+j];
+ cur_data++;
+ }
+
+ if(data_end) {
+ midi_evt(MIDIMessage(data,cur_data));
+ cur_data=0;
+ }
+ }
}
// We reactivate the endpoint to receive next characters
@@ -51,8 +137,6 @@
return true;
}
-
-
// Called in ISR context
// Set configuration. Return false if the
// configuration is not supported.
--- a/USBMIDI/USBMIDI.h Wed Apr 08 07:46:23 2015 +0100
+++ b/USBMIDI/USBMIDI.h Thu Apr 16 11:00:20 2015 +0100
@@ -102,8 +102,11 @@
virtual uint8_t * configurationDesc();
private:
+ uint8_t data[MAX_MIDI_MESSAGE_SIZE+1];
+ uint8_t cur_data=0;
+ bool data_end = true;
+
void (*midi_evt)(MIDIMessage);
-
};
#endif
