summaryrefslogtreecommitdiff
path: root/src/class
diff options
context:
space:
mode:
authorHiFiPhile <[email protected]>2025-05-15 21:35:19 +0200
committerHiFiPhile <[email protected]>2025-05-15 21:35:19 +0200
commit98da642627200c89b5fd8ce0624ed494a1c1e98d (patch)
tree228ce580e3f34ae749b6542f360ab6f9442ed089 /src/class
parent376c1063b7184984ae44ff5a3d225130bc470d14 (diff)
parent1a783b357343d053eb861ae783922371ce9e1b17 (diff)
Merge branch 'master' into xfer_close
Signed-off-by: HiFiPhile <[email protected]>
Diffstat (limited to 'src/class')
-rw-r--r--src/class/audio/audio_device.c24
-rw-r--r--src/class/cdc/cdc_device.c38
-rw-r--r--src/class/cdc/cdc_device.h22
-rw-r--r--src/class/midi/midi_host.c30
-rw-r--r--src/class/midi/midi_host.h6
-rw-r--r--src/class/msc/msc_device.c5
6 files changed, 84 insertions, 41 deletions
diff --git a/src/class/audio/audio_device.c b/src/class/audio/audio_device.c
index 388168424..7a6fd453f 100644
--- a/src/class/audio/audio_device.c
+++ b/src/class/audio/audio_device.c
@@ -208,15 +208,15 @@ tu_static CFG_TUD_MEM_SECTION struct {
#endif// CFG_TUD_AUDIO_ENABLE_EP_OUT && (USE_LINEAR_BUFFER || CFG_TUD_AUDIO_ENABLE_DECODING)
// Control buffers
-tu_static uint8_t ctrl_buf_1[CFG_TUD_AUDIO_FUNC_1_CTRL_BUF_SZ];
-
-#if CFG_TUD_AUDIO > 1
-tu_static uint8_t ctrl_buf_2[CFG_TUD_AUDIO_FUNC_2_CTRL_BUF_SZ];
-#endif
-
-#if CFG_TUD_AUDIO > 2
-tu_static uint8_t ctrl_buf_3[CFG_TUD_AUDIO_FUNC_3_CTRL_BUF_SZ];
-#endif
+tu_static CFG_TUD_MEM_SECTION struct {
+ TUD_EPBUF_DEF(buf1, CFG_TUD_AUDIO_FUNC_1_CTRL_BUF_SZ);
+ #if CFG_TUD_AUDIO > 1
+ TUD_EPBUF_DEF(buf2, CFG_TUD_AUDIO_FUNC_2_CTRL_BUF_SZ);
+ #endif
+ #if CFG_TUD_AUDIO > 2
+ TUD_EPBUF_DEF(buf3, CFG_TUD_AUDIO_FUNC_3_CTRL_BUF_SZ);
+ #endif
+} ctrl_buf;
// Active alternate setting of interfaces
tu_static uint8_t alt_setting_1[CFG_TUD_AUDIO_FUNC_1_N_AS_INT];
@@ -1223,18 +1223,18 @@ void audiod_init(void) {
// Initialize control buffers
switch (i) {
case 0:
- audio->ctrl_buf = ctrl_buf_1;
+ audio->ctrl_buf = ctrl_buf.buf1;
audio->ctrl_buf_sz = CFG_TUD_AUDIO_FUNC_1_CTRL_BUF_SZ;
break;
#if CFG_TUD_AUDIO > 1 && CFG_TUD_AUDIO_FUNC_2_CTRL_BUF_SZ > 0
case 1:
- audio->ctrl_buf = ctrl_buf_2;
+ audio->ctrl_buf = ctrl_buf.buf2;
audio->ctrl_buf_sz = CFG_TUD_AUDIO_FUNC_2_CTRL_BUF_SZ;
break;
#endif
#if CFG_TUD_AUDIO > 2 && CFG_TUD_AUDIO_FUNC_3_CTRL_BUF_SZ > 0
case 2:
- audio->ctrl_buf = ctrl_buf_3;
+ audio->ctrl_buf = ctrl_buf.buf3;
audio->ctrl_buf_sz = CFG_TUD_AUDIO_FUNC_3_CTRL_BUF_SZ;
break;
#endif
diff --git a/src/class/cdc/cdc_device.c b/src/class/cdc/cdc_device.c
index efb672201..4d19adeb4 100644
--- a/src/class/cdc/cdc_device.c
+++ b/src/class/cdc/cdc_device.c
@@ -82,7 +82,7 @@ typedef struct {
static cdcd_interface_t _cdcd_itf[CFG_TUD_CDC];
CFG_TUD_MEM_SECTION static cdcd_epbuf_t _cdcd_epbuf[CFG_TUD_CDC];
-static tud_cdc_configure_fifo_t _cdcd_fifo_cfg;
+static tud_cdc_configure_t _cdcd_cfg = TUD_CDC_CONFIGURE_DEFAULT();
static bool _prep_out_transaction(uint8_t itf) {
const uint8_t rhport = 0;
@@ -119,9 +119,9 @@ static bool _prep_out_transaction(uint8_t itf) {
// APPLICATION API
//--------------------------------------------------------------------+
-bool tud_cdc_configure_fifo(const tud_cdc_configure_fifo_t* cfg) {
- TU_VERIFY(cfg);
- _cdcd_fifo_cfg = (*cfg);
+bool tud_cdc_configure(const tud_cdc_configure_t* driver_cfg) {
+ TU_VERIFY(driver_cfg);
+ _cdcd_cfg = *driver_cfg;
return true;
}
@@ -175,7 +175,7 @@ void tud_cdc_n_read_flush(uint8_t itf) {
//--------------------------------------------------------------------+
uint32_t tud_cdc_n_write(uint8_t itf, const void* buffer, uint32_t bufsize) {
cdcd_interface_t* p_cdc = &_cdcd_itf[itf];
- uint16_t ret = tu_fifo_write_n(&p_cdc->tx_ff, buffer, (uint16_t) TU_MIN(bufsize, UINT16_MAX));
+ uint16_t wr_count = tu_fifo_write_n(&p_cdc->tx_ff, buffer, (uint16_t) TU_MIN(bufsize, UINT16_MAX));
// flush if queue more than packet size
if (tu_fifo_count(&p_cdc->tx_ff) >= BULK_PACKET_SIZE
@@ -186,7 +186,7 @@ uint32_t tud_cdc_n_write(uint8_t itf, const void* buffer, uint32_t bufsize) {
tud_cdc_n_write_flush(itf);
}
- return ret;
+ return wr_count;
}
uint32_t tud_cdc_n_write_flush(uint8_t itf) {
@@ -233,8 +233,6 @@ bool tud_cdc_n_write_clear(uint8_t itf) {
//--------------------------------------------------------------------+
void cdcd_init(void) {
tu_memclr(_cdcd_itf, sizeof(_cdcd_itf));
- tu_memclr(&_cdcd_fifo_cfg, sizeof(_cdcd_fifo_cfg));
-
for (uint8_t i = 0; i < CFG_TUD_CDC; i++) {
cdcd_interface_t* p_cdc = &_cdcd_itf[i];
@@ -249,10 +247,10 @@ void cdcd_init(void) {
// Config RX fifo
tu_fifo_config(&p_cdc->rx_ff, p_cdc->rx_ff_buf, TU_ARRAY_SIZE(p_cdc->rx_ff_buf), 1, false);
- // Config TX fifo as overwritable at initialization and will be changed to non-overwritable
- // if terminal supports DTR bit. Without DTR we do not know if data is actually polled by terminal.
- // In this way, the most current data is prioritized.
- tu_fifo_config(&p_cdc->tx_ff, p_cdc->tx_ff_buf, TU_ARRAY_SIZE(p_cdc->tx_ff_buf), 1, true);
+ // TX fifo can be configured to change to overwritable if not connected (DTR bit not set). Without DTR we do not
+ // know if data is actually polled by terminal. This way the most current data is prioritized.
+ // Default: is overwritable
+ tu_fifo_config(&p_cdc->tx_ff, p_cdc->tx_ff_buf, TU_ARRAY_SIZE(p_cdc->tx_ff_buf), 1, _cdcd_cfg.tx_overwritabe_if_not_connected);
#if OSAL_MUTEX_REQUIRED
osal_mutex_t mutex_rd = osal_mutex_create(&p_cdc->rx_ff_mutex);
@@ -294,13 +292,13 @@ void cdcd_reset(uint8_t rhport) {
cdcd_interface_t* p_cdc = &_cdcd_itf[i];
tu_memclr(p_cdc, ITF_MEM_RESET_SIZE);
- if (!_cdcd_fifo_cfg.rx_persistent) {
+ if (!_cdcd_cfg.rx_persistent) {
tu_fifo_clear(&p_cdc->rx_ff);
}
- if (!_cdcd_fifo_cfg.tx_persistent) {
+ if (!_cdcd_cfg.tx_persistent) {
tu_fifo_clear(&p_cdc->tx_ff);
}
- tu_fifo_set_overwritable(&p_cdc->tx_ff, true);
+ tu_fifo_set_overwritable(&p_cdc->tx_ff, _cdcd_cfg.tx_overwritabe_if_not_connected);
}
}
@@ -414,8 +412,12 @@ bool cdcd_control_xfer_cb(uint8_t rhport, uint8_t stage, const tusb_control_requ
p_cdc->line_state = (uint8_t) request->wValue;
- // Disable fifo overwriting if DTR bit is set
- tu_fifo_set_overwritable(&p_cdc->tx_ff, !dtr);
+ // If enabled: fifo overwriting is disabled if DTR bit is set and vice versa
+ if (_cdcd_cfg.tx_overwritabe_if_not_connected) {
+ tu_fifo_set_overwritable(&p_cdc->tx_ff, !dtr);
+ } else {
+ tu_fifo_set_overwritable(&p_cdc->tx_ff, false);
+ }
TU_LOG_DRV(" Set Control Line State: DTR = %d, RTS = %d\r\n", dtr, rts);
@@ -496,7 +498,7 @@ bool cdcd_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t result, uint32_
// xferred_bytes is multiple of EP Packet size and not zero
if (!tu_fifo_count(&p_cdc->tx_ff) && xferred_bytes && (0 == (xferred_bytes & (BULK_PACKET_SIZE - 1)))) {
if (usbd_edpt_claim(rhport, p_cdc->ep_in)) {
- usbd_edpt_xfer(rhport, p_cdc->ep_in, NULL, 0);
+ TU_ASSERT(usbd_edpt_xfer(rhport, p_cdc->ep_in, NULL, 0));
}
}
}
diff --git a/src/class/cdc/cdc_device.h b/src/class/cdc/cdc_device.h
index 2d5ba2575..b653ebd74 100644
--- a/src/class/cdc/cdc_device.h
+++ b/src/class/cdc/cdc_device.h
@@ -48,14 +48,24 @@
//--------------------------------------------------------------------+
// Driver Configuration
//--------------------------------------------------------------------+
-
typedef struct TU_ATTR_PACKED {
- uint8_t rx_persistent : 1; // keep rx fifo on bus reset or disconnect
- uint8_t tx_persistent : 1; // keep tx fifo on bus reset or disconnect
-} tud_cdc_configure_fifo_t;
+ uint8_t rx_persistent : 1; // keep rx fifo data even with bus reset or disconnect
+ uint8_t tx_persistent : 1; // keep tx fifo data even with reset or disconnect
+ uint8_t tx_overwritabe_if_not_connected : 1; // if not connected, tx fifo can be overwritten
+} tud_cdc_configure_t;
+
+#define TUD_CDC_CONFIGURE_DEFAULT() { \
+ .rx_persistent = 0, \
+ .tx_persistent = 0, \
+ .tx_overwritabe_if_not_connected = 1, \
+}
+
+// Configure CDC driver behavior
+bool tud_cdc_configure(const tud_cdc_configure_t* driver_cfg);
-// Configure CDC FIFOs behavior
-bool tud_cdc_configure_fifo(tud_cdc_configure_fifo_t const* cfg);
+// Backward compatible
+#define tud_cdc_configure_fifo_t tud_cdc_configure_t
+#define tud_cdc_configure_fifo tud_cdc_configure
//--------------------------------------------------------------------+
// Application API (Multiple Ports) i.e. CFG_TUD_CDC > 1
diff --git a/src/class/midi/midi_host.c b/src/class/midi/midi_host.c
index 4d824e04c..cd6e115ee 100644
--- a/src/class/midi/midi_host.c
+++ b/src/class/midi/midi_host.c
@@ -56,6 +56,7 @@ TU_ATTR_WEAK void tuh_midi_tx_cb(uint8_t idx, uint32_t xferred_bytes) { (void) i
typedef struct {
uint8_t daddr;
uint8_t bInterfaceNumber; // interface number of MIDI streaming
+ uint8_t iInterface;
uint8_t itf_count; // number of interface including Audio Control + MIDI streaming
uint8_t ep_in; // IN endpoint address
@@ -228,6 +229,7 @@ bool midih_open(uint8_t rhport, uint8_t dev_addr, tusb_desc_interface_t const *d
TU_LOG_DRV("MIDI opening Interface %u (addr = %u)\r\n", desc_itf->bInterfaceNumber, dev_addr);
p_midi->bInterfaceNumber = desc_itf->bInterfaceNumber;
+ p_midi->iInterface = desc_itf->iInterface;
p_midi->itf_count++;
desc_cb.desc_midi = desc_itf;
@@ -252,7 +254,9 @@ bool midih_open(uint8_t rhport, uint8_t dev_addr, tusb_desc_interface_t const *d
TU_LOG_DRV(" Jack %s %s descriptor \r\n",
tu_desc_subtype(p_desc) == MIDI_CS_INTERFACE_IN_JACK ? "IN" : "OUT",
p_desc[3] == MIDI_JACK_EXTERNAL ? "External" : "Embedded");
- desc_cb.desc_jack[desc_cb.jack_num++] = p_desc;
+ if (desc_cb.jack_num < TU_ARRAY_SIZE(desc_cb.desc_jack)) {
+ desc_cb.desc_jack[desc_cb.jack_num++] = p_desc;
+ }
break;
}
@@ -346,6 +350,28 @@ uint8_t tuh_midi_itf_get_index(uint8_t daddr, uint8_t itf_num) {
return TUSB_INDEX_INVALID_8;
}
+bool tuh_midi_itf_get_info(uint8_t idx, tuh_itf_info_t* info) {
+ midih_interface_t* p_midi = &_midi_host[idx];
+ TU_VERIFY(p_midi && info);
+
+ info->daddr = p_midi->daddr;
+
+ // re-construct descriptor
+ tusb_desc_interface_t* desc = &info->desc;
+ desc->bLength = sizeof(tusb_desc_interface_t);
+ desc->bDescriptorType = TUSB_DESC_INTERFACE;
+
+ desc->bInterfaceNumber = p_midi->bInterfaceNumber;
+ desc->bAlternateSetting = 0;
+ desc->bNumEndpoints = (uint8_t)((p_midi->ep_in != 0 ? 1:0) + (p_midi->ep_out != 0 ? 1:0));
+ desc->bInterfaceClass = TUSB_CLASS_AUDIO;
+ desc->bInterfaceSubClass = AUDIO_SUBCLASS_MIDI_STREAMING;
+ desc->bInterfaceProtocol = 0;
+ desc->iInterface = p_midi->iInterface;
+
+ return true;
+}
+
uint8_t tuh_midi_get_tx_cable_count (uint8_t idx) {
TU_VERIFY(idx < CFG_TUH_MIDI);
midih_interface_t *p_midi = &_midi_host[idx];
@@ -566,8 +592,8 @@ uint32_t tuh_midi_stream_read(uint8_t idx, uint8_t *p_cable_num, uint8_t *p_buff
break;
default:
break;
- cable_sysex_in_progress &= (uint16_t) ~cable_mask;
}
+ cable_sysex_in_progress &= (uint16_t) ~cable_mask;
} else {
// Real-time message: can be inserted into a sysex message,
// so do don't clear cable_sysex_in_progress bit
diff --git a/src/class/midi/midi_host.h b/src/class/midi/midi_host.h
index b06bb43d7..06554a03d 100644
--- a/src/class/midi/midi_host.h
+++ b/src/class/midi/midi_host.h
@@ -69,7 +69,7 @@ typedef struct {
const tusb_desc_endpoint_t* desc_epout; // endpoint OUT descriptor, CS_ENDPOINT is right after
uint8_t jack_num;
- const uint8_t* desc_jack[16]; // list of jack descriptors (embedded + external)
+ const uint8_t* desc_jack[32]; // list of jack descriptors (embedded + external)
} tuh_midi_descriptor_cb_t;
typedef struct {
@@ -90,6 +90,10 @@ bool tuh_midi_mounted(uint8_t idx);
// return TUSB_INDEX_INVALID_8 (0xFF) if not found
uint8_t tuh_midi_itf_get_index(uint8_t daddr, uint8_t itf_num);
+// Get Interface information
+// return true if index is correct and interface is currently mounted
+bool tuh_midi_itf_get_info(uint8_t idx, tuh_itf_info_t* info);
+
// return the number of virtual midi cables on the device's IN endpoint
uint8_t tuh_midi_get_rx_cable_count(uint8_t idx);
diff --git a/src/class/msc/msc_device.c b/src/class/msc/msc_device.c
index 6670045aa..87c77c9a7 100644
--- a/src/class/msc/msc_device.c
+++ b/src/class/msc/msc_device.c
@@ -344,7 +344,7 @@ bool mscd_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t event, uint32_t
msc_csw_t * p_csw = &p_msc->csw;
switch (p_msc->stage) {
- case MSC_STAGE_CMD:
+ case MSC_STAGE_CMD: {
//------------- new CBW received -------------//
// Complete IN while waiting for CMD is usually Status of previous SCSI op, ignore it
if (ep_addr != p_msc->ep_out) {
@@ -441,7 +441,8 @@ bool mscd_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t event, uint32_t
}
}
}
- break;
+ break;
+ }
case MSC_STAGE_DATA:
TU_LOG_DRV(" SCSI Data [Lun%u]\r\n", p_cbw->lun);