Support USB suspend/resume defined in USB 2.0 spec.

This commit is contained in:
NIIBE Yutaka
2017-11-14 11:17:49 +09:00
parent e398fc9689
commit 168af852a5
7 changed files with 62 additions and 36 deletions

View File

@@ -1,3 +1,16 @@
2017-11-14 NIIBE Yutaka <gniibe@fsij.org>
* usb_lld.h (DEVICE_STATE): Add prefix USB_DEVICE_STATE_.
(USB_DEVICE_STATE_DEFAULT): New.
* mcu/usb-stm32f103.c (usb_lld_init): Suspend/resume init.
(usb_lld_event_handler): Add suspend/resume support.
* example-cdc/usb-cdc.c: Follow the change of usb_lld.h.
* example-cdc-gnu-linux/usb-cdc.c: Ditto.
* example-fs-bb48/usb-cdc.c: Ditto.
* example-fraucheky/main.c: Ditto.
2017-11-13 NIIBE Yutaka <gniibe@fsij.org>
* mcu/usb-stm32f103.c (usb_lld_init): Set up interrupt on errors.

View File

@@ -244,7 +244,7 @@ usb_device_reset (struct usb_dev *dev)
tty0.flag_connected = 0;
tty0.flag_send_ready = 1;
tty0.flag_input_avail = 0;
tty0.device_state = ATTACHED;
tty0.device_state = USB_DEVICE_STATE_ATTACHED;
memcpy (&tty0.line_coding, &line_coding0, sizeof (struct line_coding));
chopstx_mutex_unlock (&tty0.mtx);
}
@@ -414,7 +414,7 @@ usb_set_configuration (struct usb_dev *dev)
for (i = 0; i < NUM_INTERFACES; i++)
vcom_setup_endpoints_for_interface (dev, i, 0);
chopstx_mutex_lock (&tty0.mtx);
tty0.device_state = CONFIGURED;
tty0.device_state = USB_DEVICE_STATE_CONFIGURED;
chopstx_cond_signal (&tty0.cnd);
chopstx_mutex_unlock (&tty0.mtx);
}
@@ -427,7 +427,7 @@ usb_set_configuration (struct usb_dev *dev)
for (i = 0; i < NUM_INTERFACES; i++)
vcom_setup_endpoints_for_interface (dev, i, 1);
chopstx_mutex_lock (&tty0.mtx);
tty0.device_state = ADDRESSED;
tty0.device_state = USB_DEVICE_STATE_ADDRESSED;
chopstx_cond_signal (&tty0.cnd);
chopstx_mutex_unlock (&tty0.mtx);
}
@@ -645,7 +645,7 @@ tty_open (void)
tty0.flag_connected = 0;
tty0.flag_send_ready = 1;
tty0.flag_input_avail = 0;
tty0.device_state = UNCONNECTED;
tty0.device_state = USB_DEVICE_STATE_UNCONNECTED;
memcpy (&tty0.line_coding, &line_coding0, sizeof (struct line_coding));
chopstx_create (PRIO_TTY, STACK_ADDR_TTY, STACK_SIZE_TTY, tty_main, &tty0);
@@ -732,7 +732,7 @@ tty_main (void *arg)
* OK.
*/
chopstx_mutex_lock (&tty0.mtx);
tty0.device_state = ADDRESSED;
tty0.device_state = USB_DEVICE_STATE_ADDRESSED;
chopstx_cond_signal (&tty0.cnd);
chopstx_mutex_unlock (&tty0.mtx);
continue;
@@ -788,7 +788,7 @@ tty_main (void *arg)
}
chopstx_mutex_lock (&t->mtx);
if (t->device_state == CONFIGURED && t->flag_connected
if (t->device_state == USB_DEVICE_STATE_CONFIGURED && t->flag_connected
&& t->flag_send_ready)
{
uint8_t line[32];
@@ -812,7 +812,7 @@ void
tty_wait_configured (struct tty *t)
{
chopstx_mutex_lock (&t->mtx);
while (t->device_state != CONFIGURED)
while (t->device_state != USB_DEVICE_STATE_CONFIGURED)
chopstx_cond_wait (&t->cnd, &t->mtx);
chopstx_mutex_unlock (&t->mtx);
}

View File

@@ -248,7 +248,7 @@ usb_device_reset (struct usb_dev *dev)
tty0.flag_connected = 0;
tty0.flag_send_ready = 1;
tty0.flag_input_avail = 0;
tty0.device_state = ATTACHED;
tty0.device_state = USB_DEVICE_STATE_ATTACHED;
memcpy (&tty0.line_coding, &line_coding0, sizeof (struct line_coding));
chopstx_mutex_unlock (&tty0.mtx);
}
@@ -417,7 +417,7 @@ usb_set_configuration (struct usb_dev *dev)
for (i = 0; i < NUM_INTERFACES; i++)
vcom_setup_endpoints_for_interface (i, 0);
chopstx_mutex_lock (&tty0.mtx);
tty0.device_state = CONFIGURED;
tty0.device_state = USB_DEVICE_STATE_CONFIGURED;
chopstx_cond_signal (&tty0.cnd);
chopstx_mutex_unlock (&tty0.mtx);
}
@@ -430,7 +430,7 @@ usb_set_configuration (struct usb_dev *dev)
for (i = 0; i < NUM_INTERFACES; i++)
vcom_setup_endpoints_for_interface (i, 1);
chopstx_mutex_lock (&tty0.mtx);
tty0.device_state = ADDRESSED;
tty0.device_state = USB_DEVICE_STATE_ADDRESSED;
chopstx_cond_signal (&tty0.cnd);
chopstx_mutex_unlock (&tty0.mtx);
}
@@ -656,7 +656,7 @@ tty_open (void)
tty0.flag_connected = 0;
tty0.flag_send_ready = 1;
tty0.flag_input_avail = 0;
tty0.device_state = UNCONNECTED;
tty0.device_state = USB_DEVICE_STATE_UNCONNECTED;
memcpy (&tty0.line_coding, &line_coding0, sizeof (struct line_coding));
chopstx_create (PRIO_TTY, STACK_ADDR_TTY, STACK_SIZE_TTY, tty_main, &tty0);
@@ -743,7 +743,7 @@ tty_main (void *arg)
* OK.
*/
chopstx_mutex_lock (&tty0.mtx);
tty0.device_state = ADDRESSED;
tty0.device_state = USB_DEVICE_STATE_ADDRESSED;
chopstx_cond_signal (&tty0.cnd);
chopstx_mutex_unlock (&tty0.mtx);
continue;
@@ -799,7 +799,7 @@ tty_main (void *arg)
}
chopstx_mutex_lock (&t->mtx);
if (t->device_state == CONFIGURED && t->flag_connected
if (t->device_state == USB_DEVICE_STATE_CONFIGURED && t->flag_connected
&& t->flag_send_ready)
{
uint8_t line[32];
@@ -823,7 +823,7 @@ void
tty_wait_configured (struct tty *t)
{
chopstx_mutex_lock (&t->mtx);
while (t->device_state != CONFIGURED)
while (t->device_state != USB_DEVICE_STATE_CONFIGURED)
chopstx_cond_wait (&t->cnd, &t->mtx);
chopstx_mutex_unlock (&t->mtx);
}

View File

@@ -11,7 +11,7 @@
static chopstx_mutex_t usb_mtx;
static chopstx_cond_t usb_cnd;
static uint32_t bDeviceState = UNCONNECTED; /* USB device status */
static uint32_t bDeviceState = USB_DEVICE_STATE_UNCONNECTED;
extern void EP6_IN_Callback (uint16_t len);
extern void EP6_OUT_Callback (uint16_t len);
@@ -47,7 +47,7 @@ usb_device_reset (struct usb_dev *dev)
/* Notify upper layer. */
chopstx_mutex_lock (&usb_mtx);
bDeviceState = ATTACHED;
bDeviceState = USB_DEVICE_STATE_ATTACHED;
chopstx_cond_signal (&usb_cnd);
chopstx_mutex_unlock (&usb_mtx);
}
@@ -95,7 +95,7 @@ usb_set_configuration (struct usb_dev *dev)
for (i = 0; i < NUM_INTERFACES; i++)
setup_endpoints_for_interface (dev, i, 0);
chopstx_mutex_lock (&usb_mtx);
bDeviceState = CONFIGURED;
bDeviceState = USB_DEVICE_STATE_CONFIGURED;
chopstx_mutex_unlock (&usb_mtx);
}
else if (current_conf != dev->dev_req.value)
@@ -107,7 +107,7 @@ usb_set_configuration (struct usb_dev *dev)
for (i = 0; i < NUM_INTERFACES; i++)
setup_endpoints_for_interface (dev, i, 1);
chopstx_mutex_lock (&usb_mtx);
bDeviceState = ADDRESSED;
bDeviceState = USB_DEVICE_STATE_ADDRESSED;
chopstx_cond_signal (&usb_cnd);
chopstx_mutex_unlock (&usb_mtx);
}
@@ -206,7 +206,7 @@ usb_main (void *arg)
case USB_EVENT_DEVICE_ADDRESSED:
chopstx_mutex_lock (&usb_mtx);
bDeviceState = ADDRESSED;
bDeviceState = USB_DEVICE_STATE_ADDRESSED;
chopstx_cond_signal (&usb_cnd);
chopstx_mutex_unlock (&usb_mtx);
continue;
@@ -304,16 +304,16 @@ main (int argc, char **argv)
chopstx_mutex_init (&usb_mtx);
chopstx_cond_init (&usb_cnd);
bDeviceState = UNCONNECTED;
bDeviceState = USB_DEVICE_STATE_UNCONNECTED;
usb_thd = chopstx_create (PRIO_USB, STACK_ADDR_USB, STACK_SIZE_USB,
usb_main, NULL);
while (bDeviceState != CONFIGURED)
while (bDeviceState != USB_DEVICE_STATE_CONFIGURED)
chopstx_usec_wait (250*1000);
fraucheky_main ();
chopstx_cancel (usb_thd);
chopstx_join (usb_thd, NULL);
usb_lld_shutdown ();
bDeviceState = UNCONNECTED;
bDeviceState = USB_DEVICE_STATE_UNCONNECTED;
return 0;
}

