|
@@ -85,6 +85,32 @@ bool tud_midi_n_mounted (uint8_t itf)
|
|
|
return midi->ep_in && midi->ep_out;
|
|
return midi->ep_in && midi->ep_out;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+static void _prep_out_transaction (midid_interface_t* p_midi)
|
|
|
|
|
+{
|
|
|
|
|
+ uint8_t const rhport = TUD_OPT_RHPORT;
|
|
|
|
|
+ uint16_t available = tu_fifo_remaining(&p_midi->rx_ff);
|
|
|
|
|
+
|
|
|
|
|
+ // Prepare for incoming data but only allow what we can store in the ring buffer.
|
|
|
|
|
+ // TODO Actually we can still carry out the transfer, keeping count of received bytes
|
|
|
|
|
+ // and slowly move it to the FIFO when read().
|
|
|
|
|
+ // This pre-check reduces endpoint claiming
|
|
|
|
|
+ TU_VERIFY(available >= sizeof(p_midi->epout_buf), );
|
|
|
|
|
+
|
|
|
|
|
+ // claim endpoint
|
|
|
|
|
+ TU_VERIFY(usbd_edpt_claim(rhport, p_midi->ep_out), );
|
|
|
|
|
+
|
|
|
|
|
+ // fifo can be changed before endpoint is claimed
|
|
|
|
|
+ available = tu_fifo_remaining(&p_midi->rx_ff);
|
|
|
|
|
+
|
|
|
|
|
+ if ( available >= sizeof(p_midi->epout_buf) ) {
|
|
|
|
|
+ usbd_edpt_xfer(rhport, p_midi->ep_out, p_midi->epout_buf, sizeof(p_midi->epout_buf));
|
|
|
|
|
+ }else
|
|
|
|
|
+ {
|
|
|
|
|
+ // Release endpoint since we don't make any transfer
|
|
|
|
|
+ usbd_edpt_release(rhport, p_midi->ep_out);
|
|
|
|
|
+ }
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
//--------------------------------------------------------------------+
|
|
//--------------------------------------------------------------------+
|
|
|
// READ API
|
|
// READ API
|
|
|
//--------------------------------------------------------------------+
|
|
//--------------------------------------------------------------------+
|
|
@@ -135,12 +161,17 @@ uint32_t tud_midi_n_read(uint8_t itf, uint8_t jack_id, void* buffer, uint32_t bu
|
|
|
void tud_midi_n_read_flush (uint8_t itf, uint8_t jack_id)
|
|
void tud_midi_n_read_flush (uint8_t itf, uint8_t jack_id)
|
|
|
{
|
|
{
|
|
|
(void) jack_id;
|
|
(void) jack_id;
|
|
|
- tu_fifo_clear(&_midid_itf[itf].rx_ff);
|
|
|
|
|
|
|
+ midid_interface_t* p_midi = &_midid_itf[itf];
|
|
|
|
|
+ tu_fifo_clear(&p_midi->rx_ff);
|
|
|
|
|
+ _prep_out_transaction(p_midi);
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
bool tud_midi_n_receive (uint8_t itf, uint8_t packet[4])
|
|
bool tud_midi_n_receive (uint8_t itf, uint8_t packet[4])
|
|
|
{
|
|
{
|
|
|
- return tu_fifo_read_n(&_midid_itf[itf].rx_ff, packet, 4);
|
|
|
|
|
|
|
+ midid_interface_t* p_midi = &_midid_itf[itf];
|
|
|
|
|
+ uint32_t num_read = tu_fifo_read_n(&p_midi->rx_ff, packet, 4);
|
|
|
|
|
+ _prep_out_transaction(p_midi);
|
|
|
|
|
+ return (num_read == 4);
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
void midi_rx_done_cb(midid_interface_t* midi, uint8_t const* buffer, uint32_t bufsize) {
|
|
void midi_rx_done_cb(midid_interface_t* midi, uint8_t const* buffer, uint32_t bufsize) {
|
|
@@ -275,8 +306,8 @@ void midid_init(void)
|
|
|
midid_interface_t* midi = &_midid_itf[i];
|
|
midid_interface_t* midi = &_midid_itf[i];
|
|
|
|
|
|
|
|
// config fifo
|
|
// config fifo
|
|
|
- tu_fifo_config(&midi->rx_ff, midi->rx_ff_buf, CFG_TUD_MIDI_RX_BUFSIZE, 1, true);
|
|
|
|
|
- tu_fifo_config(&midi->tx_ff, midi->tx_ff_buf, CFG_TUD_MIDI_TX_BUFSIZE, 1, true);
|
|
|
|
|
|
|
+ tu_fifo_config(&midi->rx_ff, midi->rx_ff_buf, CFG_TUD_MIDI_RX_BUFSIZE, 1, false); // true, true
|
|
|
|
|
+ tu_fifo_config(&midi->tx_ff, midi->tx_ff_buf, CFG_TUD_MIDI_TX_BUFSIZE, 1, false); // OBVS.
|
|
|
|
|
|
|
|
#if CFG_FIFO_MUTEX
|
|
#if CFG_FIFO_MUTEX
|
|
|
tu_fifo_config_mutex(&midi->rx_ff, osal_mutex_create(&midi->rx_ff_mutex));
|
|
tu_fifo_config_mutex(&midi->rx_ff, osal_mutex_create(&midi->rx_ff_mutex));
|
|
@@ -367,11 +398,7 @@ uint16_t midid_open(uint8_t rhport, tusb_desc_interface_t const * desc_itf, uint
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
// Prepare for incoming data
|
|
// Prepare for incoming data
|
|
|
- if ( !usbd_edpt_xfer(rhport, p_midi->ep_out, p_midi->epout_buf, CFG_TUD_MIDI_EP_BUFSIZE) )
|
|
|
|
|
- {
|
|
|
|
|
- TU_LOG1_FAILED();
|
|
|
|
|
- TU_BREAKPOINT();
|
|
|
|
|
- }
|
|
|
|
|
|
|
+ _prep_out_transaction(p_midi);
|
|
|
|
|
|
|
|
return drv_len;
|
|
return drv_len;
|
|
|
}
|
|
}
|
|
@@ -392,6 +419,7 @@ bool midid_control_xfer_cb(uint8_t rhport, uint8_t stage, tusb_control_request_t
|
|
|
bool midid_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t result, uint32_t xferred_bytes)
|
|
bool midid_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t result, uint32_t xferred_bytes)
|
|
|
{
|
|
{
|
|
|
(void) result;
|
|
(void) result;
|
|
|
|
|
+ (void) rhport;
|
|
|
|
|
|
|
|
uint8_t itf;
|
|
uint8_t itf;
|
|
|
midid_interface_t* p_midi;
|
|
midid_interface_t* p_midi;
|
|
@@ -415,7 +443,7 @@ bool midid_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t result, uint32
|
|
|
// prepare for next
|
|
// prepare for next
|
|
|
// TODO for now ep_out is not used by public API therefore there is no race condition,
|
|
// TODO for now ep_out is not used by public API therefore there is no race condition,
|
|
|
// and does not need to claim like ep_in
|
|
// and does not need to claim like ep_in
|
|
|
- TU_ASSERT(usbd_edpt_xfer(rhport, p_midi->ep_out, p_midi->epout_buf, CFG_TUD_MIDI_EP_BUFSIZE), false);
|
|
|
|
|
|
|
+ _prep_out_transaction(p_midi);
|
|
|
}
|
|
}
|
|
|
else if ( ep_addr == p_midi->ep_in )
|
|
else if ( ep_addr == p_midi->ep_in )
|
|
|
{
|
|
{
|