mirror of
https://github.com/hathach/tinyusb.git
synced 2025-03-29 01:20:19 +00:00
added tud_set_self_powered(), fix #50 reponse to GET_STATUS request
This commit is contained in:
parent
d9682f8240
commit
cabf6abb4f
@ -181,6 +181,11 @@ bool tud_mounted(void)
|
|||||||
return _usbd_dev.configured;
|
return _usbd_dev.configured;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void tud_set_self_powered(bool self_powered)
|
||||||
|
{
|
||||||
|
_usbd_dev.self_powered = self_powered;
|
||||||
|
}
|
||||||
|
|
||||||
bool tud_remote_wakeup(void)
|
bool tud_remote_wakeup(void)
|
||||||
{
|
{
|
||||||
// only wake up host if this feature is enabled
|
// only wake up host if this feature is enabled
|
||||||
@ -194,6 +199,8 @@ bool tud_remote_wakeup(void)
|
|||||||
//--------------------------------------------------------------------+
|
//--------------------------------------------------------------------+
|
||||||
bool usbd_init (void)
|
bool usbd_init (void)
|
||||||
{
|
{
|
||||||
|
tu_varclr(&_usbd_dev);
|
||||||
|
|
||||||
// Init device queue & task
|
// Init device queue & task
|
||||||
_usbd_q = osal_queue_create(&_usbd_qdef);
|
_usbd_q = osal_queue_create(&_usbd_qdef);
|
||||||
TU_ASSERT(_usbd_q != NULL);
|
TU_ASSERT(_usbd_q != NULL);
|
||||||
@ -210,7 +217,13 @@ bool usbd_init (void)
|
|||||||
|
|
||||||
static void usbd_reset(uint8_t rhport)
|
static void usbd_reset(uint8_t rhport)
|
||||||
{
|
{
|
||||||
|
// self_powered bit is set by application and unchanged
|
||||||
|
bool self_powered = _usbd_dev.self_powered;
|
||||||
|
|
||||||
tu_varclr(&_usbd_dev);
|
tu_varclr(&_usbd_dev);
|
||||||
|
|
||||||
|
_usbd_dev.self_powered = self_powered;
|
||||||
|
|
||||||
memset(_usbd_dev.itf2drv, 0xff, sizeof(_usbd_dev.itf2drv)); // invalid mapping
|
memset(_usbd_dev.itf2drv, 0xff, sizeof(_usbd_dev.itf2drv)); // invalid mapping
|
||||||
memset(_usbd_dev.ep2drv , 0xff, sizeof(_usbd_dev.ep2drv )); // invalid mapping
|
memset(_usbd_dev.ep2drv , 0xff, sizeof(_usbd_dev.ep2drv )); // invalid mapping
|
||||||
|
|
||||||
@ -304,9 +317,6 @@ void tud_task (void)
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
// NOTE: When unplugging device, the D+/D- state are unstable and can accidentally meet the
|
|
||||||
// SUSPEND condition ( Idle for 3ms ). Most likely when this happen both suspend and resume
|
|
||||||
// are submitted by DCD before the actual UNPLUGGED
|
|
||||||
case DCD_EVENT_SUSPEND:
|
case DCD_EVENT_SUSPEND:
|
||||||
if (tud_suspend_cb) tud_suspend_cb( _usbd_dev.remote_wakeup_en );
|
if (tud_suspend_cb) tud_suspend_cb( _usbd_dev.remote_wakeup_en );
|
||||||
break;
|
break;
|
||||||
@ -357,26 +367,20 @@ static bool process_control_request(uint8_t rhport, tusb_control_request_t const
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void* data_buf = NULL;
|
|
||||||
uint16_t data_len = 0;
|
|
||||||
|
|
||||||
uint8_t cfgnum_tmp;
|
|
||||||
(void) cfgnum_tmp; // only used for GET_CONFIGURATION
|
|
||||||
|
|
||||||
switch ( p_request->bRequest )
|
switch ( p_request->bRequest )
|
||||||
{
|
{
|
||||||
case TUSB_REQ_SET_ADDRESS:
|
case TUSB_REQ_SET_ADDRESS:
|
||||||
// DCD must include zero-length status response since depending on mcu,
|
// Depending on mcu, status phase could be sent either before or after changing device address
|
||||||
// status could be sent either before or after changing device address
|
// Therefore DCD must include zero-length status response
|
||||||
dcd_set_address(rhport, (uint8_t) p_request->wValue);
|
dcd_set_address(rhport, (uint8_t) p_request->wValue);
|
||||||
return true; // skip the rest
|
return true; // skip status
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case TUSB_REQ_GET_CONFIGURATION:
|
case TUSB_REQ_GET_CONFIGURATION:
|
||||||
cfgnum_tmp = _usbd_dev.configured ? 1 : 0;
|
{
|
||||||
|
uint8_t cfgnum = _usbd_dev.configured ? 1 : 0;
|
||||||
data_buf = &cfgnum_tmp;
|
usbd_control_xfer(rhport, p_request, &cfgnum, 1);
|
||||||
data_len = 1;
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case TUSB_REQ_SET_CONFIGURATION:
|
case TUSB_REQ_SET_CONFIGURATION:
|
||||||
@ -387,39 +391,51 @@ static bool process_control_request(uint8_t rhport, tusb_control_request_t const
|
|||||||
_usbd_dev.configured = cfg_num ? 1 : 0;
|
_usbd_dev.configured = cfg_num ? 1 : 0;
|
||||||
|
|
||||||
TU_ASSERT( process_set_config(rhport) );
|
TU_ASSERT( process_set_config(rhport) );
|
||||||
|
usbd_control_status(rhport, p_request);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case TUSB_REQ_GET_DESCRIPTOR:
|
case TUSB_REQ_GET_DESCRIPTOR:
|
||||||
data_buf = (void*) get_descriptor(p_request, &data_len);
|
{
|
||||||
if ( data_buf == NULL || data_len == 0 ) return false;
|
uint16_t len = 0;
|
||||||
|
void* buf = (void*) get_descriptor(p_request, &len);
|
||||||
|
if ( buf == NULL || len == 0 ) return false;
|
||||||
|
|
||||||
|
usbd_control_xfer(rhport, p_request, buf, len);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case TUSB_REQ_SET_FEATURE:
|
case TUSB_REQ_SET_FEATURE:
|
||||||
if ( TUSB_REQ_FEATURE_REMOTE_WAKEUP == p_request->wValue )
|
// Only support remote wakeup for device feature
|
||||||
{
|
TU_VERIFY(TUSB_REQ_FEATURE_REMOTE_WAKEUP == p_request->wValue);
|
||||||
// Host enable remote wake up before suspending especially HID device
|
|
||||||
_usbd_dev.remote_wakeup_en = true;
|
// Host may enable remote wake up before suspending especially HID device
|
||||||
}
|
_usbd_dev.remote_wakeup_en = true;
|
||||||
|
usbd_control_status(rhport, p_request);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case TUSB_REQ_CLEAR_FEATURE:
|
case TUSB_REQ_CLEAR_FEATURE:
|
||||||
if ( TUSB_REQ_FEATURE_REMOTE_WAKEUP == p_request->wValue )
|
// Only support remote wakeup for device feature
|
||||||
{
|
TU_VERIFY(TUSB_REQ_FEATURE_REMOTE_WAKEUP == p_request->wValue);
|
||||||
// Host disable remote wake up after resuming
|
|
||||||
_usbd_dev.remote_wakeup_en = false;
|
// Host may disable remote wake up after resuming
|
||||||
}
|
_usbd_dev.remote_wakeup_en = false;
|
||||||
|
usbd_control_status(rhport, p_request);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case TUSB_REQ_GET_STATUS:
|
case TUSB_REQ_GET_STATUS:
|
||||||
|
{
|
||||||
|
// Device status bit mask
|
||||||
|
// - Bit 0: Self Powered
|
||||||
|
// - Bit 1: Remote Wakeup enabled
|
||||||
|
uint16_t status = (_usbd_dev.self_powered ? 1 : 0) | (_usbd_dev.remote_wakeup_en ? 2 : 0);
|
||||||
|
usbd_control_xfer(rhport, p_request, &status, 2);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
// Unknown/Unsupported request
|
// Unknown/Unsupported request
|
||||||
default: TU_BREAKPOINT(); return false;
|
default: TU_BREAKPOINT(); return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
usbd_control_xfer(rhport, p_request, data_buf, data_len);
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
//------------- Class/Interface Specific Request -------------//
|
//------------- Class/Interface Specific Request -------------//
|
||||||
@ -439,12 +455,8 @@ static bool process_control_request(uint8_t rhport, tusb_control_request_t const
|
|||||||
|
|
||||||
//------------- Endpoint Request -------------//
|
//------------- Endpoint Request -------------//
|
||||||
case TUSB_REQ_RCPT_ENDPOINT:
|
case TUSB_REQ_RCPT_ENDPOINT:
|
||||||
if ( TUSB_REQ_TYPE_STANDARD != p_request->bmRequestType_bit.type )
|
// Non standard request is not supported
|
||||||
{
|
TU_VERIFY( TUSB_REQ_TYPE_STANDARD == p_request->bmRequestType_bit.type );
|
||||||
// Non standard request is not supported
|
|
||||||
TU_BREAKPOINT();
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
switch ( p_request->bRequest )
|
switch ( p_request->bRequest )
|
||||||
{
|
{
|
||||||
@ -459,16 +471,16 @@ static bool process_control_request(uint8_t rhport, tusb_control_request_t const
|
|||||||
if ( TUSB_REQ_FEATURE_EDPT_HALT == p_request->wValue )
|
if ( TUSB_REQ_FEATURE_EDPT_HALT == p_request->wValue )
|
||||||
{
|
{
|
||||||
dcd_edpt_clear_stall(rhport, tu_u16_low(p_request->wIndex));
|
dcd_edpt_clear_stall(rhport, tu_u16_low(p_request->wIndex));
|
||||||
usbd_control_status(rhport, p_request);
|
|
||||||
}
|
}
|
||||||
|
usbd_control_status(rhport, p_request);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case TUSB_REQ_SET_FEATURE:
|
case TUSB_REQ_SET_FEATURE:
|
||||||
if ( TUSB_REQ_FEATURE_EDPT_HALT == p_request->wValue )
|
if ( TUSB_REQ_FEATURE_EDPT_HALT == p_request->wValue )
|
||||||
{
|
{
|
||||||
usbd_edpt_stall(rhport, tu_u16_low(p_request->wIndex));
|
usbd_edpt_stall(rhport, tu_u16_low(p_request->wIndex));
|
||||||
usbd_control_status(rhport, p_request);
|
|
||||||
}
|
}
|
||||||
|
usbd_control_status(rhport, p_request);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
// Unknown/Unsupported request
|
// Unknown/Unsupported request
|
||||||
@ -626,23 +638,17 @@ void dcd_event_handler(dcd_event_t const * event, bool in_isr)
|
|||||||
// nothing to do now
|
// nothing to do now
|
||||||
break;
|
break;
|
||||||
|
|
||||||
// NOTE: When unplugging device, the D+/D- state are unstable and can accidentally meet the
|
|
||||||
// SUSPEND condition ( Idle for 3ms ). Most likely when this happen both suspend and resume
|
|
||||||
// are submitted by DCD before the actual UNPLUGGED
|
|
||||||
case DCD_EVENT_SUSPEND:
|
case DCD_EVENT_SUSPEND:
|
||||||
if (_usbd_dev.connected ) // skip event if disconnected
|
// NOTE: When unplugging device, the D+/D- state are unstable and can accidentally meet the
|
||||||
{
|
// SUSPEND condition ( Idle for 3ms ). Most likely when this happen both suspend and resume
|
||||||
_usbd_dev.suspended = 1;
|
// are submitted by DCD before the actual UNPLUGGED
|
||||||
osal_queue_send(_usbd_q, event, in_isr);
|
_usbd_dev.suspended = 1;
|
||||||
}
|
osal_queue_send(_usbd_q, event, in_isr);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case DCD_EVENT_RESUME:
|
case DCD_EVENT_RESUME:
|
||||||
if (_usbd_dev.connected ) // skip event if disconnected
|
_usbd_dev.suspended = 0;
|
||||||
{
|
osal_queue_send(_usbd_q, event, in_isr);
|
||||||
_usbd_dev.suspended = 0;
|
|
||||||
osal_queue_send(_usbd_q, event, in_isr);
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case DCD_EVENT_SETUP_RECEIVED:
|
case DCD_EVENT_SETUP_RECEIVED:
|
||||||
|
@ -63,6 +63,7 @@ bool tud_mounted(void);
|
|||||||
void tud_task (void);
|
void tud_task (void);
|
||||||
|
|
||||||
bool tud_remote_wakeup(void);
|
bool tud_remote_wakeup(void);
|
||||||
|
void tud_set_self_powered(bool self_powered);
|
||||||
|
|
||||||
//--------------------------------------------------------------------+
|
//--------------------------------------------------------------------+
|
||||||
// Application Callbacks (WEAK is optional)
|
// Application Callbacks (WEAK is optional)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user