Skip to content

Commit

Permalink
Merge pull request #1397 from hathach/rework-host-control-xfer
Browse files Browse the repository at this point in the history
Rework host control xfer
  • Loading branch information
hathach committed Mar 15, 2022
2 parents 228e185 + 2929afe commit 1915d69
Show file tree
Hide file tree
Showing 12 changed files with 812 additions and 570 deletions.
49 changes: 16 additions & 33 deletions examples/host/bare_api/src/main.c
Expand Up @@ -66,17 +66,9 @@ int main(void)
#define LANGUAGE_ID 0x0409

//uint8_t usb_buf[256] TU_ATTR_ALIGNED(4);
TU_ATTR_ALIGNED(4)
tusb_desc_device_t desc_device;

static volatile xfer_result_t _get_string_result;

static bool _transfer_done_cb(uint8_t daddr, tusb_control_request_t const *request, xfer_result_t result) {
(void)daddr;
(void)request;
_get_string_result = result;
return true;
}

static void _convert_utf16le_to_utf8(const uint16_t *utf16, size_t utf16_len, uint8_t *utf8, size_t utf8_len) {
// TODO: Check for runover.
(void)utf8_len;
Expand Down Expand Up @@ -116,23 +108,16 @@ static int _count_utf8_bytes(const uint16_t *buf, size_t len) {
return total_bytes;
}

static void _wait_and_convert(uint16_t *temp_buf, size_t buf_len) {
while (_get_string_result == 0xff) {
tuh_task();
}
if (_get_string_result != XFER_RESULT_SUCCESS) {
temp_buf[0] = 0;
return;
}
static void utf16_to_utf8(uint16_t *temp_buf, size_t buf_len) {
size_t utf16_len = ((temp_buf[0] & 0xff) - 2) / sizeof(uint16_t);
size_t utf8_len = _count_utf8_bytes(temp_buf + 1, utf16_len);
_convert_utf16le_to_utf8(temp_buf + 1, utf16_len, (uint8_t *) temp_buf, sizeof(uint16_t) * buf_len);
((uint8_t*) temp_buf)[utf8_len] = '\0';
}

bool print_device_descriptor(uint8_t daddr, tusb_control_request_t const * request, xfer_result_t result)
bool print_device_descriptor(uint8_t daddr, tuh_control_xfer_t const * xfer, xfer_result_t result)
{
(void) request;
(void) xfer;

if ( XFER_RESULT_SUCCESS != result )
{
Expand All @@ -153,31 +138,29 @@ bool print_device_descriptor(uint8_t daddr, tusb_control_request_t const * reque
printf(" idProduct 0x%04x\r\n" , desc_device.idProduct);
printf(" bcdDevice %04x\r\n" , desc_device.bcdDevice);

_get_string_result = 0xff;
uint32_t timeout_ms = 10;
uint16_t temp_buf[128];

printf(" iManufacturer %u " , desc_device.iManufacturer);
temp_buf[0] = 0;
if (tuh_descriptor_get_manufacturer_string(daddr, LANGUAGE_ID, temp_buf, TU_ARRAY_SIZE(temp_buf), _transfer_done_cb)) {
_wait_and_convert(temp_buf, TU_ARRAY_SIZE(temp_buf));
if (XFER_RESULT_SUCCESS == tuh_descriptor_get_manufacturer_string_sync(daddr, LANGUAGE_ID, temp_buf, TU_ARRAY_SIZE(temp_buf), timeout_ms) )
{
utf16_to_utf8(temp_buf, TU_ARRAY_SIZE(temp_buf));
printf((const char*) temp_buf);
}
printf("\r\n");

printf(" iProduct %u " , desc_device.iProduct);
_get_string_result = 0xff;
temp_buf[0] = 0;
if (tuh_descriptor_get_product_string(daddr, LANGUAGE_ID, temp_buf, TU_ARRAY_SIZE(temp_buf), _transfer_done_cb)) {
_wait_and_convert(temp_buf, TU_ARRAY_SIZE(temp_buf));
if (XFER_RESULT_SUCCESS == tuh_descriptor_get_product_string_sync(daddr, LANGUAGE_ID, temp_buf, TU_ARRAY_SIZE(temp_buf), timeout_ms))
{
utf16_to_utf8(temp_buf, TU_ARRAY_SIZE(temp_buf));
printf((const char*) temp_buf);
}
printf("\r\n");

printf(" iSerialNumber %u " , desc_device.iSerialNumber);
_get_string_result = 0xff;
temp_buf[0] = 0;
if (tuh_descriptor_get_serial_string(daddr, LANGUAGE_ID, temp_buf, TU_ARRAY_SIZE(temp_buf), _transfer_done_cb)) {
_wait_and_convert(temp_buf, TU_ARRAY_SIZE(temp_buf));
if (XFER_RESULT_SUCCESS == tuh_descriptor_get_serial_string_sync(daddr, LANGUAGE_ID, temp_buf, TU_ARRAY_SIZE(temp_buf), timeout_ms))
{
utf16_to_utf8(temp_buf, TU_ARRAY_SIZE(temp_buf));
printf((const char*) temp_buf);
}
printf("\r\n");
Expand All @@ -192,8 +175,8 @@ void tuh_mount_cb (uint8_t daddr)
{
printf("Device attached, address = %d\r\n", daddr);

// Get Device Descriptor
tuh_descriptor_get_device(daddr, &desc_device, 18, print_device_descriptor);
// Get Device Descriptor using asynchronous API
tuh_descriptor_get_device(daddr, &desc_device, 18, print_device_descriptor, 0);
}

/// Invoked when device is unmounted (bus reset/unplugged)
Expand Down
27 changes: 13 additions & 14 deletions examples/host/cdc_msc_hid/src/main.c
Expand Up @@ -71,20 +71,6 @@ int main(void)
#if CFG_TUH_CDC
CFG_TUSB_MEM_SECTION static char serial_in_buffer[64] = { 0 };

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

tuh_cdc_receive(dev_addr, serial_in_buffer, sizeof(serial_in_buffer), true); // schedule first transfer
}

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

// invoked ISR context
void tuh_cdc_xfer_isr(uint8_t dev_addr, xfer_result_t event, cdc_pipeid_t pipe_id, uint32_t xferred_bytes)
{
Expand All @@ -109,6 +95,19 @@ void cdc_task(void)
// TinyUSB Callbacks
//--------------------------------------------------------------------+

void tuh_mount_cb(uint8_t dev_addr)
{
// application set-up
printf("A device with address %d 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);
}


//--------------------------------------------------------------------+
// Blinking Task
//--------------------------------------------------------------------+
Expand Down
31 changes: 19 additions & 12 deletions src/class/cdc/cdc_host.c
Expand Up @@ -120,25 +120,32 @@ bool tuh_cdc_receive(uint8_t dev_addr, void * p_buffer, uint32_t length, bool is
return usbh_edpt_xfer(dev_addr, ep_in, p_buffer, length);
}

bool tuh_cdc_set_control_line_state(uint8_t dev_addr, bool dtr, bool rts, tuh_control_complete_cb_t complete_cb)
bool tuh_cdc_set_control_line_state(uint8_t dev_addr, bool dtr, bool rts, tuh_control_xfer_cb_t complete_cb)
{
cdch_data_t const * p_cdc = get_itf(dev_addr);
tusb_control_request_t const request =

tuh_control_xfer_t const xfer =
{
.bmRequestType_bit =
.request =
{
.recipient = TUSB_REQ_RCPT_INTERFACE,
.type = TUSB_REQ_TYPE_CLASS,
.direction = TUSB_DIR_OUT
.bmRequestType_bit =
{
.recipient = TUSB_REQ_RCPT_INTERFACE,
.type = TUSB_REQ_TYPE_CLASS,
.direction = TUSB_DIR_OUT
},
.bRequest = CDC_REQUEST_SET_CONTROL_LINE_STATE,
.wValue = (rts ? 2 : 0) | (dtr ? 1 : 0),
.wIndex = p_cdc->itf_num,
.wLength = 0
},
.bRequest = CDC_REQUEST_SET_CONTROL_LINE_STATE,
.wValue = (rts ? 2 : 0) | (dtr ? 1 : 0),
.wIndex = p_cdc->itf_num,
.wLength = 0

.buffer = NULL,
.complete_cb = complete_cb,
.user_arg = 0
};

TU_ASSERT( tuh_control_xfer(dev_addr, &request, NULL, complete_cb) );
return true;
return tuh_control_xfer(dev_addr, &xfer);
}

//--------------------------------------------------------------------+
Expand Down
6 changes: 3 additions & 3 deletions src/class/cdc/cdc_host.h
Expand Up @@ -42,14 +42,14 @@
* \defgroup CDC_Serial_Host Host
* @{ */

bool tuh_cdc_set_control_line_state(uint8_t dev_addr, bool dtr, bool rts, tuh_control_complete_cb_t complete_cb);
bool tuh_cdc_set_control_line_state(uint8_t dev_addr, bool dtr, bool rts, tuh_control_xfer_cb_t complete_cb);

static inline bool tuh_cdc_connect(uint8_t dev_addr, tuh_control_complete_cb_t complete_cb)
static inline bool tuh_cdc_connect(uint8_t dev_addr, tuh_control_xfer_cb_t complete_cb)
{
return tuh_cdc_set_control_line_state(dev_addr, true, true, complete_cb);
}

static inline bool tuh_cdc_disconnect(uint8_t dev_addr, tuh_control_complete_cb_t complete_cb)
static inline bool tuh_cdc_disconnect(uint8_t dev_addr, tuh_control_xfer_cb_t complete_cb)
{
return tuh_cdc_set_control_line_state(dev_addr, false, false, complete_cb);
}
Expand Down

0 comments on commit 1915d69

Please sign in to comment.