More improvements to the generic USB driver, implemented suspend and wakeup handling in the STM32 USB driver.

git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@2742 35acf78f-673a-0410-8e92-d51de3d6d3f4
master
gdisirio 2011-02-15 18:44:29 +00:00
parent 35ff732352
commit 60d8f68906
7 changed files with 252 additions and 132 deletions

View File

@ -1,11 +1,6 @@
***************************************************************************
Options: -O2 -fomit-frame-pointer -msdata=none -falign-functions=16
Settings: SYSCLK=80, optimal wait states, prefetching enabled
***************************************************************************
*** ChibiOS/RT test suite
***
*** Kernel: 2.1.0unstable
*** Kernel: 2.3.0unstable
*** GCC Version: 4.4.1
*** Architecture: PowerPC
*** Core Variant: e200z3
@ -34,6 +29,9 @@ Settings: SYSCLK=80, optimal wait states, prefetching enabled
--- Test Case 2.3 (Semaphores, atomic signal-wait)
--- Result: SUCCESS
----------------------------------------------------------------------------
--- Test Case 2.4 (Binary Semaphores, functionality)
--- Result: SUCCESS
----------------------------------------------------------------------------
--- Test Case 3.1 (Mutexes, priority enqueuing test)
--- Result: SUCCESS
----------------------------------------------------------------------------
@ -95,15 +93,15 @@ Settings: SYSCLK=80, optimal wait states, prefetching enabled
--- Result: SUCCESS
----------------------------------------------------------------------------
--- Test Case 11.1 (Benchmark, messages #1)
--- Score : 281168 msgs/S, 562336 ctxswc/S
--- Score : 280179 msgs/S, 560358 ctxswc/S
--- Result: SUCCESS
----------------------------------------------------------------------------
--- Test Case 11.2 (Benchmark, messages #2)
--- Score : 226208 msgs/S, 452416 ctxswc/S
--- Score : 225570 msgs/S, 451140 ctxswc/S
--- Result: SUCCESS
----------------------------------------------------------------------------
--- Test Case 11.3 (Benchmark, messages #3)
--- Score : 226208 msgs/S, 452416 ctxswc/S
--- Score : 225570 msgs/S, 451140 ctxswc/S
--- Result: SUCCESS
----------------------------------------------------------------------------
--- Test Case 11.4 (Benchmark, context switch)
@ -111,15 +109,15 @@ Settings: SYSCLK=80, optimal wait states, prefetching enabled
--- Result: SUCCESS
----------------------------------------------------------------------------
--- Test Case 11.5 (Benchmark, threads, full cycle)
--- Score : 182729 threads/S
--- Score : 183148 threads/S
--- Result: SUCCESS
----------------------------------------------------------------------------
--- Test Case 11.6 (Benchmark, threads, create only)
--- Score : 263538 threads/S
--- Score : 268864 threads/S
--- Result: SUCCESS
----------------------------------------------------------------------------
--- Test Case 11.7 (Benchmark, mass reschedule, 5 threads)
--- Score : 74067 reschedules/S, 444402 ctxswc/S
--- Score : 73999 reschedules/S, 443994 ctxswc/S
--- Result: SUCCESS
----------------------------------------------------------------------------
--- Test Case 11.8 (Benchmark, round robin context switching)
@ -127,19 +125,19 @@ Settings: SYSCLK=80, optimal wait states, prefetching enabled
--- Result: SUCCESS
----------------------------------------------------------------------------
--- Test Case 11.9 (Benchmark, I/O Queues throughput)
--- Score : 618384 bytes/S
--- Score : 613316 bytes/S
--- Result: SUCCESS
----------------------------------------------------------------------------
--- Test Case 11.10 (Benchmark, virtual timers set/reset)
--- Score : 1093664 timers/S
--- Score : 1093666 timers/S
--- Result: SUCCESS
----------------------------------------------------------------------------
--- Test Case 11.11 (Benchmark, semaphores wait/signal)
--- Score : 1027008 wait+signal/S
--- Score : 1027012 wait+signal/S
--- Result: SUCCESS
----------------------------------------------------------------------------
--- Test Case 11.12 (Benchmark, mutexes lock/unlock)
--- Score : 871856 lock+unlock/S
--- Score : 841236 lock+unlock/S
--- Result: SUCCESS
----------------------------------------------------------------------------
--- Test Case 11.13 (Benchmark, RAM footprint)

View File

@ -76,6 +76,96 @@
#define USB_EARLY_SET_ADDRESS 0
#define USB_LATE_SET_ADDRESS 1
/**
* @brief Helper macro for index values into descriptor strings.
*/
#define USB_DESC_INDEX(i) ((uint8_t)(i))
/**
* @brief Helper macro for byte values into descriptor strings.
*/
#define USB_DESC_BYTE(b) ((uint8_t)(b))
/**
* @brief Helper macro for word values into descriptor strings.
*/
#define USB_DESC_WORD(w) \
(uint8_t)((w) & 255), \
(uint8_t)(((w) >> 8) & 255)
/**
* @brief Helper macro for BCD values into descriptor strings.
*/
#define USB_DESC_BCD(bcd) \
(uint8_t)((bcd) & 255), \
(uint8_t)(((bcd) >> 8) & 255)
/**
* @brief Device Descriptor helper macro.
*/
#define USB_DESC_DEVICE(bcdUSB, bDeviceClass, bDeviceSubClass, \
bDeviceProtocol, bMaxPacketSize, idVendor, \
idProduct, bcdDevice, iManufacturer, \
iProduct, iSerialNumber, bNumConfigurations) \
USB_DESC_BYTE(18), \
USB_DESC_BYTE(USB_DESCRIPTOR_DEVICE), \
USB_DESC_BCD(bcdUSB), \
USB_DESC_BYTE(bDeviceClass), \
USB_DESC_BYTE(bDeviceSubClass), \
USB_DESC_BYTE(bDeviceProtocol), \
USB_DESC_BYTE(bMaxPacketSize), \
USB_DESC_WORD(idVendor), \
USB_DESC_WORD(idProduct), \
USB_DESC_BCD(bcdDevice), \
USB_DESC_INDEX(iManufacturer), \
USB_DESC_INDEX(iProduct), \
USB_DESC_INDEX(iSerialNumber), \
USB_DESC_BYTE(bNumConfigurations)
/**
* @brief Configuration Descriptor helper macro.
*/
#define USB_DESC_CONFIGURATION(wTotalLength, bNumInterfaces, \
bConfigurationValue, iConfiguration, \
bmAttributes, bMaxPower) \
USB_DESC_BYTE(9), \
USB_DESC_BYTE(USB_DESCRIPTOR_CONFIGURATION), \
USB_DESC_WORD(wTotalLength), \
USB_DESC_BYTE(bNumInterfaces), \
USB_DESC_BYTE(bConfigurationValue), \
USB_DESC_INDEX(iConfiguration), \
USB_DESC_BYTE(bmAttributes), \
USB_DESC_BYTE(bMaxPower)
/**
* @brief Interface Descriptor helper macro.
*/
#define USB_DESC_INTERFACE(bInterfaceNumber, bAlternateSetting, \
bNumEndpoints, bInterfaceClass, \
bInterfaceSubClass, bInterfaceProtocol, \
iInterface) \
USB_DESC_BYTE(9), \
USB_DESC_BYTE(USB_DESCRIPTOR_INTERFACE), \
USB_DESC_BYTE(bInterfaceNumber), \
USB_DESC_BYTE(bAlternateSetting), \
USB_DESC_BYTE(bNumEndpoints), \
USB_DESC_BYTE(bInterfaceClass), \
USB_DESC_BYTE(bInterfaceSubClass), \
USB_DESC_BYTE(bInterfaceProtocol), \
USB_DESC_INDEX(iInterface)
/**
* @brief Endpoint Descriptor helper macro.
*/
#define USB_DESC_ENDPOINT(bEndpointAddress, bmAttributes, wMaxPacketSize, \
bInterval) \
USB_DESC_BYTE(7), \
USB_DESC_BYTE(USB_DESCRIPTOR_ENDPOINT), \
USB_DESC_BYTE(bEndpointAddress), \
USB_DESC_BYTE(bmAttributes), \
USB_DESC_WORD(wMaxPacketSize), \
USB_DESC_BYTE(bInterval)
/**
* @brief Returned by some functions to report a busy endpoint.
*/
@ -151,7 +241,7 @@ typedef enum {
USB_EVENT_ADDRESS = 1, /**< Address assigned. */
USB_EVENT_CONFIGURED = 2, /**< Configuration selected. */
USB_EVENT_SUSPEND = 3, /**< Entering suspend mode. */
USB_EVENT_RESUME = 4, /**< Leaving suspend mode. */
USB_EVENT_WAKEUP = 4, /**< Leaving suspend mode. */
USB_EVENT_STALLED = 5, /**< Endpoint 0 error, stalled. */
} usbevent_t;

