USB stack implementation improvement

This commit is contained in:
NIIBE Yutaka
2013-03-06 17:18:59 +09:00
parent b297321cc6
commit a21e925b4e
5 changed files with 121 additions and 141 deletions

View File

@@ -345,7 +345,7 @@ main (int argc, char *argv[])
main_thread = chThdSelf (); main_thread = chThdSelf ();
usb_lld_init (Config_Descriptor.Descriptor[7]); usb_lld_init (usb_initial_feature);
random_init (); random_init ();
while (1) while (1)

View File

@@ -1,7 +1,7 @@
/* /*
* usb_ctrl.c - USB control pipe device specific code for Gnuk * usb_ctrl.c - USB control pipe device specific code for Gnuk
* *
* Copyright (C) 2010, 2011, 2012 Free Software Initiative of Japan * Copyright (C) 2010, 2011, 2012, 2013 Free Software Initiative of Japan
* Author: NIIBE Yutaka <gniibe@fsij.org> * Author: NIIBE Yutaka <gniibe@fsij.org>
* *
* This file is a part of Gnuk, a GnuPG USB Token implementation. * This file is a part of Gnuk, a GnuPG USB Token implementation.
@@ -147,8 +147,8 @@ gnuk_setup_endpoints_for_interface (uint16_t interface, int stop)
#endif #endif
} }
static void void
gnuk_device_reset (void) usb_cb_device_reset (void)
{ {
int i; int i;
@@ -156,7 +156,7 @@ gnuk_device_reset (void)
usb_lld_set_configuration (0); usb_lld_set_configuration (0);
/* Current Feature initialization */ /* Current Feature initialization */
usb_lld_set_feature (Config_Descriptor.Descriptor[7]); usb_lld_set_feature (usb_initial_feature);
usb_lld_reset (); usb_lld_reset ();
@@ -214,8 +214,8 @@ static int download_check_crc32 (const uint32_t *end_p)
return USB_UNSUPPORT; return USB_UNSUPPORT;
} }
static int int
gnuk_setup (uint8_t req, uint8_t req_no, usb_cb_setup (uint8_t req, uint8_t req_no,
uint16_t value, uint16_t index, uint16_t len) uint16_t value, uint16_t index, uint16_t len)
{ {
uint8_t type_rcp = req & (REQUEST_TYPE|RECIPIENT); uint8_t type_rcp = req & (REQUEST_TYPE|RECIPIENT);
@@ -310,9 +310,8 @@ gnuk_setup (uint8_t req, uint8_t req_no,
return USB_UNSUPPORT; return USB_UNSUPPORT;
} }
static void gnuk_ctrl_write_finish (uint8_t req, uint8_t req_no, void usb_cb_ctrl_write_finish (uint8_t req, uint8_t req_no, uint16_t value,
uint16_t value, uint16_t index, uint16_t index, uint16_t len)
uint16_t len)
{ {
uint8_t type_rcp = req & (REQUEST_TYPE|RECIPIENT); uint8_t type_rcp = req & (REQUEST_TYPE|RECIPIENT);
@@ -329,38 +328,7 @@ static void gnuk_ctrl_write_finish (uint8_t req, uint8_t req_no,
} }
static int int usb_cb_handle_event (uint8_t event_type, uint16_t value)
gnuk_get_descriptor (uint8_t desc_type, uint16_t index, uint16_t value)
{
(void)index;
if (desc_type == DEVICE_DESCRIPTOR)
{
usb_lld_set_data_to_send (Device_Descriptor.Descriptor,
Device_Descriptor.Descriptor_Size);
return USB_SUCCESS;
}
else if (desc_type == CONFIG_DESCRIPTOR)
{
usb_lld_set_data_to_send (Config_Descriptor.Descriptor,
Config_Descriptor.Descriptor_Size);
return USB_SUCCESS;
}
else if (desc_type == STRING_DESCRIPTOR)
{
uint8_t desc_index = value & 0xff;
if (desc_index < NUM_STRING_DESC)
{
usb_lld_set_data_to_send (String_Descriptors[desc_index].Descriptor,
String_Descriptors[desc_index].Descriptor_Size);
return USB_SUCCESS;
}
}
return USB_UNSUPPORT;
}
static int gnuk_usb_event (uint8_t event_type, uint16_t value)
{ {
int i; int i;
uint8_t current_conf; uint8_t current_conf;
@@ -401,7 +369,7 @@ static int gnuk_usb_event (uint8_t event_type, uint16_t value)
return USB_UNSUPPORT; return USB_UNSUPPORT;
} }
static int gnuk_interface (uint8_t cmd, uint16_t interface, uint16_t alt) int usb_cb_interface (uint8_t cmd, uint16_t interface, uint16_t alt)
{ {
static uint8_t zero = 0; static uint8_t zero = 0;
@@ -429,18 +397,6 @@ static int gnuk_interface (uint8_t cmd, uint16_t interface, uint16_t alt)
} }
} }
/*
* Interface to USB core
*/
const struct usb_device_method Device_Method = {
gnuk_device_reset,
gnuk_ctrl_write_finish,
gnuk_setup,
gnuk_get_descriptor,
gnuk_usb_event,
gnuk_interface,
};
CH_IRQ_HANDLER (Vector90) CH_IRQ_HANDLER (Vector90)
{ {

View File

@@ -9,6 +9,13 @@
#include "usb_conf.h" #include "usb_conf.h"
#include "usb-cdc.h" #include "usb-cdc.h"
struct Descriptor
{
const uint8_t *Descriptor;
uint16_t Descriptor_Size;
};
#define USB_ICC_INTERFACE_CLASS 0x0B #define USB_ICC_INTERFACE_CLASS 0x0B
#define USB_ICC_INTERFACE_SUBCLASS 0x00 #define USB_ICC_INTERFACE_SUBCLASS 0x00
#define USB_ICC_INTERFACE_BULK_PROTOCOL 0x00 #define USB_ICC_INTERFACE_BULK_PROTOCOL 0x00
@@ -53,6 +60,15 @@ static const uint8_t gnukDeviceDescriptor[] = {
#define NUM_INTERFACES (ICC_NUM_INTERFACES+VCOM_NUM_INTERFACES+MSC_NUM_INTERFACES) #define NUM_INTERFACES (ICC_NUM_INTERFACES+VCOM_NUM_INTERFACES+MSC_NUM_INTERFACES)
#if defined(USB_SELF_POWERED)
#define USB_INITIAL_FEATURE 0xC0 /* bmAttributes: self powered */
#else
#define USB_INITIAL_FEATURE 0x80 /* bmAttributes: bus powered */
#endif
const uint8_t usb_initial_feature = USB_INITIAL_FEATURE;
/* Configuation Descriptor */ /* Configuation Descriptor */
static const uint8_t gnukConfigDescriptor[] = { static const uint8_t gnukConfigDescriptor[] = {
9, /* bLength: Configuation Descriptor size */ 9, /* bLength: Configuation Descriptor size */
@@ -61,11 +77,7 @@ static const uint8_t gnukConfigDescriptor[] = {
NUM_INTERFACES, /* bNumInterfaces: */ NUM_INTERFACES, /* bNumInterfaces: */
0x01, /* bConfigurationValue: Configuration value */ 0x01, /* bConfigurationValue: Configuration value */
0x00, /* iConfiguration: Index of string descriptor describing the configuration */ 0x00, /* iConfiguration: Index of string descriptor describing the configuration */
#if defined(USB_SELF_POWERED) USB_INITIAL_FEATURE, /* bmAttributes*/
0xC0, /* bmAttributes: self powered */
#else
0x80, /* bmAttributes: bus powered */
#endif
50, /* MaxPower 100 mA */ 50, /* MaxPower 100 mA */
/* Interface Descriptor */ /* Interface Descriptor */
@@ -268,17 +280,17 @@ const uint8_t gnukStringSerial[] = {
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
}; };
const struct Descriptor Device_Descriptor = { static const struct Descriptor Device_Descriptor = {
gnukDeviceDescriptor, gnukDeviceDescriptor,
sizeof (gnukDeviceDescriptor) sizeof (gnukDeviceDescriptor)
}; };
const struct Descriptor Config_Descriptor = { static const struct Descriptor Config_Descriptor = {
gnukConfigDescriptor, gnukConfigDescriptor,
sizeof (gnukConfigDescriptor) sizeof (gnukConfigDescriptor)
}; };
const struct Descriptor String_Descriptors[NUM_STRING_DESC] = { static const struct Descriptor String_Descriptors[NUM_STRING_DESC] = {
{gnukStringLangID, sizeof (gnukStringLangID)}, {gnukStringLangID, sizeof (gnukStringLangID)},
{gnukStringVendor, sizeof (gnukStringVendor)}, {gnukStringVendor, sizeof (gnukStringVendor)},
{gnukStringProduct, sizeof (gnukStringProduct)}, {gnukStringProduct, sizeof (gnukStringProduct)},
@@ -287,3 +299,34 @@ const struct Descriptor String_Descriptors[NUM_STRING_DESC] = {
{gnuk_config_options, sizeof (gnuk_config_options)}, {gnuk_config_options, sizeof (gnuk_config_options)},
{sys_version, sizeof (sys_version)}, {sys_version, sizeof (sys_version)},
}; };
int
usb_cb_get_descriptor (uint8_t desc_type, uint16_t index, uint16_t value)
{
(void)index;
if (desc_type == DEVICE_DESCRIPTOR)
{
usb_lld_set_data_to_send (Device_Descriptor.Descriptor,
Device_Descriptor.Descriptor_Size);
return USB_SUCCESS;
}
else if (desc_type == CONFIG_DESCRIPTOR)
{
usb_lld_set_data_to_send (Config_Descriptor.Descriptor,
Config_Descriptor.Descriptor_Size);
return USB_SUCCESS;
}
else if (desc_type == STRING_DESCRIPTOR)
{
uint8_t desc_index = value & 0xff;
if (desc_index < NUM_STRING_DESC)
{
usb_lld_set_data_to_send (String_Descriptors[desc_index].Descriptor,
String_Descriptors[desc_index].Descriptor_Size);
return USB_SUCCESS;
}
}
return USB_UNSUPPORT;
}

View File

@@ -49,29 +49,20 @@ enum DESCRIPTOR_TYPE
#define USB_SETUP_SET(req) ((req & REQUEST_DIR) == 0) #define USB_SETUP_SET(req) ((req & REQUEST_DIR) == 0)
#define USB_SETUP_GET(req) ((req & REQUEST_DIR) != 0) #define USB_SETUP_GET(req) ((req & REQUEST_DIR) != 0)
struct Descriptor
{
const uint8_t *Descriptor;
uint16_t Descriptor_Size;
};
enum enum
{ {
USB_UNSUPPORT = 0, USB_UNSUPPORT = 0,
USB_SUCCESS = 1, USB_SUCCESS = 1,
}; };
struct usb_device_method void usb_cb_device_reset (void);
{ void usb_cb_ctrl_write_finish (uint8_t req, uint8_t req_no,
void (*reset) (void);
void (*ctrl_write_finish) (uint8_t req, uint8_t req_no,
uint16_t value, uint16_t index, uint16_t len); uint16_t value, uint16_t index, uint16_t len);
int (*setup) (uint8_t req, uint8_t req_no, int usb_cb_setup (uint8_t req, uint8_t req_no, uint16_t value,
uint16_t value, uint16_t index, uint16_t len); uint16_t index, uint16_t len);
int (*get_descriptor) (uint8_t desc_type, uint16_t index, uint16_t value); int usb_cb_get_descriptor (uint8_t desc_type, uint16_t index, uint16_t value);
int (*event) (uint8_t event_type, uint16_t value); int usb_cb_handle_event (uint8_t event_type, uint16_t value);
int (*interface) (uint8_t cmd, uint16_t interface, uint16_t value); int usb_cb_interface (uint8_t cmd, uint16_t interface, uint16_t value);
};
enum { enum {
USB_EVENT_ADDRESS, USB_EVENT_ADDRESS,
@@ -87,14 +78,6 @@ enum {
USB_QUERY_INTERFACE, USB_QUERY_INTERFACE,
}; };
extern void USB_Cable_Config (int NewState);
extern const struct usb_device_method Device_Method;
extern const struct Descriptor Device_Descriptor;
extern const struct Descriptor Config_Descriptor;
extern const struct Descriptor String_Descriptors[];
enum DEVICE_STATE enum DEVICE_STATE
{ {
UNCONNECTED, UNCONNECTED,
@@ -106,6 +89,7 @@ enum DEVICE_STATE
}; };
extern uint32_t bDeviceState; extern uint32_t bDeviceState;
extern const uint8_t usb_initial_feature;
#define STM32_USB_IRQ_PRIORITY 11 #define STM32_USB_IRQ_PRIORITY 11

View File

@@ -74,12 +74,10 @@ struct DEVICE_INFO
static struct CONTROL_INFO control_info; static struct CONTROL_INFO control_info;
static struct DEVICE_INFO device_info; static struct DEVICE_INFO device_info;
static struct DATA_INFO data_info; static struct DATA_INFO data_info;
extern const struct usb_device_method Device_Method;
static struct CONTROL_INFO *const ctrl_p = &control_info; static struct CONTROL_INFO *const ctrl_p = &control_info;
static struct DEVICE_INFO *const dev_p = &device_info; static struct DEVICE_INFO *const dev_p = &device_info;
static struct DATA_INFO *const data_p = &data_info; static struct DATA_INFO *const data_p = &data_info;
static const struct usb_device_method *const method_p = &Device_Method;
#define REG_BASE (0x40005C00UL) /* USB_IP Peripheral Registers base address */ #define REG_BASE (0x40005C00UL) /* USB_IP Peripheral Registers base address */
#define PMA_ADDR (0x40006000UL) /* USB_IP Packet Memory Area base address */ #define PMA_ADDR (0x40006000UL) /* USB_IP Packet Memory Area base address */
@@ -399,7 +397,7 @@ usb_interrupt_handler (void)
if (istr_value & ISTR_RESET) if (istr_value & ISTR_RESET)
{ {
st103_set_istr (CLR_RESET); st103_set_istr (CLR_RESET);
method_p->reset (); usb_cb_device_reset ();
} }
if (istr_value & ISTR_DOVR) if (istr_value & ISTR_DOVR)
@@ -529,7 +527,7 @@ static int std_get_status (uint8_t req,
if (dev_p->current_configuration == 0) if (dev_p->current_configuration == 0)
return USB_UNSUPPORT; return USB_UNSUPPORT;
r = (*method_p->interface) (USB_QUERY_INTERFACE, index, 0); r = usb_cb_interface (USB_QUERY_INTERFACE, index, 0);
if (r != USB_SUCCESS) if (r != USB_SUCCESS)
return USB_UNSUPPORT; return USB_UNSUPPORT;
@@ -700,7 +698,7 @@ static int std_get_descriptor (uint8_t req, uint16_t value,
(void)length; (void)length;
if (rcp == DEVICE_RECIPIENT) if (rcp == DEVICE_RECIPIENT)
return (*method_p->get_descriptor) ((value >> 8), index, value); return usb_cb_get_descriptor ((value >> 8), index, value);
return USB_UNSUPPORT; return USB_UNSUPPORT;
} }
@@ -736,7 +734,7 @@ static int std_set_configuration (uint8_t req, uint16_t value,
{ {
int r; int r;
r = (*method_p->event) (USB_EVENT_CONFIG, value); r = usb_cb_handle_event (USB_EVENT_CONFIG, value);
if (r == USB_SUCCESS) if (r == USB_SUCCESS)
return USB_SUCCESS; return USB_SUCCESS;
} }
@@ -760,7 +758,7 @@ static int std_get_interface (uint8_t req, uint16_t value,
if (dev_p->current_configuration == 0) if (dev_p->current_configuration == 0)
return USB_UNSUPPORT; return USB_UNSUPPORT;
return (*method_p->interface) (USB_GET_INTERFACE, index, 0); return usb_cb_interface (USB_GET_INTERFACE, index, 0);
} }
return USB_UNSUPPORT; return USB_UNSUPPORT;
@@ -784,7 +782,7 @@ static int std_set_interface (uint8_t req, uint16_t value,
if (dev_p->current_configuration != 0) if (dev_p->current_configuration != 0)
return USB_UNSUPPORT; return USB_UNSUPPORT;
r = (*method_p->interface) (USB_SET_INTERFACE, index, value); r = usb_cb_interface (USB_SET_INTERFACE, index, value);
if (r == USB_SUCCESS) if (r == USB_SUCCESS)
return USB_SUCCESS; return USB_SUCCESS;
} }
@@ -792,21 +790,6 @@ static int std_set_interface (uint8_t req, uint16_t value,
return USB_UNSUPPORT; return USB_UNSUPPORT;
} }
static const HANDLER std_request_handler[TOTAL_REQUEST] = {
std_get_status,
std_clear_feature,
std_none,
std_set_feature,
std_none,
std_set_address,
std_get_descriptor,
std_none, /* set_descriptor is not supported */
std_get_configuration,
std_set_configuration,
std_get_interface,
std_set_interface,
std_none, /* sync_frame is not supported (for now) */
};
static void handle_setup0 (void) static void handle_setup0 (void)
{ {
@@ -836,13 +819,29 @@ static void handle_setup0 (void)
{ {
if (req < TOTAL_REQUEST) if (req < TOTAL_REQUEST)
{ {
handler = std_request_handler[req]; switch ((req)&0x07)
{
case 0: handler = std_get_status; break;
case 1: handler = std_clear_feature; break;
case 2: handler = std_none; break;
case 3: handler = std_set_feature; break;
case 4: handler = std_none; break;
case 5: handler = std_set_address; break;
case 6: handler = std_get_descriptor; break;
case 7: handler = std_none; break;
case 8: handler = std_get_configuration; break;
case 9: handler = std_set_configuration; break;
case 10: handler = std_get_interface; break;
case 11: handler = std_set_interface; break;
case 12: handler = std_none; break;
}
r = (*handler) (ctrl_p->bmRequestType, r = (*handler) (ctrl_p->bmRequestType,
ctrl_p->wValue, ctrl_p->wIndex, ctrl_p->wLength); ctrl_p->wValue, ctrl_p->wIndex, ctrl_p->wLength);
} }
} }
else else
r = (*method_p->setup) (ctrl_p->bmRequestType, req, r = usb_cb_setup (ctrl_p->bmRequestType, req,
ctrl_p->wValue, ctrl_p->wIndex, ctrl_p->wLength); ctrl_p->wValue, ctrl_p->wIndex, ctrl_p->wLength);
if (r != USB_SUCCESS) if (r != USB_SUCCESS)
@@ -890,10 +889,10 @@ static void handle_in0 (void)
== (STANDARD_REQUEST | DEVICE_RECIPIENT))) == (STANDARD_REQUEST | DEVICE_RECIPIENT)))
{ {
st103_set_daddr (ctrl_p->wValue); st103_set_daddr (ctrl_p->wValue);
(*method_p->event) (USB_EVENT_ADDRESS, ctrl_p->wValue); usb_cb_handle_event (USB_EVENT_ADDRESS, ctrl_p->wValue);
} }
else else
(*method_p->ctrl_write_finish) (ctrl_p->bmRequestType, usb_cb_ctrl_write_finish (ctrl_p->bmRequestType,
ctrl_p->bRequest, ctrl_p->wValue, ctrl_p->bRequest, ctrl_p->wValue,
ctrl_p->wIndex, ctrl_p->wLength); ctrl_p->wIndex, ctrl_p->wLength);
@@ -938,26 +937,6 @@ void WEAK EP5_OUT_Callback (void);
void WEAK EP6_OUT_Callback (void); void WEAK EP6_OUT_Callback (void);
void WEAK EP7_OUT_Callback (void); void WEAK EP7_OUT_Callback (void);
void (*const ep_intr_handler_IN[7]) (void) = {
EP1_IN_Callback,
EP2_IN_Callback,
EP3_IN_Callback,
EP4_IN_Callback,
EP5_IN_Callback,
EP6_IN_Callback,
EP7_IN_Callback,
};
void (*const ep_intr_handler_OUT[7]) (void) = {
EP1_OUT_Callback,
EP2_OUT_Callback,
EP3_OUT_Callback,
EP4_OUT_Callback,
EP5_OUT_Callback,
EP6_OUT_Callback,
EP7_OUT_Callback,
};
static void static void
usb_handle_transfer (void) usb_handle_transfer (void)
{ {
@@ -1008,13 +987,31 @@ usb_handle_transfer (void)
if ((ep_value & EP_CTR_RX) != 0) if ((ep_value & EP_CTR_RX) != 0)
{ {
st103_ep_clear_ctr_rx (ep_index); st103_ep_clear_ctr_rx (ep_index);
(*ep_intr_handler_OUT[ep_index-1]) (); switch ((ep_index - 1))
{
case 0: EP1_OUT_Callback (); break;
case 1: EP2_OUT_Callback (); break;
case 2: EP3_OUT_Callback (); break;
case 3: EP4_OUT_Callback (); break;
case 4: EP5_OUT_Callback (); break;
case 5: EP6_OUT_Callback (); break;
case 6: EP7_OUT_Callback (); break;
}
} }
if ((ep_value & EP_CTR_TX) != 0) if ((ep_value & EP_CTR_TX) != 0)
{ {
st103_ep_clear_ctr_tx (ep_index); st103_ep_clear_ctr_tx (ep_index);
(*ep_intr_handler_IN[ep_index-1]) (); switch ((ep_index - 1))
{
case 0: EP1_IN_Callback (); break;
case 1: EP2_IN_Callback (); break;
case 2: EP3_IN_Callback (); break;
case 3: EP4_IN_Callback (); break;
case 4: EP5_IN_Callback (); break;
case 5: EP6_IN_Callback (); break;
case 6: EP7_IN_Callback (); break;
}
} }
} }
} }