usb: Add remote wakeup support
This commit adds support for remote wakeup and extends USB api with a wakeup request call. Remote wakeup can be dsabled in kconfig when a specific driver does not support this feature. Signed-off-by: Paweł Zadrożniak <pawel.zadrozniak@nordicsemi.no>
This commit is contained in:
parent
f940cec0d0
commit
3ecbff501a
6 changed files with 68 additions and 5 deletions
|
@ -392,6 +392,15 @@ int usb_dc_ep_read_continue(u8_t ep);
|
|||
*/
|
||||
int usb_dc_ep_mps(u8_t ep);
|
||||
|
||||
/**
|
||||
* @brief Start the host wake up procedure.
|
||||
*
|
||||
* Function to wake up the host if it's currently in sleep mode.
|
||||
*
|
||||
* @return 0 on success, negative errno code on fail.
|
||||
*/
|
||||
int usb_dc_wakeup_request(void);
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
|
|
@ -96,7 +96,10 @@
|
|||
* D5:Remote Wakeup -> 0,
|
||||
* D4...0:Reserved -> 0
|
||||
*/
|
||||
#define USB_CONFIGURATION_ATTRIBUTES 0xC0
|
||||
#define USB_CONFIGURATION_ATTRIBUTES_REMOTE_WAKEUP 0x20
|
||||
#define USB_CONFIGURATION_ATTRIBUTES 0xC0 \
|
||||
| (COND_CODE_1(CONFIG_USB_DEVICE_REMOTE_WAKEUP, \
|
||||
(USB_CONFIGURATION_ATTRIBUTES_REMOTE_WAKEUP), (0)))
|
||||
|
||||
/* Classes */
|
||||
#define COMMUNICATION_DEVICE_CLASS 0x02
|
||||
|
|
|
@ -418,6 +418,18 @@ int usb_transfer_sync(u8_t ep, u8_t *data, size_t dlen, unsigned int flags);
|
|||
*/
|
||||
void usb_cancel_transfer(u8_t ep);
|
||||
|
||||
/**
|
||||
* @brief Start the USB remote wakeup procedure
|
||||
*
|
||||
* Function to request a remote wakeup.
|
||||
* This feature must be enabled in configuration, otherwise
|
||||
* it will always return -ENOTSUP error.
|
||||
*
|
||||
* @return 0 on success, negative errno code on fail,
|
||||
* i.e. when the bus is already active.
|
||||
*/
|
||||
int usb_wakeup_request(void);
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
|
|
@ -71,6 +71,9 @@
|
|||
#define FEA_REMOTE_WAKEUP 0x01
|
||||
#define FEA_TEST_MODE 0x02
|
||||
|
||||
#define DEVICE_STATUS_SELF_POWERED 0x01
|
||||
#define DEVICE_STATUS_REMOTE_WAKEUP 0x02
|
||||
|
||||
/*
|
||||
* USB descriptors
|
||||
*/
|
||||
|
|
|
@ -64,6 +64,11 @@ config USB_COMPOSITE_BUFFER_SIZE
|
|||
config USB_DEVICE_SOF
|
||||
bool "Enable Start of Frame processing in events"
|
||||
|
||||
config USB_DEVICE_REMOTE_WAKEUP
|
||||
bool "Enable support for remote wakeup"
|
||||
help
|
||||
This option requires USBD peripheral driver to also support remote wakeup.
|
||||
|
||||
config USB_DEVICE_BOS
|
||||
bool "Enable USB Binary Device Object Store (BOS)"
|
||||
|
||||
|
|
|
@ -162,6 +162,8 @@ static struct usb_dev_priv {
|
|||
bool enabled;
|
||||
/** Currently selected configuration */
|
||||
u8_t configuration;
|
||||
/** Remote wakeup feature status */
|
||||
bool remote_wakeup;
|
||||
/** Transfer list */
|
||||
struct usb_transfer_data transfer[MAX_NUM_TRANSFERS];
|
||||
} usb_dev;
|
||||
|
@ -615,9 +617,15 @@ static bool usb_handle_std_device_req(struct usb_setup_packet *setup,
|
|||
case REQ_GET_STATUS:
|
||||
LOG_DBG("REQ_GET_STATUS");
|
||||
/* bit 0: self-powered */
|
||||
/* bit 1: remote wakeup = not supported */
|
||||
/* bit 1: remote wakeup */
|
||||
data[0] = 0U;
|
||||
data[1] = 0U;
|
||||
|
||||
if (IS_ENABLED(CONFIG_USB_DEVICE_REMOTE_WAKEUP)) {
|
||||
data[0] |= (usb_dev.remote_wakeup ?
|
||||
DEVICE_STATUS_REMOTE_WAKEUP : 0);
|
||||
}
|
||||
|
||||
*len = 2;
|
||||
break;
|
||||
|
||||
|
@ -654,18 +662,29 @@ static bool usb_handle_std_device_req(struct usb_setup_packet *setup,
|
|||
|
||||
case REQ_CLEAR_FEATURE:
|
||||
LOG_DBG("REQ_CLEAR_FEATURE");
|
||||
ret = false;
|
||||
|
||||
if (IS_ENABLED(CONFIG_USB_DEVICE_REMOTE_WAKEUP)) {
|
||||
if (value == FEA_REMOTE_WAKEUP) {
|
||||
usb_dev.remote_wakeup = false;
|
||||
ret = true;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case REQ_SET_FEATURE:
|
||||
LOG_DBG("REQ_SET_FEATURE");
|
||||
ret = false;
|
||||
|
||||
if (value == FEA_REMOTE_WAKEUP) {
|
||||
/* put DEVICE_REMOTE_WAKEUP code here */
|
||||
if (IS_ENABLED(CONFIG_USB_DEVICE_REMOTE_WAKEUP)) {
|
||||
if (value == FEA_REMOTE_WAKEUP) {
|
||||
usb_dev.remote_wakeup = true;
|
||||
ret = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (value == FEA_TEST_MODE) {
|
||||
/* put TEST_MODE code here */
|
||||
}
|
||||
ret = false;
|
||||
break;
|
||||
|
||||
case REQ_SET_DESCRIPTOR:
|
||||
|
@ -1368,6 +1387,18 @@ int usb_transfer_sync(u8_t ep, u8_t *data, size_t dlen, unsigned int flags)
|
|||
return pdata.tsize;
|
||||
}
|
||||
|
||||
int usb_wakeup_request(void)
|
||||
{
|
||||
if (IS_ENABLED(CONFIG_USB_DEVICE_REMOTE_WAKEUP)) {
|
||||
if (usb_dev.remote_wakeup) {
|
||||
return usb_dc_wakeup_request();
|
||||
}
|
||||
return -EACCES;
|
||||
} else {
|
||||
return -ENOTSUP;
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef CONFIG_USB_COMPOSITE_DEVICE
|
||||
|
||||
static u8_t iface_data_buf[CONFIG_USB_COMPOSITE_BUFFER_SIZE];
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue