Merge branch 'martinmm'.

This commit is contained in:
Uwe Hermann
2010-12-29 15:12:23 +01:00
35 changed files with 2727 additions and 185 deletions

View File

@@ -163,18 +163,19 @@ static const char *usb_strings[] = {
"DEMO"
};
static int cdcacm_control_command(struct usb_setup_data *req,
void (**complete)(struct usb_setup_data *req))
static int cdcacm_control_request(struct usb_setup_data *req, u8 **buf,
u16 *len, void (**complete)(struct usb_setup_data *req))
{
(void)complete;
char buf[10];
struct usb_cdc_notification *notif = (void*)buf;
(void)buf;
switch(req->bRequest) {
case USB_CDC_REQ_SET_CONTROL_LINE_STATE:
case USB_CDC_REQ_SET_CONTROL_LINE_STATE: {
/* This Linux cdc_acm driver requires this to be implemented
* even though it's optional in the CDC spec, and we don't
* advertise it in the ACM functional descriptor. */
char buf[10];
struct usb_cdc_notification *notif = (void*)buf;
/* We echo signals back to host as notification */
notif->bmRequestType = 0xA1;
@@ -186,19 +187,9 @@ static int cdcacm_control_command(struct usb_setup_data *req,
buf[9] = 0;
//usbd_ep_write_packet(0x83, buf, 10);
return 1;
}
return 0;
}
static int cdcacm_control_write(struct usb_setup_data *req, u8 *buf, u16 len,
void (**complete)(struct usb_setup_data *req))
{
(void)complete;
(void)buf;
switch(req->bRequest) {
}
case USB_CDC_REQ_SET_LINE_CODING:
if(len < sizeof(struct usb_cdc_line_coding))
if(*len < sizeof(struct usb_cdc_line_coding))
return 0;
return 1;
@@ -226,8 +217,10 @@ static void cdcacm_set_config(u16 wValue)
usbd_ep_setup(0x82, USB_ENDPOINT_ATTR_BULK, 64, NULL);
usbd_ep_setup(0x83, USB_ENDPOINT_ATTR_INTERRUPT, 16, NULL);
usbd_register_control_command_callback(cdcacm_control_command);
usbd_register_control_write_callback(cdcacm_control_write);
usbd_register_control_callback(
USB_REQ_TYPE_CLASS | USB_REQ_TYPE_INTERFACE,
USB_REQ_TYPE_TYPE | USB_REQ_TYPE_RECIPIENT,
cdcacm_control_request);
}
int main(void)

View File

@@ -175,18 +175,26 @@ static void usbdfu_getstatus_complete(struct usb_setup_data *req)
}
}
static int usbdfu_control_command(struct usb_setup_data *req,
void (**complete)(struct usb_setup_data *req))
static int usbdfu_control_request(struct usb_setup_data *req, u8 **buf,
u16 *len, void (**complete)(struct usb_setup_data *req))
{
(void)complete;
if(req->bmRequestType != 0x21)
if((req->bmRequestType & 0x7F) != 0x21)
return 0; /* Only accept class request */
switch(req->bRequest) {
case DFU_DNLOAD:
usbdfu_state = STATE_DFU_MANIFEST_SYNC;
return 1;
if((len == NULL) || (*len == 0)) {
usbdfu_state = STATE_DFU_MANIFEST_SYNC;
return 1;
} else {
/* Copy download data for use on GET_STATUS */
prog.blocknum = req->wValue;
prog.len = *len;
memcpy(prog.buf, *buf, *len);
usbdfu_state = STATE_DFU_DNLOAD_SYNC;
return 1;
}
case DFU_CLRSTATUS:
/* Clear error and return to dfuIDLE */
if(usbdfu_state == STATE_DFU_ERROR)
@@ -196,19 +204,6 @@ static int usbdfu_control_command(struct usb_setup_data *req,
/* Abort returns to dfuIDLE state */
usbdfu_state = STATE_DFU_IDLE;
return 1;
}
return 0;
}
static int usbdfu_control_read(struct usb_setup_data *req, u8 **buf, u16 *len,
void (**complete)(struct usb_setup_data *req))
{
if(req->bmRequestType != 0xA1)
return 0; /* Only accept class request */
switch(req->bRequest) {
case DFU_UPLOAD:
/* Upload not supported for now */
return 0;
@@ -237,26 +232,6 @@ static int usbdfu_control_read(struct usb_setup_data *req, u8 **buf, u16 *len,
return 0;
}
static int usbdfu_control_write(struct usb_setup_data *req, u8 *buf, u16 len,
void (**complete)(struct usb_setup_data *req))
{
(void)complete;
if(req->bmRequestType != 0x21)
return 0; /* Only accept class request */
if(req->bRequest != DFU_DNLOAD)
return 0;
/* Copy download data for use on GET_STATUS */
prog.blocknum = req->wValue;
prog.len = len;
memcpy(prog.buf, buf, len);
usbdfu_state = STATE_DFU_DNLOAD_SYNC;
return 1;
}
int main(void)
{
rcc_peripheral_enable_clock(&RCC_APB2ENR, RCC_APB2ENR_IOPAEN);
@@ -284,9 +259,10 @@ int main(void)
usbd_init(&dev, &config, usb_strings);
usbd_set_control_buffer_size(sizeof(usbd_control_buffer));
usbd_register_control_command_callback(usbdfu_control_command);
usbd_register_control_write_callback(usbdfu_control_write);
usbd_register_control_read_callback(usbdfu_control_read);
usbd_register_control_callback(
USB_REQ_TYPE_CLASS | USB_REQ_TYPE_INTERFACE,
USB_REQ_TYPE_TYPE | USB_REQ_TYPE_RECIPIENT,
usbdfu_control_request);
gpio_set(GPIOA, GPIO15);
gpio_set_mode(GPIOA, GPIO_MODE_OUTPUT_2_MHZ,

View File

@@ -171,7 +171,7 @@ static const char *usb_strings[] = {
"DEMO",
};
static int hid_control_read(struct usb_setup_data *req, u8 **buf, u16 *len,
static int hid_control_request(struct usb_setup_data *req, u8 **buf, u16 *len,
void (**complete)(struct usb_setup_data *req))
{
(void)complete;
@@ -200,9 +200,12 @@ static void dfu_detach_complete(struct usb_setup_data *req)
scb_reset_core();
}
static int dfu_control_command(struct usb_setup_data *req,
static int dfu_control_request(struct usb_setup_data *req, u8 **buf, u16 *len,
void (**complete)(struct usb_setup_data *req))
{
(void)buf;
(void)len;
if((req->bmRequestType != 0x21) || (req->bRequest != DFU_DETACH))
return 0; /* Only accept class request */
@@ -218,9 +221,15 @@ static void hid_set_config(u16 wValue)
usbd_ep_setup(0x81, USB_ENDPOINT_ATTR_INTERRUPT, 4, NULL);
usbd_register_control_read_callback(hid_control_read);
usbd_register_control_callback(
USB_REQ_TYPE_STANDARD | USB_REQ_TYPE_INTERFACE,
USB_REQ_TYPE_TYPE | USB_REQ_TYPE_RECIPIENT,
hid_control_request);
#ifdef INCLUDE_DFU_INTERFACE
usbd_register_control_command_callback(dfu_control_command);
usbd_register_control_callback(
USB_REQ_TYPE_CLASS | USB_REQ_TYPE_INTERFACE,
USB_REQ_TYPE_TYPE | USB_REQ_TYPE_RECIPIENT,
dfu_control_request);
#endif
systick_set_clocksource(STK_CTRL_CLKSOURCE_AHB_DIV8);