diff --git a/examples/stm32/f1/lisa-m-1/usb_cdcacm/cdcacm.c b/examples/stm32/f1/lisa-m-1/usb_cdcacm/cdcacm.c index 7ef9b621..08efa466 100644 --- a/examples/stm32/f1/lisa-m-1/usb_cdcacm/cdcacm.c +++ b/examples/stm32/f1/lisa-m-1/usb_cdcacm/cdcacm.c @@ -164,11 +164,12 @@ static const char *usb_strings[] = { "DEMO", }; -static int cdcacm_control_request(struct usb_setup_data *req, u8 **buf, - u16 *len, void (**complete)(struct usb_setup_data *req)) +static int cdcacm_control_request(usbd_device *usbd_dev, struct usb_setup_data *req, u8 **buf, + u16 *len, void (**complete)(usbd_device *usbd_dev, struct usb_setup_data *req)) { (void)complete; (void)buf; + (void)usbd_dev; switch (req->bRequest) { case USB_CDC_REQ_SET_CONTROL_LINE_STATE: { @@ -200,15 +201,15 @@ static int cdcacm_control_request(struct usb_setup_data *req, u8 **buf, return 0; } -static void cdcacm_data_rx_cb(u8 ep) +static void cdcacm_data_rx_cb(usbd_device *usbd_dev, u8 ep) { (void)ep; char buf[64]; - int len = usbd_ep_read_packet(0x01, buf, 64); + int len = usbd_ep_read_packet(usbd_dev, 0x01, buf, 64); if (len) { - while (usbd_ep_write_packet(0x82, buf, len) == 0) + while (usbd_ep_write_packet(usbd_dev, 0x82, buf, len) == 0) ; buf[len] = 0; } @@ -216,15 +217,16 @@ static void cdcacm_data_rx_cb(u8 ep) gpio_toggle(GPIOC, GPIO5); } -static void cdcacm_set_config(u16 wValue) +static void cdcacm_set_config(usbd_device *usbd_dev, u16 wValue) { (void)wValue; - usbd_ep_setup(0x01, USB_ENDPOINT_ATTR_BULK, 64, cdcacm_data_rx_cb); - usbd_ep_setup(0x82, USB_ENDPOINT_ATTR_BULK, 64, NULL); - usbd_ep_setup(0x83, USB_ENDPOINT_ATTR_INTERRUPT, 16, NULL); + usbd_ep_setup(usbd_dev, 0x01, USB_ENDPOINT_ATTR_BULK, 64, cdcacm_data_rx_cb); + usbd_ep_setup(usbd_dev, 0x82, USB_ENDPOINT_ATTR_BULK, 64, NULL); + usbd_ep_setup(usbd_dev, 0x83, USB_ENDPOINT_ATTR_INTERRUPT, 16, NULL); usbd_register_control_callback( + usbd_dev, USB_REQ_TYPE_CLASS | USB_REQ_TYPE_INTERFACE, USB_REQ_TYPE_TYPE | USB_REQ_TYPE_RECIPIENT, cdcacm_control_request); @@ -234,6 +236,8 @@ int main(void) { int i; + usbd_device *usbd_dev; + rcc_clock_setup_in_hsi_out_48mhz(); rcc_peripheral_enable_clock(&RCC_APB2ENR, RCC_APB2ENR_IOPCEN); @@ -246,13 +250,13 @@ int main(void) gpio_set_mode(GPIOC, GPIO_MODE_OUTPUT_2_MHZ, GPIO_CNF_OUTPUT_PUSHPULL, GPIO5); - usbd_init(&stm32f107_usb_driver, &dev, &config, usb_strings); - usbd_register_set_config_callback(cdcacm_set_config); + usbd_dev = usbd_init(&stm32f107_usb_driver, &dev, &config, usb_strings); + usbd_register_set_config_callback(usbd_dev, cdcacm_set_config); for (i = 0; i < 0x800000; i++) __asm__("nop"); gpio_clear(GPIOC, GPIO2); while (1) - usbd_poll(); + usbd_poll(usbd_dev); } diff --git a/examples/stm32/f1/lisa-m-1/usb_dfu/usbdfu.c b/examples/stm32/f1/lisa-m-1/usb_dfu/usbdfu.c index 4ffc0a14..71a9ac5c 100644 --- a/examples/stm32/f1/lisa-m-1/usb_dfu/usbdfu.c +++ b/examples/stm32/f1/lisa-m-1/usb_dfu/usbdfu.c @@ -130,10 +130,11 @@ static u8 usbdfu_getstatus(u32 *bwPollTimeout) } } -static void usbdfu_getstatus_complete(struct usb_setup_data *req) +static void usbdfu_getstatus_complete(usbd_device *usbd_dev, struct usb_setup_data *req) { int i; (void)req; + (void)usbd_dev; switch (usbdfu_state) { case STATE_DFU_DNBUSY: @@ -166,9 +167,11 @@ static void usbdfu_getstatus_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)) +static int usbdfu_control_request(usbd_device *usbd_dev, struct usb_setup_data *req, u8 **buf, + u16 *len, void (**complete)(usbd_device *usbd_dev, struct usb_setup_data *req)) { + (void)usbd_dev; + if ((req->bmRequestType & 0x7F) != 0x21) return 0; /* Only accept class request. */ @@ -221,6 +224,8 @@ static int usbdfu_control_request(struct usb_setup_data *req, u8 **buf, int main(void) { + usbd_device *usbd_dev; + rcc_peripheral_enable_clock(&RCC_APB2ENR, RCC_APB2ENR_IOPAEN); if (!gpio_get(GPIOA, GPIO10)) { @@ -245,9 +250,10 @@ int main(void) gpio_set_mode(GPIOC, GPIO_MODE_OUTPUT_50_MHZ, GPIO_CNF_OUTPUT_PUSHPULL, GPIO2); - usbd_init(&stm32f107_usb_driver, &dev, &config, usb_strings); - usbd_set_control_buffer_size(sizeof(usbd_control_buffer)); + usbd_dev = usbd_init(&stm32f107_usb_driver, &dev, &config, usb_strings); + usbd_set_control_buffer_size(usbd_dev, sizeof(usbd_control_buffer)); usbd_register_control_callback( + usbd_dev, USB_REQ_TYPE_CLASS | USB_REQ_TYPE_INTERFACE, USB_REQ_TYPE_TYPE | USB_REQ_TYPE_RECIPIENT, usbdfu_control_request); @@ -255,5 +261,5 @@ int main(void) gpio_clear(GPIOC, GPIO2); while (1) - usbd_poll(); + usbd_poll(usbd_dev); } diff --git a/examples/stm32/f1/lisa-m-1/usb_hid/usbhid.c b/examples/stm32/f1/lisa-m-1/usb_hid/usbhid.c index 8d83896d..9ef3f564 100644 --- a/examples/stm32/f1/lisa-m-1/usb_hid/usbhid.c +++ b/examples/stm32/f1/lisa-m-1/usb_hid/usbhid.c @@ -36,6 +36,8 @@ #include #endif +static usbd_device *usbd_dev; + const struct usb_device_descriptor dev = { .bLength = USB_DT_DEVICE_SIZE, .bDescriptorType = USB_DT_DEVICE, @@ -173,10 +175,11 @@ static const char *usb_strings[] = { "DEMO", }; -static int hid_control_request(struct usb_setup_data *req, u8 **buf, u16 *len, - void (**complete)(struct usb_setup_data *req)) +static int hid_control_request(usbd_device *usbd_dev, struct usb_setup_data *req, u8 **buf, u16 *len, + void (**complete)(usbd_device *usbd_dev, struct usb_setup_data *req)) { (void)complete; + (void)usbd_dev; if((req->bmRequestType != 0x81) || (req->bRequest != USB_REQ_GET_DESCRIPTOR) || @@ -191,9 +194,10 @@ static int hid_control_request(struct usb_setup_data *req, u8 **buf, u16 *len, } #ifdef INCLUDE_DFU_INTERFACE -static void dfu_detach_complete(struct usb_setup_data *req) +static void dfu_detach_complete(usbd_device *usbd_dev, struct usb_setup_data *req) { (void)req; + (void)usbd_dev; gpio_set_mode(GPIOA, GPIO_MODE_INPUT, 0, GPIO15); gpio_set_mode(GPIOA, GPIO_MODE_OUTPUT_2_MHZ, @@ -202,11 +206,12 @@ static void dfu_detach_complete(struct usb_setup_data *req) scb_reset_core(); } -static int dfu_control_request(struct usb_setup_data *req, u8 **buf, u16 *len, - void (**complete)(struct usb_setup_data *req)) +static int dfu_control_request(usbd_device *usbd_dev, struct usb_setup_data *req, u8 **buf, u16 *len, + void (**complete)(usbd_device *usbd_dev, struct usb_setup_data *req)) { (void)buf; (void)len; + (void)usbd_dev; if ((req->bmRequestType != 0x21) || (req->bRequest != DFU_DETACH)) return 0; /* Only accept class request. */ @@ -217,18 +222,20 @@ static int dfu_control_request(struct usb_setup_data *req, u8 **buf, u16 *len, } #endif -static void hid_set_config(u16 wValue) +static void hid_set_config(usbd_device *usbd_dev, u16 wValue) { (void)wValue; - usbd_ep_setup(0x81, USB_ENDPOINT_ATTR_INTERRUPT, 4, NULL); + usbd_ep_setup(usbd_dev, 0x81, USB_ENDPOINT_ATTR_INTERRUPT, 4, NULL); usbd_register_control_callback( + usbd_dev, 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_callback( + usbd_dev, USB_REQ_TYPE_CLASS | USB_REQ_TYPE_INTERFACE, USB_REQ_TYPE_TYPE | USB_REQ_TYPE_RECIPIENT, dfu_control_request); @@ -329,8 +336,8 @@ int main(void) gpio_set_mode(GPIOC, GPIO_MODE_OUTPUT_2_MHZ, GPIO_CNF_OUTPUT_PUSHPULL, GPIO2); - usbd_init(&stm32f107_usb_driver, &dev, &config, usb_strings); - usbd_register_set_config_callback(hid_set_config); + usbd_dev = usbd_init(&stm32f107_usb_driver, &dev, &config, usb_strings); + usbd_register_set_config_callback(usbd_dev, hid_set_config); /* Delay some seconds to show that pull-up switch works. */ for (i = 0; i < 0x800000; i++) @@ -345,7 +352,7 @@ int main(void) // OTG_FS_GCCFG &= ~OTG_FS_GCCFG_VBUSBSEN; while (1) - usbd_poll(); + usbd_poll(usbd_dev); } void sys_tick_handler(void) @@ -357,5 +364,5 @@ void sys_tick_handler(void) buf[1] = x >> 9; buf[2] = y >> 9; - usbd_ep_write_packet(0x81, buf, 4); + usbd_ep_write_packet(usbd_dev, 0x81, buf, 4); } diff --git a/examples/stm32/f1/other/usb_cdcacm/cdcacm.c b/examples/stm32/f1/other/usb_cdcacm/cdcacm.c index 2038664d..81250b5b 100644 --- a/examples/stm32/f1/other/usb_cdcacm/cdcacm.c +++ b/examples/stm32/f1/other/usb_cdcacm/cdcacm.c @@ -164,11 +164,12 @@ static const char *usb_strings[] = { "DEMO", }; -static int cdcacm_control_request(struct usb_setup_data *req, u8 **buf, - u16 *len, void (**complete)(struct usb_setup_data *req)) +static int cdcacm_control_request(usbd_device *usbd_dev, struct usb_setup_data *req, u8 **buf, + u16 *len, void (**complete)(usbd_device *usbd_dev, struct usb_setup_data *req)) { (void)complete; (void)buf; + (void)usbd_dev; switch(req->bRequest) { case USB_CDC_REQ_SET_CONTROL_LINE_STATE: { @@ -200,28 +201,29 @@ static int cdcacm_control_request(struct usb_setup_data *req, u8 **buf, return 0; } -static void cdcacm_data_rx_cb(u8 ep) +static void cdcacm_data_rx_cb(usbd_device *usbd_dev, u8 ep) { (void)ep; char buf[64]; - int len = usbd_ep_read_packet(0x01, buf, 64); + int len = usbd_ep_read_packet(usbd_dev, 0x01, buf, 64); if (len) { - usbd_ep_write_packet(0x82, buf, len); + usbd_ep_write_packet(usbd_dev, 0x82, buf, len); buf[len] = 0; } } -static void cdcacm_set_config(u16 wValue) +static void cdcacm_set_config(usbd_device *usbd_dev, u16 wValue) { (void)wValue; - usbd_ep_setup(0x01, USB_ENDPOINT_ATTR_BULK, 64, cdcacm_data_rx_cb); - usbd_ep_setup(0x82, USB_ENDPOINT_ATTR_BULK, 64, NULL); - usbd_ep_setup(0x83, USB_ENDPOINT_ATTR_INTERRUPT, 16, NULL); + usbd_ep_setup(usbd_dev, 0x01, USB_ENDPOINT_ATTR_BULK, 64, cdcacm_data_rx_cb); + usbd_ep_setup(usbd_dev, 0x82, USB_ENDPOINT_ATTR_BULK, 64, NULL); + usbd_ep_setup(usbd_dev, 0x83, USB_ENDPOINT_ATTR_INTERRUPT, 16, NULL); usbd_register_control_callback( + usbd_dev, USB_REQ_TYPE_CLASS | USB_REQ_TYPE_INTERFACE, USB_REQ_TYPE_TYPE | USB_REQ_TYPE_RECIPIENT, cdcacm_control_request); @@ -229,6 +231,8 @@ static void cdcacm_set_config(u16 wValue) int main(void) { + usbd_device *usbd_dev; + rcc_clock_setup_in_hsi_out_48mhz(); rcc_peripheral_enable_clock(&RCC_APB2ENR, RCC_APB2ENR_IOPAEN); @@ -238,13 +242,13 @@ int main(void) gpio_set_mode(GPIOA, GPIO_MODE_INPUT, 0, GPIO15); - usbd_init(&stm32f103_usb_driver, &dev, &config, usb_strings); - usbd_register_set_config_callback(cdcacm_set_config); + usbd_dev = usbd_init(&stm32f103_usb_driver, &dev, &config, usb_strings); + usbd_register_set_config_callback(usbd_dev, cdcacm_set_config); gpio_set(GPIOA, GPIO15); gpio_set_mode(GPIOA, GPIO_MODE_OUTPUT_2_MHZ, GPIO_CNF_OUTPUT_PUSHPULL, GPIO15); while (1) - usbd_poll(); + usbd_poll(usbd_dev); } diff --git a/examples/stm32/f1/other/usb_dfu/usbdfu.c b/examples/stm32/f1/other/usb_dfu/usbdfu.c index 0211a47e..5347c9d2 100644 --- a/examples/stm32/f1/other/usb_dfu/usbdfu.c +++ b/examples/stm32/f1/other/usb_dfu/usbdfu.c @@ -130,10 +130,11 @@ static u8 usbdfu_getstatus(u32 *bwPollTimeout) } } -static void usbdfu_getstatus_complete(struct usb_setup_data *req) +static void usbdfu_getstatus_complete(usbd_device *usbd_dev, struct usb_setup_data *req) { int i; (void)req; + (void)usbd_dev; switch (usbdfu_state) { case STATE_DFU_DNBUSY: @@ -166,9 +167,11 @@ static void usbdfu_getstatus_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)) +static int usbdfu_control_request(usbd_device *usbd_dev, struct usb_setup_data *req, u8 **buf, + u16 *len, void (**complete)(usbd_device *usbd_dev, struct usb_setup_data *req)) { + (void)usbd_dev; + if ((req->bmRequestType & 0x7F) != 0x21) return 0; /* Only accept class request. */ @@ -221,6 +224,8 @@ static int usbdfu_control_request(struct usb_setup_data *req, u8 **buf, int main(void) { + usbd_device *usbd_dev; + rcc_peripheral_enable_clock(&RCC_APB2ENR, RCC_APB2ENR_IOPAEN); if (!gpio_get(GPIOA, GPIO10)) { @@ -244,9 +249,10 @@ int main(void) AFIO_MAPR |= AFIO_MAPR_SWJ_CFG_JTAG_OFF_SW_ON; gpio_set_mode(GPIOA, GPIO_MODE_INPUT, 0, GPIO15); - usbd_init(&stm32f107_usb_driver, &dev, &config, usb_strings); - usbd_set_control_buffer_size(sizeof(usbd_control_buffer)); + usbd_dev = usbd_init(&stm32f107_usb_driver, &dev, &config, usb_strings); + usbd_set_control_buffer_size(usbd_dev, sizeof(usbd_control_buffer)); usbd_register_control_callback( + usbd_dev, USB_REQ_TYPE_CLASS | USB_REQ_TYPE_INTERFACE, USB_REQ_TYPE_TYPE | USB_REQ_TYPE_RECIPIENT, usbdfu_control_request); @@ -256,5 +262,5 @@ int main(void) GPIO_CNF_OUTPUT_PUSHPULL, GPIO15); while (1) - usbd_poll(); + usbd_poll(usbd_dev); } diff --git a/examples/stm32/f1/other/usb_hid/usbhid.c b/examples/stm32/f1/other/usb_hid/usbhid.c index dd3c57a8..d681da42 100644 --- a/examples/stm32/f1/other/usb_hid/usbhid.c +++ b/examples/stm32/f1/other/usb_hid/usbhid.c @@ -32,6 +32,8 @@ #include #endif +static usbd_device *usbd_dev; + const struct usb_device_descriptor dev = { .bLength = USB_DT_DEVICE_SIZE, .bDescriptorType = USB_DT_DEVICE, @@ -169,10 +171,11 @@ static const char *usb_strings[] = { "DEMO", }; -static int hid_control_request(struct usb_setup_data *req, u8 **buf, u16 *len, - void (**complete)(struct usb_setup_data *req)) +static int hid_control_request(usbd_device *usbd_dev, struct usb_setup_data *req, u8 **buf, u16 *len, + void (**complete)(usbd_device *usbd_dev, struct usb_setup_data *req)) { (void)complete; + (void)usbd_dev; if((req->bmRequestType != 0x81) || (req->bRequest != USB_REQ_GET_DESCRIPTOR) || @@ -187,9 +190,10 @@ static int hid_control_request(struct usb_setup_data *req, u8 **buf, u16 *len, } #ifdef INCLUDE_DFU_INTERFACE -static void dfu_detach_complete(struct usb_setup_data *req) +static void dfu_detach_complete(usbd_device *usbd_dev, struct usb_setup_data *req) { (void)req; + (void)usbd_dev; gpio_set_mode(GPIOA, GPIO_MODE_INPUT, 0, GPIO15); gpio_set_mode(GPIOA, GPIO_MODE_OUTPUT_2_MHZ, @@ -198,11 +202,12 @@ static void dfu_detach_complete(struct usb_setup_data *req) scb_reset_core(); } -static int dfu_control_request(struct usb_setup_data *req, u8 **buf, u16 *len, - void (**complete)(struct usb_setup_data *req)) +static int dfu_control_request(usbd_device *usbd_dev, struct usb_setup_data *req, u8 **buf, u16 *len, + void (**complete)(usbd_device *usbd_dev, struct usb_setup_data *req)) { (void)buf; (void)len; + (void)usbd_dev; if ((req->bmRequestType != 0x21) || (req->bRequest != DFU_DETACH)) return 0; /* Only accept class request. */ @@ -213,18 +218,21 @@ static int dfu_control_request(struct usb_setup_data *req, u8 **buf, u16 *len, } #endif -static void hid_set_config(u16 wValue) +static void hid_set_config(usbd_device *usbd_dev, u16 wValue) { (void)wValue; + (void)usbd_dev; - usbd_ep_setup(0x81, USB_ENDPOINT_ATTR_INTERRUPT, 4, NULL); + usbd_ep_setup(usbd_dev, 0x81, USB_ENDPOINT_ATTR_INTERRUPT, 4, NULL); usbd_register_control_callback( + usbd_dev, 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_callback( + usbd_dev, USB_REQ_TYPE_CLASS | USB_REQ_TYPE_INTERFACE, USB_REQ_TYPE_TYPE | USB_REQ_TYPE_RECIPIENT, dfu_control_request); @@ -246,15 +254,15 @@ int main(void) AFIO_MAPR |= AFIO_MAPR_SWJ_CFG_JTAG_OFF_SW_ON; gpio_set_mode(GPIOA, GPIO_MODE_INPUT, 0, GPIO15); - usbd_init(&stm32f103_usb_driver, &dev, &config, usb_strings); - usbd_register_set_config_callback(hid_set_config); + usbd_dev = usbd_init(&stm32f103_usb_driver, &dev, &config, usb_strings); + usbd_register_set_config_callback(usbd_dev, hid_set_config); gpio_set(GPIOA, GPIO15); gpio_set_mode(GPIOA, GPIO_MODE_OUTPUT_2_MHZ, GPIO_CNF_OUTPUT_PUSHPULL, GPIO15); while (1) - usbd_poll(); + usbd_poll(usbd_dev); } void sys_tick_handler(void) @@ -270,5 +278,5 @@ void sys_tick_handler(void) if (x < -30) dir = -dir; - usbd_ep_write_packet(0x81, buf, 4); + usbd_ep_write_packet(usbd_dev, 0x81, buf, 4); } diff --git a/examples/stm32/f1/stm32-h103/usb_cdcacm/cdcacm.c b/examples/stm32/f1/stm32-h103/usb_cdcacm/cdcacm.c index 779f6595..3d25c296 100644 --- a/examples/stm32/f1/stm32-h103/usb_cdcacm/cdcacm.c +++ b/examples/stm32/f1/stm32-h103/usb_cdcacm/cdcacm.c @@ -41,7 +41,7 @@ static const struct usb_device_descriptor dev = { }; /* - * This notification endpoint isn't implemented. According to CDC spec its + * This notification endpoint isn't implemented. According to CDC spec its * optional, but its absence causes a NULL pointer dereference in Linux * cdc_acm driver. */ @@ -83,7 +83,7 @@ static const struct { .bcdCDC = 0x0110, }, .call_mgmt = { - .bFunctionLength = + .bFunctionLength = sizeof(struct usb_cdc_call_management_descriptor), .bDescriptorType = CS_INTERFACE, .bDescriptorSubtype = USB_CDC_TYPE_CALL_MANAGEMENT, @@ -101,7 +101,7 @@ static const struct { .bDescriptorType = CS_INTERFACE, .bDescriptorSubtype = USB_CDC_TYPE_UNION, .bControlInterface = 0, - .bSubordinateInterface0 = 1, + .bSubordinateInterface0 = 1, }, }; @@ -164,11 +164,12 @@ static const char *usb_strings[] = { "DEMO", }; -static int cdcacm_control_request(struct usb_setup_data *req, u8 **buf, - u16 *len, void (**complete)(struct usb_setup_data *req)) +static int cdcacm_control_request(usbd_device *usbd_dev, struct usb_setup_data *req, u8 **buf, + u16 *len, void (**complete)(usbd_device *usbd_dev, struct usb_setup_data *req)) { (void)complete; (void)buf; + (void)usbd_dev; switch (req->bRequest) { case USB_CDC_REQ_SET_CONTROL_LINE_STATE: { @@ -199,28 +200,31 @@ static int cdcacm_control_request(struct usb_setup_data *req, u8 **buf, return 0; } -static void cdcacm_data_rx_cb(u8 ep) +static void cdcacm_data_rx_cb(usbd_device *usbd_dev, u8 ep) { (void)ep; + (void)usbd_dev; char buf[64]; - int len = usbd_ep_read_packet(0x01, buf, 64); + int len = usbd_ep_read_packet(usbd_dev, 0x01, buf, 64); if (len) { - usbd_ep_write_packet(0x82, buf, len); + usbd_ep_write_packet(usbd_dev, 0x82, buf, len); buf[len] = 0; } } -static void cdcacm_set_config(u16 wValue) +static void cdcacm_set_config(usbd_device *usbd_dev, u16 wValue) { (void)wValue; + (void)usbd_dev; - usbd_ep_setup(0x01, USB_ENDPOINT_ATTR_BULK, 64, cdcacm_data_rx_cb); - usbd_ep_setup(0x82, USB_ENDPOINT_ATTR_BULK, 64, NULL); - usbd_ep_setup(0x83, USB_ENDPOINT_ATTR_INTERRUPT, 16, NULL); + usbd_ep_setup(usbd_dev, 0x01, USB_ENDPOINT_ATTR_BULK, 64, cdcacm_data_rx_cb); + usbd_ep_setup(usbd_dev, 0x82, USB_ENDPOINT_ATTR_BULK, 64, NULL); + usbd_ep_setup(usbd_dev, 0x83, USB_ENDPOINT_ATTR_INTERRUPT, 16, NULL); usbd_register_control_callback( + usbd_dev, USB_REQ_TYPE_CLASS | USB_REQ_TYPE_INTERFACE, USB_REQ_TYPE_TYPE | USB_REQ_TYPE_RECIPIENT, cdcacm_control_request); @@ -230,6 +234,8 @@ int main(void) { int i; + usbd_device *usbd_dev; + rcc_clock_setup_in_hsi_out_48mhz(); rcc_peripheral_enable_clock(&RCC_APB2ENR, RCC_APB2ENR_IOPCEN); @@ -238,13 +244,13 @@ int main(void) gpio_set_mode(GPIOC, GPIO_MODE_OUTPUT_2_MHZ, GPIO_CNF_OUTPUT_PUSHPULL, GPIO11); - usbd_init(&stm32f103_usb_driver, &dev, &config, usb_strings); - usbd_register_set_config_callback(cdcacm_set_config); + usbd_dev = usbd_init(&stm32f103_usb_driver, &dev, &config, usb_strings); + usbd_register_set_config_callback(usbd_dev, cdcacm_set_config); for (i = 0; i < 0x800000; i++) __asm__("nop"); gpio_clear(GPIOC, GPIO11); while (1) - usbd_poll(); + usbd_poll(usbd_dev); } diff --git a/examples/stm32/f1/stm32-h103/usb_dfu/usbdfu.c b/examples/stm32/f1/stm32-h103/usb_dfu/usbdfu.c index 49f265b9..6282c4b1 100644 --- a/examples/stm32/f1/stm32-h103/usb_dfu/usbdfu.c +++ b/examples/stm32/f1/stm32-h103/usb_dfu/usbdfu.c @@ -114,8 +114,10 @@ static const char *usb_strings[] = { "@Internal Flash /0x08000000/8*001Ka,56*001Kg", }; -static u8 usbdfu_getstatus(u32 *bwPollTimeout) +static u8 usbdfu_getstatus(usbd_device *usbd_dev, u32 *bwPollTimeout) { + (void)usbd_dev; + switch (usbdfu_state) { case STATE_DFU_DNLOAD_SYNC: usbdfu_state = STATE_DFU_DNBUSY; @@ -130,10 +132,11 @@ static u8 usbdfu_getstatus(u32 *bwPollTimeout) } } -static void usbdfu_getstatus_complete(struct usb_setup_data *req) +static void usbdfu_getstatus_complete(usbd_device *usbd_dev, struct usb_setup_data *req) { int i; (void)req; + (void)usbd_dev; switch (usbdfu_state) { case STATE_DFU_DNBUSY: @@ -166,8 +169,8 @@ static void usbdfu_getstatus_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)) +static int usbdfu_control_request(usbd_device *usbd_dev, struct usb_setup_data *req, u8 **buf, + u16 *len, void (**complete)(usbd_device *usbd_dev, struct usb_setup_data *req)) { if ((req->bmRequestType & 0x7F) != 0x21) return 0; /* Only accept class request. */ @@ -199,7 +202,7 @@ static int usbdfu_control_request(struct usb_setup_data *req, u8 **buf, return 0; case DFU_GETSTATUS: { u32 bwPollTimeout = 0; /* 24-bit integer in DFU class spec */ - (*buf)[0] = usbdfu_getstatus(&bwPollTimeout); + (*buf)[0] = usbdfu_getstatus(usbd_dev, &bwPollTimeout); (*buf)[1] = bwPollTimeout & 0xFF; (*buf)[2] = (bwPollTimeout >> 8) & 0xFF; (*buf)[3] = (bwPollTimeout >> 16) & 0xFF; @@ -221,6 +224,8 @@ static int usbdfu_control_request(struct usb_setup_data *req, u8 **buf, int main(void) { + usbd_device *usbd_dev; + rcc_peripheral_enable_clock(&RCC_APB2ENR, RCC_APB2ENR_IOPAEN); if (!gpio_get(GPIOA, GPIO10)) { @@ -244,9 +249,10 @@ int main(void) GPIO_CNF_OUTPUT_PUSHPULL, GPIO11); gpio_set(GPIOC, GPIO11); - usbd_init(&stm32f103_usb_driver, &dev, &config, usb_strings); - usbd_set_control_buffer_size(sizeof(usbd_control_buffer)); + usbd_dev = usbd_init(&stm32f103_usb_driver, &dev, &config, usb_strings); + usbd_set_control_buffer_size(usbd_dev, sizeof(usbd_control_buffer)); usbd_register_control_callback( + usbd_dev, USB_REQ_TYPE_CLASS | USB_REQ_TYPE_INTERFACE, USB_REQ_TYPE_TYPE | USB_REQ_TYPE_RECIPIENT, usbdfu_control_request); @@ -254,5 +260,5 @@ int main(void) gpio_clear(GPIOC, GPIO11); while (1) - usbd_poll(); + usbd_poll(usbd_dev); } diff --git a/examples/stm32/f1/stm32-h103/usb_hid/usbhid.c b/examples/stm32/f1/stm32-h103/usb_hid/usbhid.c index 9ed40d13..558e68d5 100644 --- a/examples/stm32/f1/stm32-h103/usb_hid/usbhid.c +++ b/examples/stm32/f1/stm32-h103/usb_hid/usbhid.c @@ -169,10 +169,11 @@ static const char *usb_strings[] = { "DEMO", }; -static int hid_control_request(struct usb_setup_data *req, u8 **buf, u16 *len, - void (**complete)(struct usb_setup_data *req)) +static int hid_control_request(usbd_device *usbd_dev, struct usb_setup_data *req, u8 **buf, u16 *len, + void (**complete)(usbd_device *usbd_dev, struct usb_setup_data *req)) { (void)complete; + (void)usbd_dev; if ((req->bmRequestType != 0x81) || (req->bRequest != USB_REQ_GET_DESCRIPTOR) || @@ -187,9 +188,10 @@ static int hid_control_request(struct usb_setup_data *req, u8 **buf, u16 *len, } #ifdef INCLUDE_DFU_INTERFACE -static void dfu_detach_complete(struct usb_setup_data *req) +static void dfu_detach_complete(usbd_device *usbd_dev, struct usb_setup_data *req) { (void)req; + (void)usbd_dev; gpio_set_mode(GPIOA, GPIO_MODE_INPUT, 0, GPIO15); gpio_set_mode(GPIOA, GPIO_MODE_OUTPUT_2_MHZ, @@ -198,11 +200,12 @@ static void dfu_detach_complete(struct usb_setup_data *req) scb_reset_core(); } -static int dfu_control_request(struct usb_setup_data *req, u8 **buf, u16 *len, - void (**complete)(struct usb_setup_data *req)) +static int dfu_control_request(usbd_device *usbd_dev, struct usb_setup_data *req, u8 **buf, u16 *len, + void (**complete)(usbd_device *usbd_dev, struct usb_setup_data *req)) { (void)buf; (void)len; + (void)usbd_dev; if ((req->bmRequestType != 0x21) || (req->bRequest != DFU_DETACH)) return 0; /* Only accept class request. */ @@ -213,18 +216,21 @@ static int dfu_control_request(struct usb_setup_data *req, u8 **buf, u16 *len, } #endif -static void hid_set_config(u16 wValue) +static void hid_set_config(usbd_device *usbd_dev, u16 wValue) { (void)wValue; + (void)usbd_dev; - usbd_ep_setup(0x81, USB_ENDPOINT_ATTR_INTERRUPT, 4, NULL); + usbd_ep_setup(usbd_dev, 0x81, USB_ENDPOINT_ATTR_INTERRUPT, 4, NULL); usbd_register_control_callback( + usbd_dev, 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_callback( + usbd_dev, USB_REQ_TYPE_CLASS | USB_REQ_TYPE_INTERFACE, USB_REQ_TYPE_TYPE | USB_REQ_TYPE_RECIPIENT, dfu_control_request); @@ -240,6 +246,8 @@ int main(void) { int i; + usbd_device *usbd_dev; + rcc_clock_setup_in_hsi_out_48mhz(); rcc_peripheral_enable_clock(&RCC_APB2ENR, RCC_APB2ENR_IOPCEN); @@ -248,8 +256,8 @@ int main(void) gpio_set_mode(GPIOC, GPIO_MODE_OUTPUT_2_MHZ, GPIO_CNF_OUTPUT_PUSHPULL, GPIO11); - usbd_init(&stm32f103_usb_driver, &dev, &config, usb_strings); - usbd_register_set_config_callback(hid_set_config); + usbd_dev = usbd_init(&stm32f103_usb_driver, &dev, &config, usb_strings); + usbd_register_set_config_callback(usbd_dev, hid_set_config); for (i = 0; i < 0x80000; i++) __asm__("nop"); @@ -257,9 +265,10 @@ int main(void) gpio_clear(GPIOC, GPIO11); while (1) - usbd_poll(); + usbd_poll(usbd_dev); } +#if 0 /* is this used? */ void sys_tick_handler(void) { static int x = 0; @@ -273,5 +282,6 @@ void sys_tick_handler(void) if (x < -30) dir = -dir; - usbd_ep_write_packet(0x81, buf, 4); + usbd_ep_write_packet(usbd_dev, 0x81, buf, 4); } +#endif diff --git a/examples/stm32/f1/stm32-h103/usb_iap/usbiap.c b/examples/stm32/f1/stm32-h103/usb_iap/usbiap.c index c5cc8ba0..de3d6a39 100644 --- a/examples/stm32/f1/stm32-h103/usb_iap/usbiap.c +++ b/examples/stm32/f1/stm32-h103/usb_iap/usbiap.c @@ -114,8 +114,10 @@ static const char *usb_strings[] = { "@Internal Flash /0x08000000/8*001Ka,56*001Kg", }; -static u8 usbdfu_getstatus(u32 *bwPollTimeout) +static u8 usbdfu_getstatus(usbd_device *usbd_dev, u32 *bwPollTimeout) { + (void)usbd_dev; + switch (usbdfu_state) { case STATE_DFU_DNLOAD_SYNC: usbdfu_state = STATE_DFU_DNBUSY; @@ -130,10 +132,11 @@ static u8 usbdfu_getstatus(u32 *bwPollTimeout) } } -static void usbdfu_getstatus_complete(struct usb_setup_data *req) +static void usbdfu_getstatus_complete(usbd_device *usbd_dev, struct usb_setup_data *req) { int i; (void)req; + (void)usbd_dev; switch (usbdfu_state) { case STATE_DFU_DNBUSY: @@ -166,8 +169,8 @@ static void usbdfu_getstatus_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)) +static int usbdfu_control_request(usbd_device *usbd_dev, struct usb_setup_data *req, u8 **buf, + u16 *len, void (**complete)(usbd_device *usbd_dev, struct usb_setup_data *req)) { if ((req->bmRequestType & 0x7F) != 0x21) return 0; /* Only accept class request. */ @@ -199,7 +202,7 @@ static int usbdfu_control_request(struct usb_setup_data *req, u8 **buf, return 0; case DFU_GETSTATUS: { u32 bwPollTimeout = 0; /* 24-bit integer in DFU class spec */ - (*buf)[0] = usbdfu_getstatus(&bwPollTimeout); + (*buf)[0] = usbdfu_getstatus(usbd_dev, &bwPollTimeout); (*buf)[1] = bwPollTimeout & 0xFF; (*buf)[2] = (bwPollTimeout >> 8) & 0xFF; (*buf)[3] = (bwPollTimeout >> 16) & 0xFF; @@ -221,6 +224,8 @@ static int usbdfu_control_request(struct usb_setup_data *req, u8 **buf, int main(void) { + usbd_device *usbd_dev; + rcc_peripheral_enable_clock(&RCC_APB2ENR, RCC_APB2ENR_IOPAEN); if (!gpio_get(GPIOA, GPIO10)) { @@ -244,9 +249,10 @@ int main(void) AFIO_MAPR |= AFIO_MAPR_SWJ_CFG_JTAG_OFF_SW_ON; gpio_set_mode(GPIOA, GPIO_MODE_INPUT, 0, GPIO15); - usbd_init(&stm32f103_usb_driver, &dev, &config, usb_strings); - usbd_set_control_buffer_size(sizeof(usbd_control_buffer)); + usbd_dev = usbd_init(&stm32f103_usb_driver, &dev, &config, usb_strings); + usbd_set_control_buffer_size(usbd_dev, sizeof(usbd_control_buffer)); usbd_register_control_callback( + usbd_dev, USB_REQ_TYPE_CLASS | USB_REQ_TYPE_INTERFACE, USB_REQ_TYPE_TYPE | USB_REQ_TYPE_RECIPIENT, usbdfu_control_request); @@ -256,5 +262,5 @@ int main(void) GPIO_CNF_OUTPUT_PUSHPULL, GPIO15); while (1) - usbd_poll(); + usbd_poll(usbd_dev); } diff --git a/examples/stm32/f1/stm32-h107/usb_simple/usb_simple.c b/examples/stm32/f1/stm32-h107/usb_simple/usb_simple.c index e9a52b23..fc0aecd8 100644 --- a/examples/stm32/f1/stm32-h107/usb_simple/usb_simple.c +++ b/examples/stm32/f1/stm32-h107/usb_simple/usb_simple.c @@ -75,16 +75,17 @@ const char *usb_strings[] = { "1001", }; -static int simple_control_callback(struct usb_setup_data *req, u8 **buf, - u16 *len, void (**complete)(struct usb_setup_data *req)) +static int simple_control_callback(usbd_device *usbd_dev, struct usb_setup_data *req, u8 **buf, + u16 *len, void (**complete)(usbd_device *usbd_dev, struct usb_setup_data *req)) { (void)buf; (void)len; (void)complete; + (void)usbd_dev; if (req->bmRequestType != 0x40) return 0; /* Only accept vendor request. */ - + if (req->wValue & 1) gpio_set(GPIOC, GPIO6); else @@ -95,6 +96,8 @@ static int simple_control_callback(struct usb_setup_data *req, u8 **buf, int main(void) { + usbd_device *usbd_dev; + rcc_clock_setup_in_hse_8mhz_out_72mhz(); rcc_peripheral_enable_clock(&RCC_APB2ENR, RCC_APB2ENR_IOPAEN); @@ -105,13 +108,14 @@ int main(void) gpio_set_mode(GPIOC, GPIO_MODE_OUTPUT_2_MHZ, GPIO_CNF_OUTPUT_PUSHPULL, GPIO6); - usbd_init(&stm32f107_usb_driver, &dev, &config, usb_strings); + usbd_dev = usbd_init(&stm32f107_usb_driver, &dev, &config, usb_strings); usbd_register_control_callback( + usbd_dev, USB_REQ_TYPE_VENDOR, USB_REQ_TYPE_TYPE, simple_control_callback); while (1) - usbd_poll(); + usbd_poll(usbd_dev); } diff --git a/examples/stm32/f4/stm32f4-discovery/usb_cdcacm/cdcacm.c b/examples/stm32/f4/stm32f4-discovery/usb_cdcacm/cdcacm.c index 4af10393..1a12267e 100644 --- a/examples/stm32/f4/stm32f4-discovery/usb_cdcacm/cdcacm.c +++ b/examples/stm32/f4/stm32f4-discovery/usb_cdcacm/cdcacm.c @@ -22,6 +22,7 @@ #include #include #include +#include static const struct usb_device_descriptor dev = { .bLength = USB_DT_DEVICE_SIZE, @@ -164,11 +165,12 @@ static const char *usb_strings[] = { "DEMO", }; -static int cdcacm_control_request(struct usb_setup_data *req, u8 **buf, - u16 *len, void (**complete)(struct usb_setup_data *req)) +static int cdcacm_control_request(usbd_device *usbd_dev, struct usb_setup_data *req, u8 **buf, + u16 *len, void (**complete)(usbd_device *usbd_dev, struct usb_setup_data *req)) { (void)complete; (void)buf; + (void)usbd_dev; switch (req->bRequest) { case USB_CDC_REQ_SET_CONTROL_LINE_STATE: { @@ -188,30 +190,31 @@ static int cdcacm_control_request(struct usb_setup_data *req, u8 **buf, return 0; } -static void cdcacm_data_rx_cb(u8 ep) +static void cdcacm_data_rx_cb(usbd_device *usbd_dev, u8 ep) { (void)ep; char buf[64]; - int len = usbd_ep_read_packet(0x01, buf, 64); + int len = usbd_ep_read_packet(usbd_dev, 0x01, buf, 64); if (len) { - while (usbd_ep_write_packet(0x82, buf, len) == 0) + while (usbd_ep_write_packet(usbd_dev, 0x82, buf, len) == 0) ; } gpio_toggle(GPIOC, GPIO5); } -static void cdcacm_set_config(u16 wValue) +static void cdcacm_set_config(usbd_device *usbd_dev, u16 wValue) { (void)wValue; - usbd_ep_setup(0x01, USB_ENDPOINT_ATTR_BULK, 64, cdcacm_data_rx_cb); - usbd_ep_setup(0x82, USB_ENDPOINT_ATTR_BULK, 64, NULL); - usbd_ep_setup(0x83, USB_ENDPOINT_ATTR_INTERRUPT, 16, NULL); + usbd_ep_setup(usbd_dev, 0x01, USB_ENDPOINT_ATTR_BULK, 64, cdcacm_data_rx_cb); + usbd_ep_setup(usbd_dev, 0x82, USB_ENDPOINT_ATTR_BULK, 64, NULL); + usbd_ep_setup(usbd_dev, 0x83, USB_ENDPOINT_ATTR_INTERRUPT, 16, NULL); usbd_register_control_callback( + usbd_dev, USB_REQ_TYPE_CLASS | USB_REQ_TYPE_INTERFACE, USB_REQ_TYPE_TYPE | USB_REQ_TYPE_RECIPIENT, cdcacm_control_request); @@ -219,19 +222,20 @@ static void cdcacm_set_config(u16 wValue) int main(void) { + usbd_device *usbd_dev; + rcc_clock_setup_hse_3v3(&hse_8mhz_3v3[CLOCK_3V3_120MHZ]); rcc_peripheral_enable_clock(&RCC_AHB1ENR, RCC_AHB1ENR_IOPAEN); rcc_peripheral_enable_clock(&RCC_AHB2ENR, RCC_AHB2ENR_OTGFSEN); - gpio_mode_setup(GPIOA, GPIO_MODE_AF, GPIO_PUPD_NONE, + gpio_mode_setup(GPIOA, GPIO_MODE_AF, GPIO_PUPD_NONE, GPIO9 | GPIO11 | GPIO12); gpio_set_af(GPIOA, GPIO_AF10, GPIO9 | GPIO11 | GPIO12); - usbd_init(&otgfs_usb_driver, &dev, &config, usb_strings); - usbd_register_set_config_callback(cdcacm_set_config); + usbd_dev = usbd_init(&otgfs_usb_driver, &dev, &config, usb_strings); + usbd_register_set_config_callback(usbd_dev, cdcacm_set_config); while (1) - usbd_poll(); + usbd_poll(usbd_dev); } - diff --git a/include/libopencm3/stm32/otg_fs.h b/include/libopencm3/stm32/otg_fs.h index 5680e432..d8ee3938 100644 --- a/include/libopencm3/stm32/otg_fs.h +++ b/include/libopencm3/stm32/otg_fs.h @@ -24,7 +24,7 @@ #include /* Core Global Control and Status Registers */ -#define OTG_FS_OTGCTL MMIO32(USB_OTG_FS_BASE + 0x000) +#define OTG_FS_GOTGCTL MMIO32(USB_OTG_FS_BASE + 0x000) #define OTG_FS_GOTGINT MMIO32(USB_OTG_FS_BASE + 0x004) #define OTG_FS_GAHBCFG MMIO32(USB_OTG_FS_BASE + 0x008) #define OTG_FS_GUSBCFG MMIO32(USB_OTG_FS_BASE + 0x00C) @@ -42,40 +42,40 @@ #define OTG_FS_DIEPTXF(x) MMIO32(USB_OTG_FS_BASE + 0x104 + 4*(x-1)) /* Host-mode Control and Status Registers */ -#define OTG_FS_HCFG MMIO32(USB_OTG_FS_BASE + 0x400) -#define OTG_FS_HFIR MMIO32(USB_OTG_FS_BASE + 0x404) -#define OTG_FS_HFNUM MMIO32(USB_OTG_FS_BASE + 0x408) -#define OTG_FS_HPTXSTS MMIO32(USB_OTG_FS_BASE + 0x410) -#define OTG_FS_HAINT MMIO32(USB_OTG_FS_BASE + 0x414) -#define OTG_FS_HAINTMSK MMIO32(USB_OTG_FS_BASE + 0x418) -#define OTG_FS_HPRT MMIO32(USB_OTG_FS_BASE + 0x440) -#define OTG_FS_HCCHARx MMIO32(USB_OTG_FS_BASE + 0x500) -#define OTG_FS_HCINTx MMIO32(USB_OTG_FS_BASE + 0x508) -#define OTG_FS_HCINTMSKx MMIO32(USB_OTG_FS_BASE + 0x50C) -#define OTG_FS_HCTSIZx MMIO32(USB_OTG_FS_BASE + 0x510) +#define OTG_FS_HCFG MMIO32(USB_OTG_FS_BASE + 0x400) +#define OTG_FS_HFIR MMIO32(USB_OTG_FS_BASE + 0x404) +#define OTG_FS_HFNUM MMIO32(USB_OTG_FS_BASE + 0x408) +#define OTG_FS_HPTXSTS MMIO32(USB_OTG_FS_BASE + 0x410) +#define OTG_FS_HAINT MMIO32(USB_OTG_FS_BASE + 0x414) +#define OTG_FS_HAINTMSK MMIO32(USB_OTG_FS_BASE + 0x418) +#define OTG_FS_HPRT MMIO32(USB_OTG_FS_BASE + 0x440) +#define OTG_FS_HCCHARx MMIO32(USB_OTG_FS_BASE + 0x500) +#define OTG_FS_HCINTx MMIO32(USB_OTG_FS_BASE + 0x508) +#define OTG_FS_HCINTMSKx MMIO32(USB_OTG_FS_BASE + 0x50C) +#define OTG_FS_HCTSIZx MMIO32(USB_OTG_FS_BASE + 0x510) /* Device-mode Control and Status Registers */ -#define OTG_FS_DCFG MMIO32(USB_OTG_FS_BASE + 0x800) -#define OTG_FS_DCTL MMIO32(USB_OTG_FS_BASE + 0x804) -#define OTG_FS_DSTS MMIO32(USB_OTG_FS_BASE + 0x808) -#define OTG_FS_DIEPMSK MMIO32(USB_OTG_FS_BASE + 0x810) -#define OTG_FS_DOEPMSK MMIO32(USB_OTG_FS_BASE + 0x814) -#define OTG_FS_DAINT MMIO32(USB_OTG_FS_BASE + 0x818) -#define OTG_FS_DAINTMSK MMIO32(USB_OTG_FS_BASE + 0x81C) -#define OTG_FS_DVBUSDIS MMIO32(USB_OTG_FS_BASE + 0x828) -#define OTG_FS_DVBUSPULSE MMIO32(USB_OTG_FS_BASE + 0x82C) -#define OTG_FS_DIEPEMPMSK MMIO32(USB_OTG_FS_BASE + 0x834) -#define OTG_FS_DIEPCTL0 MMIO32(USB_OTG_FS_BASE + 0x900) -#define OTG_FS_DIEPCTL(x) MMIO32(USB_OTG_FS_BASE + 0x900 + 0x20*(x)) -#define OTG_FS_DOEPCTL0 MMIO32(USB_OTG_FS_BASE + 0xB00) -#define OTG_FS_DOEPCTL(x) MMIO32(USB_OTG_FS_BASE + 0xB00 + 0x20*(x)) -#define OTG_FS_DIEPINT(x) MMIO32(USB_OTG_FS_BASE + 0x908 + 0x20*(x)) -#define OTG_FS_DOEPINT(x) MMIO32(USB_OTG_FS_BASE + 0xB08 + 0x20*(x)) -#define OTG_FS_DIEPTSIZ0 MMIO32(USB_OTG_FS_BASE + 0x910) -#define OTG_FS_DOEPTSIZ0 MMIO32(USB_OTG_FS_BASE + 0xB10) -#define OTG_FS_DIEPTSIZ(x) MMIO32(USB_OTG_FS_BASE + 0x910 + 0x20*(x)) -#define OTG_FS_DTXFSTS(x) MMIO32(USB_OTG_FS_BASE + 0x918 + 0x20*(x)) -#define OTG_FS_DOEPTSIZ(x) MMIO32(USB_OTG_FS_BASE + 0xB10 + 0x20*(x)) +#define OTG_FS_DCFG MMIO32(USB_OTG_FS_BASE + 0x800) +#define OTG_FS_DCTL MMIO32(USB_OTG_FS_BASE + 0x804) +#define OTG_FS_DSTS MMIO32(USB_OTG_FS_BASE + 0x808) +#define OTG_FS_DIEPMSK MMIO32(USB_OTG_FS_BASE + 0x810) +#define OTG_FS_DOEPMSK MMIO32(USB_OTG_FS_BASE + 0x814) +#define OTG_FS_DAINT MMIO32(USB_OTG_FS_BASE + 0x818) +#define OTG_FS_DAINTMSK MMIO32(USB_OTG_FS_BASE + 0x81C) +#define OTG_FS_DVBUSDIS MMIO32(USB_OTG_FS_BASE + 0x828) +#define OTG_FS_DVBUSPULSE MMIO32(USB_OTG_FS_BASE + 0x82C) +#define OTG_FS_DIEPEMPMSK MMIO32(USB_OTG_FS_BASE + 0x834) +#define OTG_FS_DIEPCTL0 MMIO32(USB_OTG_FS_BASE + 0x900) +#define OTG_FS_DIEPCTL(x) MMIO32(USB_OTG_FS_BASE + 0x900 + 0x20*(x)) +#define OTG_FS_DOEPCTL0 MMIO32(USB_OTG_FS_BASE + 0xB00) +#define OTG_FS_DOEPCTL(x) MMIO32(USB_OTG_FS_BASE + 0xB00 + 0x20*(x)) +#define OTG_FS_DIEPINT(x) MMIO32(USB_OTG_FS_BASE + 0x908 + 0x20*(x)) +#define OTG_FS_DOEPINT(x) MMIO32(USB_OTG_FS_BASE + 0xB08 + 0x20*(x)) +#define OTG_FS_DIEPTSIZ0 MMIO32(USB_OTG_FS_BASE + 0x910) +#define OTG_FS_DOEPTSIZ0 MMIO32(USB_OTG_FS_BASE + 0xB10) +#define OTG_FS_DIEPTSIZ(x) MMIO32(USB_OTG_FS_BASE + 0x910 + 0x20*(x)) +#define OTG_FS_DTXFSTS(x) MMIO32(USB_OTG_FS_BASE + 0x918 + 0x20*(x)) +#define OTG_FS_DOEPTSIZ(x) MMIO32(USB_OTG_FS_BASE + 0xB10 + 0x20*(x)) /* Power and clock gating control and status register */ #define OTG_FS_PCGCCTL MMIO32(USB_OTG_FS_BASE + 0xE00) @@ -84,6 +84,18 @@ #define OTG_FS_FIFO(x) ((volatile u32*)(USB_OTG_FS_BASE + (((x) + 1) << 12))) /* Global CSRs */ +/* OTG_FS USB control registers (OTG_HS_GOTGCTL) */ +#define OTG_FS_GOTGCTL_BSVLD (1 << 19) +#define OTG_FS_GOTGCTL_ASVLD (1 << 18) +#define OTG_FS_GOTGCTL_DBCT (1 << 17) +#define OTG_FS_GOTGCTL_CIDSTS (1 << 16) +#define OTG_FS_GOTGCTL_DHNPEN (1 << 11) +#define OTG_FS_GOTGCTL_HSHNPEN (1 << 10) +#define OTG_FS_GOTGCTL_HNPRQ (1 << 9) +#define OTG_FS_GOTGCTL_HNGSCS (1 << 8) +#define OTG_FS_GOTGCTL_SRQ (1 << 1) +#define OTG_FS_GOTGCTL_SRQSCS (1 << 0) + /* OTG_FS AHB configuration register (OTG_FS_GAHBCFG) */ #define OTG_FS_GAHBCFG_GINT 0x0001 #define OTG_FS_GAHBCFG_TXFELVL 0x0080 @@ -175,20 +187,20 @@ /* OTG_FS Receive Status Pop Register (OTG_FS_GRXSTSP) */ /* Bits 31:25 - Reserved */ -#define OTG_FS_GRXSTSP_FRMNUM_MASK (0xf << 21) -#define OTG_FS_GRXSTSP_PKTSTS_MASK (0xf << 17) -#define OTG_FS_GRXSTSP_PKTSTS_GOUTNAK (0x1 << 17) -#define OTG_FS_GRXSTSP_PKTSTS_OUT (0x2 << 17) -#define OTG_FS_GRXSTSP_PKTSTS_OUT_COMP (0x3 << 17) +#define OTG_FS_GRXSTSP_FRMNUM_MASK (0xf << 21) +#define OTG_FS_GRXSTSP_PKTSTS_MASK (0xf << 17) +#define OTG_FS_GRXSTSP_PKTSTS_GOUTNAK (0x1 << 17) +#define OTG_FS_GRXSTSP_PKTSTS_OUT (0x2 << 17) +#define OTG_FS_GRXSTSP_PKTSTS_OUT_COMP (0x3 << 17) #define OTG_FS_GRXSTSP_PKTSTS_SETUP_COMP (0x4 << 17) -#define OTG_FS_GRXSTSP_PKTSTS_SETUP (0x6 << 17) -#define OTG_FS_GRXSTSP_DPID_MASK (0x3 << 15) -#define OTG_FS_GRXSTSP_DPID_DATA0 (0x0 << 15) -#define OTG_FS_GRXSTSP_DPID_DATA1 (0x2 << 15) -#define OTG_FS_GRXSTSP_DPID_DATA2 (0x1 << 15) -#define OTG_FS_GRXSTSP_DPID_MDATA (0x3 << 15) -#define OTG_FS_GRXSTSP_BCNT_MASK (0x7ff << 4) -#define OTG_FS_GRXSTSP_EPNUM_MASK (0xf << 0) +#define OTG_FS_GRXSTSP_PKTSTS_SETUP (0x6 << 17) +#define OTG_FS_GRXSTSP_DPID_MASK (0x3 << 15) +#define OTG_FS_GRXSTSP_DPID_DATA0 (0x0 << 15) +#define OTG_FS_GRXSTSP_DPID_DATA1 (0x2 << 15) +#define OTG_FS_GRXSTSP_DPID_DATA2 (0x1 << 15) +#define OTG_FS_GRXSTSP_DPID_MDATA (0x3 << 15) +#define OTG_FS_GRXSTSP_BCNT_MASK (0x7ff << 4) +#define OTG_FS_GRXSTSP_EPNUM_MASK (0xf << 0) /* OTG_FS general core configuration register (OTG_FS_GCCFG) */ /* Bits 31:21 - Reserved */ @@ -320,4 +332,3 @@ #define OTG_FS_DIEPSIZ0_XFRSIZ_MASK (0x7f << 0) #endif - diff --git a/include/libopencm3/stm32/otg_hs.h b/include/libopencm3/stm32/otg_hs.h new file mode 100644 index 00000000..2f59ddd9 --- /dev/null +++ b/include/libopencm3/stm32/otg_hs.h @@ -0,0 +1,396 @@ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2010 Gareth McMullin + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#ifndef LIBOPENCM3_OTG_HS_H +#define LIBOPENCM3_OTG_HS_H + +#include +#include + +/* Core Global Control and Status Registers */ +#define OTG_GOTGCTL 0x000 +#define OTG_GOTGIN 0x004 +#define OTG_GAHBCFG 0x008 +#define OTG_GUSBCFG 0x00C +#define OTG_GRSTCTL 0x010 +#define OTG_GINTSTS 0x014 +#define OTG_GINTMSK 0x018 +#define OTG_GRXSTSR 0x01C +#define OTG_GRXSTSP 0x020 +#define OTG_GRXFSIZ 0x024 +#define OTG_GNPTXFSIZ 0x028 +#define OTG_GNPTXSTS 0x02C +#define OTG_GCCFG 0x038 +#define OTG_CID 0x03C +#define OTG_HPTXFSIZ 0x100 +#define OTG_DIEPTXF(x) (0x104 + 4*(x-1)) + +/* Host-mode Control and Status Registers */ +#define OTG_HCFG 0x400 +#define OTG_HFIR 0x404 +#define OTG_HFNUM 0x408 +#define OTG_HPTXSTS 0x410 +#define OTG_HAINT 0x414 +#define OTG_HAINTMSK 0x418 +#define OTG_HPRT 0x440 +#define OTG_HCCHARx 0x500 +#define OTG_HCINTx 0x508 +#define OTG_HCINTMSKx 0x50C +#define OTG_HCTSIZx 0x510 + +/* Device-mode Control and Status Registers */ +#define OTG_DCFG 0x800 +#define OTG_DCTL 0x804 +#define OTG_DSTS 0x808 +#define OTG_DIEPMSK 0x810 +#define OTG_DOEPMSK 0x814 +#define OTG_DAINT 0x818 +#define OTG_DAINTMSK 0x81C +#define OTG_DVBUSDIS 0x828 +#define OTG_DVBUSPULSE 0x82C +#define OTG_DIEPEMPMSK 0x834 +#define OTG_DIEPCTL0 0x900 +#define OTG_DIEPCTL(x) (0x900 + 0x20*(x)) +#define OTG_DOEPCTL0 0xB00 +#define OTG_DOEPCTL(x) (0xB00 + 0x20*(x)) +#define OTG_DIEPINT(x) (0x908 + 0x20*(x)) +#define OTG_DOEPINT(x) (0xB08 + 0x20*(x)) +#define OTG_DIEPTSIZ0 0x910 +#define OTG_DOEPTSIZ0 0xB10 +#define OTG_DIEPTSIZ(x) (0x910 + 0x20*(x)) +#define OTG_DTXFSTS(x) (0x918 + 0x20*(x)) +#define OTG_DOEPTSIZ(x) (0xB10 + 0x20*(x)) + +/* Power and clock gating control and status register */ +#define OTG_PCGCCTL 0xE00 + +/* Data FIFO */ +#define OTG_FIFO(x) (((x) + 1) << 12) + +/***********************************************************************/ + +/* Core Global Control and Status Registers */ +#define OTG_HS_GOTGCTL MMIO32(USB_OTG_HS_BASE + OTG_GOTGCTL) +#define OTG_HS_GOTGINT MMIO32(USB_OTG_HS_BASE + OTG_GOTGINT) +#define OTG_HS_GAHBCFG MMIO32(USB_OTG_HS_BASE + OTG_GAHBCFG) +#define OTG_HS_GUSBCFG MMIO32(USB_OTG_HS_BASE + OTG_GUSBCFG) +#define OTG_HS_GRSTCTL MMIO32(USB_OTG_HS_BASE + OTG_GRSTCTL) +#define OTG_HS_GINTSTS MMIO32(USB_OTG_HS_BASE + OTG_GINTSTS) +#define OTG_HS_GINTMSK MMIO32(USB_OTG_HS_BASE + OTG_GINTMSK) +#define OTG_HS_GRXSTSR MMIO32(USB_OTG_HS_BASE + OTG_GRXSTSR) +#define OTG_HS_GRXSTSP MMIO32(USB_OTG_HS_BASE + OTG_GRXSTSP) +#define OTG_HS_GRXFSIZ MMIO32(USB_OTG_HS_BASE + OTG_GRXFSIZ) +#define OTG_HS_GNPTXFSIZ MMIO32(USB_OTG_HS_BASE + OTG_GNPTXFSIZ) +#define OTG_HS_GNPTXSTS MMIO32(USB_OTG_HS_BASE + OTG_GNPTXSTS) +#define OTG_HS_GCCFG MMIO32(USB_OTG_HS_BASE + OTG_GCCFG) +#define OTG_HS_CID MMIO32(USB_OTG_HS_BASE + OTG_CID) +#define OTG_HS_HPTXFSIZ MMIO32(USB_OTG_HS_BASE + OTG_HPTXFSIZ) +#define OTG_HS_DIEPTXF(x) MMIO32(USB_OTG_HS_BASE + OTG_DIEPTXF(x)) + +/* Host-mode Control and Status Registers */ +#define OTG_HS_HCFG MMIO32(USB_OTG_HS_BASE + OTG_HCFG) +#define OTG_HS_HFIR MMIO32(USB_OTG_HS_BASE + OTG_HFIR) +#define OTG_HS_HFNUM MMIO32(USB_OTG_HS_BASE + OTG_HFNUM) +#define OTG_HS_HPTXSTS MMIO32(USB_OTG_HS_BASE + OTG_HPTXSTS) +#define OTG_HS_HAINT MMIO32(USB_OTG_HS_BASE + OTG_HAINT) +#define OTG_HS_HAINTMSK MMIO32(USB_OTG_HS_BASE + OTG_HAINTMSK) +#define OTG_HS_HPRT MMIO32(USB_OTG_HS_BASE + OTG_HPRT) +#define OTG_HS_HCCHARx MMIO32(USB_OTG_HS_BASE + OTG_HCCHARx) +#define OTG_HS_HCINTx MMIO32(USB_OTG_HS_BASE + OTG_HCINTx) +#define OTG_HS_HCINTMSKx MMIO32(USB_OTG_HS_BASE + OTG_HCINTMSKx) +#define OTG_HS_HCTSIZx MMIO32(USB_OTG_HS_BASE + OTG_HCTSIZx) + +/* Device-mode Control and Status Registers */ +#define OTG_HS_DCFG MMIO32(USB_OTG_HS_BASE + OTG_DCFG) +#define OTG_HS_DCTL MMIO32(USB_OTG_HS_BASE + OTG_DCTL) +#define OTG_HS_DSTS MMIO32(USB_OTG_HS_BASE + OTG_DSTS) +#define OTG_HS_DIEPMSK MMIO32(USB_OTG_HS_BASE + OTG_DIEPMSK) +#define OTG_HS_DOEPMSK MMIO32(USB_OTG_HS_BASE + OTG_DOEPMSK) +#define OTG_HS_DAINT MMIO32(USB_OTG_HS_BASE + OTG_DAINT) +#define OTG_HS_DAINTMSK MMIO32(USB_OTG_HS_BASE + OTG_DAINTMSK) +#define OTG_HS_DVBUSDIS MMIO32(USB_OTG_HS_BASE + OTG_DVBUSDIS) +#define OTG_HS_DVBUSPULSE MMIO32(USB_OTG_HS_BASE + OTG_DVBUSPULSE) +#define OTG_HS_DIEPEMPMSK MMIO32(USB_OTG_HS_BASE + OTG_DIEPEMPMSK) +#define OTG_HS_DIEPCTL0 MMIO32(USB_OTG_HS_BASE + OTG_DIEPCTL0) +#define OTG_HS_DIEPCTL(x) MMIO32(USB_OTG_HS_BASE + OTG_DIEPCTL(x)) +#define OTG_HS_DOEPCTL0 MMIO32(USB_OTG_HS_BASE + OTG_DOEPCTL0) +#define OTG_HS_DOEPCTL(x) MMIO32(USB_OTG_HS_BASE + OTG_DOEPCTL(x)) +#define OTG_HS_DIEPINT(x) MMIO32(USB_OTG_HS_BASE + OTG_DIEPINT(x)) +#define OTG_HS_DOEPINT(x) MMIO32(USB_OTG_HS_BASE + OTG_DOEPINT(x)) +#define OTG_HS_DIEPTSIZ0 MMIO32(USB_OTG_HS_BASE + OTG_DIEPTSIZ0) +#define OTG_HS_DOEPTSIZ0 MMIO32(USB_OTG_HS_BASE + OTG_DOEPTSIZ0) +#define OTG_HS_DIEPTSIZ(x) MMIO32(USB_OTG_HS_BASE + OTG_DIEPTSIZ(x))) +#define OTG_HS_DTXFSTS(x) MMIO32(USB_OTG_HS_BASE + OTG_DTXFSTS(x)) +#define OTG_HS_DOEPTSIZ(x) MMIO32(USB_OTG_HS_BASE + OTG_DOEPTSIZ(x)) + +/* Power and clock gating control and status register */ +#define OTG_HS_PCGCCTL MMIO32(USB_OTG_HS_BASE + OTG_PCGCCTL) + +/* Data FIFO */ +#define OTG_HS_FIFO(x) ((volatile u32*)(USB_OTG_HS_BASE + OTG_FIFO(x))) + +/* Global CSRs */ +/* OTG_HS USB control registers (OTG_FS_GOTGCTL) */ +#define OTG_HS_GOTGCTL_BSVLD (1 << 19) +#define OTG_HS_GOTGCTL_ASVLD (1 << 18) +#define OTG_HS_GOTGCTL_DBCT (1 << 17) +#define OTG_HS_GOTGCTL_CIDSTS (1 << 16) +#define OTG_HS_GOTGCTL_DHNPEN (1 << 11) +#define OTG_HS_GOTGCTL_HSHNPEN (1 << 10) +#define OTG_HS_GOTGCTL_HNPRQ (1 << 9) +#define OTG_HS_GOTGCTL_HNGSCS (1 << 8) +#define OTG_HS_GOTGCTL_SRQ (1 << 1) +#define OTG_HS_GOTGCTL_SRQSCS (1 << 0) + +/* OTG_FS AHB configuration register (OTG_HS_GAHBCFG) */ +#define OTG_HS_GAHBCFG_GINT 0x0001 +#define OTG_HS_GAHBCFG_TXFELVL 0x0080 +#define OTG_HS_GAHBCFG_PTXFELVL 0x0100 + +/* OTG_FS USB configuration register (OTG_HS_GUSBCFG) */ +#define OTG_HS_GUSBCFG_TOCAL 0x00000003 +#define OTG_HS_GUSBCFG_SRPCAP 0x00000100 +#define OTG_HS_GUSBCFG_HNPCAP 0x00000200 +#define OTG_HS_GUSBCFG_TRDT_MASK (0xf << 10) +#define OTG_HS_GUSBCFG_TRDT_16BIT (0x5 << 10) +#define OTG_HS_GUSBCFG_TRDT_8BIT (0x9 << 10) +#define OTG_HS_GUSBCFG_NPTXRWEN 0x00004000 +#define OTG_HS_GUSBCFG_FHMOD 0x20000000 +#define OTG_HS_GUSBCFG_FDMOD 0x40000000 +#define OTG_HS_GUSBCFG_CTXPKT 0x80000000 +#define OTG_HS_GUSBCFG_PHYSEL (1 << 6) + +/* OTG_FS reset register (OTG_HS_GRSTCTL) */ +#define OTG_HS_GRSTCTL_AHBIDL (1 << 31) +/* Bits 30:11 - Reserved */ +#define OTG_HS_GRSTCTL_TXFNUM_MASK (0x1f << 6) +#define OTG_HS_GRSTCTL_TXFFLSH (1 << 5) +#define OTG_HS_GRSTCTL_RXFFLSH (1 << 4) +/* Bit 3 - Reserved */ +#define OTG_HS_GRSTCTL_FCRST (1 << 2) +#define OTG_HS_GRSTCTL_HSRST (1 << 1) +#define OTG_HS_GRSTCTL_CSRST (1 << 0) + +/* OTG_FS interrupt status register (OTG_HS_GINTSTS) */ +#define OTG_HS_GINTSTS_WKUPINT (1 << 31) +#define OTG_HS_GINTSTS_SRQINT (1 << 30) +#define OTG_HS_GINTSTS_DISCINT (1 << 29) +#define OTG_HS_GINTSTS_CIDSCHG (1 << 28) +/* Bit 27 - Reserved */ +#define OTG_HS_GINTSTS_PTXFE (1 << 26) +#define OTG_HS_GINTSTS_HCINT (1 << 25) +#define OTG_HS_GINTSTS_HPRTINT (1 << 24) +/* Bits 23:22 - Reserved */ +#define OTG_HS_GINTSTS_IPXFR (1 << 21) +#define OTG_HS_GINTSTS_INCOMPISOOUT (1 << 21) +#define OTG_HS_GINTSTS_IISOIXFR (1 << 20) +#define OTG_HS_GINTSTS_OEPINT (1 << 19) +#define OTG_HS_GINTSTS_IEPINT (1 << 18) +/* Bits 17:16 - Reserved */ +#define OTG_HS_GINTSTS_EOPF (1 << 15) +#define OTG_HS_GINTSTS_ISOODRP (1 << 14) +#define OTG_HS_GINTSTS_ENUMDNE (1 << 13) +#define OTG_HS_GINTSTS_USBRST (1 << 12) +#define OTG_HS_GINTSTS_USBSUSP (1 << 11) +#define OTG_HS_GINTSTS_ESUSP (1 << 10) +/* Bits 9:8 - Reserved */ +#define OTG_HS_GINTSTS_GONAKEFF (1 << 7) +#define OTG_HS_GINTSTS_GINAKEFF (1 << 6) +#define OTG_HS_GINTSTS_NPTXFE (1 << 5) +#define OTG_HS_GINTSTS_RXFLVL (1 << 4) +#define OTG_HS_GINTSTS_SOF (1 << 3) +#define OTG_HS_GINTSTS_OTGINT (1 << 2) +#define OTG_HS_GINTSTS_MMIS (1 << 1) +#define OTG_HS_GINTSTS_CMOD (1 << 0) + +/* OTG_FS interrupt mask register (OTG_HS_GINTMSK) */ +#define OTG_HS_GINTMSK_MMISM 0x00000002 +#define OTG_HS_GINTMSK_OTGINT 0x00000004 +#define OTG_HS_GINTMSK_SOFM 0x00000008 +#define OTG_HS_GINTMSK_RXFLVLM 0x00000010 +#define OTG_HS_GINTMSK_NPTXFEM 0x00000020 +#define OTG_HS_GINTMSK_GINAKEFFM 0x00000040 +#define OTG_HS_GINTMSK_GONAKEFFM 0x00000080 +#define OTG_HS_GINTMSK_ESUSPM 0x00000400 +#define OTG_HS_GINTMSK_USBSUSPM 0x00000800 +#define OTG_HS_GINTMSK_USBRST 0x00001000 +#define OTG_HS_GINTMSK_ENUMDNEM 0x00002000 +#define OTG_HS_GINTMSK_ISOODRPM 0x00004000 +#define OTG_HS_GINTMSK_EOPFM 0x00008000 +#define OTG_HS_GINTMSK_EPMISM 0x00020000 +#define OTG_HS_GINTMSK_IEPINT 0x00040000 +#define OTG_HS_GINTMSK_OEPINT 0x00080000 +#define OTG_HS_GINTMSK_IISOIXFRM 0x00100000 +#define OTG_HS_GINTMSK_IISOOXFRM 0x00200000 +#define OTG_HS_GINTMSK_IPXFRM 0x00200000 +#define OTG_HS_GINTMSK_PRTIM 0x01000000 +#define OTG_HS_GINTMSK_HCIM 0x02000000 +#define OTG_HS_GINTMSK_PTXFEM 0x04000000 +#define OTG_HS_GINTMSK_CIDSCHGM 0x10000000 +#define OTG_HS_GINTMSK_DISCINT 0x20000000 +#define OTG_HS_GINTMSK_SRQIM 0x40000000 +#define OTG_HS_GINTMSK_WUIM 0x80000000 + +/* OTG_FS Receive Status Pop Register (OTG_HS_GRXSTSP) */ +/* Bits 31:25 - Reserved */ +#define OTG_HS_GRXSTSP_FRMNUM_MASK (0xf << 21) +#define OTG_HS_GRXSTSP_PKTSTS_MASK (0xf << 17) +#define OTG_HS_GRXSTSP_PKTSTS_GOUTNAK (0x1 << 17) +#define OTG_HS_GRXSTSP_PKTSTS_OUT (0x2 << 17) +#define OTG_HS_GRXSTSP_PKTSTS_OUT_COMP (0x3 << 17) +#define OTG_HS_GRXSTSP_PKTSTS_SETUP_COMP (0x4 << 17) +#define OTG_HS_GRXSTSP_PKTSTS_SETUP (0x6 << 17) +#define OTG_HS_GRXSTSP_DPID_MASK (0x3 << 15) +#define OTG_HS_GRXSTSP_DPID_DATA0 (0x0 << 15) +#define OTG_HS_GRXSTSP_DPID_DATA1 (0x2 << 15) +#define OTG_HS_GRXSTSP_DPID_DATA2 (0x1 << 15) +#define OTG_HS_GRXSTSP_DPID_MDATA (0x3 << 15) +#define OTG_HS_GRXSTSP_BCNT_MASK (0x7ff << 4) +#define OTG_HS_GRXSTSP_EPNUM_MASK (0xf << 0) + +/* OTG_FS general core configuration register (OTG_HS_GCCFG) */ +/* Bits 31:21 - Reserved */ +#define OTG_HS_GCCFG_SOFOUTEN (1 << 20) +#define OTG_HS_GCCFG_VBUSBSEN (1 << 19) +#define OTG_HS_GCCFG_VBUSASEN (1 << 18) +/* Bit 17 - Reserved */ +#define OTG_HS_GCCFG_PWRDWN (1 << 16) +/* Bits 15:0 - Reserved */ + + +/* Device-mode CSRs */ +/* OTG_FS device control register (OTG_HS_DCTL) */ +/* Bits 31:12 - Reserved */ +#define OTG_HS_DCTL_POPRGDNE (1 << 11) +#define OTG_HS_DCTL_CGONAK (1 << 10) +#define OTG_HS_DCTL_SGONAK (1 << 9) +#define OTG_HS_DCTL_SGINAK (1 << 8) +#define OTG_HS_DCTL_TCTL_MASK (7 << 4) +#define OTG_HS_DCTL_GONSTS (1 << 3) +#define OTG_HS_DCTL_GINSTS (1 << 2) +#define OTG_HS_DCTL_SDIS (1 << 1) +#define OTG_HS_DCTL_RWUSIG (1 << 0) + +/* OTG_FS device configuration register (OTG_HS_DCFG) */ +#define OTG_HS_DCFG_DSPD 0x0003 +#define OTG_HS_DCFG_NZLSOHSK 0x0004 +#define OTG_HS_DCFG_DAD 0x07F0 +#define OTG_HS_DCFG_PFIVL 0x1800 + +/* OTG_FS Device IN Endpoint Common Interrupt Mask Register (OTG_HS_DIEPMSK) */ +/* Bits 31:10 - Reserved */ +#define OTG_HS_DIEPMSK_BIM (1 << 9) +#define OTG_HS_DIEPMSK_TXFURM (1 << 8) +/* Bit 7 - Reserved */ +#define OTG_HS_DIEPMSK_INEPNEM (1 << 6) +#define OTG_HS_DIEPMSK_INEPNMM (1 << 5) +#define OTG_HS_DIEPMSK_ITTXFEMSK (1 << 4) +#define OTG_HS_DIEPMSK_TOM (1 << 3) +/* Bit 2 - Reserved */ +#define OTG_HS_DIEPMSK_EPDM (1 << 1) +#define OTG_HS_DIEPMSK_XFRCM (1 << 0) + +/* OTG_FS Device OUT Endpoint Common Interrupt Mask Register (OTG_HS_DOEPMSK) */ +/* Bits 31:10 - Reserved */ +#define OTG_HS_DOEPMSK_BOIM (1 << 9) +#define OTG_HS_DOEPMSK_OPEM (1 << 8) +/* Bit 7 - Reserved */ +#define OTG_HS_DOEPMSK_B2BSTUP (1 << 6) +/* Bit 5 - Reserved */ +#define OTG_HS_DOEPMSK_OTEPDM (1 << 4) +#define OTG_HS_DOEPMSK_STUPM (1 << 3) +/* Bit 2 - Reserved */ +#define OTG_HS_DOEPMSK_EPDM (1 << 1) +#define OTG_HS_DOEPMSK_XFRCM (1 << 0) + +/* OTG_FS Device Control IN Endpoint 0 Control Register (OTG_HS_DIEPCTL0) */ +#define OTG_HS_DIEPCTL0_EPENA (1 << 31) +#define OTG_HS_DIEPCTL0_EPDIS (1 << 30) +/* Bits 29:28 - Reserved */ +#define OTG_HS_DIEPCTLX_SD0PID (1 << 28) +#define OTG_HS_DIEPCTL0_SNAK (1 << 27) +#define OTG_HS_DIEPCTL0_CNAK (1 << 26) +#define OTG_HS_DIEPCTL0_TXFNUM_MASK (0xf << 22) +#define OTG_HS_DIEPCTL0_STALL (1 << 21) +/* Bit 20 - Reserved */ +#define OTG_HS_DIEPCTL0_EPTYP_MASK (0x3 << 18) +#define OTG_HS_DIEPCTL0_NAKSTS (1 << 17) +/* Bit 16 - Reserved */ +#define OTG_HS_DIEPCTL0_USBAEP (1 << 15) +/* Bits 14:2 - Reserved */ +#define OTG_HS_DIEPCTL0_MPSIZ_MASK (0x3 << 0) +#define OTG_HS_DIEPCTL0_MPSIZ_64 (0x0 << 0) +#define OTG_HS_DIEPCTL0_MPSIZ_32 (0x1 << 0) +#define OTG_HS_DIEPCTL0_MPSIZ_16 (0x2 << 0) +#define OTG_HS_DIEPCTL0_MPSIZ_8 (0x3 << 0) + +/* OTG_FS Device Control OUT Endpoint 0 Control Register (OTG_HS_DOEPCTL0) */ +#define OTG_HS_DOEPCTL0_EPENA (1 << 31) +#define OTG_HS_DOEPCTL0_EPDIS (1 << 30) +/* Bits 29:28 - Reserved */ +#define OTG_HS_DOEPCTLX_SD0PID (1 << 28) +#define OTG_HS_DOEPCTL0_SNAK (1 << 27) +#define OTG_HS_DOEPCTL0_CNAK (1 << 26) +/* Bits 25:22 - Reserved */ +#define OTG_HS_DOEPCTL0_STALL (1 << 21) +#define OTG_HS_DOEPCTL0_SNPM (1 << 20) +#define OTG_HS_DOEPCTL0_EPTYP_MASK (0x3 << 18) +#define OTG_HS_DOEPCTL0_NAKSTS (1 << 17) +/* Bit 16 - Reserved */ +#define OTG_HS_DOEPCTL0_USBAEP (1 << 15) +/* Bits 14:2 - Reserved */ +#define OTG_HS_DOEPCTL0_MPSIZ_MASK (0x3 << 0) +#define OTG_HS_DOEPCTL0_MPSIZ_64 (0x0 << 0) +#define OTG_HS_DOEPCTL0_MPSIZ_32 (0x1 << 0) +#define OTG_HS_DOEPCTL0_MPSIZ_16 (0x2 << 0) +#define OTG_HS_DOEPCTL0_MPSIZ_8 (0x3 << 0) + +/* OTG_FS Device IN Endpoint Interrupt Register (OTG_HS_DIEPINTx) */ +/* Bits 31:8 - Reserved */ +#define OTG_HS_DIEPINTX_TXFE (1 << 7) +#define OTG_HS_DIEPINTX_INEPNE (1 << 6) +/* Bit 5 - Reserved */ +#define OTG_HS_DIEPINTX_ITTXFE (1 << 4) +#define OTG_HS_DIEPINTX_TOC (1 << 3) +/* Bit 2 - Reserved */ +#define OTG_HS_DIEPINTX_EPDISD (1 << 1) +#define OTG_HS_DIEPINTX_XFRC (1 << 0) + +/* OTG_FS Device IN Endpoint Interrupt Register (OTG_HS_DOEPINTx) */ +/* Bits 31:7 - Reserved */ +#define OTG_HS_DOEPINTX_B2BSTUP (1 << 6) +/* Bit 5 - Reserved */ +#define OTG_HS_DOEPINTX_OTEPDIS (1 << 4) +#define OTG_HS_DOEPINTX_STUP (1 << 3) +/* Bit 2 - Reserved */ +#define OTG_HS_DOEPINTX_EPDISD (1 << 1) +#define OTG_HS_DOEPINTX_XFRC (1 << 0) + +/* OTG_FS Device OUT Endpoint 0 Transfer Size Regsiter (OTG_HS_DOEPTSIZ0) */ +/* Bit 31 - Reserved */ +#define OTG_HS_DIEPSIZ0_STUPCNT_1 (0x1 << 29) +#define OTG_HS_DIEPSIZ0_STUPCNT_2 (0x2 << 29) +#define OTG_HS_DIEPSIZ0_STUPCNT_3 (0x3 << 29) +#define OTG_HS_DIEPSIZ0_STUPCNT_MASK (0x3 << 29) +/* Bits 28:20 - Reserved */ +#define OTG_HS_DIEPSIZ0_PKTCNT (1 << 19) +/* Bits 18:7 - Reserved */ +#define OTG_HS_DIEPSIZ0_XFRSIZ_MASK (0x7f << 0) + +#endif diff --git a/include/libopencm3/usb/cdc.h b/include/libopencm3/usb/cdc.h index 4b549613..5036411f 100644 --- a/include/libopencm3/usb/cdc.h +++ b/include/libopencm3/usb/cdc.h @@ -112,7 +112,7 @@ struct usb_cdc_line_coding { /* Table 30: Class-Specific Notification Codes for PSTN subclasses */ /* ... */ -#define USB_CDC_NOTIFY_SERIAL_STATE 0x20 +#define USB_CDC_NOTIFY_SERIAL_STATE 0x20 /* ... */ /* Notification Structure */ diff --git a/include/libopencm3/usb/usbd.h b/include/libopencm3/usb/usbd.h index e4b35785..98bf6ebb 100644 --- a/include/libopencm3/usb/usbd.h +++ b/include/libopencm3/usb/usbd.h @@ -25,9 +25,13 @@ BEGIN_DECLS typedef struct _usbd_driver usbd_driver; +typedef struct _usbd_device usbd_device; + extern const usbd_driver stm32f103_usb_driver; extern const usbd_driver stm32f107_usb_driver; +extern const usbd_driver stm32f207_usb_driver; #define otgfs_usb_driver stm32f107_usb_driver +#define otghs_usb_driver stm32f207_usb_driver /* Static buffer for control transactions: * This is defined as weak in the library, applicaiton @@ -35,45 +39,55 @@ extern const usbd_driver stm32f107_usb_driver; extern u8 usbd_control_buffer[]; /* */ -extern int usbd_init(const usbd_driver *driver, +extern usbd_device *usbd_init(const usbd_driver *driver, const struct usb_device_descriptor *dev, const struct usb_config_descriptor *conf, const char **strings); -extern void usbd_set_control_buffer_size(u16 size); +extern void usbd_set_control_buffer_size(usbd_device *usbd_dev, u16 size); -extern void usbd_register_reset_callback(void (*callback)(void)); -extern void usbd_register_suspend_callback(void (*callback)(void)); -extern void usbd_register_resume_callback(void (*callback)(void)); -extern void usbd_register_sof_callback(void (*callback)(void)); +extern void usbd_register_reset_callback(usbd_device *usbd_dev, + void (*callback)(void)); +extern void usbd_register_suspend_callback(usbd_device *usbd_dev, + void (*callback)(void)); +extern void usbd_register_resume_callback(usbd_device *usbd_dev, + void (*callback)(void)); +extern void usbd_register_sof_callback(usbd_device *usbd_dev, + void (*callback)(void)); -typedef int (*usbd_control_callback)(struct usb_setup_data *req, u8 **buf, - u16 *len, void (**complete)(struct usb_setup_data *req)); +typedef int (*usbd_control_callback)(usbd_device *usbd_dev, + struct usb_setup_data *req, u8 **buf, u16 *len, + void (**complete)(usbd_device *usbd_dev, + struct usb_setup_data *req)); /* */ -extern int usbd_register_control_callback(u8 type, u8 type_mask, - usbd_control_callback callback); +extern int usbd_register_control_callback(usbd_device *usbd_dev, u8 type, + u8 type_mask, + usbd_control_callback callback); /* */ -extern void usbd_register_set_config_callback(void (*callback)(u16 wValue)); +extern void usbd_register_set_config_callback(usbd_device *usbd_dev, + void (*callback)(usbd_device *usbd_dev, u16 wValue)); /* Functions to be provided by the hardware abstraction layer */ -extern void usbd_poll(void); -extern void usbd_disconnect(bool disconnected); +extern void usbd_poll(usbd_device *usbd_dev); +extern void usbd_disconnect(usbd_device *usbd_dev, bool disconnected); -extern void usbd_ep_setup(u8 addr, u8 type, u16 max_size, - void (*callback)(u8 ep)); +extern void usbd_ep_setup(usbd_device *usbd_dev, u8 addr, u8 type, u16 max_size, + void (*callback)(usbd_device *usbd_dev, u8 ep)); -extern u16 usbd_ep_write_packet(u8 addr, const void *buf, u16 len); +extern u16 usbd_ep_write_packet(usbd_device *usbd_dev, u8 addr, + const void *buf, u16 len); -extern u16 usbd_ep_read_packet(u8 addr, void *buf, u16 len); +extern u16 usbd_ep_read_packet(usbd_device *usbd_dev, u8 addr, + void *buf, u16 len); -extern void usbd_ep_stall_set(u8 addr, u8 stall); -extern u8 usbd_ep_stall_get(u8 addr); +extern void usbd_ep_stall_set(usbd_device *usbd_dev, u8 addr, u8 stall); +extern u8 usbd_ep_stall_get(usbd_device *usbd_dev, u8 addr); -extern void usbd_ep_nak_set(u8 addr, u8 nak); +extern void usbd_ep_nak_set(usbd_device *usbd_dev, u8 addr, u8 nak); /* Optional */ -extern void usbd_cable_connect(u8 on); +extern void usbd_cable_connect(usbd_device *usbd_dev, u8 on); END_DECLS diff --git a/lib/stm32/f1/Makefile b/lib/stm32/f1/Makefile index 3b4252ba..1c7a0790 100644 --- a/lib/stm32/f1/Makefile +++ b/lib/stm32/f1/Makefile @@ -31,7 +31,7 @@ ARFLAGS = rcs OBJS = vector.o rcc.o gpio.o usart.o adc.o spi.o flash.o nvic.o \ rtc.o i2c.o dma.o systick.o exti.o scb.o ethernet.o \ usb_f103.o usb.o usb_control.o usb_standard.o can.o \ - timer.o usb_f107.o desig.o crc.o + timer.o usb_f107.o desig.o crc.o usb_fx07_common.o VPATH += ../../usb:../ diff --git a/lib/stm32/f4/Makefile b/lib/stm32/f4/Makefile index 5760d29b..1d880c9d 100644 --- a/lib/stm32/f4/Makefile +++ b/lib/stm32/f4/Makefile @@ -30,7 +30,8 @@ CFLAGS = -Os -g -Wall -Wextra -I../../../include -fno-common \ ARFLAGS = rcs OBJS = vector.o rcc.o gpio.o usart.o spi.o flash.o nvic.o \ i2c.o systick.o exti.o scb.o pwr.o timer.o \ - usb.o usb_standard.o usb_control.o usb_f107.o \ + usb.o usb_standard.o usb_control.o usb_fx07_common.o usb_f107.o \ + usb_f207.o \ VPATH += ../../usb:../ diff --git a/lib/usb/usb.c b/lib/usb/usb.c index 1ebb6ec5..ecebde2d 100644 --- a/lib/usb/usb.c +++ b/lib/usb/usb.c @@ -21,8 +21,6 @@ #include #include "usb_private.h" -struct _usbd_device _usbd_device; - u8 usbd_control_buffer[128] __attribute__((weak)); /** @@ -43,104 +41,111 @@ u8 usbd_control_buffer[128] __attribute__((weak)); * @param strings TODO * @return Zero on success (currently cannot fail). */ -int usbd_init(const usbd_driver *driver, - const struct usb_device_descriptor *dev, - const struct usb_config_descriptor *conf, const char **strings) +usbd_device *usbd_init(const usbd_driver *driver, + const struct usb_device_descriptor *dev, + const struct usb_config_descriptor *conf, + const char **strings) { - _usbd_device.driver = driver; - _usbd_device.desc = dev; - _usbd_device.config = conf; - _usbd_device.strings = strings; - _usbd_device.ctrl_buf = usbd_control_buffer; - _usbd_device.ctrl_buf_len = sizeof(usbd_control_buffer); + usbd_device *usbd_dev; - _usbd_hw_init(); + usbd_dev = driver->init(); - _usbd_device.user_callback_ctr[0][USB_TRANSACTION_SETUP] = + usbd_dev->driver = driver; + usbd_dev->desc = dev; + usbd_dev->config = conf; + usbd_dev->strings = strings; + usbd_dev->ctrl_buf = usbd_control_buffer; + usbd_dev->ctrl_buf_len = sizeof(usbd_control_buffer); + + usbd_dev->user_callback_ctr[0][USB_TRANSACTION_SETUP] = _usbd_control_setup; - _usbd_device.user_callback_ctr[0][USB_TRANSACTION_OUT] = + usbd_dev->user_callback_ctr[0][USB_TRANSACTION_OUT] = _usbd_control_out; - _usbd_device.user_callback_ctr[0][USB_TRANSACTION_IN] = + usbd_dev->user_callback_ctr[0][USB_TRANSACTION_IN] = _usbd_control_in; - return 0; + return usbd_dev; } -void usbd_register_reset_callback(void (*callback)(void)) +void usbd_register_reset_callback(usbd_device *usbd_dev, void (*callback)(void)) { - _usbd_device.user_callback_reset = callback; + usbd_dev->user_callback_reset = callback; } -void usbd_register_suspend_callback(void (*callback)(void)) +void usbd_register_suspend_callback(usbd_device *usbd_dev, + void (*callback)(void)) { - _usbd_device.user_callback_suspend = callback; + usbd_dev->user_callback_suspend = callback; } -void usbd_register_resume_callback(void (*callback)(void)) +void usbd_register_resume_callback(usbd_device *usbd_dev, + void (*callback)(void)) { - _usbd_device.user_callback_resume = callback; + usbd_dev->user_callback_resume = callback; } -void usbd_register_sof_callback(void (*callback)(void)) +void usbd_register_sof_callback(usbd_device *usbd_dev, void (*callback)(void)) { - _usbd_device.user_callback_sof = callback; + usbd_dev->user_callback_sof = callback; } -void usbd_set_control_buffer_size(u16 size) +void usbd_set_control_buffer_size(usbd_device *usbd_dev, u16 size) { - _usbd_device.ctrl_buf_len = size; + usbd_dev->ctrl_buf_len = size; } -void _usbd_reset(void) +void _usbd_reset(usbd_device *usbd_dev) { - _usbd_device.current_address = 0; - _usbd_device.current_config = 0; - usbd_ep_setup(0, USB_ENDPOINT_ATTR_CONTROL, 64, NULL); - _usbd_hw_set_address(0); + usbd_dev->current_address = 0; + usbd_dev->current_config = 0; + usbd_ep_setup(usbd_dev, 0, USB_ENDPOINT_ATTR_CONTROL, 64, NULL); + usbd_dev->driver->set_address(usbd_dev, 0); - if (_usbd_device.user_callback_reset) - _usbd_device.user_callback_reset(); + if (usbd_dev->user_callback_reset) + usbd_dev->user_callback_reset(); } /* Functions to wrap the low-level driver */ -void usbd_poll(void) +void usbd_poll(usbd_device *usbd_dev) { - _usbd_device.driver->poll(); + usbd_dev->driver->poll(usbd_dev); } -void usbd_disconnect(bool disconnected) +void usbd_disconnect(usbd_device *usbd_dev, bool disconnected) { /* not all drivers support disconnection */ - if (_usbd_device.driver->disconnect) - _usbd_device.driver->disconnect(disconnected); + if (usbd_dev->driver->disconnect) + usbd_dev->driver->disconnect(usbd_dev, disconnected); } -void usbd_ep_setup(u8 addr, u8 type, u16 max_size, void (*callback)(u8 ep)) +void usbd_ep_setup(usbd_device *usbd_dev, u8 addr, u8 type, u16 max_size, + void (*callback)(usbd_device *usbd_dev, u8 ep)) { - _usbd_device.driver->ep_setup(addr, type, max_size, callback); + usbd_dev->driver->ep_setup(usbd_dev, addr, type, max_size, callback); } -u16 usbd_ep_write_packet(u8 addr, const void *buf, u16 len) +u16 usbd_ep_write_packet(usbd_device *usbd_dev, u8 addr, + const void *buf, u16 len) { - return _usbd_device.driver->ep_write_packet(addr, buf, len); + return usbd_dev->driver->ep_write_packet(usbd_dev, addr, buf, len); } -u16 usbd_ep_read_packet(u8 addr, void *buf, u16 len) +u16 usbd_ep_read_packet(usbd_device *usbd_dev, u8 addr, void *buf, u16 len) { - return _usbd_device.driver->ep_read_packet(addr, buf, len); + return usbd_dev->driver->ep_read_packet(usbd_dev, addr, buf, len); } -void usbd_ep_stall_set(u8 addr, u8 stall) +void usbd_ep_stall_set(usbd_device *usbd_dev, u8 addr, u8 stall) { - _usbd_device.driver->ep_stall_set(addr, stall); + usbd_dev->driver->ep_stall_set(usbd_dev, addr, stall); } -u8 usbd_ep_stall_get(u8 addr) +u8 usbd_ep_stall_get(usbd_device *usbd_dev, u8 addr) { - return _usbd_device.driver->ep_stall_get(addr); + return usbd_dev->driver->ep_stall_get(usbd_dev, addr); } -void usbd_ep_nak_set(u8 addr, u8 nak) +void usbd_ep_nak_set(usbd_device *usbd_dev, u8 addr, u8 nak) { - _usbd_device.driver->ep_nak_set(addr, nak); + usbd_dev->driver->ep_nak_set(usbd_dev, addr, nak); } diff --git a/lib/usb/usb_control.c b/lib/usb/usb_control.c index 02188372..245ab1ce 100644 --- a/lib/usb/usb_control.c +++ b/lib/usb/usb_control.c @@ -21,77 +21,73 @@ #include #include "usb_private.h" -static struct usb_control_state { - enum { - IDLE, STALLED, - DATA_IN, LAST_DATA_IN, STATUS_IN, - DATA_OUT, LAST_DATA_OUT, STATUS_OUT, - } state; - struct usb_setup_data req __attribute__((aligned(4))); - u8 *ctrl_buf; - u16 ctrl_len; - void (*complete)(struct usb_setup_data *req); -} control_state; - /* Register application callback function for handling USB control requests. */ -int usbd_register_control_callback(u8 type, u8 type_mask, +int usbd_register_control_callback(usbd_device *usbd_dev, u8 type, u8 type_mask, usbd_control_callback callback) { int i; for (i = 0; i < MAX_USER_CONTROL_CALLBACK; i++) { - if (_usbd_device.user_control_callback[i].cb) + if (usbd_dev->user_control_callback[i].cb) continue; - _usbd_device.user_control_callback[i].type = type; - _usbd_device.user_control_callback[i].type_mask = type_mask; - _usbd_device.user_control_callback[i].cb = callback; + usbd_dev->user_control_callback[i].type = type; + usbd_dev->user_control_callback[i].type_mask = type_mask; + usbd_dev->user_control_callback[i].cb = callback; return 0; } return -1; } -static void usb_control_send_chunk(void) +static void usb_control_send_chunk(usbd_device *usbd_dev) { - if (_usbd_device.desc->bMaxPacketSize0 < control_state.ctrl_len) { + if (usbd_dev->desc->bMaxPacketSize0 < usbd_dev->control_state.ctrl_len) { /* Data stage, normal transmission */ - usbd_ep_write_packet(0, control_state.ctrl_buf, - _usbd_device.desc->bMaxPacketSize0); - control_state.state = DATA_IN; - control_state.ctrl_buf += _usbd_device.desc->bMaxPacketSize0; - control_state.ctrl_len -= _usbd_device.desc->bMaxPacketSize0; + usbd_ep_write_packet(usbd_dev, 0, + usbd_dev->control_state.ctrl_buf, + usbd_dev->desc->bMaxPacketSize0); + usbd_dev->control_state.state = DATA_IN; + usbd_dev->control_state.ctrl_buf += + usbd_dev->desc->bMaxPacketSize0; + usbd_dev->control_state.ctrl_len -= + usbd_dev->desc->bMaxPacketSize0; } else { /* Data stage, end of transmission */ - usbd_ep_write_packet(0, control_state.ctrl_buf, - control_state.ctrl_len); - control_state.state = LAST_DATA_IN; - control_state.ctrl_len = 0; - control_state.ctrl_buf = NULL; + usbd_ep_write_packet(usbd_dev, 0, + usbd_dev->control_state.ctrl_buf, + usbd_dev->control_state.ctrl_len); + usbd_dev->control_state.state = LAST_DATA_IN; + usbd_dev->control_state.ctrl_len = 0; + usbd_dev->control_state.ctrl_buf = NULL; } } -static int usb_control_recv_chunk(void) +static int usb_control_recv_chunk(usbd_device *usbd_dev) { - u16 packetsize = MIN(_usbd_device.desc->bMaxPacketSize0, - control_state.req.wLength - control_state.ctrl_len); - u16 size = usbd_ep_read_packet(0, control_state.ctrl_buf + - control_state.ctrl_len, packetsize); + u16 packetsize = MIN(usbd_dev->desc->bMaxPacketSize0, + usbd_dev->control_state.req.wLength - + usbd_dev->control_state.ctrl_len); + u16 size = usbd_ep_read_packet(usbd_dev, 0, + usbd_dev->control_state.ctrl_buf + + usbd_dev->control_state.ctrl_len, + packetsize); if (size != packetsize) { - usbd_ep_stall_set(0, 1); + usbd_ep_stall_set(usbd_dev, 0, 1); return -1; } - control_state.ctrl_len += size; + usbd_dev->control_state.ctrl_len += size; return packetsize; } -static int usb_control_request_dispatch(struct usb_setup_data *req) +static int usb_control_request_dispatch(usbd_device *usbd_dev, + struct usb_setup_data *req) { int i, result = 0; - struct user_control_callback *cb = _usbd_device.user_control_callback; + struct user_control_callback *cb = usbd_dev->user_control_callback; /* Call user command hook function. */ for (i = 0; i < MAX_USER_CONTROL_CALLBACK; i++) { @@ -99,140 +95,148 @@ static int usb_control_request_dispatch(struct usb_setup_data *req) break; if ((req->bmRequestType & cb[i].type_mask) == cb[i].type) { - result = cb[i].cb(req, &control_state.ctrl_buf, - &control_state.ctrl_len, - &control_state.complete); + result = cb[i].cb(usbd_dev, req, + &(usbd_dev->control_state.ctrl_buf), + &(usbd_dev->control_state.ctrl_len), + &(usbd_dev->control_state.complete)); if (result) return result; } } /* Try standard request if not already handled. */ - return _usbd_standard_request(req, &control_state.ctrl_buf, - &control_state.ctrl_len); + return _usbd_standard_request(usbd_dev, req, + &(usbd_dev->control_state.ctrl_buf), + &(usbd_dev->control_state.ctrl_len)); } /* Handle commands and read requests. */ -static void usb_control_setup_read(struct usb_setup_data *req) +static void usb_control_setup_read(usbd_device *usbd_dev, + struct usb_setup_data *req) { - control_state.ctrl_buf = _usbd_device.ctrl_buf; - control_state.ctrl_len = req->wLength; + usbd_dev->control_state.ctrl_buf = usbd_dev->ctrl_buf; + usbd_dev->control_state.ctrl_len = req->wLength; - if (usb_control_request_dispatch(req)) { - if (control_state.ctrl_len) { + if (usb_control_request_dispatch(usbd_dev, req)) { + if (usbd_dev->control_state.ctrl_len) { /* Go to data out stage if handled. */ - usb_control_send_chunk(); + usb_control_send_chunk(usbd_dev); } else { /* Go to status stage if handled. */ - usbd_ep_write_packet(0, NULL, 0); - control_state.state = STATUS_IN; + usbd_ep_write_packet(usbd_dev, 0, NULL, 0); + usbd_dev->control_state.state = STATUS_IN; } } else { /* Stall endpoint on failure. */ - usbd_ep_stall_set(0, 1); + usbd_ep_stall_set(usbd_dev, 0, 1); } } -static void usb_control_setup_write(struct usb_setup_data *req) +static void usb_control_setup_write(usbd_device *usbd_dev, + struct usb_setup_data *req) { - if (req->wLength > _usbd_device.ctrl_buf_len) { - usbd_ep_stall_set(0, 1); + if (req->wLength > usbd_dev->ctrl_buf_len) { + usbd_ep_stall_set(usbd_dev, 0, 1); return; } /* Buffer into which to write received data. */ - control_state.ctrl_buf = _usbd_device.ctrl_buf; - control_state.ctrl_len = 0; + usbd_dev->control_state.ctrl_buf = usbd_dev->ctrl_buf; + usbd_dev->control_state.ctrl_len = 0; /* Wait for DATA OUT stage. */ - if (req->wLength > _usbd_device.desc->bMaxPacketSize0) - control_state.state = DATA_OUT; + if (req->wLength > usbd_dev->desc->bMaxPacketSize0) + usbd_dev->control_state.state = DATA_OUT; else - control_state.state = LAST_DATA_OUT; + usbd_dev->control_state.state = LAST_DATA_OUT; } -void _usbd_control_setup(u8 ea) +void _usbd_control_setup(usbd_device *usbd_dev, u8 ea) { - struct usb_setup_data *req = &control_state.req; + struct usb_setup_data *req = &usbd_dev->control_state.req; (void)ea; - control_state.complete = NULL; + usbd_dev->control_state.complete = NULL; - if (usbd_ep_read_packet(0, req, 8) != 8) { - usbd_ep_stall_set(0, 1); + if (usbd_ep_read_packet(usbd_dev, 0, req, 8) != 8) { + usbd_ep_stall_set(usbd_dev, 0, 1); return; } if (req->wLength == 0) { - usb_control_setup_read(req); + usb_control_setup_read(usbd_dev, req); } else if (req->bmRequestType & 0x80) { - usb_control_setup_read(req); + usb_control_setup_read(usbd_dev, req); } else { - usb_control_setup_write(req); + usb_control_setup_write(usbd_dev, req); } } -void _usbd_control_out(u8 ea) +void _usbd_control_out(usbd_device *usbd_dev, u8 ea) { (void)ea; - switch (control_state.state) { + switch (usbd_dev->control_state.state) { case DATA_OUT: - if (usb_control_recv_chunk() < 0) + if (usb_control_recv_chunk(usbd_dev) < 0) break; - if ((control_state.req.wLength - control_state.ctrl_len) <= - _usbd_device.desc->bMaxPacketSize0) - control_state.state = LAST_DATA_OUT; + if ((usbd_dev->control_state.req.wLength - + usbd_dev->control_state.ctrl_len) <= + usbd_dev->desc->bMaxPacketSize0) + usbd_dev->control_state.state = LAST_DATA_OUT; break; case LAST_DATA_OUT: - if (usb_control_recv_chunk() < 0) + if (usb_control_recv_chunk(usbd_dev) < 0) break; /* * We have now received the full data payload. * Invoke callback to process. */ - if (usb_control_request_dispatch(&control_state.req)) { + if (usb_control_request_dispatch(usbd_dev, + &(usbd_dev->control_state.req))) { /* Got to status stage on success. */ - usbd_ep_write_packet(0, NULL, 0); - control_state.state = STATUS_IN; + usbd_ep_write_packet(usbd_dev, 0, NULL, 0); + usbd_dev->control_state.state = STATUS_IN; } else { - usbd_ep_stall_set(0, 1); + usbd_ep_stall_set(usbd_dev, 0, 1); } break; case STATUS_OUT: - usbd_ep_read_packet(0, NULL, 0); - control_state.state = IDLE; - if (control_state.complete) - control_state.complete(&control_state.req); - control_state.complete = NULL; + usbd_ep_read_packet(usbd_dev, 0, NULL, 0); + usbd_dev->control_state.state = IDLE; + if (usbd_dev->control_state.complete) + usbd_dev->control_state.complete(usbd_dev, + &(usbd_dev->control_state.req)); + usbd_dev->control_state.complete = NULL; break; default: - usbd_ep_stall_set(0, 1); + usbd_ep_stall_set(usbd_dev, 0, 1); } } -void _usbd_control_in(u8 ea) +void _usbd_control_in(usbd_device *usbd_dev, u8 ea) { (void)ea; - struct usb_setup_data *req = &control_state.req; + struct usb_setup_data *req = &(usbd_dev->control_state.req); - switch (control_state.state) { + switch (usbd_dev->control_state.state) { case DATA_IN: - usb_control_send_chunk(); + usb_control_send_chunk(usbd_dev); break; case LAST_DATA_IN: - control_state.state = STATUS_OUT; + usbd_dev->control_state.state = STATUS_OUT; break; case STATUS_IN: - if (control_state.complete) - control_state.complete(&control_state.req); + if (usbd_dev->control_state.complete) + usbd_dev->control_state.complete(usbd_dev, + &(usbd_dev->control_state.req)); /* Exception: Handle SET ADDRESS function here... */ if ((req->bmRequestType == 0) && (req->bRequest == USB_REQ_SET_ADDRESS)) - _usbd_hw_set_address(req->wValue); - control_state.state = IDLE; + usbd_dev->driver->set_address(usbd_dev, req->wValue); + usbd_dev->control_state.state = IDLE; break; default: - usbd_ep_stall_set(0, 1); + usbd_ep_stall_set(usbd_dev, 0, 1); } } diff --git a/lib/usb/usb_f103.c b/lib/usb/usb_f103.c index 22db8ccf..aa323d97 100644 --- a/lib/usb/usb_f103.c +++ b/lib/usb/usb_f103.c @@ -24,19 +24,23 @@ #include #include "usb_private.h" -static void stm32f103_usbd_init(void); -static void stm32f103_set_address(u8 addr); -static void stm32f103_ep_setup(u8 addr, u8 type, u16 max_size, - void (*callback) (u8 ep)); -static void stm32f103_endpoints_reset(void); -static void stm32f103_ep_stall_set(u8 addr, u8 stall); -static u8 stm32f103_ep_stall_get(u8 addr); -static void stm32f103_ep_nak_set(u8 addr, u8 nak); -static u16 stm32f103_ep_write_packet(u8 addr, const void *buf, u16 len); -static u16 stm32f103_ep_read_packet(u8 addr, void *buf, u16 len); -static void stm32f103_poll(void); +static usbd_device *stm32f103_usbd_init(void); +static void stm32f103_set_address(usbd_device *usbd_dev, u8 addr); +static void stm32f103_ep_setup(usbd_device *usbd_dev, u8 addr, u8 type, + u16 max_size, + void (*callback) (usbd_device *usbd_dev, u8 ep)); +static void stm32f103_endpoints_reset(usbd_device *usbd_dev); +static void stm32f103_ep_stall_set(usbd_device *usbd_dev, u8 addr, u8 stall); +static u8 stm32f103_ep_stall_get(usbd_device *usbd_dev, u8 addr); +static void stm32f103_ep_nak_set(usbd_device *usbd_dev, u8 addr, u8 nak); +static u16 stm32f103_ep_write_packet(usbd_device *usbd_dev, u8 addr, + const void *buf, u16 len); +static u16 stm32f103_ep_read_packet(usbd_device *usbd_dev, u8 addr, void *buf, + u16 len); +static void stm32f103_poll(usbd_device *usbd_dev); static u8 force_nak[8]; +static struct _usbd_device usbd_dev; const struct _usbd_driver stm32f103_usb_driver = { .init = stm32f103_usbd_init, @@ -52,7 +56,7 @@ const struct _usbd_driver stm32f103_usb_driver = { }; /** Initialize the USB device controller hardware of the STM32. */ -static void stm32f103_usbd_init(void) +static usbd_device *stm32f103_usbd_init(void) { rcc_peripheral_enable_clock(&RCC_APB1ENR, RCC_APB1ENR_USBEN); SET_REG(USB_CNTR_REG, 0); @@ -62,10 +66,12 @@ static void stm32f103_usbd_init(void) /* Enable RESET, SUSPEND, RESUME and CTR interrupts. */ SET_REG(USB_CNTR_REG, USB_CNTR_RESETM | USB_CNTR_CTRM | USB_CNTR_SUSPM | USB_CNTR_WKUPM); + return &usbd_dev; } -static void stm32f103_set_address(u8 addr) +static void stm32f103_set_address(usbd_device *usbd_dev, u8 addr) { + (void)usbd_dev; /* Set device address and enable. */ SET_REG(USB_DADDR_REG, (addr & USB_DADDR_ADDR) | USB_DADDR_ENABLE); } @@ -76,8 +82,9 @@ static void stm32f103_set_address(u8 addr) * @param ep Index of endpoint to configure. * @param size Size in bytes of the RX buffer. */ -static void usb_set_ep_rx_bufsize(u8 ep, u32 size) +static void usb_set_ep_rx_bufsize(usbd_device *usbd_dev, u8 ep, u32 size) { + (void)usbd_dev; if (size > 62) { if (size & 0x1f) size -= 32; @@ -89,8 +96,9 @@ static void usb_set_ep_rx_bufsize(u8 ep, u32 size) } } -static void stm32f103_ep_setup(u8 addr, u8 type, u16 max_size, - void (*callback) (u8 ep)) +static void stm32f103_ep_setup(usbd_device *usbd_dev, u8 addr, u8 type, + u16 max_size, + void (*callback) (usbd_device *usbd_dev, u8 ep)) { /* Translate USB standard type codes to STM32. */ const u16 typelookup[] = { @@ -107,32 +115,30 @@ static void stm32f103_ep_setup(u8 addr, u8 type, u16 max_size, USB_SET_EP_TYPE(addr, typelookup[type]); if (dir || (addr == 0)) { - USB_SET_EP_TX_ADDR(addr, _usbd_device.pm_top); + USB_SET_EP_TX_ADDR(addr, usbd_dev->pm_top); if (callback) { - _usbd_device. - user_callback_ctr[addr][USB_TRANSACTION_IN] = + usbd_dev->user_callback_ctr[addr][USB_TRANSACTION_IN] = (void *)callback; } USB_CLR_EP_TX_DTOG(addr); USB_SET_EP_TX_STAT(addr, USB_EP_TX_STAT_NAK); - _usbd_device.pm_top += max_size; + usbd_dev->pm_top += max_size; } if (!dir) { - USB_SET_EP_RX_ADDR(addr, _usbd_device.pm_top); - usb_set_ep_rx_bufsize(addr, max_size); + USB_SET_EP_RX_ADDR(addr, usbd_dev->pm_top); + usb_set_ep_rx_bufsize(usbd_dev, addr, max_size); if (callback) { - _usbd_device. - user_callback_ctr[addr][USB_TRANSACTION_OUT] = + usbd_dev->user_callback_ctr[addr][USB_TRANSACTION_OUT] = (void *)callback; } USB_CLR_EP_RX_DTOG(addr); USB_SET_EP_RX_STAT(addr, USB_EP_RX_STAT_VALID); - _usbd_device.pm_top += max_size; + usbd_dev->pm_top += max_size; } } -static void stm32f103_endpoints_reset(void) +static void stm32f103_endpoints_reset(usbd_device *usbd_dev) { int i; @@ -141,11 +147,12 @@ static void stm32f103_endpoints_reset(void) USB_SET_EP_TX_STAT(i, USB_EP_TX_STAT_DISABLED); USB_SET_EP_RX_STAT(i, USB_EP_RX_STAT_DISABLED); } - _usbd_device.pm_top = 0x40 + (2 * _usbd_device.desc->bMaxPacketSize0); + usbd_dev->pm_top = 0x40 + (2 * usbd_dev->desc->bMaxPacketSize0); } -static void stm32f103_ep_stall_set(u8 addr, u8 stall) +static void stm32f103_ep_stall_set(usbd_device *usbd_dev, u8 addr, u8 stall) { + (void)usbd_dev; if (addr == 0) USB_SET_EP_TX_STAT(addr, stall ? USB_EP_TX_STAT_STALL : USB_EP_TX_STAT_NAK); @@ -169,8 +176,9 @@ static void stm32f103_ep_stall_set(u8 addr, u8 stall) } } -static u8 stm32f103_ep_stall_get(u8 addr) +static u8 stm32f103_ep_stall_get(usbd_device *usbd_dev, u8 addr) { + (void)usbd_dev; if (addr & 0x80) { if ((*USB_EP_REG(addr & 0x7F) & USB_EP_TX_STAT) == USB_EP_TX_STAT_STALL) @@ -183,8 +191,9 @@ static u8 stm32f103_ep_stall_get(u8 addr) return 0; } -static void stm32f103_ep_nak_set(u8 addr, u8 nak) +static void stm32f103_ep_nak_set(usbd_device *usbd_dev, u8 addr, u8 nak) { + (void)usbd_dev; /* It does not make sence to force NAK on IN endpoints. */ if (addr & 0x80) return; @@ -213,8 +222,10 @@ static void usb_copy_to_pm(volatile void *vPM, const void *buf, u16 len) *PM = *lbuf; } -static u16 stm32f103_ep_write_packet(u8 addr, const void *buf, u16 len) +static u16 stm32f103_ep_write_packet(usbd_device *usbd_dev, u8 addr, + const void *buf, u16 len) { + (void)usbd_dev; addr &= 0x7F; if ((*USB_EP_REG(addr) & USB_EP_TX_STAT) == USB_EP_TX_STAT_VALID) @@ -247,8 +258,10 @@ static void usb_copy_from_pm(void *buf, const volatile void *vPM, u16 len) *(u8 *) lbuf = *(u8 *) PM; } -static u16 stm32f103_ep_read_packet(u8 addr, void *buf, u16 len) +static u16 stm32f103_ep_read_packet(usbd_device *usbd_dev, u8 addr, void *buf, + u16 len) { + (void)usbd_dev; if ((*USB_EP_REG(addr) & USB_EP_RX_STAT) == USB_EP_RX_STAT_VALID) return 0; @@ -262,13 +275,13 @@ static u16 stm32f103_ep_read_packet(u8 addr, void *buf, u16 len) return len; } -static void stm32f103_poll(void) +static void stm32f103_poll(usbd_device *usbd_dev) { u16 istr = *USB_ISTR_REG; if (istr & USB_ISTR_RESET) { - _usbd_device.pm_top = 0x40; - _usbd_reset(); + usbd_dev->pm_top = 0x40; + _usbd_reset(usbd_dev); USB_CLR_ISTR_RESET(); return; } @@ -282,27 +295,27 @@ static void stm32f103_poll(void) else /* IN transaction */ USB_CLR_EP_TX_CTR(ep); - if (_usbd_device.user_callback_ctr[ep][type]) - _usbd_device.user_callback_ctr[ep][type] (ep); + if (usbd_dev->user_callback_ctr[ep][type]) + usbd_dev->user_callback_ctr[ep][type] (usbd_dev, ep); else USB_CLR_EP_RX_CTR(ep); } if (istr & USB_ISTR_SUSP) { USB_CLR_ISTR_SUSP(); - if (_usbd_device.user_callback_suspend) - _usbd_device.user_callback_suspend(); + if (usbd_dev->user_callback_suspend) + usbd_dev->user_callback_suspend(); } if (istr & USB_ISTR_WKUP) { USB_CLR_ISTR_WKUP(); - if (_usbd_device.user_callback_resume) - _usbd_device.user_callback_resume(); + if (usbd_dev->user_callback_resume) + usbd_dev->user_callback_resume(); } if (istr & USB_ISTR_SOF) { - if (_usbd_device.user_callback_sof) - _usbd_device.user_callback_sof(); + if (usbd_dev->user_callback_sof) + usbd_dev->user_callback_sof(); USB_CLR_ISTR_SOF(); } } diff --git a/lib/usb/usb_f107.c b/lib/usb/usb_f107.c index a5a4a6c9..009979d6 100644 --- a/lib/usb/usb_f107.c +++ b/lib/usb/usb_f107.c @@ -23,49 +23,34 @@ #include #include #include "usb_private.h" +#include "usb_fx07_common.h" /* Receive FIFO size in 32-bit words. */ #define RX_FIFO_SIZE 128 -static uint16_t fifo_mem_top; -static uint16_t fifo_mem_top_ep0; -static u8 force_nak[4]; +static usbd_device *stm32f107_usbd_init(void); -static void stm32f107_usbd_init(void); -static void stm32f107_set_address(u8 addr); -static void stm32f107_ep_setup(u8 addr, u8 type, u16 max_size, - void (*callback)(u8 ep)); -static void stm32f107_endpoints_reset(void); -static void stm32f107_ep_stall_set(u8 addr, u8 stall); -static u8 stm32f107_ep_stall_get(u8 addr); -static void stm32f107_ep_nak_set(u8 addr, u8 nak); -static u16 stm32f107_ep_write_packet(u8 addr, const void *buf, u16 len); -static u16 stm32f107_ep_read_packet(u8 addr, void *buf, u16 len); -static void stm32f107_poll(void); -static void stm32f107_disconnect(bool disconnected); - -/* - * We keep a backup copy of the out endpoint size registers to restore them - * after a transaction. - */ -static u32 doeptsiz[4]; +static struct _usbd_device usbd_dev; const struct _usbd_driver stm32f107_usb_driver = { .init = stm32f107_usbd_init, - .set_address = stm32f107_set_address, - .ep_setup = stm32f107_ep_setup, - .ep_reset = stm32f107_endpoints_reset, - .ep_stall_set = stm32f107_ep_stall_set, - .ep_stall_get = stm32f107_ep_stall_get, - .ep_nak_set = stm32f107_ep_nak_set, - .ep_write_packet = stm32f107_ep_write_packet, - .ep_read_packet = stm32f107_ep_read_packet, - .poll = stm32f107_poll, - .disconnect = stm32f107_disconnect, + .set_address = stm32fx07_set_address, + .ep_setup = stm32fx07_ep_setup, + .ep_reset = stm32fx07_endpoints_reset, + .ep_stall_set = stm32fx07_ep_stall_set, + .ep_stall_get = stm32fx07_ep_stall_get, + .ep_nak_set = stm32fx07_ep_nak_set, + .ep_write_packet = stm32fx07_ep_write_packet, + .ep_read_packet = stm32fx07_ep_read_packet, + .poll = stm32fx07_poll, + .disconnect = stm32fx07_disconnect, + .base_address = USB_OTG_FS_BASE, + .set_address_before_status = 1, + .rx_fifo_size = RX_FIFO_SIZE, }; /** Initialize the USB device controller hardware of the STM32. */ -static void stm32f107_usbd_init(void) +static usbd_device *stm32f107_usbd_init(void) { OTG_FS_GINTSTS = OTG_FS_GINTSTS_MMIS; @@ -88,8 +73,8 @@ static void stm32f107_usbd_init(void) /* Restart the PHY clock. */ OTG_FS_PCGCCTL = 0; - OTG_FS_GRXFSIZ = RX_FIFO_SIZE; - fifo_mem_top = RX_FIFO_SIZE; + OTG_FS_GRXFSIZ = stm32f107_usb_driver.rx_fifo_size; + usbd_dev.fifo_mem_top = stm32f107_usb_driver.rx_fifo_size; /* Unmask interrupts for TX and RX. */ OTG_FS_GAHBCFG |= OTG_FS_GAHBCFG_GINT; @@ -101,289 +86,6 @@ static void stm32f107_usbd_init(void) OTG_FS_GINTMSK_SOFM; OTG_FS_DAINTMSK = 0xF; OTG_FS_DIEPMSK = OTG_FS_DIEPMSK_XFRCM; -} - -static void stm32f107_set_address(u8 addr) -{ - OTG_FS_DCFG = (OTG_FS_DCFG & ~OTG_FS_DCFG_DAD) | (addr << 4); -} - -static void stm32f107_ep_setup(u8 addr, u8 type, u16 max_size, - void (*callback) (u8 ep)) -{ - /* - * Configure endpoint address and type. Allocate FIFO memory for - * endpoint. Install callback funciton. - */ - u8 dir = addr & 0x80; - addr &= 0x7f; - - if (addr == 0) { /* For the default control endpoint */ - /* Configure IN part. */ - if (max_size >= 64) { - OTG_FS_DIEPCTL0 = OTG_FS_DIEPCTL0_MPSIZ_64; - } else if (max_size >= 32) { - OTG_FS_DIEPCTL0 = OTG_FS_DIEPCTL0_MPSIZ_32; - } else if (max_size >= 16) { - OTG_FS_DIEPCTL0 = OTG_FS_DIEPCTL0_MPSIZ_16; - } else { - OTG_FS_DIEPCTL0 = OTG_FS_DIEPCTL0_MPSIZ_8; - } - OTG_FS_DIEPTSIZ0 = (max_size & OTG_FS_DIEPSIZ0_XFRSIZ_MASK); - OTG_FS_DIEPCTL0 |= OTG_FS_DIEPCTL0_EPENA | OTG_FS_DIEPCTL0_SNAK; - - /* Configure OUT part. */ - doeptsiz[0] = OTG_FS_DIEPSIZ0_STUPCNT_1 | (1 << 19) | - (max_size & OTG_FS_DIEPSIZ0_XFRSIZ_MASK); - OTG_FS_DOEPTSIZ(0) = doeptsiz[0]; - OTG_FS_DOEPCTL(0) |= - OTG_FS_DOEPCTL0_EPENA | OTG_FS_DIEPCTL0_SNAK; - - OTG_FS_GNPTXFSIZ = ((max_size / 4) << 16) | RX_FIFO_SIZE; - fifo_mem_top += max_size / 4; - fifo_mem_top_ep0 = fifo_mem_top; - - return; - } - - if (dir) { - OTG_FS_DIEPTXF(addr) = ((max_size / 4) << 16) | fifo_mem_top; - fifo_mem_top += max_size / 4; - - OTG_FS_DIEPTSIZ(addr) = - (max_size & OTG_FS_DIEPSIZ0_XFRSIZ_MASK); - OTG_FS_DIEPCTL(addr) |= - OTG_FS_DIEPCTL0_EPENA | OTG_FS_DIEPCTL0_SNAK | (type << 18) - | OTG_FS_DIEPCTL0_USBAEP | OTG_FS_DIEPCTLX_SD0PID - | (addr << 22) | max_size; - - if (callback) { - _usbd_device. - user_callback_ctr[addr][USB_TRANSACTION_IN] = - (void *)callback; - } - } - - if (!dir) { - doeptsiz[addr] = (1 << 19) | - (max_size & OTG_FS_DIEPSIZ0_XFRSIZ_MASK); - OTG_FS_DOEPTSIZ(addr) = doeptsiz[addr]; - OTG_FS_DOEPCTL(addr) |= OTG_FS_DOEPCTL0_EPENA | - OTG_FS_DOEPCTL0_USBAEP | OTG_FS_DIEPCTL0_CNAK | - OTG_FS_DOEPCTLX_SD0PID | (type << 18) | max_size; - - if (callback) { - _usbd_device. - user_callback_ctr[addr][USB_TRANSACTION_OUT] = - (void *)callback; - } - } -} - -static void stm32f107_endpoints_reset(void) -{ - /* The core resets the endpoints automatically on reset. */ - fifo_mem_top = fifo_mem_top_ep0; -} - -static void stm32f107_ep_stall_set(u8 addr, u8 stall) -{ - if (addr == 0) { - if (stall) - OTG_FS_DIEPCTL(addr) |= OTG_FS_DIEPCTL0_STALL; - else - OTG_FS_DIEPCTL(addr) &= ~OTG_FS_DIEPCTL0_STALL; - } - - if (addr & 0x80) { - addr &= 0x7F; - - if (stall) { - OTG_FS_DIEPCTL(addr) |= OTG_FS_DIEPCTL0_STALL; - } else { - OTG_FS_DIEPCTL(addr) &= ~OTG_FS_DIEPCTL0_STALL; - OTG_FS_DIEPCTL(addr) |= OTG_FS_DIEPCTLX_SD0PID; - } - } else { - if (stall) { - OTG_FS_DOEPCTL(addr) |= OTG_FS_DOEPCTL0_STALL; - } else { - OTG_FS_DOEPCTL(addr) &= ~OTG_FS_DOEPCTL0_STALL; - OTG_FS_DOEPCTL(addr) |= OTG_FS_DOEPCTLX_SD0PID; - } - } -} - -static u8 stm32f107_ep_stall_get(u8 addr) -{ - /* Return non-zero if STALL set. */ - if (addr & 0x80) - return - (OTG_FS_DIEPCTL(addr & 0x7f) & OTG_FS_DIEPCTL0_STALL) ? 1 : 0; - else - return (OTG_FS_DOEPCTL(addr) & OTG_FS_DOEPCTL0_STALL) ? 1 : 0; -} - -static void stm32f107_ep_nak_set(u8 addr, u8 nak) -{ - /* It does not make sence to force NAK on IN endpoints. */ - if (addr & 0x80) - return; - - force_nak[addr] = nak; - - if (nak) - OTG_FS_DOEPCTL(addr) |= OTG_FS_DOEPCTL0_SNAK; - else - OTG_FS_DOEPCTL(addr) |= OTG_FS_DOEPCTL0_CNAK; -} - -static u16 stm32f107_ep_write_packet(u8 addr, const void *buf, u16 len) -{ - const u32 *buf32 = buf; - int i; - - addr &= 0x7F; - - /* Return if endpoint is already enabled. */ - if (OTG_FS_DIEPTSIZ(addr) & OTG_FS_DIEPSIZ0_PKTCNT) - return 0; - - /* Enable endpoint for transmission. */ - OTG_FS_DIEPTSIZ(addr) = (1 << 19) | len; - OTG_FS_DIEPCTL(addr) |= OTG_FS_DIEPCTL0_EPENA | OTG_FS_DIEPCTL0_CNAK; - - /* Copy buffer to endpoint FIFO. */ - volatile u32 *fifo = OTG_FS_FIFO(addr); - for (i = len; i > 0; i -= 4) - *fifo++ = *buf32++; - - return len; -} - -/* - * Received packet size for each endpoint. This is assigned in - * stm32f107_poll() which reads the packet status push register GRXSTSP - * for use in stm32f107_ep_read_packet(). - */ -static uint16_t rxbcnt; - -static u16 stm32f107_ep_read_packet(u8 addr, void *buf, u16 len) -{ - int i; - u32 *buf32 = buf; - u32 extra; - - len = MIN(len, rxbcnt); - rxbcnt -= len; - - volatile u32 *fifo = OTG_FS_FIFO(addr); - for (i = len; i >= 4; i -= 4) - *buf32++ = *fifo++; - - if (i) { - extra = *fifo++; - memcpy(buf32, &extra, i); - } - - OTG_FS_DOEPTSIZ(addr) = doeptsiz[addr]; - OTG_FS_DOEPCTL(addr) |= OTG_FS_DOEPCTL0_EPENA | - (force_nak[addr] ? OTG_FS_DOEPCTL0_SNAK : OTG_FS_DOEPCTL0_CNAK); - - return len; -} - -static void stm32f107_poll(void) -{ - /* Read interrupt status register. */ - u32 intsts = OTG_FS_GINTSTS; - int i; - - if (intsts & OTG_FS_GINTSTS_ENUMDNE) { - /* Handle USB RESET condition. */ - OTG_FS_GINTSTS = OTG_FS_GINTSTS_ENUMDNE; - fifo_mem_top = RX_FIFO_SIZE; - _usbd_reset(); - return; - } - - /* Note: RX and TX handled differently in this device. */ - if (intsts & OTG_FS_GINTSTS_RXFLVL) { - /* Receive FIFO non-empty. */ - u32 rxstsp = OTG_FS_GRXSTSP; - u32 pktsts = rxstsp & OTG_FS_GRXSTSP_PKTSTS_MASK; - if ((pktsts != OTG_FS_GRXSTSP_PKTSTS_OUT) && - (pktsts != OTG_FS_GRXSTSP_PKTSTS_SETUP)) - return; - - u8 ep = rxstsp & OTG_FS_GRXSTSP_EPNUM_MASK; - u8 type; - if (pktsts == OTG_FS_GRXSTSP_PKTSTS_SETUP) - type = USB_TRANSACTION_SETUP; - else - type = USB_TRANSACTION_OUT; - - /* Save packet size for stm32f107_ep_read_packet(). */ - rxbcnt = (rxstsp & OTG_FS_GRXSTSP_BCNT_MASK) >> 4; - - /* - * FIXME: Why is a delay needed here? - * This appears to fix a problem where the first 4 bytes - * of the DATA OUT stage of a control transaction are lost. - */ - for (i = 0; i < 1000; i++) - __asm__("nop"); - - if (_usbd_device.user_callback_ctr[ep][type]) - _usbd_device.user_callback_ctr[ep][type] (ep); - - /* Discard unread packet data. */ - for (i = 0; i < rxbcnt; i += 4) - (void)*OTG_FS_FIFO(ep); - - rxbcnt = 0; - } - - /* - * There is no global interrupt flag for transmit complete. - * The XFRC bit must be checked in each OTG_FS_DIEPINT(x). - */ - for (i = 0; i < 4; i++) { /* Iterate over endpoints. */ - if (OTG_FS_DIEPINT(i) & OTG_FS_DIEPINTX_XFRC) { - /* Transfer complete. */ - if (_usbd_device. - user_callback_ctr[i][USB_TRANSACTION_IN]) { - _usbd_device. - user_callback_ctr[i][USB_TRANSACTION_IN](i); - } - OTG_FS_DIEPINT(i) = OTG_FS_DIEPINTX_XFRC; - } - } - - if (intsts & OTG_FS_GINTSTS_USBSUSP) { - if (_usbd_device.user_callback_suspend) - _usbd_device.user_callback_suspend(); - OTG_FS_GINTSTS = OTG_FS_GINTSTS_USBSUSP; - } - - if (intsts & OTG_FS_GINTSTS_WKUPINT) { - if (_usbd_device.user_callback_resume) - _usbd_device.user_callback_resume(); - OTG_FS_GINTSTS = OTG_FS_GINTSTS_WKUPINT; - } - - if (intsts & OTG_FS_GINTSTS_SOF) { - if (_usbd_device.user_callback_sof) - _usbd_device.user_callback_sof(); - OTG_FS_GINTSTS = OTG_FS_GINTSTS_SOF; - } -} - -static void stm32f107_disconnect(bool disconnected) -{ - if (disconnected) { - OTG_FS_DCTL |= OTG_FS_DCTL_SDIS; - } else { - OTG_FS_DCTL &= ~OTG_FS_DCTL_SDIS; - } + + return &usbd_dev; } diff --git a/lib/usb/usb_f207.c b/lib/usb/usb_f207.c new file mode 100644 index 00000000..b2509e5e --- /dev/null +++ b/lib/usb/usb_f207.c @@ -0,0 +1,91 @@ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2011 Gareth McMullin + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#include +#include +#include +#include +#include +#include "usb_private.h" +#include "usb_fx07_common.h" + +/* Receive FIFO size in 32-bit words. */ +#define RX_FIFO_SIZE 512 + +static usbd_device *stm32f207_usbd_init(void); + +static struct _usbd_device usbd_dev; + +const struct _usbd_driver stm32f207_usb_driver = { + .init = stm32f207_usbd_init, + .set_address = stm32fx07_set_address, + .ep_setup = stm32fx07_ep_setup, + .ep_reset = stm32fx07_endpoints_reset, + .ep_stall_set = stm32fx07_ep_stall_set, + .ep_stall_get = stm32fx07_ep_stall_get, + .ep_nak_set = stm32fx07_ep_nak_set, + .ep_write_packet = stm32fx07_ep_write_packet, + .ep_read_packet = stm32fx07_ep_read_packet, + .poll = stm32fx07_poll, + .disconnect = stm32fx07_disconnect, + .base_address = USB_OTG_HS_BASE, + .set_address_before_status = 1, + .rx_fifo_size = RX_FIFO_SIZE, +}; + +/** Initialize the USB device controller hardware of the STM32. */ +static usbd_device *stm32f207_usbd_init(void) +{ + OTG_HS_GINTSTS = OTG_HS_GINTSTS_MMIS; + + OTG_HS_GUSBCFG |= OTG_HS_GUSBCFG_PHYSEL; + /* Enable VBUS sensing in device mode and power down the PHY. */ + OTG_HS_GCCFG |= OTG_HS_GCCFG_VBUSBSEN | OTG_HS_GCCFG_PWRDWN; + + /* Wait for AHB idle. */ + while (!(OTG_HS_GRSTCTL & OTG_HS_GRSTCTL_AHBIDL)) ; + /* Do core soft reset. */ + OTG_HS_GRSTCTL |= OTG_HS_GRSTCTL_CSRST; + while (OTG_HS_GRSTCTL & OTG_HS_GRSTCTL_CSRST) ; + + /* Force peripheral only mode. */ + OTG_HS_GUSBCFG |= OTG_HS_GUSBCFG_FDMOD | OTG_HS_GUSBCFG_TRDT_MASK; + + /* Full speed device. */ + OTG_HS_DCFG |= OTG_HS_DCFG_DSPD; + + /* Restart the PHY clock. */ + OTG_HS_PCGCCTL = 0; + + OTG_HS_GRXFSIZ = stm32f207_usb_driver.rx_fifo_size; + usbd_dev.fifo_mem_top = stm32f207_usb_driver.rx_fifo_size; + + /* Unmask interrupts for TX and RX. */ + OTG_HS_GAHBCFG |= OTG_HS_GAHBCFG_GINT; + OTG_HS_GINTMSK = OTG_HS_GINTMSK_ENUMDNEM | + OTG_HS_GINTMSK_RXFLVLM | + OTG_HS_GINTMSK_IEPINT | + OTG_HS_GINTMSK_USBSUSPM | + OTG_HS_GINTMSK_WUIM | + OTG_HS_GINTMSK_SOFM; + OTG_HS_DAINTMSK = 0xF; + OTG_HS_DIEPMSK = OTG_HS_DIEPMSK_XFRCM; + + return &usbd_dev; +} diff --git a/lib/usb/usb_fx07_common.c b/lib/usb/usb_fx07_common.c new file mode 100644 index 00000000..9178092c --- /dev/null +++ b/lib/usb/usb_fx07_common.c @@ -0,0 +1,318 @@ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2011 Gareth McMullin + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#include +#include +#include +#include +#include +#include +#include "usb_private.h" +#include "usb_fx07_common.h" + +/* The FS core and the HS core have the same register layout. + * As the code can be used on both cores, the registers offset is modified + * according to the selected cores base address. */ +#define dev_base_address (usbd_dev->driver->base_address) +#define REBASE(x) MMIO32((x)+(dev_base_address)) +#define REBASE_FIFO(x) ((volatile u32*)((dev_base_address) + (OTG_FIFO(x)))) + +void stm32fx07_set_address(usbd_device *usbd_dev, u8 addr) +{ + REBASE(OTG_DCFG) = (REBASE(OTG_DCFG) & ~OTG_FS_DCFG_DAD) | (addr << 4); +} + +void stm32fx07_ep_setup(usbd_device *usbd_dev, u8 addr, u8 type, u16 max_size, + void (*callback) (usbd_device *usbd_dev, u8 ep)) +{ + /* + * Configure endpoint address and type. Allocate FIFO memory for + * endpoint. Install callback funciton. + */ + u8 dir = addr & 0x80; + addr &= 0x7f; + + if (addr == 0) { /* For the default control endpoint */ + /* Configure IN part. */ + if (max_size >= 64) { + REBASE(OTG_DIEPCTL0) = OTG_FS_DIEPCTL0_MPSIZ_64; + } else if (max_size >= 32) { + REBASE(OTG_DIEPCTL0) = OTG_FS_DIEPCTL0_MPSIZ_32; + } else if (max_size >= 16) { + REBASE(OTG_DIEPCTL0) = OTG_FS_DIEPCTL0_MPSIZ_16; + } else { + REBASE(OTG_DIEPCTL0) = OTG_FS_DIEPCTL0_MPSIZ_8; + } + REBASE(OTG_DIEPTSIZ0) = + (max_size & OTG_FS_DIEPSIZ0_XFRSIZ_MASK); + REBASE(OTG_DIEPCTL0) |= + OTG_FS_DIEPCTL0_EPENA | OTG_FS_DIEPCTL0_SNAK; + + /* Configure OUT part. */ + usbd_dev->doeptsiz[0] = OTG_FS_DIEPSIZ0_STUPCNT_1 | + OTG_FS_DIEPSIZ0_PKTCNT | + (max_size & OTG_FS_DIEPSIZ0_XFRSIZ_MASK); + REBASE(OTG_DOEPTSIZ(0)) = usbd_dev->doeptsiz[0]; + REBASE(OTG_DOEPCTL(0)) |= + OTG_FS_DOEPCTL0_EPENA | OTG_FS_DIEPCTL0_SNAK; + + REBASE(OTG_GNPTXFSIZ) = ((max_size / 4) << 16) | + usbd_dev->driver->rx_fifo_size; + usbd_dev->fifo_mem_top += max_size / 4; + usbd_dev->fifo_mem_top_ep0 = usbd_dev->fifo_mem_top; + + return; + } + + if (dir) { + REBASE(OTG_DIEPTXF(addr)) = ((max_size / 4) << 16) | + usbd_dev->fifo_mem_top; + usbd_dev->fifo_mem_top += max_size / 4; + + REBASE(OTG_DIEPTSIZ(addr)) = + (max_size & OTG_FS_DIEPSIZ0_XFRSIZ_MASK); + REBASE(OTG_DIEPCTL(addr)) |= + OTG_FS_DIEPCTL0_EPENA | OTG_FS_DIEPCTL0_SNAK | (type << 18) + | OTG_FS_DIEPCTL0_USBAEP | OTG_FS_DIEPCTLX_SD0PID + | (addr << 22) | max_size; + + if (callback) { + usbd_dev->user_callback_ctr[addr][USB_TRANSACTION_IN] = + (void *)callback; + } + } + + if (!dir) { + usbd_dev->doeptsiz[addr] = OTG_FS_DIEPSIZ0_PKTCNT | + (max_size & OTG_FS_DIEPSIZ0_XFRSIZ_MASK); + REBASE(OTG_DOEPTSIZ(addr)) = usbd_dev->doeptsiz[addr]; + REBASE(OTG_DOEPCTL(addr)) |= OTG_FS_DOEPCTL0_EPENA | + OTG_FS_DOEPCTL0_USBAEP | OTG_FS_DIEPCTL0_CNAK | + OTG_FS_DOEPCTLX_SD0PID | (type << 18) | max_size; + + if (callback) { + usbd_dev->user_callback_ctr[addr][USB_TRANSACTION_OUT] = + (void *)callback; + } + } +} + +void stm32fx07_endpoints_reset(usbd_device *usbd_dev) +{ + /* The core resets the endpoints automatically on reset. */ + usbd_dev->fifo_mem_top = usbd_dev->fifo_mem_top_ep0; +} + +void stm32fx07_ep_stall_set(usbd_device *usbd_dev, u8 addr, u8 stall) +{ + if (addr == 0) { + if (stall) + REBASE(OTG_DIEPCTL(addr)) |= OTG_FS_DIEPCTL0_STALL; + else + REBASE(OTG_DIEPCTL(addr)) &= ~OTG_FS_DIEPCTL0_STALL; + } + + if (addr & 0x80) { + addr &= 0x7F; + + if (stall) { + REBASE(OTG_DIEPCTL(addr)) |= OTG_FS_DIEPCTL0_STALL; + } else { + REBASE(OTG_DIEPCTL(addr)) &= ~OTG_FS_DIEPCTL0_STALL; + REBASE(OTG_DIEPCTL(addr)) |= OTG_FS_DIEPCTLX_SD0PID; + } + } else { + if (stall) { + REBASE(OTG_DOEPCTL(addr)) |= OTG_FS_DOEPCTL0_STALL; + } else { + REBASE(OTG_DOEPCTL(addr)) &= ~OTG_FS_DOEPCTL0_STALL; + REBASE(OTG_DOEPCTL(addr)) |= OTG_FS_DOEPCTLX_SD0PID; + } + } +} + +u8 stm32fx07_ep_stall_get(usbd_device *usbd_dev, u8 addr) +{ + /* Return non-zero if STALL set. */ + if (addr & 0x80) + return (REBASE(OTG_DIEPCTL(addr & 0x7f)) & + OTG_FS_DIEPCTL0_STALL) ? 1 : 0; + else + return (REBASE(OTG_DOEPCTL(addr)) & + OTG_FS_DOEPCTL0_STALL) ? 1 : 0; +} + +void stm32fx07_ep_nak_set(usbd_device *usbd_dev, u8 addr, u8 nak) +{ + /* It does not make sence to force NAK on IN endpoints. */ + if (addr & 0x80) + return; + + usbd_dev->force_nak[addr] = nak; + + if (nak) + REBASE(OTG_DOEPCTL(addr)) |= OTG_FS_DOEPCTL0_SNAK; + else + REBASE(OTG_DOEPCTL(addr)) |= OTG_FS_DOEPCTL0_CNAK; +} + +u16 stm32fx07_ep_write_packet(usbd_device *usbd_dev, u8 addr, + const void *buf, u16 len) +{ + const u32 *buf32 = buf; + int i; + + addr &= 0x7F; + + /* Return if endpoint is already enabled. */ + if (REBASE(OTG_DIEPTSIZ(addr)) & OTG_FS_DIEPSIZ0_PKTCNT) + return 0; + + /* Enable endpoint for transmission. */ + REBASE(OTG_DIEPTSIZ(addr)) = OTG_FS_DIEPSIZ0_PKTCNT | len; + REBASE(OTG_DIEPCTL(addr)) |= OTG_FS_DIEPCTL0_EPENA | + OTG_FS_DIEPCTL0_CNAK; + volatile u32 *fifo = REBASE_FIFO(addr); + + /* Copy buffer to endpoint FIFO, note - memcpy does not work */ + for (i = len; i > 0; i -= 4) + *fifo++ = *buf32++; + + return len; +} + +u16 stm32fx07_ep_read_packet(usbd_device *usbd_dev, u8 addr, void *buf, u16 len) +{ + int i; + u32 *buf32 = buf; + u32 extra; + + len = MIN(len, usbd_dev->rxbcnt); + usbd_dev->rxbcnt -= len; + + volatile u32 *fifo = REBASE_FIFO(addr); + for (i = len; i >= 4; i -= 4) + *buf32++ = *fifo++; + + if (i) { + extra = *fifo++; + memcpy(buf32, &extra, i); + } + + REBASE(OTG_DOEPTSIZ(addr)) = usbd_dev->doeptsiz[addr]; + REBASE(OTG_DOEPCTL(addr)) |= OTG_FS_DOEPCTL0_EPENA | + (usbd_dev->force_nak[addr] ? + OTG_FS_DOEPCTL0_SNAK : OTG_FS_DOEPCTL0_CNAK); + + return len; +} + +void stm32fx07_poll(usbd_device *usbd_dev) +{ + /* Read interrupt status register. */ + u32 intsts = REBASE(OTG_GINTSTS); + int i; + + if (intsts & OTG_FS_GINTSTS_ENUMDNE) { + /* Handle USB RESET condition. */ + REBASE(OTG_GINTSTS) = OTG_FS_GINTSTS_ENUMDNE; + usbd_dev->fifo_mem_top = usbd_dev->driver->rx_fifo_size; + _usbd_reset(usbd_dev); + return; + } + + /* Note: RX and TX handled differently in this device. */ + if (intsts & OTG_FS_GINTSTS_RXFLVL) { + /* Receive FIFO non-empty. */ + u32 rxstsp = REBASE(OTG_GRXSTSP); + u32 pktsts = rxstsp & OTG_FS_GRXSTSP_PKTSTS_MASK; + if ((pktsts != OTG_FS_GRXSTSP_PKTSTS_OUT) && + (pktsts != OTG_FS_GRXSTSP_PKTSTS_SETUP)) + return; + + u8 ep = rxstsp & OTG_FS_GRXSTSP_EPNUM_MASK; + u8 type; + if (pktsts == OTG_FS_GRXSTSP_PKTSTS_SETUP) + type = USB_TRANSACTION_SETUP; + else + type = USB_TRANSACTION_OUT; + + /* Save packet size for stm32f107_ep_read_packet(). */ + usbd_dev->rxbcnt = (rxstsp & OTG_FS_GRXSTSP_BCNT_MASK) >> 4; + + /* + * FIXME: Why is a delay needed here? + * This appears to fix a problem where the first 4 bytes + * of the DATA OUT stage of a control transaction are lost. + */ + for (i = 0; i < 1000; i++) + __asm__("nop"); + + if (usbd_dev->user_callback_ctr[ep][type]) + usbd_dev->user_callback_ctr[ep][type] (usbd_dev, ep); + + /* Discard unread packet data. */ + for (i = 0; i < usbd_dev->rxbcnt; i += 4) + (void)*REBASE_FIFO(ep); + + usbd_dev->rxbcnt = 0; + } + + /* + * There is no global interrupt flag for transmit complete. + * The XFRC bit must be checked in each OTG_FS_DIEPINT(x). + */ + for (i = 0; i < 4; i++) { /* Iterate over endpoints. */ + if (REBASE(OTG_DIEPINT(i)) & OTG_FS_DIEPINTX_XFRC) { + /* Transfer complete. */ + if (usbd_dev->user_callback_ctr[i][USB_TRANSACTION_IN]) + usbd_dev->user_callback_ctr[i] + [USB_TRANSACTION_IN](usbd_dev, i); + + REBASE(OTG_DIEPINT(i)) = OTG_FS_DIEPINTX_XFRC; + } + } + + if (intsts & OTG_FS_GINTSTS_USBSUSP) { + if (usbd_dev->user_callback_suspend) + usbd_dev->user_callback_suspend(); + REBASE(OTG_GINTSTS) = OTG_FS_GINTSTS_USBSUSP; + } + + if (intsts & OTG_FS_GINTSTS_WKUPINT) { + if (usbd_dev->user_callback_resume) + usbd_dev->user_callback_resume(); + REBASE(OTG_GINTSTS) = OTG_FS_GINTSTS_WKUPINT; + } + + if (intsts & OTG_FS_GINTSTS_SOF) { + if (usbd_dev->user_callback_sof) + usbd_dev->user_callback_sof(); + REBASE(OTG_GINTSTS) = OTG_FS_GINTSTS_SOF; + } +} + +void stm32fx07_disconnect(usbd_device *usbd_dev, bool disconnected) +{ + if (disconnected) { + REBASE(OTG_DCTL) |= OTG_FS_DCTL_SDIS; + } else { + REBASE(OTG_DCTL) &= ~OTG_FS_DCTL_SDIS; + } +} diff --git a/lib/usb/usb_fx07_common.h b/lib/usb/usb_fx07_common.h new file mode 100644 index 00000000..4d8d38e2 --- /dev/null +++ b/lib/usb/usb_fx07_common.h @@ -0,0 +1,38 @@ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2011 Gareth McMullin + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#ifndef __USB_FX07_COMMON_H_ +#define __USB_FX07_COMMON_H_ + +void stm32fx07_set_address(usbd_device *usbd_dev, u8 addr); +void stm32fx07_ep_setup(usbd_device *usbd_dev, u8 addr, u8 type, u16 max_size, + void (*callback)(usbd_device *usbd_dev, u8 ep)); +void stm32fx07_endpoints_reset(usbd_device *usbd_dev); +void stm32fx07_ep_stall_set(usbd_device *usbd_dev, u8 addr, u8 stall); +u8 stm32fx07_ep_stall_get(usbd_device *usbd_dev, u8 addr); +void stm32fx07_ep_nak_set(usbd_device *usbd_dev, u8 addr, u8 nak); +u16 stm32fx07_ep_write_packet(usbd_device *usbd_dev, u8 addr, const void *buf, + u16 len); +u16 stm32fx07_ep_read_packet(usbd_device *usbd_dev, u8 addr, void *buf, + u16 len); +void stm32fx07_poll(usbd_device *usbd_dev); +void stm32fx07_disconnect(usbd_device *usbd_dev, bool disconnected); + + +#endif /* __USB_FX07_COMMON_H_ */ diff --git a/lib/usb/usb_private.h b/lib/usb/usb_private.h index a1e5e4c8..2506ba53 100644 --- a/lib/usb/usb_private.h +++ b/lib/usb/usb_private.h @@ -25,7 +25,7 @@ #define MIN(a, b) ((a)<(b) ? (a) : (b)) /** Internal collection of device information. */ -extern struct _usbd_device { +struct _usbd_device { const struct usb_device_descriptor *desc; const struct usb_config_descriptor *config; const char **strings; @@ -44,19 +44,49 @@ extern struct _usbd_device { void (*user_callback_resume)(void); void (*user_callback_sof)(void); + struct usb_control_state { + enum { + IDLE, STALLED, + DATA_IN, LAST_DATA_IN, STATUS_IN, + DATA_OUT, LAST_DATA_OUT, STATUS_OUT, + } state; + struct usb_setup_data req __attribute__((aligned(4))); + u8 *ctrl_buf; + u16 ctrl_len; + void (*complete)(usbd_device *usbd_dev, + struct usb_setup_data *req); + } control_state; + struct user_control_callback { usbd_control_callback cb; u8 type; u8 type_mask; } user_control_callback[MAX_USER_CONTROL_CALLBACK]; - void (*user_callback_ctr[8][3])(u8 ea); + void (*user_callback_ctr[8][3])(usbd_device *usbd_dev, u8 ea); /* User callback function for some standard USB function hooks */ - void (*user_callback_set_config)(u16 wValue); + void (*user_callback_set_config)(usbd_device *usbd_dev, u16 wValue); const struct _usbd_driver *driver; -} _usbd_device; + + /* private driver data */ + + uint16_t fifo_mem_top; + uint16_t fifo_mem_top_ep0; + u8 force_nak[4]; + /* + * We keep a backup copy of the out endpoint size registers to restore them + * after a transaction. + */ + u32 doeptsiz[4]; + /* + * Received packet size for each endpoint. This is assigned in + * stm32f107_poll() which reads the packet status push register GRXSTSP + * for use in stm32f107_ep_read_packet(). + */ + uint16_t rxbcnt; +}; enum _usbd_transaction { USB_TRANSACTION_IN, @@ -64,31 +94,34 @@ enum _usbd_transaction { USB_TRANSACTION_SETUP, }; -void _usbd_control_in(u8 ea); -void _usbd_control_out(u8 ea); -void _usbd_control_setup(u8 ea); +void _usbd_control_in(usbd_device *usbd_dev, u8 ea); +void _usbd_control_out(usbd_device *usbd_dev, u8 ea); +void _usbd_control_setup(usbd_device *usbd_dev, u8 ea); -int _usbd_standard_request(struct usb_setup_data *req, u8 **buf, u16 *len); +int _usbd_standard_request(usbd_device *usbd_dev, struct usb_setup_data *req, + u8 **buf, u16 *len); -void _usbd_reset(void); +void _usbd_reset(usbd_device *usbd_dev); /* Functions provided by the hardware abstraction. */ struct _usbd_driver { - void (*init)(void); - void (*set_address)(u8 addr); - void (*ep_setup)(u8 addr, u8 type, u16 max_size, void (*cb)(u8 ep)); - void (*ep_reset)(void); - void (*ep_stall_set)(u8 addr, u8 stall); - void (*ep_nak_set)(u8 addr, u8 nak); - u8 (*ep_stall_get)(u8 addr); - u16 (*ep_write_packet)(u8 addr, const void *buf, u16 len); - u16 (*ep_read_packet)(u8 addr, void *buf, u16 len); - void (*poll)(void); - void (*disconnect)(bool disconnected); + usbd_device *(*init)(void); + void (*set_address)(usbd_device *usbd_dev, u8 addr); + void (*ep_setup)(usbd_device *usbd_dev, u8 addr, u8 type, u16 max_size, + void (*cb)(usbd_device *usbd_dev, u8 ep)); + void (*ep_reset)(usbd_device *usbd_dev); + void (*ep_stall_set)(usbd_device *usbd_dev, u8 addr, u8 stall); + void (*ep_nak_set)(usbd_device *usbd_dev, u8 addr, u8 nak); + u8 (*ep_stall_get)(usbd_device *usbd_dev, u8 addr); + u16 (*ep_write_packet)(usbd_device *usbd_dev, u8 addr, const void *buf, + u16 len); + u16 (*ep_read_packet)(usbd_device *usbd_dev, u8 addr, void *buf, + u16 len); + void (*poll)(usbd_device *usbd_dev); + void (*disconnect)(usbd_device *usbd_dev, bool disconnected); + u32 base_address; + bool set_address_before_status; + u16 rx_fifo_size; }; -#define _usbd_hw_init() _usbd_device.driver->init() -#define _usbd_hw_set_address(addr) _usbd_device.driver->set_address(addr) -#define _usbd_hw_endpoints_reset() _usbd_device.driver->ep_reset() - #endif diff --git a/lib/usb/usb_standard.c b/lib/usb/usb_standard.c index 2d7c619e..5a92cd85 100644 --- a/lib/usb/usb_standard.c +++ b/lib/usb/usb_standard.c @@ -21,15 +21,18 @@ #include #include "usb_private.h" -void usbd_register_set_config_callback(void (*callback)(u16 wValue)) +void usbd_register_set_config_callback(usbd_device *usbd_dev, + void (*callback)(usbd_device *usbd_dev, + u16 wValue)) { - _usbd_device.user_callback_set_config = callback; + usbd_dev->user_callback_set_config = callback; } -static u16 build_config_descriptor(u8 index, u8 *buf, u16 len) +static u16 build_config_descriptor(usbd_device *usbd_dev, + u8 index, u8 *buf, u16 len) { u8 *tmpbuf = buf; - const struct usb_config_descriptor *cfg = &_usbd_device.config[index]; + const struct usb_config_descriptor *cfg = &usbd_dev->config[index]; u16 count, total = 0, totallen = 0; u16 i, j, k; @@ -43,7 +46,7 @@ static u16 build_config_descriptor(u8 index, u8 *buf, u16 len) for (i = 0; i < cfg->bNumInterfaces; i++) { /* Interface Association Descriptor, if any */ if (cfg->interface[i].iface_assoc) { - const struct usb_iface_assoc_descriptor *assoc = + const struct usb_iface_assoc_descriptor *assoc = cfg->interface[i].iface_assoc; memcpy(buf, assoc, count = MIN(len, assoc->bLength)); buf += count; @@ -87,7 +90,8 @@ static u16 build_config_descriptor(u8 index, u8 *buf, u16 len) return total; } -static int usb_standard_get_descriptor(struct usb_setup_data *req, +static int usb_standard_get_descriptor(usbd_device *usbd_dev, + struct usb_setup_data *req, u8 **buf, u16 *len) { int i; @@ -95,25 +99,26 @@ static int usb_standard_get_descriptor(struct usb_setup_data *req, switch (req->wValue >> 8) { case USB_DT_DEVICE: - *buf = (u8 *) _usbd_device.desc; - *len = MIN(*len, _usbd_device.desc->bLength); + *buf = (u8 *) usbd_dev->desc; + *len = MIN(*len, usbd_dev->desc->bLength); return 1; case USB_DT_CONFIGURATION: - *buf = _usbd_device.ctrl_buf; - *len = build_config_descriptor(req->wValue & 0xff, *buf, *len); + *buf = usbd_dev->ctrl_buf; + *len = build_config_descriptor(usbd_dev, req->wValue & 0xff, + *buf, *len); return 1; case USB_DT_STRING: - sd = (struct usb_string_descriptor *)_usbd_device.ctrl_buf; + sd = (struct usb_string_descriptor *)usbd_dev->ctrl_buf; - if (!_usbd_device.strings) + if (!usbd_dev->strings) return 0; /* Device doesn't support strings. */ /* Check that string index is in range. */ for (i = 0; i <= (req->wValue & 0xff); i++) - if (_usbd_device.strings[i] == NULL) + if (usbd_dev->strings[i] == NULL) return 0; - sd->bLength = strlen(_usbd_device.strings[req->wValue & 0xff]) + sd->bLength = strlen(usbd_dev->strings[req->wValue & 0xff]) * 2 + 2; sd->bDescriptorType = USB_DT_STRING; @@ -122,7 +127,7 @@ static int usb_standard_get_descriptor(struct usb_setup_data *req, for (i = 0; i < (*len / 2) - 1; i++) sd->wData[i] = - _usbd_device.strings[req->wValue & 0xff][i]; + usbd_dev->strings[req->wValue & 0xff][i]; /* Send sane Language ID descriptor... */ if ((req->wValue & 0xff) == 0) @@ -133,7 +138,8 @@ static int usb_standard_get_descriptor(struct usb_setup_data *req, return 0; } -static int usb_standard_set_address(struct usb_setup_data *req, u8 **buf, +static int usb_standard_set_address(usbd_device *usbd_dev, + struct usb_setup_data *req, u8 **buf, u16 *len) { (void)req; @@ -144,19 +150,20 @@ static int usb_standard_set_address(struct usb_setup_data *req, u8 **buf, if ((req->bmRequestType != 0) || (req->wValue >= 128)) return 0; - _usbd_device.current_address = req->wValue; + usbd_dev->current_address = req->wValue; /* * Special workaround for STM32F10[57] that require the address * to be set here. This is undocumented! */ - if (_usbd_device.driver == &stm32f107_usb_driver) - _usbd_device.driver->set_address(req->wValue); + if ( usbd_dev->driver->set_address_before_status) + usbd_dev->driver->set_address(usbd_dev, req->wValue); return 1; } -static int usb_standard_set_configuration(struct usb_setup_data *req, +static int usb_standard_set_configuration(usbd_device *usbd_dev, + struct usb_setup_data *req, u8 **buf, u16 *len) { int i; @@ -166,43 +173,46 @@ static int usb_standard_set_configuration(struct usb_setup_data *req, (void)len; /* Is this correct, or should we reset alternate settings. */ - if (req->wValue == _usbd_device.current_config) + if (req->wValue == usbd_dev->current_config) return 1; - _usbd_device.current_config = req->wValue; + usbd_dev->current_config = req->wValue; /* Reset all endpoints. */ - _usbd_hw_endpoints_reset(); + usbd_dev->driver->ep_reset(usbd_dev); - if (_usbd_device.user_callback_set_config) { + if (usbd_dev->user_callback_set_config) { /* * Flush control callbacks. These will be reregistered * by the user handler. */ for (i = 0; i < MAX_USER_CONTROL_CALLBACK; i++) - _usbd_device.user_control_callback[i].cb = NULL; + usbd_dev->user_control_callback[i].cb = NULL; - _usbd_device.user_callback_set_config(req->wValue); + usbd_dev->user_callback_set_config(usbd_dev, req->wValue); } return 1; } -static int usb_standard_get_configuration(struct usb_setup_data *req, +static int usb_standard_get_configuration(usbd_device *usbd_dev, + struct usb_setup_data *req, u8 **buf, u16 *len) { (void)req; if (*len > 1) *len = 1; - (*buf)[0] = _usbd_device.current_config; + (*buf)[0] = usbd_dev->current_config; return 1; } -static int usb_standard_set_interface(struct usb_setup_data *req, +static int usb_standard_set_interface(usbd_device *usbd_dev, + struct usb_setup_data *req, u8 **buf, u16 *len) { + (void)usbd_dev; (void)req; (void)buf; @@ -214,9 +224,11 @@ static int usb_standard_set_interface(struct usb_setup_data *req, return 1; } -static int usb_standard_get_interface(struct usb_setup_data *req, +static int usb_standard_get_interface(usbd_device *usbd_dev, + struct usb_setup_data *req, u8 **buf, u16 *len) { + (void)usbd_dev; (void)req; (void)buf; @@ -227,9 +239,11 @@ static int usb_standard_get_interface(struct usb_setup_data *req, return 1; } -static int usb_standard_device_get_status(struct usb_setup_data *req, +static int usb_standard_device_get_status(usbd_device *usbd_dev, + struct usb_setup_data *req, u8 **buf, u16 *len) { + (void)usbd_dev; (void)req; /* bit 0: self powered */ @@ -242,9 +256,11 @@ static int usb_standard_device_get_status(struct usb_setup_data *req, return 1; } -static int usb_standard_interface_get_status(struct usb_setup_data *req, +static int usb_standard_interface_get_status(usbd_device *usbd_dev, + struct usb_setup_data *req, u8 **buf, u16 *len) { + (void)usbd_dev; (void)req; /* not defined */ @@ -256,45 +272,50 @@ static int usb_standard_interface_get_status(struct usb_setup_data *req, return 1; } -static int usb_standard_endpoint_get_status(struct usb_setup_data *req, +static int usb_standard_endpoint_get_status(usbd_device *usbd_dev, + struct usb_setup_data *req, u8 **buf, u16 *len) { (void)req; if (*len > 2) *len = 2; - (*buf)[0] = usbd_ep_stall_get(req->wIndex) ? 1 : 0; + (*buf)[0] = usbd_ep_stall_get(usbd_dev, req->wIndex) ? 1 : 0; (*buf)[1] = 0; return 1; } -static int usb_standard_endpoint_stall(struct usb_setup_data *req, +static int usb_standard_endpoint_stall(usbd_device *usbd_dev, + struct usb_setup_data *req, u8 **buf, u16 *len) { (void)buf; (void)len; - usbd_ep_stall_set(req->wIndex, 1); + usbd_ep_stall_set(usbd_dev, req->wIndex, 1); return 1; } -static int usb_standard_endpoint_unstall(struct usb_setup_data *req, +static int usb_standard_endpoint_unstall(usbd_device *usbd_dev, + struct usb_setup_data *req, u8 **buf, u16 *len) { (void)buf; (void)len; - usbd_ep_stall_set(req->wIndex, 0); + usbd_ep_stall_set(usbd_dev, req->wIndex, 0); return 1; } -int _usbd_standard_request_device(struct usb_setup_data *req, u8 **buf, +int _usbd_standard_request_device(usbd_device *usbd_dev, + struct usb_setup_data *req, u8 **buf, u16 *len) { - int (*command)(struct usb_setup_data *req, u8 **buf, u16 *len) = NULL; + int (*command)(usbd_device *usbd_dev, struct usb_setup_data *req, u8 + **buf, u16 *len) = NULL; switch (req->bRequest) { case USB_REQ_CLEAR_FEATURE: @@ -337,13 +358,15 @@ int _usbd_standard_request_device(struct usb_setup_data *req, u8 **buf, if (!command) return 0; - return command(req, buf, len); + return command(usbd_dev, req, buf, len); } -int _usbd_standard_request_interface(struct usb_setup_data *req, u8 **buf, +int _usbd_standard_request_interface(usbd_device *usbd_dev, + struct usb_setup_data *req, u8 **buf, u16 *len) { - int (*command)(struct usb_setup_data *req, u8 **buf, u16 *len) = NULL; + int (*command)(usbd_device *usbd_dev, struct usb_setup_data *req, + u8 **buf, u16 *len) = NULL; switch (req->bRequest) { case USB_REQ_CLEAR_FEATURE: @@ -364,13 +387,15 @@ int _usbd_standard_request_interface(struct usb_setup_data *req, u8 **buf, if (!command) return 0; - return command(req, buf, len); + return command(usbd_dev, req, buf, len); } -int _usbd_standard_request_endpoint(struct usb_setup_data *req, u8 **buf, +int _usbd_standard_request_endpoint(usbd_device *usbd_dev, + struct usb_setup_data *req, u8 **buf, u16 *len) { - int (*command) (struct usb_setup_data *req, u8 **buf, u16 *len) = NULL; + int (*command) (usbd_device *usbd_dev, struct usb_setup_data *req, + u8 **buf, u16 *len) = NULL; switch (req->bRequest) { case USB_REQ_CLEAR_FEATURE: @@ -396,10 +421,11 @@ int _usbd_standard_request_endpoint(struct usb_setup_data *req, u8 **buf, if (!command) return 0; - return command(req, buf, len); + return command(usbd_dev, req, buf, len); } -int _usbd_standard_request(struct usb_setup_data *req, u8 **buf, u16 *len) +int _usbd_standard_request(usbd_device *usbd_dev, + struct usb_setup_data *req, u8 **buf, u16 *len) { /* FIXME: Have class/vendor requests as well. */ if ((req->bmRequestType & USB_REQ_TYPE_TYPE) != USB_REQ_TYPE_STANDARD) @@ -407,11 +433,12 @@ int _usbd_standard_request(struct usb_setup_data *req, u8 **buf, u16 *len) switch (req->bmRequestType & USB_REQ_TYPE_RECIPIENT) { case USB_REQ_TYPE_DEVICE: - return _usbd_standard_request_device(req, buf, len); + return _usbd_standard_request_device(usbd_dev, req, buf, len); case USB_REQ_TYPE_INTERFACE: - return _usbd_standard_request_interface(req, buf, len); + return _usbd_standard_request_interface(usbd_dev, req, + buf, len); case USB_REQ_TYPE_ENDPOINT: - return _usbd_standard_request_endpoint(req, buf, len); + return _usbd_standard_request_endpoint(usbd_dev, req, buf, len); default: return 0; }