mirror of
https://github.com/hathach/tinyusb.git
synced 2025-03-14 04:18:56 +00:00
Merge pull request #618 from homeodor/master
A CDC-like blocking behaviour for MIDI, incl. SysEx
This commit is contained in:
commit
be1bd74b4b
@ -165,6 +165,12 @@ void midi_task(void)
|
||||
{
|
||||
static uint32_t start_ms = 0;
|
||||
|
||||
// The MIDI interface always creates input and output port/jack descriptors
|
||||
// regardless of these being used or not. Therefore incoming traffic should be read
|
||||
// (possibly just discarded) to avoid the sender blocking in IO
|
||||
uint8_t packet[4];
|
||||
while(tud_midi_available()) tud_midi_receive(packet);
|
||||
|
||||
// send note every 1000 ms
|
||||
if (board_millis() - start_ms < 286) return; // not enough time
|
||||
start_ms += 286;
|
||||
|
@ -125,6 +125,12 @@ void midi_task(void)
|
||||
{
|
||||
static uint32_t start_ms = 0;
|
||||
|
||||
// The MIDI interface always creates input and output port/jack descriptors
|
||||
// regardless of these being used or not. Therefore incoming traffic should be read
|
||||
// (possibly just discarded) to avoid the sender blocking in IO
|
||||
uint8_t packet[4];
|
||||
while(tud_midi_available()) tud_midi_receive(packet);
|
||||
|
||||
// send note every 1000 ms
|
||||
if (board_millis() - start_ms < 286) return; // not enough time
|
||||
start_ms += 286;
|
||||
|
@ -85,6 +85,32 @@ bool tud_midi_n_mounted (uint8_t itf)
|
||||
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
|
||||
//--------------------------------------------------------------------+
|
||||
@ -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) 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])
|
||||
{
|
||||
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) {
|
||||
@ -275,8 +306,8 @@ void midid_init(void)
|
||||
midid_interface_t* midi = &_midid_itf[i];
|
||||
|
||||
// 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
|
||||
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
|
||||
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;
|
||||
}
|
||||
@ -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)
|
||||
{
|
||||
(void) result;
|
||||
(void) rhport;
|
||||
|
||||
uint8_t itf;
|
||||
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
|
||||
// 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
|
||||
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 )
|
||||
{
|
||||
|
Loading…
x
Reference in New Issue
Block a user