View File

@ -199,6 +199,35 @@ CH_IRQ_HANDLER(USB_LP_IRQHandler) {
STM32_USB->ISTR = ~ISTR_RESET;
}
/* USB bus SUSPEND condition handling.*/
if (istr & ISTR_SUSP) {
STM32_USB->CNTR |= CNTR_FSUSP;
if (usbp->config->event_cb)
usbp->config->event_cb(usbp, USB_EVENT_SUSPEND);
#if STM32_USB_LOW_POWER_ON_SUSPEND
STM32_USB->CNTR |= CNTR_LP_MODE;
#endif
STM32_USB->ISTR = ~ISTR_SUSP;
}
/* USB bus WAKEUP condition handling.*/
if (istr & ISTR_WKUP) {
uint32_t fnr = STM32_USB->FNR;
if (!(fnr & FNR_RXDP)) {
STM32_USB->CNTR &= ~CNTR_FSUSP;
if (usbp->config->event_cb)
usbp->config->event_cb(usbp, USB_EVENT_WAKEUP);
}
#if STM32_USB_LOW_POWER_ON_SUSPEND
else {
/* Just noise, going back in SUSPEND mode, reference manual 22.4.5,
table 169.*/
STM32_USB->CNTR |= CNTR_LP_MODE;
}
#endif
STM32_USB->ISTR = ~ISTR_WKUP;
}
/* SOF handling.*/
if (istr & ISTR_SOF) {
if (usbp->config->sof_cb)
@ -371,8 +400,8 @@ void usb_lld_reset(USBDriver *usbp) {
STM32_USB->BTABLE = 0;
STM32_USB->ISTR = 0;
STM32_USB->DADDR = DADDR_EF;
cntr = /*CNTR_ESOFM | */ CNTR_RESETM | /*CNTR_SUSPM |*/
/*CNTR_WKUPM | CNTR_ERRM | CNTR_PMAOVRM |*/ CNTR_CTRM;
cntr = /*CNTR_ESOFM | */ CNTR_RESETM | CNTR_SUSPM |
CNTR_WKUPM | /*CNTR_ERRM | CNTR_PMAOVRM |*/ CNTR_CTRM;
/* The SOF interrupt is only enabled if a callback is defined for
this service because it is an high rate source.*/
if (usbp->config->sof_cb != NULL)

View File

@ -59,6 +59,13 @@
#define STM32_USB_USE_USB1 TRUE
#endif
/**
* @brief Enables the USB device low power mode on suspend.
*/
#if !defined(STM32_USB_LOW_POWER_ON_SUSPEND) || defined(__DOXYGEN__)
#define STM32_USB_LOW_POWER_ON_SUSPEND FALSE
#endif
/**
* @brief USB1 interrupt priority level setting.
*/

View File

@ -110,7 +110,6 @@
#define HAL_USE_UART FALSE
#endif
/**
* @brief Enables the USB subsystem.
*/

View File

@ -30,129 +30,118 @@
#define DATA_AVAILABLE_EP 3
/*
* USB driver structure.
* USB Driver structure.
*/
static SerialUSBDriver SDU1;
/*
* USB Device Descriptor.
*/
static const uint8_t vcom_device_descriptor_data[] = {
18, /* bLength. */
USB_DESCRIPTOR_DEVICE, /* bDescriptorType. */
0x10, 0x01, /* bcdUSB (1.1). */
static const uint8_t vcom_device_descriptor_data[18] = {
USB_DESC_DEVICE (0x0110, /* bcdUSB (1.1). */
0x02, /* bDeviceClass (CDC). */
0x00, /* bDeviceSubClass. */
0x00, /* bDeviceProtocol. */
0x40, /* bMaxPacketSize. */
0x83, 0x04, /* idVendor (0x0483). */
0x40, 0x57, /* idProduct (0x7540). */
0x00, 0x02, /* bcdDevice (2.00). */
0x0483, /* idVendor (ST). */
0x5740, /* idProduct. */
0x0200, /* bcdDevice. */
1, /* iManufacturer. */
2, /* iProduct. */
3, /* IiSerialNumber. */
1 /* bNumConfigurations. */
3, /* iSerialNumber. */
1) /* bNumConfigurations. */
};
/*
* Device descriptor wrapper.
* Device Descriptor wrapper.
*/
static const USBDescriptor vcom_device_descriptor = {
sizeof (vcom_device_descriptor_data),
sizeof vcom_device_descriptor_data,
vcom_device_descriptor_data
};
/* Configuration Descriptor tree for a VCOM.*/
static const uint8_t vcom_configuration_descriptor_data[] = {
/* Configuration descriptor.*/
9, /* bLength. */
USB_DESCRIPTOR_CONFIGURATION, /* bDescriptorType. */
67, 0, /* wTotalLength. */
/* Configuration Descriptor tree for a CDC.*/
static const uint8_t vcom_configuration_descriptor_data[67] = {
/* Configuration Descriptor.*/
USB_DESC_CONFIGURATION(67, /* wTotalLength. */
0x02, /* bNumInterfaces. */
0x01, /* bConfigurationValue. */
0, /* iConfiguration. */
0xC0, /* bmAttributes (self powered). */
50, /* MaxPower (100mA). */
50), /* bMaxPower (100mA). */
/* Interface Descriptor.*/
9, /* bLength. */
USB_DESCRIPTOR_INTERFACE, /* bDescriptorType. */
0x00, /* bInterfaceNumber. */
USB_DESC_INTERFACE (0x00, /* bInterfaceNumber. */
0x00, /* bAlternateSetting. */
0x01, /* bNumEndpoints. */
0x02, /* bInterfaceClass (Communications
Interface Class, CDC section 4.2). */
0x02, /* bInterfaceSubClass (Abstract Control
Model, CDC section 4.3). */
0x01, /* bInterfaceProtocol (AT commands, CDC
section 4.4). */
0, /* iInterface. */
Interface Class, CDC section
4.2). */
0x02, /* bInterfaceSubClass (Abstract
Control Model, CDC section 4.3). */
0x01, /* bInterfaceProtocol (AT commands,
CDC section 4.4). */
0), /* iInterface. */
/* Header Functional Descriptor (CDC section 5.2.3).*/
5, /* bLength. */
0x24, /* bDescriptorType (CS_INTERFACE). */
0x00, /* bDescriptorSubtype (Header Functional
Descriptor. */
0x10, 0x01, /* bcdCDC (1.10). */
/* Call Managment Functional Descriptor. */
5, /* bFunctionLength. */
0x24, /* bDescriptorType (CS_INTERFACE). */
0x01, /* bDescriptorSubtype (Call Management
USB_DESC_BYTE (5), /* bLength. */
USB_DESC_BYTE (0x24), /* bDescriptorType (CS_INTERFACE). */
USB_DESC_BYTE (0x00), /* bDescriptorSubtype (Header
Functional Descriptor. */
USB_DESC_BCD (0x0110), /* bcdCDC. */
/* Call Management Functional Descriptor. */
USB_DESC_BYTE (5), /* bFunctionLength. */
USB_DESC_BYTE (0x24), /* bDescriptorType (CS_INTERFACE). */
USB_DESC_BYTE (0x01), /* bDescriptorSubtype (Call Management
Functional Descriptor). */
0x00, /* bmCapabilities (D0+D1). */
0x01, /* bDataInterface. */
USB_DESC_BYTE (0x00), /* bmCapabilities (D0+D1). */
USB_DESC_BYTE (0x01), /* bDataInterface. */
/* ACM Functional Descriptor.*/
4, /* bFunctionLength. */
0x24, /* bDescriptorType (CS_INTERFACE). */
0x02, /* bDescriptorSubtype (Abstract Control
Management Descriptor). */
0x02, /* bmCapabilities. */
USB_DESC_BYTE (4), /* bFunctionLength. */
USB_DESC_BYTE (0x24), /* bDescriptorType (CS_INTERFACE). */
USB_DESC_BYTE (0x02), /* bDescriptorSubtype (Abstract
Control Management Descriptor). */
USB_DESC_BYTE (0x02), /* bmCapabilities. */
/* Union Functional Descriptor.*/
5, /* bFunctionLength. */
0x24, /* bDescriptorType (CS_INTERFACE). */
0x06, /* bDescriptorSubtype (Union Functional
Descriptor). */
0x00, /* bMasterInterface (Communication Class
Interface). */
0x01, /* bSlaveInterface0 (Data Class
USB_DESC_BYTE (5), /* bFunctionLength. */
USB_DESC_BYTE (0x24), /* bDescriptorType (CS_INTERFACE). */
USB_DESC_BYTE (0x06), /* bDescriptorSubtype (Union
Functional Descriptor). */
USB_DESC_BYTE (0x00), /* bMasterInterface (Communication
Class Interface). */
USB_DESC_BYTE (0x01), /* bSlaveInterface0 (Data Class
Interface). */
/* Endpoint 2 Descriptor.*/
7, /* bLength. */
USB_DESCRIPTOR_ENDPOINT, /* bDescriptorType. */
INTERRUPT_REQUEST_EP | 0x80, /* bEndpointAddress (IN). */
USB_DESC_ENDPOINT (INTERRUPT_REQUEST_EP|0x80, /* bEndpointAddress. */
0x03, /* bmAttributes (Interrupt). */
0x08, 0x00, /* wMaxPacketSize. */
0xFF, /* bInterval. */
0x0008, /* wMaxPacketSize. */
0xFF), /* bInterval. */
/* Interface Descriptor.*/
9, /* bLength. */
USB_DESCRIPTOR_INTERFACE, /* bDescriptorType. */
0x01, /* bInterfaceNumber. */
USB_DESC_INTERFACE (0x01, /* bInterfaceNumber. */
0x00, /* bAlternateSetting. */
0x02, /* bNumEndpoints. */
0x0A, /* bInterfaceClass (Data Class
Interface, CDC section 4.5). */
0x00, /* bInterfaceSubClass (CDC section 4.6).*/
0x00, /* bInterfaceProtocol (CDC section 4.7).*/
0x00, /* iInterface. */
0x00, /* bInterfaceSubClass (CDC section
4.6). */
0x00, /* bInterfaceProtocol (CDC section
4.7). */
0x00), /* iInterface. */
/* Endpoint 3 Descriptor.*/
7, /* bLength. */
USB_DESCRIPTOR_ENDPOINT, /* bDescriptorType. */
DATA_AVAILABLE_EP, /* bEndpointAddress (OUT). */
USB_DESC_ENDPOINT (DATA_AVAILABLE_EP, /* bEndpointAddress. */
0x02, /* bmAttributes (Bulk). */
0x40, 0x00, /* wMaxPacketSize. */
0x00, /* bInterval (ignored for bulk. */
0x0040, /* wMaxPacketSize. */
0x00), /* bInterval. */
/* Endpoint 1 Descriptor.*/
7, /* bLength. */
USB_DESCRIPTOR_ENDPOINT, /* bDescriptorType. */
DATA_REQUEST_EP | 0x80, /* bEndpointAddress (IN). */
USB_DESC_ENDPOINT (DATA_REQUEST_EP|0x80, /* bEndpointAddress. */
0x02, /* bmAttributes (Bulk). */
0x40, 0x00, /* wMaxPacketSize. */
0x00 /* bInterval (ignored for bulk. */
0x0040, /* wMaxPacketSize. */
0x00) /* bInterval. */
};
/*
* Configuration descriptor wrapper.
* Configuration Descriptor wrapper.
*/
static const USBDescriptor vcom_configuration_descriptor = {
sizeof (vcom_configuration_descriptor_data),
sizeof vcom_configuration_descriptor_data,
vcom_configuration_descriptor_data
};
@ -160,28 +149,28 @@ static const USBDescriptor vcom_configuration_descriptor = {
* U.S. English language identifier.
*/
static const uint8_t vcom_string0[] = {
4, /* bLength. */
USB_DESCRIPTOR_STRING, /* bDescriptorType. */
0x09, 0x04 /* wLANGID (0x0409, U.S. English). */
USB_DESC_BYTE(4), /* bLength. */
USB_DESC_BYTE(USB_DESCRIPTOR_STRING), /* bDescriptorType. */
USB_DESC_WORD(0x0409) /* wLANGID (U.S. English). */
};
/*
* Vendor string.
*/
static const uint8_t vcom_string1[] = {
38, /* bLength. */
USB_DESCRIPTOR_STRING, /* bDescriptorType. */
USB_DESC_BYTE(38), /* bLength. */
USB_DESC_BYTE(USB_DESCRIPTOR_STRING), /* bDescriptorType. */
'S', 0, 'T', 0, 'M', 0, 'i', 0, 'c', 0, 'r', 0, 'o', 0, 'e', 0,
'l', 0, 'e', 0, 'c', 0, 't', 0, 'r', 0, 'o', 0, 'n', 0, 'i', 0,
'c', 0, 's', 0
};
/*
* Device description string.
* Device Description string.
*/
static const uint8_t vcom_string2[] = {
56, /* bLength. */
USB_DESCRIPTOR_STRING, /* bDescriptorType. */
USB_DESC_BYTE(56), /* bLength. */
USB_DESC_BYTE(USB_DESCRIPTOR_STRING), /* bDescriptorType. */
'C', 0, 'h', 0, 'i', 0, 'b', 0, 'i', 0, 'O', 0, 'S', 0, '/', 0,
'R', 0, 'T', 0, ' ', 0, 'V', 0, 'i', 0, 'r', 0, 't', 0, 'u', 0,
'a', 0, 'l', 0, ' ', 0, 'C', 0, 'O', 0, 'M', 0, ' ', 0, 'P', 0,
@ -189,11 +178,11 @@ static const uint8_t vcom_string2[] = {
};
/*
* Serial number string.
* Serial Number string.
*/
static const uint8_t vcom_string3[] = {
8, /* bLength. */
USB_DESCRIPTOR_STRING, /* bDescriptorType. */
USB_DESC_BYTE(8), /* bLength. */
USB_DESC_BYTE(USB_DESCRIPTOR_STRING), /* bDescriptorType. */
'0' + CH_KERNEL_MAJOR, 0,
'0' + CH_KERNEL_MINOR, 0,
'0' + CH_KERNEL_PATCH, 0
@ -203,10 +192,10 @@ static const uint8_t vcom_string3[] = {
* Strings wrappers array.
*/
static const USBDescriptor vcom_strings[] = {
{sizeof(vcom_string0), vcom_string0},
{sizeof(vcom_string1), vcom_string1},
{sizeof(vcom_string2), vcom_string2},
{sizeof(vcom_string3), vcom_string3}
{sizeof vcom_string0, vcom_string0},
{sizeof vcom_string1, vcom_string1},
{sizeof vcom_string2, vcom_string2},
{sizeof vcom_string3, vcom_string3}
};
/*
@ -291,7 +280,7 @@ static void usb_event(USBDriver *usbp, usbevent_t event) {
return;
case USB_EVENT_SUSPEND:
return;
case USB_EVENT_RESUME:
case USB_EVENT_WAKEUP:
return;
case USB_EVENT_STALLED:
return;

View File

@ -118,3 +118,11 @@
#define STM32_UART_USART1_DMA_ERROR_HOOK() chSysHalt()
#define STM32_UART_USART2_DMA_ERROR_HOOK() chSysHalt()
#define STM32_UART_USART3_DMA_ERROR_HOOK() chSysHalt()
/*
* USB driver system settings.
*/
#define STM32_USB_USE_USB1 TRUE
#define STM32_USB_LOW_POWER_ON_SUSPEND FALSE
#define STM32_USB_USB1_HP_IRQ_PRIORITY 6
#define STM32_USB_USB1_LP_IRQ_PRIORITY 14