View File

@@ -245,7 +245,7 @@ usb_device_reset (struct usb_dev *dev)
tty0.flag_connected = 0;
tty0.flag_send_ready = 1;
tty0.flag_input_avail = 0;
tty0.device_state = ATTACHED;
tty0.device_state = USB_DEVICE_STATE_ATTACHED;
memcpy (&tty0.line_coding, &line_coding0, sizeof (struct line_coding));
chopstx_mutex_unlock (&tty0.mtx);
}
@@ -409,7 +409,7 @@ usb_set_configuration (struct usb_dev *dev)
for (i = 0; i < NUM_INTERFACES; i++)
vcom_setup_endpoints_for_interface (dev, i, 0);
chopstx_mutex_lock (&tty0.mtx);
tty0.device_state = CONFIGURED;
tty0.device_state = USB_DEVICE_STATE_CONFIGURED;
chopstx_cond_signal (&tty0.cnd);
chopstx_mutex_unlock (&tty0.mtx);
}
@@ -422,7 +422,7 @@ usb_set_configuration (struct usb_dev *dev)
for (i = 0; i < NUM_INTERFACES; i++)
vcom_setup_endpoints_for_interface (dev, i, 1);
chopstx_mutex_lock (&tty0.mtx);
tty0.device_state = ADDRESSED;
tty0.device_state = USB_DEVICE_STATE_ADDRESSED;
chopstx_cond_signal (&tty0.cnd);
chopstx_mutex_unlock (&tty0.mtx);
}
@@ -642,7 +642,7 @@ tty_open (void)
tty0.flag_connected = 0;
tty0.flag_send_ready = 1;
tty0.flag_input_avail = 0;
tty0.device_state = UNCONNECTED;
tty0.device_state = USB_DEVICE_STATE_UNCONNECTED;
memcpy (&tty0.line_coding, &line_coding0, sizeof (struct line_coding));
chopstx_create (PRIO_TTY, STACK_ADDR_TTY, STACK_SIZE_TTY, tty_main, &tty0);
@@ -732,7 +732,7 @@ tty_main (void *arg)
* OK.
*/
chopstx_mutex_lock (&tty0.mtx);
tty0.device_state = ADDRESSED;
tty0.device_state = USB_DEVICE_STATE_ADDRESSED;
chopstx_cond_signal (&tty0.cnd);
chopstx_mutex_unlock (&tty0.mtx);
continue;
@@ -788,7 +788,7 @@ tty_main (void *arg)
}
chopstx_mutex_lock (&t->mtx);
if (t->device_state == CONFIGURED && t->flag_connected
if (t->device_state == USB_DEVICE_STATE_CONFIGURED && t->flag_connected
&& t->flag_send_ready)
{
uint8_t line[32];
@@ -812,7 +812,7 @@ void
tty_wait_configured (struct tty *t)
{
chopstx_mutex_lock (&t->mtx);
while (t->device_state != CONFIGURED)
while (t->device_state != USB_DEVICE_STATE_CONFIGURED)
chopstx_cond_wait (&t->cnd, &t->mtx);
chopstx_mutex_unlock (&t->mtx);
}

View File

@@ -340,7 +340,7 @@ void usb_lld_init (struct usb_dev *dev, uint8_t feature)
/* Clear Interrupt Status Register, and enable interrupt for USB */
st103_set_istr (0);
st103_set_cntr (CNTR_CTRM | CNTR_OVRM | CNTR_ERRM
| CNTR_RESETM);
| CNTR_WKUPM | CNTR_SUSPM | CNTR_RESETM);
}
void usb_lld_prepare_shutdown (void)
@@ -368,6 +368,18 @@ usb_lld_event_handler (struct usb_dev *dev)
st103_set_istr (CLR_RESET);
return USB_MAKE_EV (USB_EVENT_DEVICE_RESET);
}
else if ((istr_value & ISTR_WKUP))
{
st103_set_istr (CLR_WKUP);
*CNTR &= ~CNTR_FSUSP;
return USB_MAKE_EV (USB_EVENT_DEVICE_WAKEUP);
}
else if ((istr_value & ISTR_SUSP))
{
st103_set_istr (CLR_SUSP);
*CNTR |= (CNTR_FSUSP | CNTR_LPMODE);
return USB_MAKE_EV (USB_EVENT_DEVICE_SUSPEND);
}
else
{
if ((istr_value & ISTR_OVR))

View File

@@ -84,12 +84,13 @@ enum {
};
enum DEVICE_STATE {
UNCONNECTED,
ATTACHED,
POWERED,
SUSPENDED,
ADDRESSED,
CONFIGURED
USB_DEVICE_STATE_UNCONNECTED = 0, /* No USB */
USB_DEVICE_STATE_ATTACHED = 1,
USB_DEVICE_STATE_POWERED = 2,
USB_DEVICE_STATE_DEFAULT = 3,
USB_DEVICE_STATE_ADDRESSED = 4,
USB_DEVICE_STATE_CONFIGURED = 5,
USB_DEVICE_STATE_SUSPEND = 128 /* Or-ed to other states */
};
void usb_lld_init (struct usb_dev *dev, uint8_t feature);