1
0
Fork 0

Squashed 'tmk_core/' changes from 7967731..b9e0ea0

b9e0ea0 Merge commit '7fa9d8bdea3773d1195b04d98fcf27cf48ddd81d' as 'tool/mbed/mbed-sdk'
7fa9d8b Squashed 'tool/mbed/mbed-sdk/' content from commit 7c21ce5

git-subtree-dir: tmk_core
git-subtree-split: b9e0ea08cb940de20b3610ecdda18e9d8cd7c552
This commit is contained in:
Jun Wako 2015-04-24 16:26:14 +09:00
parent a20ef7052c
commit 1fe4406f37
4198 changed files with 2016457 additions and 0 deletions

View file

@ -0,0 +1,276 @@
/* Copyright (c) 2010-2011 mbed.org, MIT License
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of this software
* and associated documentation files (the "Software"), to deal in the Software without
* restriction, including without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all copies or
* substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
* BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#ifndef MIDIMESSAGE_H
#define MIDIMESSAGE_H
#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) ]
//
// MIDI Data Messages (Channel Specific)
//
// Message msg n m
// ---------------------------------------------
// Note Off 0x8 Key Velocity
// Note On 0x9 Key Velocity
// Polyphonic Aftertouch 0xA Key Pressure
// Control Change 0xB Controller Value
// Program Change 0xC Program -
// Channel Aftertouch 0xD Pressure -
// Pitch Wheel 0xE LSB MSB
#define CABLE_NUM (0<<4)
/** A MIDI message container */
class MIDIMessage {
public:
MIDIMessage() : length(4) {}
MIDIMessage(uint8_t *buf) : length(4) {
for (int i = 0; i < 4; i++)
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
* @param key Key ID
* @param velocity Key velocity (0-127, default = 127)
* @param channel Key channel (0-15, default 0)
* @returns A MIDIMessage
*/
static MIDIMessage NoteOff(int key, int velocity = 127, int channel = 0) {
MIDIMessage msg;
msg.data[0] = CABLE_NUM | 0x08;
msg.data[1] = 0x80 | (channel & 0x0F);
msg.data[2] = key & 0x7F;
msg.data[3] = velocity & 0x7F;
return msg;
}
/** Create a NoteOn message
* @param key Key ID
* @param velocity Key velocity (0-127, default = 127)
* @param channel Key channel (0-15, default 0)
* @returns A MIDIMessage
*/
static MIDIMessage NoteOn(int key, int velocity = 127, int channel = 0) {
MIDIMessage msg;
msg.data[0] = CABLE_NUM | 0x09;
msg.data[1] = 0x90 | (channel & 0x0F);
msg.data[2] = key & 0x7F;
msg.data[3] = velocity & 0x7F;
return msg;
}
/** Create a PolyPhonic Aftertouch message
* @param key Key ID
* @param pressure Aftertouch pressure (0-127)
* @param channel Key channel (0-15, default 0)
* @returns A MIDIMessage
*/
static MIDIMessage PolyphonicAftertouch(int key, int pressure, int channel = 0) {
MIDIMessage msg;
msg.data[0] = CABLE_NUM | 0x0A;
msg.data[1] = 0xA0 | (channel & 0x0F);
msg.data[2] = key & 0x7F;
msg.data[3] = pressure & 0x7F;
return msg;
}
/** Create a Control Change message
* @param control Controller ID
* @param value Controller value (0-127)
* @param channel Controller channel (0-15, default 0)
* @returns A MIDIMessage
*/
static MIDIMessage ControlChange(int control, int value, int channel = 0) {
MIDIMessage msg;
msg.data[0] = CABLE_NUM | 0x0B;
msg.data[1] = 0xB0 | (channel & 0x0F);
msg.data[2] = control & 0x7F;
msg.data[3] = value & 0x7F;
return msg;
}
/** Create a Program Change message
* @param program Program ID
* @param channel Channel (0-15, default 0)
* @returns A MIDIMessage
*/
static MIDIMessage ProgramChange(int program, int channel = 0) {
MIDIMessage msg;
msg.data[0] = CABLE_NUM | 0x0C;
msg.data[1] = 0xC0 | (channel & 0x0F);
msg.data[2] = program & 0x7F;
msg.data[3] = 0x00;
return msg;
}
/** Create a Channel Aftertouch message
* @param pressure Pressure
* @param channel Key channel (0-15, default 0)
* @returns A MIDIMessage
*/
static MIDIMessage ChannelAftertouch(int pressure, int channel = 0) {
MIDIMessage msg;
msg.data[0] = CABLE_NUM | 0x0D;
msg.data[1] = 0xD0 | (channel & 0x0F);
msg.data[2] = pressure & 0x7F;
msg.data[3] = 0x00;
return msg;
}
/** Create a Pitch Wheel message
* @param pitch Pitch (-8192 - 8191, default = 0)
* @param channel Channel (0-15, default 0)
* @returns A MIDIMessage
*/
static MIDIMessage PitchWheel(int pitch = 0, int channel = 0) {
MIDIMessage msg;
int p = pitch + 8192; // 0 - 16383, 8192 is center
msg.data[0] = CABLE_NUM | 0x0E;
msg.data[1] = 0xE0 | (channel & 0x0F);
msg.data[2] = p & 0x7F;
msg.data[3] = (p >> 7) & 0x7F;
return msg;
}
/** Create an All Notes Off message
* @param channel Channel (0-15, default 0)
* @returns A MIDIMessage
*/
static MIDIMessage AllNotesOff(int channel = 0) {
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 */
enum MIDIMessageType {
ErrorType,
NoteOffType,
NoteOnType,
PolyphonicAftertouchType,
ControlChangeType,
ProgramChangeType,
ChannelAftertouchType,
PitchWheelType,
AllNotesOffType,
SysExType
};
/** Read the message type
* @returns MIDIMessageType
*/
MIDIMessageType type() {
switch((data[1] >> 4) & 0xF) {
case 0x8: return NoteOffType;
case 0x9: return NoteOnType;
case 0xA: return PolyphonicAftertouchType;
case 0xB:
if(controller() < 120) { // standard controllers
return ControlChangeType;
} else if(controller() == 123) {
return AllNotesOffType;
} else {
return ErrorType; // unsupported atm
}
case 0xC: return ProgramChangeType;
case 0xD: return ChannelAftertouchType;
case 0xE: return PitchWheelType;
case 0xF: return SysExType;
default: return ErrorType;
}
}
/** Read the channel number */
int channel() {
return (data[1] & 0x0F);
}
/** Read the key ID */
int key() {
return (data[2] & 0x7F);
}
/** Read the velocity */
int velocity() {
return (data[3] & 0x7F);
}
/** Read the controller value */
int value() {
return (data[3] & 0x7F);
}
/** Read the aftertouch pressure */
int pressure() {
if(type() == PolyphonicAftertouchType) {
return (data[3] & 0x7F);
} else {
return (data[2] & 0x7F);
}
}
/** Read the controller number */
int controller() {
return (data[2] & 0x7F);
}
/** Read the program number */
int program() {
return (data[2] & 0x7F);
}
/** Read the pitch value */
int pitch() {
int p = ((data[3] & 0x7F) << 7) | (data[2] & 0x7F);
return p - 8192; // 0 - 16383, 8192 is center
}
uint8_t data[MAX_MIDI_MESSAGE_SIZE+1];
uint8_t length;
};
#endif

View file

@ -0,0 +1,207 @@
/* Copyright (c) 2010-2011 mbed.org, MIT License
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of this software
* and associated documentation files (the "Software"), to deal in the Software without
* restriction, including without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all copies or
* substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
* BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#include "stdint.h"
#include "USBMIDI.h"
USBMIDI::USBMIDI(uint16_t vendor_id, uint16_t product_id, uint16_t product_release)
: USBDevice(vendor_id, product_id, product_release), cur_data(0), data_end(true)
{
midi_evt = NULL;
USBDevice::connect();
}
// write plain MIDIMessage that will be converted to USBMidi event packet
void USBMIDI::write(MIDIMessage m) {
// 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);
}
}
void USBMIDI::attach(void (*fptr)(MIDIMessage)) {
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) {
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
readStart(EPBULK_OUT, MAX_PACKET_SIZE_EPBULK);
return true;
}
// Called in ISR context
// Set configuration. Return false if the
// configuration is not supported.
bool USBMIDI::USBCallback_setConfiguration(uint8_t configuration) {
if (configuration != DEFAULT_CONFIGURATION) {
return false;
}
// Configure endpoints > 0
addEndpoint(EPBULK_IN, MAX_PACKET_SIZE_EPBULK);
addEndpoint(EPBULK_OUT, MAX_PACKET_SIZE_EPBULK);
// We activate the endpoint to be able to receive data
readStart(EPBULK_OUT, MAX_PACKET_SIZE_EPBULK);
return true;
}
uint8_t * USBMIDI::stringIinterfaceDesc() {
static uint8_t stringIinterfaceDescriptor[] = {
0x0c, //bLength
STRING_DESCRIPTOR, //bDescriptorType 0x03
'A',0,'u',0,'d',0,'i',0,'o',0 //bString iInterface - Audio
};
return stringIinterfaceDescriptor;
}
uint8_t * USBMIDI::stringIproductDesc() {
static uint8_t stringIproductDescriptor[] = {
0x16, //bLength
STRING_DESCRIPTOR, //bDescriptorType 0x03
'M',0,'b',0,'e',0,'d',0,' ',0,'A',0,'u',0,'d',0,'i',0,'o',0 //bString iProduct - Mbed Audio
};
return stringIproductDescriptor;
}
uint8_t * USBMIDI::configurationDesc() {
static uint8_t configDescriptor[] = {
// configuration descriptor
0x09, 0x02, 0x65, 0x00, 0x02, 0x01, 0x00, 0xc0, 0x50,
// The Audio Interface Collection
0x09, 0x04, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, // Standard AC Interface Descriptor
0x09, 0x24, 0x01, 0x00, 0x01, 0x09, 0x00, 0x01, 0x01, // Class-specific AC Interface Descriptor
0x09, 0x04, 0x01, 0x00, 0x02, 0x01, 0x03, 0x00, 0x00, // MIDIStreaming Interface Descriptors
0x07, 0x24, 0x01, 0x00, 0x01, 0x41, 0x00, // Class-Specific MS Interface Header Descriptor
// MIDI IN JACKS
0x06, 0x24, 0x02, 0x01, 0x01, 0x00,
0x06, 0x24, 0x02, 0x02, 0x02, 0x00,
// MIDI OUT JACKS
0x09, 0x24, 0x03, 0x01, 0x03, 0x01, 0x02, 0x01, 0x00,
0x09, 0x24, 0x03, 0x02, 0x06, 0x01, 0x01, 0x01, 0x00,
// OUT endpoint descriptor
0x09, 0x05, 0x02, 0x02, 0x40, 0x00, 0x00, 0x00, 0x00,
0x05, 0x25, 0x01, 0x01, 0x01,
// IN endpoint descriptor
0x09, 0x05, 0x82, 0x02, 0x40, 0x00, 0x00, 0x00, 0x00,
0x05, 0x25, 0x01, 0x01, 0x03,
};
return configDescriptor;
}

View file

@ -0,0 +1,112 @@
/* Copyright (c) 2010-2011 mbed.org, MIT License
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of this software
* and associated documentation files (the "Software"), to deal in the Software without
* restriction, including without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all copies or
* substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
* BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#ifndef USBMIDI_H
#define USBMIDI_H
/* These headers are included for child class. */
#include "USBEndpoints.h"
#include "USBDescriptor.h"
#include "USBDevice_Types.h"
#include "USBDevice.h"
#include "MIDIMessage.h"
#define DEFAULT_CONFIGURATION (1)
/**
* USBMIDI example
*
* @code
* #include "mbed.h"
* #include "USBMIDI.h"
*
* USBMIDI midi;
*
* int main() {
* while (1) {
* for(int i=48; i<83; i++) { // send some messages!
* midi.write(MIDIMessage::NoteOn(i));
* wait(0.25);
* midi.write(MIDIMessage::NoteOff(i));
* wait(0.5);
* }
* }
* }
* @endcode
*/
class USBMIDI: public USBDevice {
public:
/**
* Constructor
*
* @param vendor_id Your vendor_id
* @param product_id Your product_id
* @param product_release Your preoduct_release
*/
USBMIDI(uint16_t vendor_id = 0x0700, uint16_t product_id = 0x0101, uint16_t product_release = 0x0001);
/**
* Send a MIDIMessage
*
* @param m The MIDIMessage to send
*/
void write(MIDIMessage m);
/**
* Attach a callback for when a MIDIEvent is received
*
* @param fptr function pointer
*/
void attach(void (*fptr)(MIDIMessage));
protected:
virtual bool EPBULK_OUT_callback();
virtual bool USBCallback_setConfiguration(uint8_t configuration);
/*
* Get string product descriptor
*
* @returns pointer to the string product descriptor
*/
virtual uint8_t * stringIproductDesc();
/*
* Get string interface descriptor
*
* @returns pointer to the string interface descriptor
*/
virtual uint8_t * stringIinterfaceDesc();
/*
* Get configuration descriptor
*
* @returns pointer to the configuration descriptor
*/
virtual uint8_t * configurationDesc();
private:
uint8_t data[MAX_MIDI_MESSAGE_SIZE+1];
uint8_t cur_data;
bool data_end;
void (*midi_evt)(MIDIMessage);
};
#endif