|
|
|
|
|
|
|
|
#define print USBHost::print_ |
|
|
#define print USBHost::print_ |
|
|
#define println USBHost::println_ |
|
|
#define println USBHost::println_ |
|
|
|
|
|
|
|
|
void MIDIDevice::init() |
|
|
|
|
|
|
|
|
void MIDIDeviceBase::init() |
|
|
{ |
|
|
{ |
|
|
contribute_Pipes(mypipes, sizeof(mypipes)/sizeof(Pipe_t)); |
|
|
contribute_Pipes(mypipes, sizeof(mypipes)/sizeof(Pipe_t)); |
|
|
contribute_Transfers(mytransfers, sizeof(mytransfers)/sizeof(Transfer_t)); |
|
|
contribute_Transfers(mytransfers, sizeof(mytransfers)/sizeof(Transfer_t)); |
|
|
|
|
|
|
|
|
// EP_CONTROL_UNDEFINED 0x00 |
|
|
// EP_CONTROL_UNDEFINED 0x00 |
|
|
// ASSOCIATION_CONTROL 0x01 |
|
|
// ASSOCIATION_CONTROL 0x01 |
|
|
|
|
|
|
|
|
bool MIDIDevice::claim(Device_t *dev, int type, const uint8_t *descriptors, uint32_t len) |
|
|
|
|
|
|
|
|
bool MIDIDeviceBase::claim(Device_t *dev, int type, const uint8_t *descriptors, uint32_t len) |
|
|
{ |
|
|
{ |
|
|
// only claim at interface level |
|
|
// only claim at interface level |
|
|
if (type != 1) return false; |
|
|
if (type != 1) return false; |
|
|
|
|
|
|
|
|
return false; |
|
|
return false; |
|
|
} |
|
|
} |
|
|
// if an IN endpoint was found, create its pipe |
|
|
// if an IN endpoint was found, create its pipe |
|
|
if (rx_ep && rx_size <= MAX_PACKET_SIZE) { |
|
|
|
|
|
|
|
|
if (rx_ep && rx_size <= max_packet_size) { |
|
|
rxpipe = new_Pipe(dev, rx_ep_type, rx_ep, 1, rx_size); |
|
|
rxpipe = new_Pipe(dev, rx_ep_type, rx_ep, 1, rx_size); |
|
|
if (rxpipe) { |
|
|
if (rxpipe) { |
|
|
rxpipe->callback_function = rx_callback; |
|
|
rxpipe->callback_function = rx_callback; |
|
|
|
|
|
|
|
|
rxpipe = NULL; |
|
|
rxpipe = NULL; |
|
|
} |
|
|
} |
|
|
// if an OUT endpoint was found, create its pipe |
|
|
// if an OUT endpoint was found, create its pipe |
|
|
if (tx_ep && tx_size <= MAX_PACKET_SIZE) { |
|
|
|
|
|
|
|
|
if (tx_ep && tx_size <= max_packet_size) { |
|
|
txpipe = new_Pipe(dev, tx_ep_type, tx_ep, 0, tx_size); |
|
|
txpipe = new_Pipe(dev, tx_ep_type, tx_ep, 0, tx_size); |
|
|
if (txpipe) { |
|
|
if (txpipe) { |
|
|
txpipe->callback_function = tx_callback; |
|
|
txpipe->callback_function = tx_callback; |
|
|
|
|
|
|
|
|
return (rxpipe || txpipe); |
|
|
return (rxpipe || txpipe); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
void MIDIDevice::rx_callback(const Transfer_t *transfer) |
|
|
|
|
|
|
|
|
void MIDIDeviceBase::rx_callback(const Transfer_t *transfer) |
|
|
{ |
|
|
{ |
|
|
if (transfer->driver) { |
|
|
if (transfer->driver) { |
|
|
((MIDIDevice *)(transfer->driver))->rx_data(transfer); |
|
|
((MIDIDevice *)(transfer->driver))->rx_data(transfer); |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
void MIDIDevice::tx_callback(const Transfer_t *transfer) |
|
|
|
|
|
|
|
|
void MIDIDeviceBase::tx_callback(const Transfer_t *transfer) |
|
|
{ |
|
|
{ |
|
|
if (transfer->driver) { |
|
|
if (transfer->driver) { |
|
|
((MIDIDevice *)(transfer->driver))->tx_data(transfer); |
|
|
((MIDIDevice *)(transfer->driver))->tx_data(transfer); |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
void MIDIDevice::rx_data(const Transfer_t *transfer) |
|
|
|
|
|
|
|
|
void MIDIDeviceBase::rx_data(const Transfer_t *transfer) |
|
|
{ |
|
|
{ |
|
|
println("MIDIDevice Receive"); |
|
|
println("MIDIDevice Receive"); |
|
|
print(" MIDI Data: "); |
|
|
print(" MIDI Data: "); |
|
|
|
|
|
|
|
|
for (uint32_t i=0; i < len; i++) { |
|
|
for (uint32_t i=0; i < len; i++) { |
|
|
uint32_t msg = rx_buffer[i]; |
|
|
uint32_t msg = rx_buffer[i]; |
|
|
if (msg) { |
|
|
if (msg) { |
|
|
if (++head >= RX_QUEUE_SIZE) head = 0; |
|
|
|
|
|
|
|
|
if (++head >= rx_queue_size) head = 0; |
|
|
rx_queue[head] = msg; |
|
|
rx_queue[head] = msg; |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
rx_head = head; |
|
|
rx_head = head; |
|
|
rx_tail = tail; |
|
|
rx_tail = tail; |
|
|
uint32_t avail = (head < tail) ? tail - head - 1 : RX_QUEUE_SIZE - 1 - head + tail; |
|
|
|
|
|
|
|
|
uint32_t avail = (head < tail) ? tail - head - 1 : rx_queue_size - 1 - head + tail; |
|
|
//println("rx_size = ", rx_size); |
|
|
//println("rx_size = ", rx_size); |
|
|
println("avail = ", avail); |
|
|
println("avail = ", avail); |
|
|
if (avail >= (uint32_t)(rx_size>>2)) { |
|
|
if (avail >= (uint32_t)(rx_size>>2)) { |
|
|
|
|
|
|
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
void MIDIDevice::tx_data(const Transfer_t *transfer) |
|
|
|
|
|
|
|
|
void MIDIDeviceBase::tx_data(const Transfer_t *transfer) |
|
|
{ |
|
|
{ |
|
|
println("MIDIDevice transmit complete"); |
|
|
println("MIDIDevice transmit complete"); |
|
|
print(" MIDI Data: "); |
|
|
print(" MIDI Data: "); |
|
|
|
|
|
|
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void MIDIDevice::disconnect() |
|
|
|
|
|
|
|
|
void MIDIDeviceBase::disconnect() |
|
|
{ |
|
|
{ |
|
|
// should rx_queue be cleared? |
|
|
// should rx_queue be cleared? |
|
|
// as-is, the user can still read MIDI messages |
|
|
// as-is, the user can still read MIDI messages |
|
|
|
|
|
|
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void MIDIDevice::write_packed(uint32_t data) |
|
|
|
|
|
|
|
|
void MIDIDeviceBase::write_packed(uint32_t data) |
|
|
{ |
|
|
{ |
|
|
if (!txpipe) return; |
|
|
if (!txpipe) return; |
|
|
uint32_t tx_max = tx_size / 4; |
|
|
uint32_t tx_max = tx_size / 4; |
|
|
|
|
|
|
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
void MIDIDevice::send_sysex_buffer_has_term(const uint8_t *data, uint32_t length, uint8_t cable) |
|
|
|
|
|
|
|
|
void MIDIDeviceBase::send_sysex_buffer_has_term(const uint8_t *data, uint32_t length, uint8_t cable) |
|
|
{ |
|
|
{ |
|
|
cable = (cable & 0x0F) << 4; |
|
|
cable = (cable & 0x0F) << 4; |
|
|
while (length > 3) { |
|
|
while (length > 3) { |
|
|
|
|
|
|
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
void MIDIDevice::send_sysex_add_term_bytes(const uint8_t *data, uint32_t length, uint8_t cable) |
|
|
|
|
|
|
|
|
void MIDIDeviceBase::send_sysex_add_term_bytes(const uint8_t *data, uint32_t length, uint8_t cable) |
|
|
{ |
|
|
{ |
|
|
cable = (cable & 0x0F) << 4; |
|
|
cable = (cable & 0x0F) << 4; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
bool MIDIDevice::read(uint8_t channel) |
|
|
|
|
|
|
|
|
bool MIDIDeviceBase::read(uint8_t channel) |
|
|
{ |
|
|
{ |
|
|
uint32_t n, head, tail, avail, ch, type1, type2, b1; |
|
|
uint32_t n, head, tail, avail, ch, type1, type2, b1; |
|
|
|
|
|
|
|
|
head = rx_head; |
|
|
head = rx_head; |
|
|
tail = rx_tail; |
|
|
tail = rx_tail; |
|
|
if (head == tail) return false; |
|
|
if (head == tail) return false; |
|
|
if (++tail >= RX_QUEUE_SIZE) tail = 0; |
|
|
|
|
|
|
|
|
if (++tail >= rx_queue_size) tail = 0; |
|
|
n = rx_queue[tail]; |
|
|
n = rx_queue[tail]; |
|
|
rx_tail = tail; |
|
|
rx_tail = tail; |
|
|
if (!rx_packet_queued && rxpipe) { |
|
|
if (!rx_packet_queued && rxpipe) { |
|
|
avail = (head < tail) ? tail - head - 1 : RX_QUEUE_SIZE - 1 - head + tail; |
|
|
|
|
|
|
|
|
avail = (head < tail) ? tail - head - 1 : rx_queue_size - 1 - head + tail; |
|
|
if (avail >= (uint32_t)(rx_size>>2)) { |
|
|
if (avail >= (uint32_t)(rx_size>>2)) { |
|
|
__disable_irq(); |
|
|
__disable_irq(); |
|
|
queue_Data_Transfer(rxpipe, rx_buffer, rx_size, this); |
|
|
queue_Data_Transfer(rxpipe, rx_buffer, rx_size, this); |
|
|
|
|
|
|
|
|
return false; |
|
|
return false; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
void MIDIDevice::sysex_byte(uint8_t b) |
|
|
|
|
|
|
|
|
void MIDIDeviceBase::sysex_byte(uint8_t b) |
|
|
{ |
|
|
{ |
|
|
if (handleSysExPartial && msg_sysex_len >= SYSEX_MAX_LEN) { |
|
|
if (handleSysExPartial && msg_sysex_len >= SYSEX_MAX_LEN) { |
|
|
// when buffer is full, send another chunk to partial handler. |
|
|
// when buffer is full, send another chunk to partial handler. |