aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--libmaple/usb/stm32f1/usb_midi_device.c95
1 files changed, 45 insertions, 50 deletions
diff --git a/libmaple/usb/stm32f1/usb_midi_device.c b/libmaple/usb/stm32f1/usb_midi_device.c
index bd2855e..393b0e1 100644
--- a/libmaple/usb/stm32f1/usb_midi_device.c
+++ b/libmaple/usb/stm32f1/usb_midi_device.c
@@ -34,7 +34,7 @@
* the result made cleaner.
*/
-//#define USETXBUFFER
+#define USETXBUFFER
#include <libmaple/usb_midi_device.h>
#include <libmaple/midi_specs.h>
@@ -85,6 +85,8 @@ static RESULT usbNoDataSetup(uint8 request);
static RESULT usbGetInterfaceSetting(uint8 interface, uint8 alt_setting);
static void usbSetConfiguration(void);
static void usbSetDeviceAddress(void);
+static uint32 usb_midi_tx_send_buffer();
+
/* I/O state */
@@ -201,6 +203,7 @@ void usb_midi_disable(gpio_dev *disc_dev, uint8 disc_bit) {
*
* It copies data from a usercode buffer into the USB peripheral TX
* buffer, and returns the number of bytes copied. */
+#ifndef USETXBUFFER
uint32 usb_midi_tx(const uint32* buf, uint32 packets) {
uint32 bytes=packets*4;
/* Last transmission hasn't finished, so abort. */
@@ -231,72 +234,61 @@ uint32 usb_midi_tx(const uint32* buf, uint32 packets) {
return packets;
}
+#else
+
/*
- * Theese functions replaces EP double buffering:
+ * Theese functions implements a Tx buffer
*
- * usb_midi_tx_buffered(const uint8* buf, uint32 len)
+ * usb_midi_tx(const uint8* buf, uint32 len)
* usb_midi_tx_send_buffer()
*
* TODO: Use the modules EP double buffering instead
*
- * */
-uint32 usb_midi_tx_buffered(const uint32* buf, uint32 len) {
- if (usb_midi_is_transmitting()) {
- uint8 count;
- /* Copy to TxBuffer */
- /* Disable USB EP interrupts */
- USB_BASE->CNTR = USB_ISR_MSK&~USB_CNTR_CTRM;
- if (len>(USB_MIDI_TX_EPSIZE-tx_offset)) len = USB_MIDI_TX_EPSIZE-tx_offset;
- for (count=0;count<len;count++)
- {
- midiBufferTx[tx_offset+count]=buf[count];
- }
- tx_offset += len;
- /* Reenable USB EP interrupts */
- USB_BASE->CNTR = USB_ISR_MSK&~USB_CNTR_CTRM;
- return len; /* return len */
- }
-
- /* We can only put USB_MIDI_TX_EPSIZE bytes in the buffer. */
- if (len > USB_MIDI_TX_EPSIZE) {
- len = USB_MIDI_TX_EPSIZE;
- }
+ *
+ */
+
+/* Use this to signal the interrupt handler that application is writing to the Tx buffer */
+static volatile uint32 locktxbuffer = 0;
- /* Queue bytes for sending. */
- if (len) {
- usb_copy_to_pma((uint8 *)buf, 4*len, USB_MIDI_TX_ADDR);
+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;
}
- // 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, len);
- n_unsent_packets = len;
- transmitting = 1;
- usb_set_ep_tx_stat(USB_MIDI_TX_ENDP, USB_EP_STAT_TX_VALID);
-
- return len;
+ locktxbuffer = 0;
+ return count;
}
+#endif
#ifdef USETXBUFFER
uint32 usb_midi_tx_send_buffer() {
- if (usb_midi_is_transmitting()) {
- return 0;
- }
/* Queue bytes for sending. */
if (tx_offset) {
- usb_copy_to_pma((const uint8 *)midiBufferTx, tx_offset, USB_MIDI_TX_ADDR);
+ usb_copy_to_pma((const uint8 *)midiBufferTx, 4*tx_offset, USB_MIDI_TX_ADDR);
}
- else return 0;
- // 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, tx_offset);
- n_unsent_bytes = tx_offset;
+ usb_set_ep_tx_count(USB_MIDI_TX_ENDP, 4*tx_offset);
+ n_unsent_packets = tx_offset;
tx_offset = 0;
transmitting = 1;
usb_set_ep_tx_stat(USB_MIDI_TX_ENDP, USB_EP_STAT_TX_VALID);
- return n_unsent_bytes;
+ return n_unsent_packets;
}
#endif
@@ -356,10 +348,13 @@ uint32 usb_midi_peek(uint32* buf, uint32 packets) {
*/
static void midiDataTxCb(void) {
- n_unsent_packets = 0;
+// n_unsent_packets = 0;
transmitting = 0;
#ifdef USETXBUFFER
- usb_midi_tx_send_buffer();
+ /* If locktxbuffer is set then application is writing data to midibuffer and will soon enable transmit ?? */
+ if (locktxbuffer) return;
+ /* Send next USB packet or zero length if previous was nonzero */
+ if ((n_unsent_packets>0) || (tx_offset>0)) usb_midi_tx_send_buffer();
#endif
}