Skip to content

Commit

Permalink
add tuh_midi_mount_cb_t struct for tuh_midi_mount_cb()
Browse files Browse the repository at this point in the history
change tuh_midi_rx/tx_cb() to have xferred_bytes
rename tuh_midi_get_num_rx/tx_cables() to tuh_midi_get_rx/tx_cable_count()
use default empty callback instead of weak null to be compatible with keil compiler
  • Loading branch information
hathach committed Feb 24, 2025
1 parent 56e84bd commit 4bcbfaf
Show file tree
Hide file tree
Showing 8 changed files with 71 additions and 76 deletions.
4 changes: 2 additions & 2 deletions examples/host/cdc_msc_hid/src/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -82,12 +82,12 @@ int main(void) {

void tuh_mount_cb(uint8_t dev_addr) {
// application set-up
printf("A device with address %d is mounted\r\n", dev_addr);
printf("A device with address %u is mounted\r\n", dev_addr);
}

void tuh_umount_cb(uint8_t dev_addr) {
// application tear-down
printf("A device with address %d is unmounted \r\n", dev_addr);
printf("A device with address %u is unmounted \r\n", dev_addr);
}


Expand Down
13 changes: 7 additions & 6 deletions examples/host/midi_rx/src/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -91,18 +91,18 @@ void midi_host_rx_task(void) {
//--------------------------------------------------------------------+

// Invoked when device with MIDI interface is mounted.
void tuh_midi_mount_cb(uint8_t idx, uint8_t num_cables_rx, uint16_t num_cables_tx) {
printf("MIDI Interface Index = %u, Number of RX cables = %u, Number of TX cables = %u\r\n",
idx, num_cables_rx, num_cables_tx);
void tuh_midi_mount_cb(uint8_t idx, const tuh_midi_mount_cb_t* mount_cb_data) {
printf("MIDI Interface Index = %u, Address = %u, Number of RX cables = %u, Number of TX cables = %u\r\n",
idx, mount_cb_data->daddr, mount_cb_data->rx_cable_count, mount_cb_data->tx_cable_count);
}

// Invoked when device with hid interface is un-mounted
void tuh_midi_umount_cb(uint8_t idx) {
printf("MIDI Interface Index = %u is unmounted\r\n", idx);
}

void tuh_midi_rx_cb(uint8_t idx, uint32_t num_packets) {
if (num_packets == 0) {
void tuh_midi_rx_cb(uint8_t idx, uint32_t xferred_bytes) {
if (xferred_bytes == 0) {
return;
}

Expand All @@ -117,6 +117,7 @@ void tuh_midi_rx_cb(uint8_t idx, uint32_t num_packets) {
printf("\r\n");
}

void tuh_midi_tx_cb(uint8_t idx) {
void tuh_midi_tx_cb(uint8_t idx, uint32_t xferred_bytes) {
(void) idx;
(void) xferred_bytes;
}
2 changes: 1 addition & 1 deletion examples/host/midi_rx/src/tusb_config.h
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ extern "C" {
#define CFG_TUH_ENABLED 1

#if CFG_TUSB_MCU == OPT_MCU_RP2040
// #define CFG_TUH_RPI_PIO_USB 1 // use pio-usb as host controller
#define CFG_TUH_RPI_PIO_USB 1 // use pio-usb as host controller
// #define CFG_TUH_MAX3421 1 // use max3421 as host controller

// host roothub port is 1 if using either pio-usb or max3421
Expand Down
8 changes: 4 additions & 4 deletions src/class/cdc/cdc_host.h
Original file line number Diff line number Diff line change
Expand Up @@ -49,22 +49,22 @@

// RX FIFO size
#ifndef CFG_TUH_CDC_RX_BUFSIZE
#define CFG_TUH_CDC_RX_BUFSIZE USBH_EPSIZE_BULK_MAX
#define CFG_TUH_CDC_RX_BUFSIZE TUH_EPSIZE_BULK_MPS
#endif

// RX Endpoint size
#ifndef CFG_TUH_CDC_RX_EPSIZE
#define CFG_TUH_CDC_RX_EPSIZE USBH_EPSIZE_BULK_MAX
#define CFG_TUH_CDC_RX_EPSIZE TUH_EPSIZE_BULK_MPS
#endif

// TX FIFO size
#ifndef CFG_TUH_CDC_TX_BUFSIZE
#define CFG_TUH_CDC_TX_BUFSIZE USBH_EPSIZE_BULK_MAX
#define CFG_TUH_CDC_TX_BUFSIZE TUH_EPSIZE_BULK_MPS
#endif

// TX Endpoint size
#ifndef CFG_TUH_CDC_TX_EPSIZE
#define CFG_TUH_CDC_TX_EPSIZE USBH_EPSIZE_BULK_MAX
#define CFG_TUH_CDC_TX_EPSIZE TUH_EPSIZE_BULK_MPS
#endif

//--------------------------------------------------------------------+
Expand Down
5 changes: 0 additions & 5 deletions src/class/midi/midi_device.c
Original file line number Diff line number Diff line change
Expand Up @@ -39,9 +39,6 @@
//--------------------------------------------------------------------+
// MACRO CONSTANT TYPEDEF
//--------------------------------------------------------------------+



typedef struct {
uint8_t itf_num;
uint8_t ep_in;
Expand Down Expand Up @@ -440,8 +437,6 @@ uint16_t midid_open(uint8_t rhport, const tusb_desc_interface_t* desc_itf, uint1
drv_len += tu_desc_len(p_desc);
p_desc = tu_desc_next(p_desc);
}
} else {
TU_LOG2("Warning: MIDI Device has no Audio Control Interface");
}

// 2nd Interface is MIDI Streaming
Expand Down
81 changes: 35 additions & 46 deletions src/class/midi/midi_host.c
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,15 @@

#define TU_LOG_DRV(...) TU_LOG(CFG_TUH_MIDI_LOG_LEVEL, __VA_ARGS__)

//--------------------------------------------------------------------+
// Weak stubs: invoked if no strong implementation is available
//--------------------------------------------------------------------+
TU_ATTR_WEAK void tuh_midi_descriptor_cb(uint8_t idx, const tuh_midi_descriptor_cb_t * desc_cb_data) { (void) idx; (void) desc_cb_data; }
TU_ATTR_WEAK void tuh_midi_mount_cb(uint8_t idx, const tuh_midi_mount_cb_t* mount_cb_data) { (void) idx; (void) mount_cb_data; }
TU_ATTR_WEAK void tuh_midi_umount_cb(uint8_t idx) { (void) idx; }
TU_ATTR_WEAK void tuh_midi_rx_cb(uint8_t idx, uint32_t xferred_bytes) { (void) idx; (void) xferred_bytes; }
TU_ATTR_WEAK void tuh_midi_tx_cb(uint8_t idx, uint32_t xferred_bytes) { (void) idx; (void) xferred_bytes; }

//--------------------------------------------------------------------+
// MACRO CONSTANT TYPEDEF
//--------------------------------------------------------------------+
Expand All @@ -52,8 +61,8 @@ typedef struct {
uint8_t ep_in; // IN endpoint address
uint8_t ep_out; // OUT endpoint address

uint8_t num_cables_rx; // IN endpoint CS descriptor bNumEmbMIDIJack value
uint8_t num_cables_tx; // OUT endpoint CS descriptor bNumEmbMIDIJack value
uint8_t rx_cable_count; // IN endpoint CS descriptor bNumEmbMIDIJack value
uint8_t tx_cable_count; // OUT endpoint CS descriptor bNumEmbMIDIJack value

#if CFG_TUH_MIDI_STREAM_API
// For Stream read()/write() API
Expand Down Expand Up @@ -135,16 +144,13 @@ void midih_close(uint8_t daddr) {
midih_interface_t* p_midi = &_midi_host[idx];
if (p_midi->daddr == daddr) {
TU_LOG_DRV(" MIDI close addr = %u index = %u\r\n", daddr, idx);

if (tuh_midi_umount_cb) {
tuh_midi_umount_cb(idx);
}
tuh_midi_umount_cb(idx);

p_midi->ep_in = 0;
p_midi->ep_out = 0;
p_midi->bInterfaceNumber = 0;
p_midi->num_cables_rx = 0;
p_midi->num_cables_tx = 0;
p_midi->rx_cable_count = 0;
p_midi->tx_cable_count = 0;
p_midi->daddr = 0;
p_midi->mounted = false;
tu_memclr(&p_midi->stream_read, sizeof(p_midi->stream_read));
Expand All @@ -163,33 +169,16 @@ bool midih_xfer_cb(uint8_t dev_addr, uint8_t ep_addr, xfer_result_t result, uint
midih_interface_t *p_midi_host = &_midi_host[idx];

if (ep_addr == p_midi_host->ep_stream.rx.ep_addr) {
// receive new data if available
// receive new data, put it into FIFO and invoke callback if available
if (xferred_bytes) {
// put in the RX FIFO only non-zero MIDI IN 4-byte packets
uint32_t packets_queued = 0;
uint8_t *buf = _midi_epbuf->rx;
const uint32_t npackets = xferred_bytes / 4;
for (uint32_t p = 0; p < npackets; p++) {
// some devices send back all zero packets even if there is no data ready
const uint32_t packet = tu_unaligned_read32(buf);
if (packet != 0) {
tu_edpt_stream_read_xfer_complete_with_buf(&p_midi_host->ep_stream.rx, buf, 4);
++packets_queued;
TU_LOG3("MIDI RX=%08x\r\n", packet);
}
buf += 4;
}

if (tuh_midi_rx_cb) {
tuh_midi_rx_cb(idx, packets_queued);
}
tu_edpt_stream_read_xfer_complete(&p_midi_host->ep_stream.rx, xferred_bytes);
tuh_midi_rx_cb(idx, xferred_bytes);
}

tu_edpt_stream_read_xfer(dev_addr, &p_midi_host->ep_stream.rx); // prepare for next transfer
} else if (ep_addr == p_midi_host->ep_stream.tx.ep_addr) {
if (tuh_midi_tx_cb) {
tuh_midi_tx_cb(idx);
}
tuh_midi_tx_cb(idx, xferred_bytes);

if (0 == tu_edpt_stream_write_xfer(dev_addr, &p_midi_host->ep_stream.tx)) {
// If there is no data left, a ZLP should be sent if
// xferred_bytes is multiple of EP size and not zero
Expand All @@ -207,7 +196,6 @@ bool midih_open(uint8_t rhport, uint8_t dev_addr, tusb_desc_interface_t const *d
(void) rhport;

TU_VERIFY(TUSB_CLASS_AUDIO == desc_itf->bInterfaceClass);
// const uint8_t* p_start = ((uint8_t const*) desc_itf);
const uint8_t *p_end = ((const uint8_t *) desc_itf) + max_len;
const uint8_t *p_desc = (const uint8_t *) desc_itf;

Expand Down Expand Up @@ -286,14 +274,14 @@ bool midih_open(uint8_t rhport, uint8_t dev_addr, tusb_desc_interface_t const *d
TU_LOG_DRV(" Endpoint and CS_Endpoint descriptor %02x\r\n", p_ep->bEndpointAddress);
if (tu_edpt_dir(p_ep->bEndpointAddress) == TUSB_DIR_OUT) {
p_midi->ep_out = p_ep->bEndpointAddress;
p_midi->num_cables_tx = p_csep->bNumEmbMIDIJack;
p_midi->tx_cable_count = p_csep->bNumEmbMIDIJack;
desc_cb.desc_epout = p_ep;

TU_ASSERT(tuh_edpt_open(dev_addr, p_ep));
tu_edpt_stream_open(&p_midi->ep_stream.tx, p_ep);
} else {
p_midi->ep_in = p_ep->bEndpointAddress;
p_midi->num_cables_rx = p_csep->bNumEmbMIDIJack;
p_midi->rx_cable_count = p_csep->bNumEmbMIDIJack;
desc_cb.desc_epin = p_ep;

TU_ASSERT(tuh_edpt_open(dev_addr, p_ep));
Expand All @@ -309,10 +297,7 @@ bool midih_open(uint8_t rhport, uint8_t dev_addr, tusb_desc_interface_t const *d
desc_cb.desc_midi_total_len = (uint16_t) ((uintptr_t)p_desc - (uintptr_t) desc_itf);

p_midi->daddr = dev_addr;

if (tuh_midi_descriptor_cb) {
tuh_midi_descriptor_cb(idx, &desc_cb);
}
tuh_midi_descriptor_cb(idx, &desc_cb);

return true;
}
Expand All @@ -323,9 +308,13 @@ bool midih_set_config(uint8_t dev_addr, uint8_t itf_num) {
midih_interface_t *p_midi = &_midi_host[idx];
p_midi->mounted = true;

if (tuh_midi_mount_cb) {
tuh_midi_mount_cb(idx, p_midi->num_cables_rx, p_midi->num_cables_tx);
}
const tuh_midi_mount_cb_t mount_cb_data = {
.daddr = dev_addr,
.bInterfaceNumber = itf_num,
.rx_cable_count = p_midi->rx_cable_count,
.tx_cable_count = p_midi->tx_cable_count,
};
tuh_midi_mount_cb(idx, &mount_cb_data);

tu_edpt_stream_read_xfer(dev_addr, &p_midi->ep_stream.rx); // prepare for incoming data

Expand Down Expand Up @@ -355,18 +344,18 @@ uint8_t tuh_midi_itf_get_index(uint8_t daddr, uint8_t itf_num) {
return TUSB_INDEX_INVALID_8;
}

uint8_t tuh_midi_get_num_tx_cables (uint8_t idx) {
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];
TU_VERIFY(p_midi->ep_stream.tx.ep_addr != 0, 0);
return p_midi->num_cables_tx;
return p_midi->tx_cable_count;
}

uint8_t tuh_midi_get_num_rx_cables (uint8_t idx) {
uint8_t tuh_midi_get_rx_cable_count (uint8_t idx) {
TU_VERIFY(idx < CFG_TUH_MIDI);
midih_interface_t *p_midi = &_midi_host[idx];
TU_VERIFY(p_midi->ep_stream.rx.ep_addr != 0, 0);
return p_midi->num_cables_rx;
return p_midi->rx_cable_count;
}

uint32_t tuh_midi_read_available(uint8_t idx) {
Expand Down Expand Up @@ -410,7 +399,7 @@ uint32_t tuh_midi_packet_write_n(uint8_t idx, const uint8_t* buffer, uint32_t bu
uint32_t tuh_midi_stream_write(uint8_t idx, uint8_t cable_num, uint8_t const *buffer, uint32_t bufsize) {
TU_VERIFY(idx < CFG_TUH_MIDI && buffer && bufsize > 0);
midih_interface_t *p_midi = &_midi_host[idx];
TU_VERIFY(cable_num < p_midi->num_cables_tx);
TU_VERIFY(cable_num < p_midi->tx_cable_count);
midi_driver_stream_t *stream = &p_midi->stream_write;

uint32_t byte_count = 0;
Expand Down Expand Up @@ -520,7 +509,7 @@ uint32_t tuh_midi_stream_read(uint8_t idx, uint8_t *p_cable_num, uint8_t *p_buff
while (nread == 4 && bytes_buffered < bufsize) {
*p_cable_num = (p_midi->stream_read.buffer[0] >> 4) & 0x0f;
uint8_t bytes_to_add_to_stream = 0;
if (*p_cable_num < p_midi->num_cables_rx) {
if (*p_cable_num < p_midi->rx_cable_count) {
// ignore the CIN field; too many devices out there encode this wrong
uint8_t status = p_midi->stream_read.buffer[1];
uint16_t cable_mask = (uint16_t) (1 << *p_cable_num);
Expand Down
30 changes: 22 additions & 8 deletions src/class/midi/midi_host.h
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@
#endif

//--------------------------------------------------------------------+
// Application API
// Application Types
//--------------------------------------------------------------------+
typedef struct {
const tusb_desc_interface_t* desc_audio_control;
Expand All @@ -76,6 +76,17 @@ typedef struct {
const uint8_t* desc_jack[16]; // list of jack descriptors (embedded + external)
} tuh_midi_descriptor_cb_t;

typedef struct {
uint8_t daddr;
uint8_t bInterfaceNumber; // interface number of MIDI streaming
uint8_t rx_cable_count;
uint8_t tx_cable_count;
} tuh_midi_mount_cb_t;

//--------------------------------------------------------------------+
// Application API
//--------------------------------------------------------------------+

// Check if MIDI interface is mounted
bool tuh_midi_mounted(uint8_t idx);

Expand All @@ -84,10 +95,10 @@ bool tuh_midi_mounted(uint8_t idx);
uint8_t tuh_midi_itf_get_index(uint8_t daddr, uint8_t itf_num);

// return the number of virtual midi cables on the device's IN endpoint
uint8_t tuh_midi_get_num_rx_cables(uint8_t idx);
uint8_t tuh_midi_get_rx_cable_count(uint8_t idx);

// return the number of virtual midi cables on the device's OUT endpoint
uint8_t tuh_midi_get_num_tx_cables(uint8_t idx);
uint8_t tuh_midi_get_tx_cable_count(uint8_t idx);

// return the raw number of bytes available.
// Note: this is related but not the same as number of stream bytes available.
Expand Down Expand Up @@ -151,16 +162,19 @@ uint32_t tuh_midi_stream_read(uint8_t idx, uint8_t *p_cable_num, uint8_t *p_buff

// Invoked when MIDI interface is detected in enumeration. Application can copy/parse descriptor if needed.
// Note: may be fired before tuh_midi_mount_cb(), therefore midi interface is not mounted/ready.
TU_ATTR_WEAK void tuh_midi_descriptor_cb(uint8_t idx, const tuh_midi_descriptor_cb_t * desc_cb);
void tuh_midi_descriptor_cb(uint8_t idx, const tuh_midi_descriptor_cb_t * desc_cb_data);

// Invoked when device with MIDI interface is mounted.
TU_ATTR_WEAK void tuh_midi_mount_cb(uint8_t idx, uint8_t num_cables_rx, uint16_t num_cables_tx);
void tuh_midi_mount_cb(uint8_t idx, const tuh_midi_mount_cb_t* mount_cb_data);

// Invoked when device with MIDI interface is un-mounted
TU_ATTR_WEAK void tuh_midi_umount_cb(uint8_t idx);
void tuh_midi_umount_cb(uint8_t idx);

// Invoked when received new data
void tuh_midi_rx_cb(uint8_t idx, uint32_t xferred_bytes);

TU_ATTR_WEAK void tuh_midi_rx_cb(uint8_t idx, uint32_t num_packets);
TU_ATTR_WEAK void tuh_midi_tx_cb(uint8_t idx);
// Invoked when a TX is complete and therefore space becomes available in TX buffer
void tuh_midi_tx_cb(uint8_t idx, uint32_t xferred_bytes);

//--------------------------------------------------------------------+
// Internal Class Driver API
Expand Down
4 changes: 0 additions & 4 deletions src/host/usbh_pvt.h
Original file line number Diff line number Diff line change
Expand Up @@ -41,10 +41,6 @@
#define TU_LOG_INT_USBH(...) TU_LOG_INT(CFG_TUH_LOG_LEVEL, __VA_ARGS__)
#define TU_LOG_HEX_USBH(...) TU_LOG_HEX(CFG_TUH_LOG_LEVEL, __VA_ARGS__)

enum {
USBH_EPSIZE_BULK_MAX = (TUH_OPT_HIGH_SPEED ? TUSB_EPSIZE_BULK_HS : TUSB_EPSIZE_BULK_FS)
};

//--------------------------------------------------------------------+
// Class Driver API
//--------------------------------------------------------------------+
Expand Down

0 comments on commit 4bcbfaf

Please sign in to comment.