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 ();
usb_lld_init (Config_Descriptor.Descriptor[7]);
usb_lld_init (usb_initial_feature);
random_init ();
while (1)

View File

@ -1,7 +1,7 @@
/*
* 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>
*
* 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
}
static void
gnuk_device_reset (void)
void
usb_cb_device_reset (void)
{
int i;
@ -156,7 +156,7 @@ gnuk_device_reset (void)
usb_lld_set_configuration (0);
/* Current Feature initialization */
usb_lld_set_feature (Config_Descriptor.Descriptor[7]);
usb_lld_set_feature (usb_initial_feature);
usb_lld_reset ();
@ -214,9 +214,9 @@ static int download_check_crc32 (const uint32_t *end_p)
return USB_UNSUPPORT;
}
static int
gnuk_setup (uint8_t req, uint8_t req_no,
uint16_t value, uint16_t index, uint16_t len)
int
usb_cb_setup (uint8_t req, uint8_t req_no,
uint16_t value, uint16_t index, uint16_t len)
{
uint8_t type_rcp = req & (REQUEST_TYPE|RECIPIENT);
@ -310,9 +310,8 @@ gnuk_setup (uint8_t req, uint8_t req_no,
return USB_UNSUPPORT;
}
static void gnuk_ctrl_write_finish (uint8_t req, uint8_t req_no,
uint16_t value, uint16_t index,
uint16_t len)
void usb_cb_ctrl_write_finish (uint8_t req, uint8_t req_no, uint16_t value,
uint16_t index, uint16_t len)
{
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
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 usb_cb_handle_event (uint8_t event_type, uint16_t value)
{
int i;
uint8_t current_conf;
@ -401,7 +369,7 @@ static int gnuk_usb_event (uint8_t event_type, uint16_t value)
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;
@ -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)
{

View File

@ -9,6 +9,13 @@
#include "usb_conf.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_SUBCLASS 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)
#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 */
static const uint8_t gnukConfigDescriptor[] = {
9, /* bLength: Configuation Descriptor size */
@ -61,11 +77,7 @@ static const uint8_t gnukConfigDescriptor[] = {
NUM_INTERFACES, /* bNumInterfaces: */
0x01, /* bConfigurationValue: Configuration value */
0x00, /* iConfiguration: Index of string descriptor describing the configuration */
#if defined(USB_SELF_POWERED)
0xC0, /* bmAttributes: self powered */
#else
0x80, /* bmAttributes: bus powered */
#endif
USB_INITIAL_FEATURE, /* bmAttributes*/
50, /* MaxPower 100 mA */
/* Interface Descriptor */
@ -268,17 +280,17 @@ const uint8_t gnukStringSerial[] = {
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
};
const struct Descriptor Device_Descriptor = {
static const struct Descriptor Device_Descriptor = {
gnukDeviceDescriptor,
sizeof (gnukDeviceDescriptor)
};
const struct Descriptor Config_Descriptor = {
static const struct Descriptor Config_Descriptor = {
gnukConfigDescriptor,
sizeof (gnukConfigDescriptor)
};
const struct Descriptor String_Descriptors[NUM_STRING_DESC] = {
static const struct Descriptor String_Descriptors[NUM_STRING_DESC] = {
{gnukStringLangID, sizeof (gnukStringLangID)},
{gnukStringVendor, sizeof (gnukStringVendor)},
{gnukStringProduct, sizeof (gnukStringProduct)},
@ -287,3 +299,34 @@ const struct Descriptor String_Descriptors[NUM_STRING_DESC] = {
{gnuk_config_options, sizeof (gnuk_config_options)},
{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_GET(req) ((req & REQUEST_DIR) != 0)
struct Descriptor
{
const uint8_t *Descriptor;
uint16_t Descriptor_Size;
};
enum
{
USB_UNSUPPORT = 0,
USB_SUCCESS = 1,
};
struct usb_device_method
{
void (*reset) (void);
void (*ctrl_write_finish) (uint8_t req, uint8_t req_no,
uint16_t value, uint16_t index, uint16_t len);
int (*setup) (uint8_t req, uint8_t req_no,
uint16_t value, uint16_t index, uint16_t len);
int (*get_descriptor) (uint8_t desc_type, uint16_t index, uint16_t value);
int (*event) (uint8_t event_type, uint16_t value);
int (*interface) (uint8_t cmd, uint16_t interface, uint16_t value);
};
void usb_cb_device_reset (void);
void usb_cb_ctrl_write_finish (uint8_t req, uint8_t req_no,
uint16_t value, uint16_t index, uint16_t len);
int usb_cb_setup (uint8_t req, uint8_t req_no, uint16_t value,
uint16_t index, uint16_t len);
int usb_cb_get_descriptor (uint8_t desc_type, uint16_t index, uint16_t value);
int usb_cb_handle_event (uint8_t event_type, uint16_t value);
int usb_cb_interface (uint8_t cmd, uint16_t interface, uint16_t value);
enum {
USB_EVENT_ADDRESS,
@ -87,14 +78,6 @@ enum {
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
{
UNCONNECTED,
@ -106,6 +89,7 @@ enum DEVICE_STATE
};
extern uint32_t bDeviceState;
extern const uint8_t usb_initial_feature;
#define STM32_USB_IRQ_PRIORITY 11

View File

@ -74,12 +74,10 @@ struct DEVICE_INFO
static struct CONTROL_INFO control_info;
static struct DEVICE_INFO device_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 DEVICE_INFO *const dev_p = &device_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 PMA_ADDR (0x40006000UL) /* USB_IP Packet Memory Area base address */
@ -399,7 +397,7 @@ usb_interrupt_handler (void)
if (istr_value & ISTR_RESET)
{
st103_set_istr (CLR_RESET);
method_p->reset ();
usb_cb_device_reset ();
}
if (istr_value & ISTR_DOVR)
@ -529,7 +527,7 @@ static int std_get_status (uint8_t req,
if (dev_p->current_configuration == 0)
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)
return USB_UNSUPPORT;
@ -700,7 +698,7 @@ static int std_get_descriptor (uint8_t req, uint16_t value,
(void)length;
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;
}
@ -736,7 +734,7 @@ static int std_set_configuration (uint8_t req, uint16_t value,
{
int r;
r = (*method_p->event) (USB_EVENT_CONFIG, value);
r = usb_cb_handle_event (USB_EVENT_CONFIG, value);
if (r == 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)
return USB_UNSUPPORT;
return (*method_p->interface) (USB_GET_INTERFACE, index, 0);
return usb_cb_interface (USB_GET_INTERFACE, index, 0);
}
return USB_UNSUPPORT;
@ -784,7 +782,7 @@ static int std_set_interface (uint8_t req, uint16_t value,
if (dev_p->current_configuration != 0)
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)
return USB_SUCCESS;
}
@ -792,21 +790,6 @@ static int std_set_interface (uint8_t req, uint16_t value,
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)
{
@ -836,14 +819,30 @@ static void handle_setup0 (void)
{
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,
ctrl_p->wValue, ctrl_p->wIndex, ctrl_p->wLength);
}
}
else
r = (*method_p->setup) (ctrl_p->bmRequestType, req,
ctrl_p->wValue, ctrl_p->wIndex, ctrl_p->wLength);
r = usb_cb_setup (ctrl_p->bmRequestType, req,
ctrl_p->wValue, ctrl_p->wIndex, ctrl_p->wLength);
if (r != USB_SUCCESS)
dev_p->state = STALLED;
@ -890,12 +889,12 @@ static void handle_in0 (void)
== (STANDARD_REQUEST | DEVICE_RECIPIENT)))
{
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
(*method_p->ctrl_write_finish) (ctrl_p->bmRequestType,
ctrl_p->bRequest, ctrl_p->wValue,
ctrl_p->wIndex, ctrl_p->wLength);
usb_cb_ctrl_write_finish (ctrl_p->bmRequestType,
ctrl_p->bRequest, ctrl_p->wValue,
ctrl_p->wIndex, ctrl_p->wLength);
dev_p->state = STALLED;
}
@ -938,26 +937,6 @@ void WEAK EP5_OUT_Callback (void);
void WEAK EP6_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
usb_handle_transfer (void)
{
@ -1008,13 +987,31 @@ usb_handle_transfer (void)
if ((ep_value & EP_CTR_RX) != 0)
{
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)
{
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;
}
}
}
}