add actual_len supported

This commit is contained in:
hathach 2022-03-17 20:48:32 +07:00
parent 8aedb2ff37
commit 102b99a0e8
No known key found for this signature in database
GPG Key ID: 2FA891220FBFD581
2 changed files with 30 additions and 24 deletions

View File

@ -250,6 +250,7 @@ struct
tuh_control_xfer_cb_t complete_cb;
uintptr_t user_arg;
volatile uint16_t actual_len;
uint8_t daddr; // device address that is transferring
volatile uint8_t stage;
}_ctrl_xfer;
@ -306,7 +307,7 @@ void osal_task_delay(uint32_t msec)
#endif
//--------------------------------------------------------------------+
// Descriptors
// Descriptors Async
//--------------------------------------------------------------------+
static bool _get_descriptor(uint8_t daddr, uint8_t type, uint8_t index, uint16_t language_id, void* buffer, uint16_t len,
@ -455,7 +456,7 @@ bool tuh_configuration_set(uint8_t daddr, uint8_t config_num,
}
//--------------------------------------------------------------------+
// Asynchronous
// Descriptor Sync
//--------------------------------------------------------------------+
#define _CONTROL_SYNC_API(_async_func, _timeout, ...) \
@ -903,13 +904,13 @@ bool tuh_control_xfer (uint8_t daddr, tuh_control_xfer_t* xfer)
usbh_unlock();
TU_VERIFY(is_idle);
const uint8_t rhport = usbh_get_rhport(daddr);
TU_LOG2("[%u:%u] %s: ", rhport, daddr, xfer->setup->bRequest <= TUSB_REQ_SYNCH_FRAME ? tu_str_std_request[xfer->setup->bRequest] : "Unknown Request");
TU_LOG2_VAR(&xfer->setup);
TU_LOG2("\r\n");
_ctrl_xfer.actual_len = 0;
_ctrl_xfer.daddr = daddr;
_ctrl_xfer.request = (*xfer->setup);
_ctrl_xfer.buffer = xfer->buffer;
@ -941,8 +942,15 @@ bool tuh_control_xfer (uint8_t daddr, tuh_control_xfer_t* xfer)
// TODO probably some timeout to prevent hanged
}
// update result
//xfer->result = result;
// update xfer result
xfer->result = result;
if ( xfer->user_arg )
{
// if user_arg is not NULL, it is also updated
*((xfer_result_t*) xfer->user_arg) = result;
}
xfer->actual_len = _ctrl_xfer.actual_len;
}
return true;
@ -952,19 +960,16 @@ bool tuh_control_xfer_sync(uint8_t daddr, tuh_control_xfer_t* xfer, uint32_t tim
{
(void) timeout_ms;
xfer_result_t result = XFER_RESULT_INVALID;
tuh_control_xfer_t xfer_sync = (*xfer);
xfer_sync.complete_cb = NULL;
xfer_sync.user_arg = (uintptr_t) &result;
// clear callback for sync
xfer->complete_cb = NULL;
// TODO use timeout to wait
TU_VERIFY(tuh_control_xfer(daddr, &xfer_sync), XFER_RESULT_TIMEOUT);
TU_VERIFY(tuh_control_xfer(daddr, xfer));
return result;
return true;
}
TU_ATTR_ALWAYS_INLINE static inline void set_control_xfer_stage(uint8_t stage)
TU_ATTR_ALWAYS_INLINE static inline void _set_control_xfer_stage(uint8_t stage)
{
usbh_lock();
_ctrl_xfer.stage = stage;
@ -982,7 +987,7 @@ static void _xfer_complete(uint8_t dev_addr, xfer_result_t result)
.ep_addr = 0,
.result = result,
.setup = &request,
.actual_len = 0,
.actual_len = (uint32_t) _ctrl_xfer.actual_len,
.buffer = _ctrl_xfer.buffer,
.complete_cb = _ctrl_xfer.complete_cb,
.user_arg = _ctrl_xfer.user_arg
@ -1001,7 +1006,6 @@ static void _xfer_complete(uint8_t dev_addr, xfer_result_t result)
static bool usbh_control_xfer_cb (uint8_t dev_addr, uint8_t ep_addr, xfer_result_t result, uint32_t xferred_bytes)
{
(void) ep_addr;
(void) xferred_bytes;
const uint8_t rhport = usbh_get_rhport(dev_addr);
tusb_control_request_t const * request = &_ctrl_xfer.request;
@ -1020,20 +1024,22 @@ static bool usbh_control_xfer_cb (uint8_t dev_addr, uint8_t ep_addr, xfer_result
if (request->wLength)
{
// DATA stage: initial data toggle is always 1
set_control_xfer_stage(CONTROL_STAGE_DATA);
_set_control_xfer_stage(CONTROL_STAGE_DATA);
return hcd_edpt_xfer(rhport, dev_addr, tu_edpt_addr(0, request->bmRequestType_bit.direction), _ctrl_xfer.buffer, request->wLength);
}
__attribute__((fallthrough));
case CONTROL_STAGE_DATA:
if (request->wLength)
if (xferred_bytes)
{
TU_LOG2("[%u:%u] Control data:\r\n", rhport, dev_addr);
TU_LOG2_MEM(_ctrl_xfer.buffer, request->wLength, 2);
TU_LOG2_MEM(_ctrl_xfer.buffer, xferred_bytes, 2);
}
_ctrl_xfer.actual_len = xferred_bytes;
// ACK stage: toggle is always 1
set_control_xfer_stage(CONTROL_STAGE_ACK);
_set_control_xfer_stage(CONTROL_STAGE_ACK);
hcd_edpt_xfer(rhport, dev_addr, tu_edpt_addr(0, 1-request->bmRequestType_bit.direction), NULL, 0);
break;
@ -1083,7 +1089,7 @@ static void process_device_unplugged(uint8_t rhport, uint8_t hub_addr, uint8_t h
hcd_device_close(rhport, dev_addr);
clear_device(dev);
// abort on-going control xfer if any
if (_ctrl_xfer.daddr == dev_addr) set_control_xfer_stage(CONTROL_STAGE_IDLE);
if (_ctrl_xfer.daddr == dev_addr) _set_control_xfer_stage(CONTROL_STAGE_IDLE);
}
}
}

View File

@ -50,7 +50,7 @@ struct tuh_control_xfer_s
xfer_result_t result;
tusb_control_request_t const* setup;
uint32_t actual_len;
uint32_t actual_len; // excluding setup packet
uint8_t* buffer;
tuh_control_xfer_cb_t complete_cb;
@ -115,7 +115,8 @@ static inline bool tuh_ready(uint8_t daddr)
// Carry out a control transfer
// true on success, false if there is on-going control transfer or incorrect parameters
// Blocking if complete callback is NULL, in this case 'user_arg' must contain xfer_result_t variable
// Note: blocking if complete callback is NULL. In this case 'xfer->result' will be updated
// and if 'user_arg' point to a xfer_result_t variable, it will be updated as well.
bool tuh_control_xfer(uint8_t daddr, tuh_control_xfer_t* xfer);
//bool tuh_edpt_xfer(uint8_t daddr, uint8_t ep_addr, uint8_t * buffer, uint16_t total_bytes);
@ -123,7 +124,6 @@ bool tuh_control_xfer(uint8_t daddr, tuh_control_xfer_t* xfer);
// Set Configuration (control transfer)
// config_num = 0 will un-configure device. Note: config_num = config_descriptor_index + 1
// true on success, false if there is on-going control transfer or incorrect parameters
// Blocking if complete callback is NULL, in this case 'user_arg' must contain xfer_result_t variable
bool tuh_configuration_set(uint8_t daddr, uint8_t config_num,
tuh_control_xfer_cb_t complete_cb, uintptr_t user_arg);
@ -132,7 +132,7 @@ bool tuh_configuration_set(uint8_t daddr, uint8_t config_num,
//--------------------------------------------------------------------+
// Sync (blocking) version of tuh_control_xfer()
// return transfer result
// xfer contents will be updated to reflect the transfer
bool tuh_control_xfer_sync(uint8_t daddr, tuh_control_xfer_t * xfer, uint32_t timeout_ms);
//--------------------------------------------------------------------+