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; | ||||||
|   if (AUDIO_SUBCLASS_CONTROL == desc_itf->bInterfaceSubClass) { |  | ||||||
|     // This driver does not support audio streaming. However, if this is the audio control interface |  | ||||||
|     // 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 |  | ||||||
|     while (len_parsed < max_len && |  | ||||||
|           (desc_itf->bInterfaceClass != TUSB_CLASS_AUDIO || desc_itf->bInterfaceSubClass != AUDIO_SUBCLASS_MIDI_STREAMING)) { |  | ||||||
|       len_parsed += desc_itf->bLength; |  | ||||||
|       p_desc = tu_desc_next(p_desc); |  | ||||||
|       desc_itf = (tusb_desc_interface_t const *)p_desc; |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|  |   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) { | ||||||
|  |     TU_VERIFY(max_len > 2*sizeof(tusb_desc_interface_t) + sizeof(audio_desc_cs_ac_interface_t)); | ||||||
|  |  | ||||||
|  |     p_desc = tu_desc_next(p_desc); | ||||||
|  |     TU_VERIFY(tu_desc_type(p_desc) == TUSB_DESC_CS_INTERFACE && | ||||||
|  |               tu_desc_subtype(p_desc) == AUDIO_CS_AC_INTERFACE_HEADER); | ||||||
|  |  | ||||||
|  |     p_desc = tu_desc_next(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 && |  | ||||||
|             p_mdh->bDescriptorSubType == MIDI_CS_INTERFACE_HEADER); |  | ||||||
|   TU_LOG_DRV("  Interface Header descriptor\r\n"); |  | ||||||
|  |  | ||||||
|   // p_desc = tu_desc_next(p_desc); |   bool found_new_interface = false; | ||||||
|   uint8_t prev_ep_addr = 0; // the CS endpoint descriptor is associated with the previous endpoint descriptor |   while ((p_desc < p_end) && (tu_desc_next(p_desc) <= p_end) && !found_new_interface) { | ||||||
|   tusb_desc_endpoint_t const* in_desc = NULL; |     switch (tu_desc_type(p_desc)) { | ||||||
|   tusb_desc_endpoint_t const* out_desc = NULL; |       case TUSB_DESC_INTERFACE: | ||||||
|   while (len_parsed < max_len) { |         found_new_interface = true; | ||||||
|     TU_VERIFY((p_mdh->bDescriptorType == TUSB_DESC_CS_INTERFACE) || |         break; | ||||||
|               (p_mdh->bDescriptorType == TUSB_DESC_CS_ENDPOINT && p_mdh->bDescriptorSubType == MIDI_CS_ENDPOINT_GENERAL) || |  | ||||||
|               p_mdh->bDescriptorType == TUSB_DESC_ENDPOINT); |  | ||||||
|  |  | ||||||
|     if (p_mdh->bDescriptorType == TUSB_DESC_CS_INTERFACE) { |       case TUSB_DESC_CS_INTERFACE: | ||||||
|       // The USB host doesn't really need this information unless it uses |         switch (tu_desc_subtype(p_desc)) { | ||||||
|       // the string descriptor for a jack or Element |           case MIDI_CS_INTERFACE_HEADER: | ||||||
|  |             TU_LOG_DRV("  Interface Header descriptor\r\n"); | ||||||
|  |             desc_cb.desc_header = p_desc; | ||||||
|  |             break; | ||||||
|  |  | ||||||
|       // assume it is an input jack |           case MIDI_CS_INTERFACE_IN_JACK: | ||||||
|       midi_desc_in_jack_t const *p_mdij = (midi_desc_in_jack_t const *) p_desc; |           case MIDI_CS_INTERFACE_OUT_JACK: { | ||||||
|       if (p_mdij->bDescriptorSubType == MIDI_CS_INTERFACE_HEADER) { |             TU_LOG_DRV("  Jack %s %s descriptor \r\n", | ||||||
|         TU_LOG_DRV("  Interface Header descriptor\r\n"); |                        tu_desc_subtype(p_desc) == MIDI_CS_INTERFACE_IN_JACK ? "IN" : "OUT", | ||||||
|       } else if (p_mdij->bDescriptorSubType == MIDI_CS_INTERFACE_IN_JACK) { |                        p_desc[3] == MIDI_JACK_EXTERNAL ? "External" : "Embedded"); | ||||||
|         // Then it is an in jack. |             desc_cb.desc_jack[desc_cb.jack_num++] = p_desc; | ||||||
|         TU_LOG_DRV("  IN Jack %s descriptor \r\n", p_mdij->bJackType == MIDI_JACK_EXTERNAL ? "External" : "Embedded"); |             break; | ||||||
|       } 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"); |           case MIDI_CS_INTERFACE_ELEMENT: | ||||||
|       } else if (p_mdij->bDescriptorSubType == MIDI_CS_INTERFACE_ELEMENT) { |             TU_LOG_DRV("  Element descriptor\r\n"); | ||||||
|         // the it is an element; |             desc_cb.desc_element = p_desc; | ||||||
|         TU_LOG_DRV("Found element\r\n"); |             break; | ||||||
|       } else { |  | ||||||
|         TU_LOG_DRV("  Unknown CS Interface sub-type %u\r\n", p_mdij->bDescriptorSubType); |           default: | ||||||
|         TU_VERIFY(false);// unknown CS Interface sub-type |             TU_LOG_DRV("  Unknown CS Interface sub-type %u\r\n", tu_desc_subtype(p_desc)); | ||||||
|  |             break; | ||||||
|  |         } | ||||||
|  |         break; | ||||||
|  |  | ||||||
|  |       case TUSB_DESC_ENDPOINT: { | ||||||
|  |         tusb_desc_endpoint_t const *p_ep = (tusb_desc_endpoint_t const *) p_desc; | ||||||
|  |         p_desc = tu_desc_next(p_desc); // next to CS endpoint | ||||||
|  |         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) { | ||||||
|  |           p_midi->ep_out = p_ep->bEndpointAddress; | ||||||
|  |           p_midi->num_cables_tx = 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; | ||||||
|  |           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); | ||||||
|  |         } | ||||||
|  |         break; | ||||||
|       } |       } | ||||||
|       len_parsed += p_mdij->bLength; |  | ||||||
|     } else if (p_mdh->bDescriptorType == TUSB_DESC_CS_ENDPOINT) { |       default: break; // skip unknown descriptor | ||||||
|       TU_LOG_DRV("  CS_ENDPOINT descriptor\r\n"); |  | ||||||
|       TU_VERIFY(prev_ep_addr != 0); |  | ||||||
|       // parse out the mapping between the device's embedded jacks and the endpoints |  | ||||||
|       // 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; |  | ||||||
|       if (tu_edpt_dir(prev_ep_addr) == TUSB_DIR_OUT) { |  | ||||||
|         TU_VERIFY(p_midi->ep_out == prev_ep_addr); |  | ||||||
|         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; |  | ||||||
|       prev_ep_addr = 0; |  | ||||||
|     } else if (p_mdh->bDescriptorType == TUSB_DESC_ENDPOINT) { |  | ||||||
|       // parse out the bulk endpoint info |  | ||||||
|       tusb_desc_endpoint_t const *p_ep = (tusb_desc_endpoint_t const *) p_mdh; |  | ||||||
|       TU_LOG_DRV("  Endpoint descriptor %02x\r\n", p_ep->bEndpointAddress); |  | ||||||
|       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; |  | ||||||
|         prev_ep_addr = p_midi->ep_out; |  | ||||||
|         out_desc = p_ep; |  | ||||||
|       } else { |  | ||||||
|         TU_VERIFY(p_midi->ep_in == 0); |  | ||||||
|         TU_VERIFY(p_midi->num_cables_rx == 0); |  | ||||||
|         p_midi->ep_in = p_ep->bEndpointAddress; |  | ||||||
|         prev_ep_addr = p_midi->ep_in; |  | ||||||
|         in_desc = p_ep; |  | ||||||
|       } |  | ||||||
|       len_parsed += p_mdh->bLength; |  | ||||||
|     } |     } | ||||||
|     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
	 hathach
					hathach