diff --git a/examples/host/bare_api/src/main.c b/examples/host/bare_api/src/main.c index fa50c7af3..eb3f7d8d7 100644 --- a/examples/host/bare_api/src/main.c +++ b/examples/host/bare_api/src/main.c @@ -37,6 +37,13 @@ // English #define LANGUAGE_ID 0x0409 +#define BUF_COUNT 4 + + +tusb_desc_device_t desc_device; + +uint8_t buf_pool[BUF_COUNT][64]; +uint8_t buf_owner[BUF_COUNT] = { 0 }; // device address that owns buffer //--------------------------------------------------------------------+ // MACRO CONSTANT TYPEDEF PROTYPES @@ -47,12 +54,8 @@ static void print_utf16(uint16_t *temp_buf, size_t buf_len); void print_device_descriptor(tuh_xfer_t* xfer); void parse_config_descriptor(uint8_t dev_addr, tusb_desc_configuration_t const* desc_cfg); -tusb_desc_device_t desc_device; - -#define BUF_COUNT 4 - -uint8_t buf_pool[BUF_COUNT][64]; -uint8_t buf_owner[BUF_COUNT] = { 0 }; // device address that owns buffer +uint8_t* get_hid_buf(uint8_t daddr); +void free_hid_buf(uint8_t daddr); /*------------- MAIN -------------*/ int main(void) @@ -88,6 +91,7 @@ void tuh_mount_cb (uint8_t daddr) void tuh_umount_cb(uint8_t daddr) { printf("Device removed, address = %d\r\n", daddr); + free_hid_buf(daddr); } //--------------------------------------------------------------------+ @@ -150,115 +154,14 @@ void print_device_descriptor(tuh_xfer_t* xfer) } } - //--------------------------------------------------------------------+ // Configuration Descriptor //--------------------------------------------------------------------+ -// get an buffer from pool -uint8_t* get_hid_buf(uint8_t daddr) -{ - for(size_t i=0; ibuffer is NULL. We have used user_data to store buffer when submitted callback - uint8_t* buf = (uint8_t*) xfer->user_data; - - if (xfer->result == XFER_RESULT_SUCCESS) - { - printf("[dev %u: ep %02x] HID Report:", xfer->daddr, xfer->ep_addr); - for(uint32_t i=0; iactual_len; i++) - { - if (i%16 == 0) printf("\r\n "); - printf("%02X ", buf[i]); - } - printf("\r\n"); - } - - // continue to submit transfer, with updated buffer - // other field remain the same - xfer->buflen = 64; - xfer->buffer = buf; - - tuh_edpt_xfer(xfer); -} - // count total length of an interface uint16_t count_interface_total_len(tusb_desc_interface_t const* desc_itf, uint8_t itf_count, uint16_t max_len); -void open_hid_interface(uint8_t daddr, tusb_desc_interface_t const *desc_itf, uint16_t max_len) -{ - // len = interface + hid + n*endpoints - uint16_t const drv_len = sizeof(tusb_desc_interface_t) + sizeof(tusb_hid_descriptor_hid_t) + desc_itf->bNumEndpoints*sizeof(tusb_desc_endpoint_t); - - // corrupted descriptor - if (max_len < drv_len) return; - - uint8_t const *p_desc = (uint8_t const *) desc_itf; - - // HID descriptor - p_desc = tu_desc_next(p_desc); - tusb_hid_descriptor_hid_t const *desc_hid = (tusb_hid_descriptor_hid_t const *) p_desc; - if(HID_DESC_TYPE_HID != desc_hid->bDescriptorType) return; - - // Endpoint descriptor - p_desc = tu_desc_next(p_desc); - tusb_desc_endpoint_t const * desc_ep = (tusb_desc_endpoint_t const *) p_desc; - - for(int i = 0; i < desc_itf->bNumEndpoints; i++) - { - if (TUSB_DESC_ENDPOINT != desc_ep->bDescriptorType) return; - - if(tu_edpt_dir(desc_ep->bEndpointAddress) == TUSB_DIR_IN) - { - // skip if failed to open endpoint - if ( ! tuh_edpt_open(daddr, desc_ep) ) return; - - uint8_t* buf = get_hid_buf(daddr); - if (!buf) return; // out of memory - - tuh_xfer_t xfer = - { - .daddr = daddr, - .ep_addr = desc_ep->bEndpointAddress, - .buflen = 64, - .buffer = buf, - .complete_cb = hid_report_received, - .user_data = (uintptr_t) buf, // since buffer is not available in callback, use user data to store the buffer - }; - - // submit transfer for this EP - tuh_edpt_xfer(&xfer); - - printf("Listen to [dev %u: ep %02x]\r\n", daddr, desc_ep->bEndpointAddress); - } - - p_desc = tu_desc_next(p_desc); - desc_ep = (tusb_desc_endpoint_t const *) p_desc; - } -} +void open_hid_interface(uint8_t daddr, tusb_desc_interface_t const *desc_itf, uint16_t max_len); // simple configuration parser to open and listen to HID Endpoint IN void parse_config_descriptor(uint8_t dev_addr, tusb_desc_configuration_t const* desc_cfg) @@ -330,6 +233,117 @@ uint16_t count_interface_total_len(tusb_desc_interface_t const* desc_itf, uint8_ return len; } +//--------------------------------------------------------------------+ +// HID Interface +//--------------------------------------------------------------------+ + +void hid_report_received(tuh_xfer_t* xfer); + +void open_hid_interface(uint8_t daddr, tusb_desc_interface_t const *desc_itf, uint16_t max_len) +{ + // len = interface + hid + n*endpoints + uint16_t const drv_len = sizeof(tusb_desc_interface_t) + sizeof(tusb_hid_descriptor_hid_t) + desc_itf->bNumEndpoints*sizeof(tusb_desc_endpoint_t); + + // corrupted descriptor + if (max_len < drv_len) return; + + uint8_t const *p_desc = (uint8_t const *) desc_itf; + + // HID descriptor + p_desc = tu_desc_next(p_desc); + tusb_hid_descriptor_hid_t const *desc_hid = (tusb_hid_descriptor_hid_t const *) p_desc; + if(HID_DESC_TYPE_HID != desc_hid->bDescriptorType) return; + + // Endpoint descriptor + p_desc = tu_desc_next(p_desc); + tusb_desc_endpoint_t const * desc_ep = (tusb_desc_endpoint_t const *) p_desc; + + for(int i = 0; i < desc_itf->bNumEndpoints; i++) + { + if (TUSB_DESC_ENDPOINT != desc_ep->bDescriptorType) return; + + if(tu_edpt_dir(desc_ep->bEndpointAddress) == TUSB_DIR_IN) + { + // skip if failed to open endpoint + if ( ! tuh_edpt_open(daddr, desc_ep) ) return; + + uint8_t* buf = get_hid_buf(daddr); + if (!buf) return; // out of memory + + tuh_xfer_t xfer = + { + .daddr = daddr, + .ep_addr = desc_ep->bEndpointAddress, + .buflen = 64, + .buffer = buf, + .complete_cb = hid_report_received, + .user_data = (uintptr_t) buf, // since buffer is not available in callback, use user data to store the buffer + }; + + // submit transfer for this EP + tuh_edpt_xfer(&xfer); + + printf("Listen to [dev %u: ep %02x]\r\n", daddr, desc_ep->bEndpointAddress); + } + + p_desc = tu_desc_next(p_desc); + desc_ep = (tusb_desc_endpoint_t const *) p_desc; + } +} + +void hid_report_received(tuh_xfer_t* xfer) +{ + // Note: not all field in xfer is available for use (i.e filled by tinyusb stack) in callback to save sram + // For instance, xfer->buffer is NULL. We have used user_data to store buffer when submitted callback + uint8_t* buf = (uint8_t*) xfer->user_data; + + if (xfer->result == XFER_RESULT_SUCCESS) + { + printf("[dev %u: ep %02x] HID Report:", xfer->daddr, xfer->ep_addr); + for(uint32_t i=0; iactual_len; i++) + { + if (i%16 == 0) printf("\r\n "); + printf("%02X ", buf[i]); + } + printf("\r\n"); + } + + // continue to submit transfer, with updated buffer + // other field remain the same + xfer->buflen = 64; + xfer->buffer = buf; + + tuh_edpt_xfer(xfer); +} + +//--------------------------------------------------------------------+ +// Buffer helper +//--------------------------------------------------------------------+ + +// get an buffer from pool +uint8_t* get_hid_buf(uint8_t daddr) +{ + for(size_t i=0; i