uint32 usb_midi_tx(const uint32* buf, uint32 packets) { uint32 bytes=packets*4; /* Last transmission hasn't finished, so abort. */ if (usb_midi_is_transmitting()) { /* Copy to TxBuffer */ return 0; /* return len */ } /* We can only put USB_MIDI_TX_EPSIZE bytes in the buffer. */ if (bytes > USB_MIDI_TX_EPSIZE) { bytes = USB_MIDI_TX_EPSIZE; packets=bytes/4; } /* Queue bytes for sending. */ if (packets) { usb_copy_to_pma((uint8 *)buf, bytes, USB_MIDI_TX_ADDR); } // We still need to wait for the interrupt, even if we're sending // zero bytes. (Sending zero-size packets is useful for flushing // host-side buffers.) usb_set_ep_tx_count(USB_MIDI_TX_ENDP, bytes); n_unsent_packets = packets; transmitting = 1; usb_set_ep_tx_stat(USB_MIDI_TX_ENDP, USB_EP_STAT_TX_VALID); return packets; }
void USBMidi::writePackets(const void *buf, uint32 len) { if (!this->isConnected() || !buf) { return; } uint32 txed = 0; uint32 old_txed = 0; uint32 start = millis(); uint32 sent = 0; while (txed < len && (millis() - start < USB_TIMEOUT)) { sent = usb_midi_tx((const uint32*)buf + txed, len - txed); txed += sent; if (old_txed != txed) { start = millis(); } old_txed = txed; } if (sent == USB_MIDI_TX_EPSIZE) { while (usb_midi_is_transmitting() != 0) { } /* flush out to avoid having the pc wait for more data */ usb_midi_tx(NULL, 0); } }
uint32 usb_midi_tx(const uint32* buf, uint32 packets) { int count = 0; locktxbuffer = 1; if (locktxbuffer) { int bpos = 0; count = USB_MIDI_TX_EPSIZE/4 - tx_offset; if (packets < count) count = packets; while (bpos < count) { midiBufferTx[tx_offset++] = buf[bpos++]; } /* Disable USB EP interrupts */ USB_BASE->CNTR = USB_ISR_MSK&~USB_CNTR_CTRM; if (!usb_midi_is_transmitting()) { usb_midi_tx_send_buffer(); } locktxbuffer = 0; /* Reenable USB EP interrupts */ USB_BASE->CNTR = USB_ISR_MSK&~USB_CNTR_CTRM; } locktxbuffer = 0; return count; }