summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHa Thach <[email protected]>2025-11-12 20:34:39 +0700
committerGitHub <[email protected]>2025-11-12 20:34:39 +0700
commit8b8f1f80b4f01fc0fc56ad58af9b784e161636b0 (patch)
tree6c850325fc08f87f6af116b01dbca5013f5ed39c
parent8a094e807b34bcc018c971d59acb660b1a9ddf9f (diff)
parentfc661abc18beefb57f5d1352219ed72678b59e0b (diff)
Merge pull request #3337 from hathach/midi-edpt-stream
migrate midi_device to use edpt stream API
-rw-r--r--.clang-format1
-rw-r--r--src/class/midi/midi_device.c505
-rw-r--r--src/class/midi/midi_device.h130
-rw-r--r--src/class/vendor/vendor_device.c3
-rw-r--r--src/common/tusb_fifo.c25
-rw-r--r--src/common/tusb_fifo.h38
-rw-r--r--src/common/tusb_private.h14
-rw-r--r--src/tusb.c4
8 files changed, 285 insertions, 435 deletions
diff --git a/.clang-format b/.clang-format
index 907dd7cdd..c278fec37 100644
--- a/.clang-format
+++ b/.clang-format
@@ -70,6 +70,7 @@ IncludeCategories:
- Regex: '.*'
Priority: 3
IncludeIsMainRegex: '([-_](test|unittest))?$'
+IndentPPDirectives: BeforeHash
InsertBraces: true
IndentCaseLabels: true
InsertNewlineAtEOF: true
diff --git a/src/class/midi/midi_device.c b/src/class/midi/midi_device.c
index 7dac7c4a5..f065e486a 100644
--- a/src/class/midi/midi_device.c
+++ b/src/class/midi/midi_device.c
@@ -37,12 +37,18 @@
#include "midi_device.h"
//--------------------------------------------------------------------+
+// Weak stubs: invoked if no strong implementation is available
+//--------------------------------------------------------------------+
+TU_ATTR_WEAK void tud_midi_rx_cb(uint8_t itf) {
+ (void)itf;
+}
+
+//--------------------------------------------------------------------+
// MACRO CONSTANT TYPEDEF
//--------------------------------------------------------------------+
typedef struct {
+ uint8_t rhport;
uint8_t itf_num;
- uint8_t ep_in;
- uint8_t ep_out;
// For Stream read()/write() API
// Messages are always 4 bytes long, queue them for reading and writing so the
@@ -51,134 +57,97 @@ typedef struct {
midi_driver_stream_t stream_read;
/*------------- From this point, data is not cleared by bus reset -------------*/
- // FIFO
- tu_fifo_t rx_ff;
- tu_fifo_t tx_ff;
- uint8_t rx_ff_buf[CFG_TUD_MIDI_RX_BUFSIZE];
- uint8_t tx_ff_buf[CFG_TUD_MIDI_TX_BUFSIZE];
+ // Endpoint stream
+ struct {
+ tu_edpt_stream_t tx;
+ tu_edpt_stream_t rx;
- #if CFG_FIFO_MUTEX
- osal_mutex_def_t rx_ff_mutex;
- osal_mutex_def_t tx_ff_mutex;
- #endif
+ uint8_t rx_ff_buf[CFG_TUD_MIDI_RX_BUFSIZE];
+ uint8_t tx_ff_buf[CFG_TUD_MIDI_TX_BUFSIZE];
+ } ep_stream;
} midid_interface_t;
-#define ITF_MEM_RESET_SIZE offsetof(midid_interface_t, rx_ff)
+#define ITF_MEM_RESET_SIZE offsetof(midid_interface_t, ep_stream)
+
+static midid_interface_t _midid_itf[CFG_TUD_MIDI];
// Endpoint Transfer buffer
-CFG_TUD_MEM_SECTION static struct {
+typedef struct {
TUD_EPBUF_DEF(epin, CFG_TUD_MIDI_EP_BUFSIZE);
TUD_EPBUF_DEF(epout, CFG_TUD_MIDI_EP_BUFSIZE);
-} _midid_epbuf[CFG_TUD_MIDI];
+} midid_epbuf_t;
+
+CFG_TUD_MEM_SECTION static midid_epbuf_t _midid_epbuf[CFG_TUD_MIDI];
//--------------------------------------------------------------------+
// INTERNAL OBJECT & FUNCTION DECLARATION
//--------------------------------------------------------------------+
-static midid_interface_t _midid_itf[CFG_TUD_MIDI];
-
bool tud_midi_n_mounted (uint8_t itf) {
- midid_interface_t* midi = &_midid_itf[itf];
- return midi->ep_in && midi->ep_out;
-}
-
-static void _prep_out_transaction(uint8_t idx) {
- const uint8_t rhport = 0;
- midid_interface_t* p_midi = &_midid_itf[idx];
- 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 >= CFG_TUD_MIDI_EP_BUFSIZE, );
-
- // 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 >= CFG_TUD_MIDI_EP_BUFSIZE ) {
- usbd_edpt_xfer(rhport, p_midi->ep_out, _midid_epbuf[idx].epout, CFG_TUD_MIDI_EP_BUFSIZE);
- }else
- {
- // Release endpoint since we don't make any transfer
- usbd_edpt_release(rhport, p_midi->ep_out);
- }
-}
-
+ midid_interface_t *p_midi = &_midid_itf[itf];
-//--------------------------------------------------------------------+
-// Weak stubs: invoked if no strong implementation is available
-//--------------------------------------------------------------------+
-TU_ATTR_WEAK void tud_midi_rx_cb(uint8_t itf) {
- (void) itf;
+ const bool tx_opened = tu_edpt_stream_is_opened(&p_midi->ep_stream.tx);
+ const bool rx_opened = tu_edpt_stream_is_opened(&p_midi->ep_stream.rx);
+ return tx_opened && rx_opened;
}
//--------------------------------------------------------------------+
// READ API
//--------------------------------------------------------------------+
-uint32_t tud_midi_n_available(uint8_t itf, uint8_t cable_num)
-{
+uint32_t tud_midi_n_available(uint8_t itf, uint8_t cable_num) {
(void) cable_num;
-
- midid_interface_t* midi = &_midid_itf[itf];
- const midi_driver_stream_t* stream = &midi->stream_read;
+ const midid_interface_t *p_midi = &_midid_itf[itf];
+ const midi_driver_stream_t *stream = &p_midi->stream_read;
+ const tu_edpt_stream_t *ep_str = &p_midi->ep_stream.rx;
// when using with packet API stream total & index are both zero
- return tu_fifo_count(&midi->rx_ff) + (uint8_t) (stream->total - stream->index);
+ return tu_edpt_stream_read_available(ep_str) + (uint8_t)(stream->total - stream->index);
}
-uint32_t tud_midi_n_stream_read(uint8_t itf, uint8_t cable_num, void* buffer, uint32_t bufsize)
-{
+uint32_t tud_midi_n_stream_read(uint8_t itf, uint8_t cable_num, void *buffer, uint32_t bufsize) {
(void) cable_num;
- TU_VERIFY(bufsize, 0);
-
- uint8_t* buf8 = (uint8_t*) buffer;
+ TU_VERIFY(buffer != NULL && bufsize > 0, 0);
- midid_interface_t* midi = &_midid_itf[itf];
- midi_driver_stream_t* stream = &midi->stream_read;
+ uint8_t *buf8 = (uint8_t *)buffer;
+ midid_interface_t *p_midi = &_midid_itf[itf];
+ midi_driver_stream_t *stream = &p_midi->stream_read;
uint32_t total_read = 0;
- while( bufsize )
- {
+ while (bufsize > 0) {
// Get new packet from fifo, then set packet expected bytes
- if ( stream->total == 0 )
- {
- // return if there is no more data from fifo
- if ( !tud_midi_n_packet_read(itf, stream->buffer) ) return total_read;
+ if (stream->total == 0) {
+ if (!tud_midi_n_packet_read(itf, stream->buffer)) {
+ return total_read; // return if there is no more data from fifo
+ }
- uint8_t const code_index = stream->buffer[0] & 0x0f;
+ const uint8_t code_index = stream->buffer[0] & 0x0f;
// MIDI 1.0 Table 4-1: Code Index Number Classifications
- switch(code_index)
- {
+ switch (code_index) {
case MIDI_CIN_MISC:
case MIDI_CIN_CABLE_EVENT:
// These are reserved and unused, possibly issue somewhere, skip this packet
return 0;
- break;
case MIDI_CIN_SYSEX_END_1BYTE:
case MIDI_CIN_1BYTE_DATA:
stream->total = 1;
- break;
+ break;
case MIDI_CIN_SYSCOM_2BYTE :
case MIDI_CIN_SYSEX_END_2BYTE :
case MIDI_CIN_PROGRAM_CHANGE :
case MIDI_CIN_CHANNEL_PRESSURE :
stream->total = 2;
- break;
+ break;
default:
stream->total = 3;
- break;
+ break;
}
}
// Copy data up to bufsize
- uint8_t const count = (uint8_t) tu_min32(stream->total - stream->index, bufsize);
+ const uint8_t count = (uint8_t)tu_min32((uint32_t)(stream->total - stream->index), bufsize);
// Skip the header (1st byte) in the buffer
TU_VERIFY(0 == tu_memcpy_s(buf8, bufsize, stream->buffer + 1 + stream->index, count));
@@ -189,8 +158,7 @@ uint32_t tud_midi_n_stream_read(uint8_t itf, uint8_t cable_num, void* buffer, ui
bufsize -= count;
// complete current event packet, reset stream
- if ( stream->total == stream->index )
- {
+ if (stream->total == stream->index) {
stream->index = 0;
stream->total = 0;
}
@@ -199,150 +167,107 @@ uint32_t tud_midi_n_stream_read(uint8_t itf, uint8_t cable_num, void* buffer, ui
return total_read;
}
-bool tud_midi_n_packet_read (uint8_t itf, uint8_t packet[4])
-{
- midid_interface_t* midi = &_midid_itf[itf];
- TU_VERIFY(midi->ep_out);
+bool tud_midi_n_packet_read(uint8_t itf, uint8_t packet[4]) {
+ midid_interface_t *p_midi = &_midid_itf[itf];
+ tu_edpt_stream_t *ep_str = &p_midi->ep_stream.rx;
+ TU_VERIFY(tu_edpt_stream_is_opened(ep_str));
+ return 4 == tu_edpt_stream_read(p_midi->rhport, ep_str, packet, 4);
+}
+
+uint32_t tud_midi_n_packet_read_n(uint8_t itf, uint8_t packets[], uint32_t max_packets) {
+ midid_interface_t *p_midi = &_midid_itf[itf];
+ tu_edpt_stream_t *ep_str = &p_midi->ep_stream.rx;
+ TU_VERIFY(tu_edpt_stream_is_opened(ep_str), 0);
- const uint32_t num_read = tu_fifo_read_n(&midi->rx_ff, packet, 4);
- _prep_out_transaction(itf);
- return (num_read == 4);
+ const uint32_t num_read = tu_edpt_stream_read(p_midi->rhport, ep_str, packets, 4u * max_packets);
+ return num_read >> 2u;
}
//--------------------------------------------------------------------+
// WRITE API
//--------------------------------------------------------------------+
-
-static uint32_t write_flush(uint8_t idx) {
- midid_interface_t* midi = &_midid_itf[idx];
-
- if (!tu_fifo_count(&midi->tx_ff)) {
- return 0; // No data to send
- }
-
- const uint8_t rhport = 0;
-
- // skip if previous transfer not complete
- TU_VERIFY( usbd_edpt_claim(rhport, midi->ep_in), 0 );
-
- uint16_t count = tu_fifo_read_n(&midi->tx_ff, _midid_epbuf[idx].epin, CFG_TUD_MIDI_EP_BUFSIZE);
-
- if (count) {
- TU_ASSERT( usbd_edpt_xfer(rhport, midi->ep_in, _midid_epbuf[idx].epin, count), 0 );
- return count;
- }else {
- // Release endpoint since we don't make any transfer
- usbd_edpt_release(rhport, midi->ep_in);
- return 0;
- }
-}
-
-uint32_t tud_midi_n_stream_write(uint8_t itf, uint8_t cable_num, const uint8_t* buffer, uint32_t bufsize)
-{
- midid_interface_t* midi = &_midid_itf[itf];
- TU_VERIFY(midi->ep_in, 0);
-
- midi_driver_stream_t* stream = &midi->stream_write;
+uint32_t tud_midi_n_stream_write(uint8_t itf, uint8_t cable_num, const uint8_t *buffer, uint32_t bufsize) {
+ midid_interface_t *p_midi = &_midid_itf[itf];
+ midi_driver_stream_t *stream = &p_midi->stream_write;
+ tu_edpt_stream_t *ep_str = &p_midi->ep_stream.tx;
+ TU_VERIFY(tu_edpt_stream_is_opened(ep_str), 0);
uint32_t i = 0;
- while ( (i < bufsize) && (tu_fifo_remaining(&midi->tx_ff) >= 4) )
- {
+ while (i < bufsize) {
+ if (tu_edpt_stream_write_available(p_midi->rhport, ep_str) < 4) {
+ break;
+ }
+
const uint8_t data = buffer[i];
i++;
- if ( stream->index == 0 )
- {
+ if (stream->index == 0) {
//------------- New event packet -------------//
const uint8_t msg = data >> 4;
- stream->index = 2;
+ stream->index = 2;
stream->buffer[1] = data;
// Check to see if we're still in a SysEx transmit.
- if ( ((stream->buffer[0]) & 0xF) == MIDI_CIN_SYSEX_START )
- {
- if ( data == MIDI_STATUS_SYSEX_END )
- {
- stream->buffer[0] = (uint8_t) ((cable_num << 4) | MIDI_CIN_SYSEX_END_1BYTE);
- stream->total = 2;
- }
- else
- {
+ if (((stream->buffer[0]) & 0xF) == MIDI_CIN_SYSEX_START) {
+ if (data == MIDI_STATUS_SYSEX_END) {
+ stream->buffer[0] = (uint8_t)((cable_num << 4) | MIDI_CIN_SYSEX_END_1BYTE);
+ stream->total = 2;
+ } else {
stream->total = 4;
}
- }
- else if ( (msg >= 0x8 && msg <= 0xB) || msg == 0xE )
- {
+ } else if ((msg >= 0x8 && msg <= 0xB) || msg == 0xE) {
// Channel Voice Messages
- stream->buffer[0] = (uint8_t) ((cable_num << 4) | msg);
- stream->total = 4;
- }
- else if ( msg == 0xC || msg == 0xD)
- {
+ stream->buffer[0] = (uint8_t)((cable_num << 4) | msg);
+ stream->total = 4;
+ } else if (msg == 0xC || msg == 0xD) {
// Channel Voice Messages, two-byte variants (Program Change and Channel Pressure)
- stream->buffer[0] = (uint8_t) ((cable_num << 4) | msg);
- stream->total = 3;
- }
- else if ( msg == 0xf )
- {
+ stream->buffer[0] = (uint8_t)((cable_num << 4) | msg);
+ stream->total = 3;
+ } else if (msg == 0xf) {
// System message
- if ( data == MIDI_STATUS_SYSEX_START )
- {
+ if (data == MIDI_STATUS_SYSEX_START) {
stream->buffer[0] = MIDI_CIN_SYSEX_START;
- stream->total = 4;
- }
- else if ( data == MIDI_STATUS_SYSCOM_TIME_CODE_QUARTER_FRAME || data == MIDI_STATUS_SYSCOM_SONG_SELECT )
- {
+ stream->total = 4;
+ } else if (data == MIDI_STATUS_SYSCOM_TIME_CODE_QUARTER_FRAME || data == MIDI_STATUS_SYSCOM_SONG_SELECT) {
stream->buffer[0] = MIDI_CIN_SYSCOM_2BYTE;
- stream->total = 3;
- }
- else if ( data == MIDI_STATUS_SYSCOM_SONG_POSITION_POINTER )
- {
+ stream->total = 3;
+ } else if (data == MIDI_STATUS_SYSCOM_SONG_POSITION_POINTER) {
stream->buffer[0] = MIDI_CIN_SYSCOM_3BYTE;
- stream->total = 4;
- }
- else
- {
+ stream->total = 4;
+ } else {
stream->buffer[0] = MIDI_CIN_SYSEX_END_1BYTE;
- stream->total = 2;
+ stream->total = 2;
}
stream->buffer[0] |= (uint8_t)(cable_num << 4);
- }
- else
- {
+ } else {
// Pack individual bytes if we don't support packing them into words.
- stream->buffer[0] = (uint8_t) (cable_num << 4 | 0xf);
+ stream->buffer[0] = (uint8_t)(cable_num << 4 | 0xf);
stream->buffer[2] = 0;
stream->buffer[3] = 0;
- stream->index = 2;
- stream->total = 2;
+ stream->total = 2; // index already set to 2
}
- }
- else
- {
+ } else {
//------------- On-going (buffering) packet -------------//
-
TU_ASSERT(stream->index < 4, i);
stream->buffer[stream->index] = data;
stream->index++;
// See if this byte ends a SysEx.
- if ( (stream->buffer[0] & 0xF) == MIDI_CIN_SYSEX_START && data == MIDI_STATUS_SYSEX_END )
- {
- stream->buffer[0] = (uint8_t) ((cable_num << 4) | (MIDI_CIN_SYSEX_START + (stream->index - 1)));
- stream->total = stream->index;
+ if ((stream->buffer[0] & 0xF) == MIDI_CIN_SYSEX_START && data == MIDI_STATUS_SYSEX_END) {
+ stream->buffer[0] = (uint8_t)((cable_num << 4) | (MIDI_CIN_SYSEX_START + (stream->index - 1)));
+ stream->total = stream->index;
}
}
// Send out packet
- if ( stream->index == stream->total )
- {
+ if (stream->index == stream->total) {
// zeroes unused bytes
for (uint8_t idx = stream->total; idx < 4; idx++) {
stream->buffer[idx] = 0;
}
- const uint16_t count = tu_fifo_write_n(&midi->tx_ff, stream->buffer, 4);
+ const uint32_t count = tu_edpt_stream_write(p_midi->rhport, ep_str, stream->buffer, 4);
// complete current event packet, reset stream
stream->index = stream->total = 0;
@@ -352,25 +277,37 @@ uint32_t tud_midi_n_stream_write(uint8_t itf, uint8_t cable_num, const uint8_t*
}
}
- write_flush(itf);
+ (void)tu_edpt_stream_write_xfer(p_midi->rhport, ep_str);
return i;
}
bool tud_midi_n_packet_write (uint8_t itf, const uint8_t packet[4]) {
- midid_interface_t* midi = &_midid_itf[itf];
- TU_VERIFY(midi->ep_in);
+ midid_interface_t *p_midi = &_midid_itf[itf];
+ tu_edpt_stream_t *ep_str = &p_midi->ep_stream.tx;
+ TU_VERIFY(tu_edpt_stream_is_opened(ep_str));
- if (tu_fifo_remaining(&midi->tx_ff) < 4) {
- return false;
- }
-
- tu_fifo_write_n(&midi->tx_ff, packet, 4);
- write_flush(itf);
+ TU_VERIFY(tu_edpt_stream_write_available(p_midi->rhport, ep_str) >= 4);
+ TU_VERIFY(tu_edpt_stream_write(p_midi->rhport, ep_str, packet, 4) > 0);
+ (void)tu_edpt_stream_write_xfer(p_midi->rhport, ep_str);
return true;
}
+uint32_t tud_midi_n_packet_write_n(uint8_t itf, const uint8_t packets[], uint32_t n_packets) {
+ midid_interface_t *p_midi = &_midid_itf[itf];
+ tu_edpt_stream_t *ep_str = &p_midi->ep_stream.tx;
+ TU_VERIFY(tu_edpt_stream_is_opened(ep_str), 0);
+
+ uint32_t n_bytes = tu_edpt_stream_write_available(p_midi->rhport, ep_str);
+ n_bytes = tu_min32(tu_align4(n_bytes), n_packets << 2u);
+
+ const uint32_t n_write = tu_edpt_stream_write(p_midi->rhport, ep_str, packets, n_bytes);
+ (void)tu_edpt_stream_write_xfer(p_midi->rhport, ep_str);
+
+ return n_write >> 2u;
+}
+
//--------------------------------------------------------------------+
// USBD Driver API
//--------------------------------------------------------------------+
@@ -378,72 +315,64 @@ void midid_init(void) {
tu_memclr(_midid_itf, sizeof(_midid_itf));
for (uint8_t i = 0; i < CFG_TUD_MIDI; i++) {
- 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, false); // true, true
- tu_fifo_config(&midi->tx_ff, midi->tx_ff_buf, CFG_TUD_MIDI_TX_BUFSIZE, 1, false); // OBVS.
+ midid_interface_t *p_midi = &_midid_itf[i];
+ midid_epbuf_t *p_epbuf = &_midid_epbuf[i];
- #if CFG_FIFO_MUTEX
- osal_mutex_t mutex_rd = osal_mutex_create(&midi->rx_ff_mutex);
- osal_mutex_t mutex_wr = osal_mutex_create(&midi->tx_ff_mutex);
- TU_ASSERT(mutex_wr != NULL && mutex_wr != NULL, );
+ tu_edpt_stream_init(
+ &p_midi->ep_stream.rx, false, false, false, p_midi->ep_stream.rx_ff_buf, CFG_TUD_MIDI_RX_BUFSIZE,
+ p_epbuf->epout, CFG_TUD_MIDI_EP_BUFSIZE);
- tu_fifo_config_mutex(&midi->rx_ff, NULL, mutex_rd);
- tu_fifo_config_mutex(&midi->tx_ff, mutex_wr, NULL);
- #endif
+ tu_edpt_stream_init(
+ &p_midi->ep_stream.tx, false, true, false, p_midi->ep_stream.tx_ff_buf, CFG_TUD_MIDI_TX_BUFSIZE, p_epbuf->epin,
+ CFG_TUD_MIDI_EP_BUFSIZE);
}
}
bool midid_deinit(void) {
- #if CFG_FIFO_MUTEX
- for(uint8_t i=0; i<CFG_TUD_MIDI; i++) {
- midid_interface_t* midi = &_midid_itf[i];
- osal_mutex_t mutex_rd = midi->rx_ff.mutex_rd;
- osal_mutex_t mutex_wr = midi->tx_ff.mutex_wr;
-
- if (mutex_rd) {
- osal_mutex_delete(mutex_rd);
- tu_fifo_config_mutex(&midi->rx_ff, NULL, NULL);
- }
-
- if (mutex_wr) {
- osal_mutex_delete(mutex_wr);
- tu_fifo_config_mutex(&midi->tx_ff, NULL, NULL);
- }
+ for (uint8_t i = 0; i < CFG_TUD_MIDI; i++) {
+ midid_interface_t *p_midi = &_midid_itf[i];
+ tu_edpt_stream_deinit(&p_midi->ep_stream.rx);
+ tu_edpt_stream_deinit(&p_midi->ep_stream.tx);
}
- #endif
-
return true;
}
-void midid_reset(uint8_t rhport)
-{
- (void) rhport;
+void midid_reset(uint8_t rhport) {
+ (void)rhport;
+ for (uint8_t i = 0; i < CFG_TUD_MIDI; i++) {
+ midid_interface_t *p_midi = &_midid_itf[i];
+ tu_memclr(p_midi, ITF_MEM_RESET_SIZE);
+
+ tu_edpt_stream_clear(&p_midi->ep_stream.rx);
+ tu_edpt_stream_close(&p_midi->ep_stream.rx);
+
+ tu_edpt_stream_clear(&p_midi->ep_stream.tx);
+ tu_edpt_stream_close(&p_midi->ep_stream.tx);
+ }
+}
- for(uint8_t i=0; i<CFG_TUD_MIDI; i++)
- {
- midid_interface_t* midi = &_midid_itf[i];
- tu_memclr(midi, ITF_MEM_RESET_SIZE);
- tu_fifo_clear(&midi->rx_ff);
- tu_fifo_clear(&midi->tx_ff);
+TU_ATTR_ALWAYS_INLINE static inline uint8_t find_midi_itf(uint8_t ep_addr) {
+ for (uint8_t idx = 0; idx < CFG_TUD_MIDI; idx++) {
+ const midid_interface_t *p_midi = &_midid_itf[idx];
+ if (ep_addr == p_midi->ep_stream.rx.ep_addr || ep_addr == p_midi->ep_stream.tx.ep_addr) {
+ return idx;
+ }
}
+ return TUSB_INDEX_INVALID_8;
}
-uint16_t midid_open(uint8_t rhport, const tusb_desc_interface_t* desc_itf, uint16_t max_len) {
- uint16_t drv_len = 0;
- uint8_t const * p_desc = (uint8_t const *)desc_itf;
+uint16_t midid_open(uint8_t rhport, const tusb_desc_interface_t *desc_itf, uint16_t max_len) {
+ const uint8_t *p_desc = (const uint8_t *)desc_itf;
+ const uint8_t *desc_end = p_desc + max_len;
// 1st Interface is Audio Control v1 (optional)
if (TUSB_CLASS_AUDIO == desc_itf->bInterfaceClass &&
AUDIO_SUBCLASS_CONTROL == desc_itf->bInterfaceSubClass &&
AUDIO_FUNC_PROTOCOL_CODE_UNDEF == desc_itf->bInterfaceProtocol) {
- drv_len = tu_desc_len(desc_itf);
p_desc = tu_desc_next(desc_itf);
// Skip Class Specific descriptors
- while (TUSB_DESC_CS_INTERFACE == tu_desc_type(p_desc) && drv_len <= max_len) {
- drv_len += tu_desc_len(p_desc);
- p_desc = tu_desc_next(p_desc);
+ while (tu_desc_in_bounds(p_desc, desc_end) && TUSB_DESC_CS_INTERFACE == tu_desc_type(p_desc)) {
+ p_desc = tu_desc_next(p_desc);
}
}
@@ -451,59 +380,44 @@ uint16_t midid_open(uint8_t rhport, const tusb_desc_interface_t* desc_itf, uint1
TU_VERIFY(TUSB_DESC_INTERFACE == tu_desc_type(p_desc), 0);
const tusb_desc_interface_t* desc_midi = (const tusb_desc_interface_t*) p_desc;
- TU_VERIFY(TUSB_CLASS_AUDIO == desc_midi->bInterfaceClass &&
- AUDIO_SUBCLASS_MIDI_STREAMING == desc_midi->bInterfaceSubClass &&
- AUDIO_FUNC_PROTOCOL_CODE_UNDEF == desc_midi->bInterfaceProtocol, 0);
+ TU_VERIFY(TUSB_CLASS_AUDIO == desc_midi->bInterfaceClass &&
+ AUDIO_SUBCLASS_MIDI_STREAMING == desc_midi->bInterfaceSubClass &&
+ AUDIO_FUNC_PROTOCOL_CODE_UNDEF == desc_midi->bInterfaceProtocol,
+ 0);
- // Find available interface
- midid_interface_t * p_midi = NULL;
- uint8_t idx;
- for(idx=0; idx<CFG_TUD_MIDI; idx++) {
- if ( _midid_itf[idx].ep_in == 0 && _midid_itf[idx].ep_out == 0 ) {
- p_midi = &_midid_itf[idx];
- break;
- }
- }
- TU_ASSERT(p_midi);
+ uint8_t idx = find_midi_itf(0); // find unused interface
+ TU_ASSERT(idx < CFG_TUD_MIDI, 0);
+ midid_interface_t *p_midi = &_midid_itf[idx];
+ p_midi->rhport = rhport;
p_midi->itf_num = desc_midi->bInterfaceNumber;
(void) p_midi->itf_num;
- // next descriptor
- drv_len += tu_desc_len(p_desc);
- p_desc = tu_desc_next(p_desc);
+ p_desc = tu_desc_next(p_desc);
// Find and open endpoint descriptors
- uint8_t found_endpoints = 0;
- while ( (found_endpoints < desc_midi->bNumEndpoints) && (drv_len <= max_len) )
- {
- if ( TUSB_DESC_ENDPOINT == tu_desc_type(p_desc) )
- {
- TU_ASSERT(usbd_edpt_open(rhport, (const tusb_desc_endpoint_t*) p_desc), 0);
- uint8_t ep_addr = ((const tusb_desc_endpoint_t*) p_desc)->bEndpointAddress;
+ uint8_t found_ep = 0;
+ while ((found_ep < desc_midi->bNumEndpoints) && tu_desc_in_bounds(p_desc, desc_end)) {
+ if (TUSB_DESC_ENDPOINT == tu_desc_type(p_desc)) {
+ const tusb_desc_endpoint_t *desc_ep = (const tusb_desc_endpoint_t *)p_desc;
+ TU_ASSERT(usbd_edpt_open(rhport, desc_ep), 0);
+ const uint8_t ep_addr = ((const tusb_desc_endpoint_t *)p_desc)->bEndpointAddress;
- if (tu_edpt_dir(ep_addr) == TUSB_DIR_IN)
- {
- p_midi->ep_in = ep_addr;
+ if (tu_edpt_dir(ep_addr) == TUSB_DIR_IN) {
+ tu_edpt_stream_open(&p_midi->ep_stream.tx, desc_ep);
} else {
- p_midi->ep_out = ep_addr;
+ tu_edpt_stream_open(&p_midi->ep_stream.rx, desc_ep);
+ TU_ASSERT(tu_edpt_stream_read_xfer(rhport, &p_midi->ep_stream.rx) > 0, 0); // prepare to receive data
}
- // Class Specific MIDI Stream endpoint descriptor
- drv_len += tu_desc_len(p_desc);
- p_desc = tu_desc_next(p_desc);
-
- found_endpoints += 1;
+ p_desc = tu_desc_next(p_desc); // skip CS Endpoint descriptor
+ found_ep++;
}
- drv_len += tu_desc_len(p_desc);
- p_desc = tu_desc_next(p_desc);
+ p_desc = tu_desc_next(p_desc);
}
- // Prepare for incoming data
- _prep_out_transaction(idx);
-
- return drv_len;
+ return (uint16_t)(p_desc - (const uint8_t *)desc_itf);
}
// Invoked when a control transfer occurred on an interface of this class
@@ -514,44 +428,31 @@ bool midid_control_xfer_cb(uint8_t rhport, uint8_t stage, const tusb_control_req
return false; // driver doesn't support any request yet
}
-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 idx;
- midid_interface_t* p_midi;
+bool midid_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t result, uint32_t xferred_bytes) {
+ (void)result;
- // Identify which interface to use
- for (idx = 0; idx < CFG_TUD_MIDI; idx++) {
- p_midi = &_midid_itf[idx];
- if ((ep_addr == p_midi->ep_out) || (ep_addr == p_midi->ep_in)) {
- break;
- }
- }
+ uint8_t idx = find_midi_itf(ep_addr);
TU_ASSERT(idx < CFG_TUD_MIDI);
+ midid_interface_t *p_midi = &_midid_itf[idx];
- // receive new data
- if (ep_addr == p_midi->ep_out) {
- tu_fifo_write_n(&p_midi->rx_ff, _midid_epbuf[idx].epout, (uint16_t)xferred_bytes);
+ tu_edpt_stream_t *ep_st_rx = &p_midi->ep_stream.rx;
+ tu_edpt_stream_t *ep_st_tx = &p_midi->ep_stream.tx;
- // invoke receive callback if available
- tud_midi_rx_cb(idx);
-
- // 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
- _prep_out_transaction(idx);
- } else if (ep_addr == p_midi->ep_in) {
- if (0 == write_flush(idx)) {
- // If there is no data left, a ZLP should be sent if
- // xferred_bytes is multiple of EP size and not zero
- if (!tu_fifo_count(&p_midi->tx_ff) && xferred_bytes && (0 == (xferred_bytes % CFG_TUD_MIDI_EP_BUFSIZE))) {
- if (usbd_edpt_claim(rhport, p_midi->ep_in)) {
- usbd_edpt_xfer(rhport, p_midi->ep_in, NULL, 0);
- }
- }
+ if (ep_addr == ep_st_rx->ep_addr) {
+ // Received new data: put into stream's fifo
+ if (result == XFER_RESULT_SUCCESS) {
+ tu_edpt_stream_read_xfer_complete(ep_st_rx, xferred_bytes);
+ tud_midi_rx_cb(idx); // invoke callback
}
+ tu_edpt_stream_read_xfer(rhport, ep_st_rx); // prepare for next data
+ } else if (ep_addr == ep_st_tx->ep_addr && result == XFER_RESULT_SUCCESS) {
+ // sent complete: try to send more if possible
+ if (0 == tu_edpt_stream_write_xfer(rhport, ep_st_tx)) {
+ // If there is no data left, a ZLP should be sent if needed
+ (void)tu_edpt_stream_write_zlp_if_needed(rhport, ep_st_tx, xferred_bytes);
+ }
+ } else {
+ return false;
}
return true;
diff --git a/src/class/midi/midi_device.h b/src/class/midi/midi_device.h
index d23516cec..ddbc2f9f0 100644
--- a/src/class/midi/midi_device.h
+++ b/src/class/midi/midi_device.h
@@ -36,21 +36,21 @@
#if !defined(CFG_TUD_MIDI_EP_BUFSIZE) && defined(CFG_TUD_MIDI_EPSIZE)
#warning CFG_TUD_MIDI_EPSIZE is renamed to CFG_TUD_MIDI_EP_BUFSIZE, please update to use the new name
- #define CFG_TUD_MIDI_EP_BUFSIZE CFG_TUD_MIDI_EPSIZE
+ #define CFG_TUD_MIDI_EP_BUFSIZE CFG_TUD_MIDI_EPSIZE
#endif
#ifndef CFG_TUD_MIDI_EP_BUFSIZE
- #define CFG_TUD_MIDI_EP_BUFSIZE (TUD_OPT_HIGH_SPEED ? 512 : 64)
+ #define CFG_TUD_MIDI_EP_BUFSIZE (TUD_OPT_HIGH_SPEED ? 512 : 64)
#endif
#ifdef __cplusplus
- extern "C" {
+extern "C" {
#endif
-/** \addtogroup MIDI_Serial Serial
- * @{
- * \defgroup MIDI_Serial_Device Device
- * @{ */
+//--------------------------------------------------------------------+
+// Application Callback API (optional)
+//--------------------------------------------------------------------+
+void tud_midi_rx_cb(uint8_t itf);
//--------------------------------------------------------------------+
// Application API (Multiple Interfaces)
@@ -58,117 +58,77 @@
//--------------------------------------------------------------------+
// Check if midi interface is mounted
-bool tud_midi_n_mounted (uint8_t itf);
+bool tud_midi_n_mounted(uint8_t itf);
// Get the number of bytes available for reading
-uint32_t tud_midi_n_available (uint8_t itf, uint8_t cable_num);
-
-// Read byte stream (legacy)
-uint32_t tud_midi_n_stream_read (uint8_t itf, uint8_t cable_num, void* buffer, uint32_t bufsize);
-
-// Write byte Stream (legacy)
-uint32_t tud_midi_n_stream_write (uint8_t itf, uint8_t cable_num, uint8_t const* buffer, uint32_t bufsize);
-
-// Read event packet (4 bytes)
-bool tud_midi_n_packet_read (uint8_t itf, uint8_t packet[4]);
-
-// Write event packet (4 bytes)
-bool tud_midi_n_packet_write (uint8_t itf, uint8_t const packet[4]);
+uint32_t tud_midi_n_available(uint8_t itf, uint8_t cable_num);
-//--------------------------------------------------------------------+
-// Application API (Single Interface)
-//--------------------------------------------------------------------+
-static inline bool tud_midi_mounted (void);
-static inline uint32_t tud_midi_available (void);
-
-static inline uint32_t tud_midi_stream_read (void* buffer, uint32_t bufsize);
-static inline uint32_t tud_midi_stream_write (uint8_t cable_num, uint8_t const* buffer, uint32_t bufsize);
-
-static inline bool tud_midi_packet_read (uint8_t packet[4]);
-static inline bool tud_midi_packet_write (uint8_t const packet[4]);
-
-//------------- Deprecated API name -------------//
-// TODO remove after 0.10.0 release
-
-TU_ATTR_DEPRECATED("tud_midi_read() is renamed to tud_midi_stream_read()")
-static inline uint32_t tud_midi_read (void* buffer, uint32_t bufsize)
-{
- return tud_midi_stream_read(buffer, bufsize);
-}
+// Read byte stream (legacy)
+uint32_t tud_midi_n_stream_read(uint8_t itf, uint8_t cable_num, void *buffer, uint32_t bufsize);
-TU_ATTR_DEPRECATED("tud_midi_write() is renamed to tud_midi_stream_write()")
-static inline uint32_t tud_midi_write(uint8_t cable_num, uint8_t const* buffer, uint32_t bufsize)
-{
- return tud_midi_stream_write(cable_num, buffer, bufsize);
-}
+// Write byte Stream (legacy)
+uint32_t tud_midi_n_stream_write(uint8_t itf, uint8_t cable_num, const uint8_t *buffer, uint32_t bufsize);
+// Read an event 4-byte packet
+bool tud_midi_n_packet_read(uint8_t itf, uint8_t packet[4]);
-TU_ATTR_DEPRECATED("tud_midi_send() is renamed to tud_midi_packet_write()")
-static inline bool tud_midi_send(uint8_t packet[4])
-{
- return tud_midi_packet_write(packet);
-}
+// Read multiple event packets, return number of read packets
+uint32_t tud_midi_n_packet_read_n(uint8_t itf, uint8_t packets[], uint32_t max_packets);
-TU_ATTR_DEPRECATED("tud_midi_receive() is renamed to tud_midi_packet_read()")
-static inline bool tud_midi_receive(uint8_t packet[4])
-{
- return tud_midi_packet_read(packet);
-}
+// Write an event 4-byte packet
+bool tud_midi_n_packet_write(uint8_t itf, const uint8_t packet[4]);
-//--------------------------------------------------------------------+
-// Application Callback API (optional)
-//--------------------------------------------------------------------+
-void tud_midi_rx_cb(uint8_t itf);
+// Write multiple event packets, return number of written packets
+uint32_t tud_midi_n_packet_write_n(uint8_t itf, const uint8_t packets[], uint32_t n_packets);
//--------------------------------------------------------------------+
-// Inline Functions
+// Application API (Single Interface)
//--------------------------------------------------------------------+
-
-static inline bool tud_midi_mounted (void)
-{
+TU_ATTR_ALWAYS_INLINE static inline bool tud_midi_mounted(void) {
return tud_midi_n_mounted(0);
}
-static inline uint32_t tud_midi_available (void)
-{
+TU_ATTR_ALWAYS_INLINE static inline uint32_t tud_midi_available(void) {
return tud_midi_n_available(0, 0);
}
-static inline uint32_t tud_midi_stream_read (void* buffer, uint32_t bufsize)
-{
+TU_ATTR_ALWAYS_INLINE static inline uint32_t tud_midi_stream_read(void *buffer, uint32_t bufsize) {
return tud_midi_n_stream_read(0, 0, buffer, bufsize);
}
-static inline uint32_t tud_midi_stream_write (uint8_t cable_num, uint8_t const* buffer, uint32_t bufsize)
-{
+TU_ATTR_ALWAYS_INLINE static inline uint32_t
+tud_midi_stream_write(uint8_t cable_num, const uint8_t *buffer, uint32_t bufsize) {
return tud_midi_n_stream_write(0, cable_num, buffer, bufsize);
}
-static inline bool tud_midi_packet_read (uint8_t packet[4])
-{
+TU_ATTR_ALWAYS_INLINE static inline bool tud_midi_packet_read(uint8_t packet[4]) {
return tud_midi_n_packet_read(0, packet);
}
-static inline bool tud_midi_packet_write (uint8_t const packet[4])
-{
+TU_ATTR_ALWAYS_INLINE static inline uint32_t tud_midi_packet_read_n(uint8_t packets[], uint32_t max_packets) {
+ return tud_midi_n_packet_read_n(0, packets, max_packets);
+}
+
+TU_ATTR_ALWAYS_INLINE static inline bool tud_midi_packet_write(const uint8_t packet[4]) {
return tud_midi_n_packet_write(0, packet);
}
+TU_ATTR_ALWAYS_INLINE static inline uint32_t tud_midi_packet_write_n(const uint8_t packets[], uint32_t n_packets) {
+ return tud_midi_n_packet_write_n(0, packets, n_packets);
+}
+
//--------------------------------------------------------------------+
// Internal Class Driver API
//--------------------------------------------------------------------+
-void midid_init (void);
-bool midid_deinit (void);
-void midid_reset (uint8_t rhport);
-uint16_t midid_open (uint8_t rhport, tusb_desc_interface_t const * itf_desc, uint16_t max_len);
-bool midid_control_xfer_cb (uint8_t rhport, uint8_t stage, tusb_control_request_t const * request);
-bool midid_xfer_cb (uint8_t rhport, uint8_t edpt_addr, xfer_result_t result, uint32_t xferred_bytes);
+void midid_init(void);
+bool midid_deinit(void);
+void midid_reset(uint8_t rhport);
+uint16_t midid_open(uint8_t rhport, const tusb_desc_interface_t *itf_desc, uint16_t max_len);
+bool midid_control_xfer_cb(uint8_t rhport, uint8_t stage, const tusb_control_request_t *request);
+bool midid_xfer_cb(uint8_t rhport, uint8_t edpt_addr, xfer_result_t result, uint32_t xferred_bytes);
#ifdef __cplusplus
- }
+}
#endif
-#endif /* TUSB_MIDI_DEVICE_H_ */
-
-/** @} */
-/** @} */
+#endif
diff --git a/src/class/vendor/vendor_device.c b/src/class/vendor/vendor_device.c
index 27724b194..c916ebe47 100644
--- a/src/class/vendor/vendor_device.c
+++ b/src/class/vendor/vendor_device.c
@@ -202,8 +202,9 @@ void vendord_reset(uint8_t rhport) {
vendord_interface_t* p_itf = &_vendord_itf[i];
tu_memclr(p_itf, ITF_MEM_RESET_SIZE);
tu_edpt_stream_clear(&p_itf->rx.stream);
- tu_edpt_stream_clear(&p_itf->tx.stream);
tu_edpt_stream_close(&p_itf->rx.stream);
+
+ tu_edpt_stream_clear(&p_itf->tx.stream);
tu_edpt_stream_close(&p_itf->tx.stream);
}
}
diff --git a/src/common/tusb_fifo.c b/src/common/tusb_fifo.c
index 419046b8b..5c9e586fb 100644
--- a/src/common/tusb_fifo.c
+++ b/src/common/tusb_fifo.c
@@ -551,29 +551,12 @@ static uint16_t _tu_fifo_read_n(tu_fifo_t *f, void *buffer, uint16_t n, tu_fifo_
@returns Number of items in FIFO
*/
/******************************************************************************/
-uint16_t tu_fifo_count(tu_fifo_t *f) {
+uint16_t tu_fifo_count(const tu_fifo_t *f) {
return tu_min16(_ff_count(f->depth, f->wr_idx, f->rd_idx), f->depth);
}
/******************************************************************************/
/*!
- @brief Check if FIFO is empty.
-
- As this function only reads the read and write pointers once, this function is
- reentrant and thus thread and ISR save without any mutexes.
-
- @param[in] f
- Pointer to the FIFO buffer to manipulate
-
- @returns Number of items in FIFO
- */
-/******************************************************************************/
-bool tu_fifo_empty(tu_fifo_t *f) {
- return f->wr_idx == f->rd_idx;
-}
-
-/******************************************************************************/
-/*!
@brief Check if FIFO is full.
As this function only reads the read and write pointers once, this function is
@@ -585,7 +568,7 @@ bool tu_fifo_empty(tu_fifo_t *f) {
@returns Number of items in FIFO
*/
/******************************************************************************/
-bool tu_fifo_full(tu_fifo_t *f) {
+bool tu_fifo_full(const tu_fifo_t *f) {
return _ff_count(f->depth, f->wr_idx, f->rd_idx) >= f->depth;
}
@@ -602,7 +585,7 @@ bool tu_fifo_full(tu_fifo_t *f) {
@returns Number of items in FIFO
*/
/******************************************************************************/
-uint16_t tu_fifo_remaining(tu_fifo_t *f) {
+uint16_t tu_fifo_remaining(const tu_fifo_t *f) {
return _ff_remaining(f->depth, f->wr_idx, f->rd_idx);
}
@@ -627,7 +610,7 @@ uint16_t tu_fifo_remaining(tu_fifo_t *f) {
@returns True if overflow happened
*/
/******************************************************************************/
-bool tu_fifo_overflowed(tu_fifo_t *f) {
+bool tu_fifo_overflowed(const tu_fifo_t *f) {
return _ff_count(f->depth, f->wr_idx, f->rd_idx) > f->depth;
}
diff --git a/src/common/tusb_fifo.h b/src/common/tusb_fifo.h
index 0f4ba00d8..9d8b864e9 100644
--- a/src/common/tusb_fifo.h
+++ b/src/common/tusb_fifo.h
@@ -155,33 +155,35 @@ void tu_fifo_config_mutex(tu_fifo_t *f, osal_mutex_t wr_mutex, osal_mutex_t rd_m
#define tu_fifo_config_mutex(_f, _wr_mutex, _rd_mutex)
#endif
-bool tu_fifo_write (tu_fifo_t* f, void const * data);
-uint16_t tu_fifo_write_n (tu_fifo_t* f, void const * data, uint16_t n);
-#ifdef TUP_MEM_CONST_ADDR
-uint16_t tu_fifo_write_n_const_addr_full_words (tu_fifo_t* f, const void * data, uint16_t n);
-#endif
+bool tu_fifo_write(tu_fifo_t *f, void const *data);
+uint16_t tu_fifo_write_n(tu_fifo_t *f, const void *data, uint16_t n);
+
+bool tu_fifo_read(tu_fifo_t *f, void *buffer);
+uint16_t tu_fifo_read_n(tu_fifo_t *f, void *buffer, uint16_t n);
-bool tu_fifo_read (tu_fifo_t* f, void * buffer);
-uint16_t tu_fifo_read_n (tu_fifo_t* f, void * buffer, uint16_t n);
#ifdef TUP_MEM_CONST_ADDR
-uint16_t tu_fifo_read_n_const_addr_full_words (tu_fifo_t* f, void * buffer, uint16_t n);
+uint16_t tu_fifo_write_n_const_addr_full_words(tu_fifo_t *f, const void *data, uint16_t n);
+uint16_t tu_fifo_read_n_const_addr_full_words(tu_fifo_t *f, void *buffer, uint16_t n);
#endif
-bool tu_fifo_peek (tu_fifo_t* f, void * p_buffer);
-uint16_t tu_fifo_peek_n (tu_fifo_t* f, void * p_buffer, uint16_t n);
+bool tu_fifo_peek(tu_fifo_t *f, void *p_buffer);
+uint16_t tu_fifo_peek_n(tu_fifo_t *f, void *p_buffer, uint16_t n);
-uint16_t tu_fifo_count (tu_fifo_t* f);
-uint16_t tu_fifo_remaining (tu_fifo_t* f);
-bool tu_fifo_empty (tu_fifo_t* f);
-bool tu_fifo_full (tu_fifo_t* f);
-bool tu_fifo_overflowed (tu_fifo_t* f);
-void tu_fifo_correct_read_pointer (tu_fifo_t* f);
+uint16_t tu_fifo_count(const tu_fifo_t *f);
+uint16_t tu_fifo_remaining(const tu_fifo_t *f);
+bool tu_fifo_full(const tu_fifo_t *f);
+bool tu_fifo_overflowed(const tu_fifo_t *f);
-TU_ATTR_ALWAYS_INLINE static inline
-uint16_t tu_fifo_depth(tu_fifo_t* f) {
+TU_ATTR_ALWAYS_INLINE static inline bool tu_fifo_empty(const tu_fifo_t *f) {
+ return f->wr_idx == f->rd_idx;
+}
+
+TU_ATTR_ALWAYS_INLINE static inline uint16_t tu_fifo_depth(const tu_fifo_t *f) {
return f->depth;
}
+void tu_fifo_correct_read_pointer(tu_fifo_t *f);
+
// Pointer modifications intended to be used in combinations with DMAs.
// USE WITH CARE - NO SAFETY CHECKS CONDUCTED HERE! NOT MUTEX PROTECTED!
void tu_fifo_advance_write_pointer(tu_fifo_t *f, uint16_t n);
diff --git a/src/common/tusb_private.h b/src/common/tusb_private.h
index dcd5c45d6..367209e57 100644
--- a/src/common/tusb_private.h
+++ b/src/common/tusb_private.h
@@ -105,6 +105,10 @@ TU_ATTR_ALWAYS_INLINE static inline void tu_edpt_stream_open(tu_edpt_stream_t* s
s->is_mps512 = tu_edpt_packet_size(desc_ep) == 512;
}
+TU_ATTR_ALWAYS_INLINE static inline bool tu_edpt_stream_is_opened(const tu_edpt_stream_t *s) {
+ return s->ep_addr != 0;
+}
+
TU_ATTR_ALWAYS_INLINE static inline void tu_edpt_stream_close(tu_edpt_stream_t* s) {
s->ep_addr = 0;
}
@@ -121,7 +125,7 @@ TU_ATTR_ALWAYS_INLINE static inline bool tu_edpt_stream_clear(tu_edpt_stream_t*
// Write to stream
uint32_t tu_edpt_stream_write(uint8_t hwid, tu_edpt_stream_t* s, void const *buffer, uint32_t bufsize);
-// Start an usb transfer if endpoint is not busy
+// Start an usb transfer if endpoint is not busy. Return number of queued bytes
uint32_t tu_edpt_stream_write_xfer(uint8_t hwid, tu_edpt_stream_t* s);
// Start an zero-length packet if needed
@@ -151,20 +155,18 @@ void tu_edpt_stream_read_xfer_complete(tu_edpt_stream_t* s, uint32_t xferred_byt
// Complete read transfer with provided buffer
TU_ATTR_ALWAYS_INLINE static inline
-void tu_edpt_stream_read_xfer_complete_with_buf(tu_edpt_stream_t* s, const void * buf, uint32_t xferred_bytes) {
+void tu_edpt_stream_read_xfer_complete_with_buf(tu_edpt_stream_t *s, const void *buf, uint32_t xferred_bytes) {
if (0u != tu_fifo_depth(&s->ff)) {
tu_fifo_write_n(&s->ff, buf, (uint16_t) xferred_bytes);
}
}
// Get the number of bytes available for reading
-TU_ATTR_ALWAYS_INLINE static inline
-uint32_t tu_edpt_stream_read_available(tu_edpt_stream_t* s) {
+TU_ATTR_ALWAYS_INLINE static inline uint32_t tu_edpt_stream_read_available(const tu_edpt_stream_t *s) {
return (uint32_t) tu_fifo_count(&s->ff);
}
-TU_ATTR_ALWAYS_INLINE static inline
-bool tu_edpt_stream_peek(tu_edpt_stream_t* s, uint8_t* ch) {
+TU_ATTR_ALWAYS_INLINE static inline bool tu_edpt_stream_peek(tu_edpt_stream_t *s, uint8_t *ch) {
return tu_fifo_peek(&s->ff, ch);
}
diff --git a/src/tusb.c b/src/tusb.c
index 7411f19df..b308e2915 100644
--- a/src/tusb.c
+++ b/src/tusb.c
@@ -424,7 +424,7 @@ uint32_t tu_edpt_stream_write_xfer(uint8_t hwid, tu_edpt_stream_t* s) {
TU_VERIFY(stream_claim(hwid, s), 0);
// Pull data from FIFO -> EP buf
- uint16_t const count = tu_fifo_read_n(&s->ff, s->ep_buf, s->ep_bufsize);
+ const uint16_t count = tu_fifo_read_n(&s->ff, s->ep_buf, s->ep_bufsize);
if (count > 0) {
TU_ASSERT(stream_xfer(hwid, s, count), 0);
@@ -437,7 +437,7 @@ uint32_t tu_edpt_stream_write_xfer(uint8_t hwid, tu_edpt_stream_t* s) {
}
}
-uint32_t tu_edpt_stream_write(uint8_t hwid, tu_edpt_stream_t* s, void const* buffer, uint32_t bufsize) {
+uint32_t tu_edpt_stream_write(uint8_t hwid, tu_edpt_stream_t *s, const void *buffer, uint32_t bufsize) {
TU_VERIFY(bufsize > 0); // TODO support ZLP
if (0 == tu_fifo_depth(&s->ff)) {