add tuh_midi_descriptor_cb()
This commit is contained in:
@@ -661,6 +661,7 @@ typedef struct TU_ATTR_PACKED
|
|||||||
uint16_t wTotalLength ; ///< Total number of bytes returned for the class-specific AudioControl interface descriptor. Includes the combined length of this descriptor header and all Clock Source, Unit and Terminal descriptors.
|
uint16_t wTotalLength ; ///< Total number of bytes returned for the class-specific AudioControl interface descriptor. Includes the combined length of this descriptor header and all Clock Source, Unit and Terminal descriptors.
|
||||||
uint8_t bmControls ; ///< See: audio_cs_ac_interface_control_pos_t.
|
uint8_t bmControls ; ///< See: audio_cs_ac_interface_control_pos_t.
|
||||||
} audio_desc_cs_ac_interface_t;
|
} audio_desc_cs_ac_interface_t;
|
||||||
|
TU_VERIFY_STATIC(sizeof(audio_desc_cs_ac_interface_t) == 9, "size is not correct");
|
||||||
|
|
||||||
/// AUDIO Clock Source Descriptor (4.7.2.1)
|
/// AUDIO Clock Source Descriptor (4.7.2.1)
|
||||||
typedef struct TU_ATTR_PACKED
|
typedef struct TU_ATTR_PACKED
|
||||||
|
@@ -628,10 +628,6 @@ static uint8_t audiod_get_audio_fct_idx(audiod_function_t *audio);
|
|||||||
|
|
||||||
#if (CFG_TUD_AUDIO_ENABLE_EP_IN && (CFG_TUD_AUDIO_EP_IN_FLOW_CONTROL || CFG_TUD_AUDIO_ENABLE_ENCODING)) || (CFG_TUD_AUDIO_ENABLE_EP_OUT && CFG_TUD_AUDIO_ENABLE_DECODING)
|
#if (CFG_TUD_AUDIO_ENABLE_EP_IN && (CFG_TUD_AUDIO_EP_IN_FLOW_CONTROL || CFG_TUD_AUDIO_ENABLE_ENCODING)) || (CFG_TUD_AUDIO_ENABLE_EP_OUT && CFG_TUD_AUDIO_ENABLE_DECODING)
|
||||||
static void audiod_parse_for_AS_params(audiod_function_t *audio, uint8_t const *p_desc, uint8_t const *p_desc_end, uint8_t const as_itf);
|
static void audiod_parse_for_AS_params(audiod_function_t *audio, uint8_t const *p_desc, uint8_t const *p_desc_end, uint8_t const as_itf);
|
||||||
|
|
||||||
static inline uint8_t tu_desc_subtype(void const *desc) {
|
|
||||||
return ((uint8_t const *) desc)[2];
|
|
||||||
}
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if CFG_TUD_AUDIO_ENABLE_EP_IN && CFG_TUD_AUDIO_EP_IN_FLOW_CONTROL
|
#if CFG_TUD_AUDIO_ENABLE_EP_IN && CFG_TUD_AUDIO_EP_IN_FLOW_CONTROL
|
||||||
|
@@ -150,27 +150,6 @@ typedef midi_desc_out_jack_n_t(1) midi_desc_out_jack_1in_t; // 1 input
|
|||||||
typedef midi_desc_out_jack_1in_t midi_desc_out_jack_t; // backward compatible
|
typedef midi_desc_out_jack_1in_t midi_desc_out_jack_t; // backward compatible
|
||||||
TU_VERIFY_STATIC(sizeof(midi_desc_out_jack_1in_t) == 7 + 2 * 1, "size is not correct");
|
TU_VERIFY_STATIC(sizeof(midi_desc_out_jack_1in_t) == 7 + 2 * 1, "size is not correct");
|
||||||
|
|
||||||
/// MIDI Element Descriptor
|
|
||||||
typedef struct TU_ATTR_PACKED {
|
|
||||||
uint8_t bLength ; ///< Size of this descriptor in bytes.
|
|
||||||
uint8_t bDescriptorType ; ///< Descriptor Type, must be Class-Specific
|
|
||||||
uint8_t bDescriptorSubType ; ///< Descriptor SubType
|
|
||||||
uint8_t bElementID;
|
|
||||||
|
|
||||||
uint8_t bNrInputPins;
|
|
||||||
uint8_t baSourceID;
|
|
||||||
uint8_t baSourcePin;
|
|
||||||
|
|
||||||
uint8_t bNrOutputPins;
|
|
||||||
uint8_t bInTerminalLink;
|
|
||||||
uint8_t bOutTerminalLink;
|
|
||||||
uint8_t bElCapsSize;
|
|
||||||
|
|
||||||
uint16_t bmElementCaps;
|
|
||||||
uint8_t iElement;
|
|
||||||
} midi_desc_element_t;
|
|
||||||
TU_VERIFY_STATIC(sizeof(midi_desc_element_t) == 14, "size is not correct");
|
|
||||||
|
|
||||||
/// MIDI Element Descriptor with multiple pins
|
/// MIDI Element Descriptor with multiple pins
|
||||||
#define midi_desc_element_n_t(input_num) \
|
#define midi_desc_element_n_t(input_num) \
|
||||||
struct TU_ATTR_PACKED { \
|
struct TU_ATTR_PACKED { \
|
||||||
|
@@ -194,123 +194,108 @@ bool midih_open(uint8_t rhport, uint8_t dev_addr, tusb_desc_interface_t const *d
|
|||||||
|
|
||||||
midih_interface_t *p_midi = find_new_midi();
|
midih_interface_t *p_midi = find_new_midi();
|
||||||
TU_VERIFY(p_midi != NULL);
|
TU_VERIFY(p_midi != NULL);
|
||||||
|
|
||||||
TU_VERIFY(TUSB_CLASS_AUDIO == desc_itf->bInterfaceClass);
|
TU_VERIFY(TUSB_CLASS_AUDIO == desc_itf->bInterfaceClass);
|
||||||
// There can be just a MIDI interface or an audio and a MIDI interface. Only open the MIDI interface
|
|
||||||
|
// There can be just a MIDI or an Audio + MIDI interface
|
||||||
|
// const uint8_t* p_start = ((uint8_t const*) desc_itf);
|
||||||
|
const uint8_t* p_end = ((uint8_t const*) desc_itf) + max_len;
|
||||||
uint8_t const *p_desc = (uint8_t const *) desc_itf;
|
uint8_t const *p_desc = (uint8_t const *) desc_itf;
|
||||||
uint16_t len_parsed = 0;
|
uint16_t len_parsed = 0;
|
||||||
|
|
||||||
|
tuh_midi_descriptor_cb_t desc_cb = { 0 };
|
||||||
|
desc_cb.jack_num = 0;
|
||||||
|
|
||||||
|
// If there is Audio Control Interface + Audio Header descriptor, skip it
|
||||||
if (AUDIO_SUBCLASS_CONTROL == desc_itf->bInterfaceSubClass) {
|
if (AUDIO_SUBCLASS_CONTROL == desc_itf->bInterfaceSubClass) {
|
||||||
// This driver does not support audio streaming. However, if this is the audio control interface
|
TU_VERIFY(max_len > 2*sizeof(tusb_desc_interface_t) + sizeof(audio_desc_cs_ac_interface_t));
|
||||||
// there might be a MIDI interface following it. Search through every descriptor until a MIDI
|
|
||||||
// interface is found or the end of the descriptor is found
|
p_desc = tu_desc_next(p_desc);
|
||||||
while (len_parsed < max_len &&
|
TU_VERIFY(tu_desc_type(p_desc) == TUSB_DESC_CS_INTERFACE &&
|
||||||
(desc_itf->bInterfaceClass != TUSB_CLASS_AUDIO || desc_itf->bInterfaceSubClass != AUDIO_SUBCLASS_MIDI_STREAMING)) {
|
tu_desc_subtype(p_desc) == AUDIO_CS_AC_INTERFACE_HEADER);
|
||||||
len_parsed += desc_itf->bLength;
|
|
||||||
p_desc = tu_desc_next(p_desc);
|
p_desc = tu_desc_next(p_desc);
|
||||||
desc_itf = (tusb_desc_interface_t const *)p_desc;
|
desc_itf = (tusb_desc_interface_t const *)p_desc;
|
||||||
}
|
|
||||||
|
|
||||||
TU_VERIFY(TUSB_CLASS_AUDIO == desc_itf->bInterfaceClass);
|
TU_VERIFY(TUSB_CLASS_AUDIO == desc_itf->bInterfaceClass);
|
||||||
}
|
}
|
||||||
TU_VERIFY(AUDIO_SUBCLASS_MIDI_STREAMING == desc_itf->bInterfaceSubClass);
|
TU_VERIFY(AUDIO_SUBCLASS_MIDI_STREAMING == desc_itf->bInterfaceSubClass);
|
||||||
|
desc_cb.desc_interface = desc_itf;
|
||||||
|
|
||||||
len_parsed += desc_itf->bLength;
|
len_parsed += desc_itf->bLength;
|
||||||
|
|
||||||
TU_LOG_DRV("MIDI opening Interface %u (addr = %u)\r\n", desc_itf->bInterfaceNumber, dev_addr);
|
TU_LOG_DRV("MIDI opening Interface %u (addr = %u)\r\n", desc_itf->bInterfaceNumber, dev_addr);
|
||||||
p_midi->itf_num = desc_itf->bInterfaceNumber;
|
p_midi->itf_num = desc_itf->bInterfaceNumber;
|
||||||
|
|
||||||
// CS Header descriptor
|
|
||||||
p_desc = tu_desc_next(p_desc);
|
p_desc = tu_desc_next(p_desc);
|
||||||
midi_desc_header_t const *p_mdh = (midi_desc_header_t const *) p_desc;
|
|
||||||
TU_VERIFY(p_mdh->bDescriptorType == TUSB_DESC_CS_INTERFACE &&
|
bool found_new_interface = false;
|
||||||
p_mdh->bDescriptorSubType == MIDI_CS_INTERFACE_HEADER);
|
while ((p_desc < p_end) && (tu_desc_next(p_desc) <= p_end) && !found_new_interface) {
|
||||||
|
switch (tu_desc_type(p_desc)) {
|
||||||
|
case TUSB_DESC_INTERFACE:
|
||||||
|
found_new_interface = true;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case TUSB_DESC_CS_INTERFACE:
|
||||||
|
switch (tu_desc_subtype(p_desc)) {
|
||||||
|
case MIDI_CS_INTERFACE_HEADER:
|
||||||
TU_LOG_DRV(" Interface Header descriptor\r\n");
|
TU_LOG_DRV(" Interface Header descriptor\r\n");
|
||||||
|
desc_cb.desc_header = p_desc;
|
||||||
|
break;
|
||||||
|
|
||||||
// p_desc = tu_desc_next(p_desc);
|
case MIDI_CS_INTERFACE_IN_JACK:
|
||||||
uint8_t prev_ep_addr = 0; // the CS endpoint descriptor is associated with the previous endpoint descriptor
|
case MIDI_CS_INTERFACE_OUT_JACK: {
|
||||||
tusb_desc_endpoint_t const* in_desc = NULL;
|
TU_LOG_DRV(" Jack %s %s descriptor \r\n",
|
||||||
tusb_desc_endpoint_t const* out_desc = NULL;
|
tu_desc_subtype(p_desc) == MIDI_CS_INTERFACE_IN_JACK ? "IN" : "OUT",
|
||||||
while (len_parsed < max_len) {
|
p_desc[3] == MIDI_JACK_EXTERNAL ? "External" : "Embedded");
|
||||||
TU_VERIFY((p_mdh->bDescriptorType == TUSB_DESC_CS_INTERFACE) ||
|
desc_cb.desc_jack[desc_cb.jack_num++] = p_desc;
|
||||||
(p_mdh->bDescriptorType == TUSB_DESC_CS_ENDPOINT && p_mdh->bDescriptorSubType == MIDI_CS_ENDPOINT_GENERAL) ||
|
break;
|
||||||
p_mdh->bDescriptorType == TUSB_DESC_ENDPOINT);
|
|
||||||
|
|
||||||
if (p_mdh->bDescriptorType == TUSB_DESC_CS_INTERFACE) {
|
|
||||||
// The USB host doesn't really need this information unless it uses
|
|
||||||
// the string descriptor for a jack or Element
|
|
||||||
|
|
||||||
// assume it is an input jack
|
|
||||||
midi_desc_in_jack_t const *p_mdij = (midi_desc_in_jack_t const *) p_desc;
|
|
||||||
if (p_mdij->bDescriptorSubType == MIDI_CS_INTERFACE_HEADER) {
|
|
||||||
TU_LOG_DRV(" Interface Header descriptor\r\n");
|
|
||||||
} else if (p_mdij->bDescriptorSubType == MIDI_CS_INTERFACE_IN_JACK) {
|
|
||||||
// Then it is an in jack.
|
|
||||||
TU_LOG_DRV(" IN Jack %s descriptor \r\n", p_mdij->bJackType == MIDI_JACK_EXTERNAL ? "External" : "Embedded");
|
|
||||||
} else if (p_mdij->bDescriptorSubType == MIDI_CS_INTERFACE_OUT_JACK) {
|
|
||||||
// then it is an out jack
|
|
||||||
TU_LOG_DRV(" OUT Jack %s descriptor\r\n", p_mdij->bJackType == MIDI_JACK_EXTERNAL ? "External" : "Embedded");
|
|
||||||
} else if (p_mdij->bDescriptorSubType == MIDI_CS_INTERFACE_ELEMENT) {
|
|
||||||
// the it is an element;
|
|
||||||
TU_LOG_DRV("Found element\r\n");
|
|
||||||
} else {
|
|
||||||
TU_LOG_DRV(" Unknown CS Interface sub-type %u\r\n", p_mdij->bDescriptorSubType);
|
|
||||||
TU_VERIFY(false);// unknown CS Interface sub-type
|
|
||||||
}
|
}
|
||||||
len_parsed += p_mdij->bLength;
|
|
||||||
} else if (p_mdh->bDescriptorType == TUSB_DESC_CS_ENDPOINT) {
|
case MIDI_CS_INTERFACE_ELEMENT:
|
||||||
TU_LOG_DRV(" CS_ENDPOINT descriptor\r\n");
|
TU_LOG_DRV(" Element descriptor\r\n");
|
||||||
TU_VERIFY(prev_ep_addr != 0);
|
desc_cb.desc_element = p_desc;
|
||||||
// parse out the mapping between the device's embedded jacks and the endpoints
|
break;
|
||||||
// Each embedded IN jack is associated with an OUT endpoint
|
|
||||||
midi_desc_cs_endpoint_t const *p_csep = (midi_desc_cs_endpoint_t const *) p_mdh;
|
default:
|
||||||
if (tu_edpt_dir(prev_ep_addr) == TUSB_DIR_OUT) {
|
TU_LOG_DRV(" Unknown CS Interface sub-type %u\r\n", tu_desc_subtype(p_desc));
|
||||||
TU_VERIFY(p_midi->ep_out == prev_ep_addr);
|
break;
|
||||||
TU_VERIFY(p_midi->num_cables_tx == 0);
|
|
||||||
p_midi->num_cables_tx = p_csep->bNumEmbMIDIJack;
|
|
||||||
} else {
|
|
||||||
TU_VERIFY(p_midi->ep_in == prev_ep_addr);
|
|
||||||
TU_VERIFY(p_midi->num_cables_rx == 0);
|
|
||||||
p_midi->num_cables_rx = p_csep->bNumEmbMIDIJack;
|
|
||||||
}
|
}
|
||||||
len_parsed += p_csep->bLength;
|
break;
|
||||||
prev_ep_addr = 0;
|
|
||||||
} else if (p_mdh->bDescriptorType == TUSB_DESC_ENDPOINT) {
|
case TUSB_DESC_ENDPOINT: {
|
||||||
// parse out the bulk endpoint info
|
tusb_desc_endpoint_t const *p_ep = (tusb_desc_endpoint_t const *) p_desc;
|
||||||
tusb_desc_endpoint_t const *p_ep = (tusb_desc_endpoint_t const *) p_mdh;
|
p_desc = tu_desc_next(p_desc); // next to CS endpoint
|
||||||
TU_LOG_DRV(" Endpoint descriptor %02x\r\n", p_ep->bEndpointAddress);
|
TU_VERIFY(p_desc < p_end && tu_desc_next(p_desc) <= p_end);
|
||||||
|
midi_desc_cs_endpoint_t const *p_csep = (midi_desc_cs_endpoint_t const *) p_desc;
|
||||||
|
|
||||||
|
TU_LOG_DRV(" Endpoint and CS_Endpoint descriptor %02x\r\n", p_ep->bEndpointAddress);
|
||||||
if (tu_edpt_dir(p_ep->bEndpointAddress) == TUSB_DIR_OUT) {
|
if (tu_edpt_dir(p_ep->bEndpointAddress) == TUSB_DIR_OUT) {
|
||||||
TU_VERIFY(p_midi->ep_out == 0);
|
|
||||||
TU_VERIFY(p_midi->num_cables_tx == 0);
|
|
||||||
p_midi->ep_out = p_ep->bEndpointAddress;
|
p_midi->ep_out = p_ep->bEndpointAddress;
|
||||||
prev_ep_addr = p_midi->ep_out;
|
p_midi->num_cables_tx = p_csep->bNumEmbMIDIJack;
|
||||||
out_desc = p_ep;
|
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 {
|
} else {
|
||||||
TU_VERIFY(p_midi->ep_in == 0);
|
|
||||||
TU_VERIFY(p_midi->num_cables_rx == 0);
|
|
||||||
p_midi->ep_in = p_ep->bEndpointAddress;
|
p_midi->ep_in = p_ep->bEndpointAddress;
|
||||||
prev_ep_addr = p_midi->ep_in;
|
p_midi->num_cables_rx = p_csep->bNumEmbMIDIJack;
|
||||||
in_desc = p_ep;
|
desc_cb.desc_epin = p_ep;
|
||||||
|
|
||||||
|
TU_ASSERT(tuh_edpt_open(dev_addr, p_ep));
|
||||||
|
tu_edpt_stream_open(&p_midi->ep_stream.rx, p_ep);
|
||||||
}
|
}
|
||||||
len_parsed += p_mdh->bLength;
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
default: break; // skip unknown descriptor
|
||||||
}
|
}
|
||||||
p_desc = tu_desc_next(p_desc);
|
p_desc = tu_desc_next(p_desc);
|
||||||
p_mdh = (midi_desc_header_t const *) p_desc;
|
|
||||||
}
|
}
|
||||||
TU_VERIFY((p_midi->ep_out != 0 && p_midi->num_cables_tx != 0) ||
|
desc_cb.desc_interface_len = (uint16_t) ((uintptr_t)p_desc - (uintptr_t) desc_itf);
|
||||||
(p_midi->ep_in != 0 && p_midi->num_cables_rx != 0));
|
|
||||||
|
|
||||||
if (in_desc) {
|
|
||||||
TU_ASSERT(tuh_edpt_open(dev_addr, in_desc));
|
|
||||||
tu_edpt_stream_open(&p_midi->ep_stream.rx, in_desc);
|
|
||||||
}
|
|
||||||
if (out_desc) {
|
|
||||||
TU_ASSERT(tuh_edpt_open(dev_addr, out_desc));
|
|
||||||
tu_edpt_stream_open(&p_midi->ep_stream.tx, out_desc);
|
|
||||||
}
|
|
||||||
p_midi->dev_addr = dev_addr;
|
p_midi->dev_addr = dev_addr;
|
||||||
|
|
||||||
// if (tuh_midi_interface_descriptor_cb) {
|
if (tuh_midi_descriptor_cb) {
|
||||||
// tuh_midi_interface_descriptor_cb(dev_addr, desc_itf, );
|
tuh_midi_descriptor_cb(dev_addr, &desc_cb);
|
||||||
// }
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@@ -62,6 +62,18 @@
|
|||||||
//--------------------------------------------------------------------+
|
//--------------------------------------------------------------------+
|
||||||
// Application API
|
// Application API
|
||||||
//--------------------------------------------------------------------+
|
//--------------------------------------------------------------------+
|
||||||
|
typedef struct {
|
||||||
|
const tusb_desc_interface_t* desc_interface; // start of whole midi interface descriptor
|
||||||
|
uint16_t desc_interface_len;
|
||||||
|
|
||||||
|
const uint8_t* desc_header;
|
||||||
|
const uint8_t* desc_element;
|
||||||
|
const tusb_desc_endpoint_t* desc_epin; // endpoint IN descriptor, CS_ENDPOINT is right after
|
||||||
|
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)
|
||||||
|
} tuh_midi_descriptor_cb_t;
|
||||||
|
|
||||||
// Check if MIDI interface is mounted
|
// Check if MIDI interface is mounted
|
||||||
bool tuh_midi_mounted(uint8_t dev_addr);
|
bool tuh_midi_mounted(uint8_t dev_addr);
|
||||||
@@ -134,7 +146,7 @@ uint32_t tuh_midi_stream_read (uint8_t dev_addr, uint8_t *p_cable_num, uint8_t *
|
|||||||
|
|
||||||
// Invoked when MIDI interface is detected in enumeration. Application can copy/parse descriptor if needed.
|
// 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.
|
// Note: may be fired before tuh_midi_mount_cb(), therefore midi interface is not mounted/ready.
|
||||||
// TU_ATTR_WEAK void tuh_midi_interface_descriptor_cb(uint8_t dev_addr, const uint8_t* desc_itf, uint16_t desc_len);
|
TU_ATTR_WEAK void tuh_midi_descriptor_cb(uint8_t dev_addr, tuh_midi_descriptor_cb_t const* desc_cb);
|
||||||
|
|
||||||
// Invoked when device with MIDI interface is mounted.
|
// Invoked when device with MIDI interface is mounted.
|
||||||
TU_ATTR_WEAK void tuh_midi_mount_cb(uint8_t dev_addr, uint8_t num_cables_rx, uint16_t num_cables_tx);
|
TU_ATTR_WEAK void tuh_midi_mount_cb(uint8_t dev_addr, uint8_t num_cables_rx, uint16_t num_cables_tx);
|
||||||
|
@@ -281,7 +281,8 @@ typedef enum {
|
|||||||
// TODO remove
|
// TODO remove
|
||||||
enum {
|
enum {
|
||||||
DESC_OFFSET_LEN = 0,
|
DESC_OFFSET_LEN = 0,
|
||||||
DESC_OFFSET_TYPE = 1
|
DESC_OFFSET_TYPE = 1,
|
||||||
|
DESC_OFFSET_SUBTYPE = 2
|
||||||
};
|
};
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
@@ -570,14 +571,19 @@ TU_ATTR_ALWAYS_INLINE static inline uint8_t const * tu_desc_next(void const* des
|
|||||||
return desc8 + desc8[DESC_OFFSET_LEN];
|
return desc8 + desc8[DESC_OFFSET_LEN];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// get descriptor length
|
||||||
|
TU_ATTR_ALWAYS_INLINE static inline uint8_t tu_desc_len(void const* desc) {
|
||||||
|
return ((uint8_t const*) desc)[DESC_OFFSET_LEN];
|
||||||
|
}
|
||||||
|
|
||||||
// get descriptor type
|
// get descriptor type
|
||||||
TU_ATTR_ALWAYS_INLINE static inline uint8_t tu_desc_type(void const* desc) {
|
TU_ATTR_ALWAYS_INLINE static inline uint8_t tu_desc_type(void const* desc) {
|
||||||
return ((uint8_t const*) desc)[DESC_OFFSET_TYPE];
|
return ((uint8_t const*) desc)[DESC_OFFSET_TYPE];
|
||||||
}
|
}
|
||||||
|
|
||||||
// get descriptor length
|
// get descriptor subtype
|
||||||
TU_ATTR_ALWAYS_INLINE static inline uint8_t tu_desc_len(void const* desc) {
|
TU_ATTR_ALWAYS_INLINE static inline uint8_t tu_desc_subtype(void const* desc) {
|
||||||
return ((uint8_t const*) desc)[DESC_OFFSET_LEN];
|
return ((uint8_t const*) desc)[DESC_OFFSET_SUBTYPE];
|
||||||
}
|
}
|
||||||
|
|
||||||
// find descriptor that match byte1 (type)
|
// find descriptor that match byte1 (type)
|
||||||
|
12
src/tusb.c
12
src/tusb.c
@@ -142,7 +142,9 @@ void tusb_int_handler(uint8_t rhport, bool in_isr) {
|
|||||||
|
|
||||||
uint8_t const* tu_desc_find(uint8_t const* desc, uint8_t const* end, uint8_t byte1) {
|
uint8_t const* tu_desc_find(uint8_t const* desc, uint8_t const* end, uint8_t byte1) {
|
||||||
while (desc + 1 < end) {
|
while (desc + 1 < end) {
|
||||||
if (desc[1] == byte1) return desc;
|
if (desc[1] == byte1) {
|
||||||
|
return desc;
|
||||||
|
}
|
||||||
desc += desc[DESC_OFFSET_LEN];
|
desc += desc[DESC_OFFSET_LEN];
|
||||||
}
|
}
|
||||||
return NULL;
|
return NULL;
|
||||||
@@ -150,7 +152,9 @@ uint8_t const* tu_desc_find(uint8_t const* desc, uint8_t const* end, uint8_t byt
|
|||||||
|
|
||||||
uint8_t const* tu_desc_find2(uint8_t const* desc, uint8_t const* end, uint8_t byte1, uint8_t byte2) {
|
uint8_t const* tu_desc_find2(uint8_t const* desc, uint8_t const* end, uint8_t byte1, uint8_t byte2) {
|
||||||
while (desc + 2 < end) {
|
while (desc + 2 < end) {
|
||||||
if (desc[1] == byte1 && desc[2] == byte2) return desc;
|
if (desc[1] == byte1 && desc[2] == byte2) {
|
||||||
|
return desc;
|
||||||
|
}
|
||||||
desc += desc[DESC_OFFSET_LEN];
|
desc += desc[DESC_OFFSET_LEN];
|
||||||
}
|
}
|
||||||
return NULL;
|
return NULL;
|
||||||
@@ -158,7 +162,9 @@ uint8_t const* tu_desc_find2(uint8_t const* desc, uint8_t const* end, uint8_t by
|
|||||||
|
|
||||||
uint8_t const* tu_desc_find3(uint8_t const* desc, uint8_t const* end, uint8_t byte1, uint8_t byte2, uint8_t byte3) {
|
uint8_t const* tu_desc_find3(uint8_t const* desc, uint8_t const* end, uint8_t byte1, uint8_t byte2, uint8_t byte3) {
|
||||||
while (desc + 3 < end) {
|
while (desc + 3 < end) {
|
||||||
if (desc[1] == byte1 && desc[2] == byte2 && desc[3] == byte3) return desc;
|
if (desc[1] == byte1 && desc[2] == byte2 && desc[3] == byte3) {
|
||||||
|
return desc;
|
||||||
|
}
|
||||||
desc += desc[DESC_OFFSET_LEN];
|
desc += desc[DESC_OFFSET_LEN];
|
||||||
}
|
}
|
||||||
return NULL;
|
return NULL;
|
||||||
|
Reference in New Issue
Block a user