From a9284b71549bed1a44a338a6c615696df53f1417 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?King=20K=C3=A9vin?= Date: Fri, 27 Nov 2020 16:43:57 +0100 Subject: [PATCH] USB CDC ACM: port to STM32F4 --- lib/usb_cdcacm.c | 65 +++++++++--------------------------------------- lib/usb_cdcacm.h | 3 +-- 2 files changed, 13 insertions(+), 55 deletions(-) diff --git a/lib/usb_cdcacm.c b/lib/usb_cdcacm.c index 387e743..b9b5770 100644 --- a/lib/usb_cdcacm.c +++ b/lib/usb_cdcacm.c @@ -234,33 +234,6 @@ static const char* usb_strings[] = { "DFU bootloader (runtime mode)", /**< DFU interface string */ }; -/** disconnect USB to force re-enumerate */ -static void usb_disconnect(void) -{ - if (usb_device) { - usbd_disconnect(usb_device, true); - } -#if defined(MAPLE_MINI) - // disconnect USB D+ using dedicated DISC line/circuit on PB9 - rcc_periph_clock_enable(RCC_GPIOB); - gpio_set_mode(GPIOB, GPIO_MODE_OUTPUT_2_MHZ, GPIO_CNF_OUTPUT_PUSHPULL, GPIO9); - gpio_set(GPIOB, GPIO9); -#elif defined(BLASTER) - // enable USB D+ pull-up - rcc_periph_clock_enable(RCC_GPIOB); - gpio_set_mode(GPIOB, GPIO_MODE_OUTPUT_2_MHZ, GPIO_CNF_OUTPUT_PUSHPULL, GPIO6); - gpio_clear(GPIOB, GPIO6); -#endif - // pull USB D+ low for a short while - rcc_periph_clock_enable(RCC_GPIOA); - gpio_set_mode(GPIOA, GPIO_MODE_OUTPUT_2_MHZ, GPIO_CNF_OUTPUT_PUSHPULL, GPIO12); - gpio_clear(GPIOA, GPIO12); - // USB disconnected must be at least 10 ms long, at most 100 ms - for (uint32_t i = 0; i < 0x2000; i++) { - __asm__("nop"); - } -} - /** DFU detach (disconnect USB and perform core reset) * @param[in] usbd_dev USB device (unused) * @param[in] req USB request (unused) @@ -269,14 +242,10 @@ static void usb_dfu_detach(usbd_device *usbd_dev, struct usb_setup_data *req) { (void)usbd_dev; // variable not used (void)req; // variable not used - usb_disconnect(); // USB detach (disconnect to force re-enumeration) - // set DFU magic - __dfu_magic[0] = 'D'; - __dfu_magic[1] = 'F'; - __dfu_magic[2] = 'U'; - __dfu_magic[3] = '!'; - scb_reset_system(); // reset system (core and peripherals) - while (true); // wait for the reset to happen + if (usb_device) { + usbd_disconnect(usb_device, true); + } + dfu_bootloader(); // start DFU bootloader } /** incoming USB CDC ACM control request @@ -431,27 +400,17 @@ static void usb_cdcacm_set_config(usbd_device *usbd_dev, uint16_t wValue) void usb_cdcacm_setup(void) { - snprintf(usb_serial, LENGTH(usb_serial), "%08x%08x%04x%04x", DESIG_UNIQUE_ID2, DESIG_UNIQUE_ID1, DESIG_UNIQUE_ID0 & 0xffff, DESIG_UNIQUE_ID0 >> 16); // set actual device ID as serial + // set serial according to STM32 USB-FS_Device developer kit + // see https://community.st.com/s/question/0D50X0000ADCaTJSQ1/dfu-serial-number + snprintf(usb_serial, LENGTH(usb_serial), "%08x%04x", DESIG_UNIQUE_ID0 + DESIG_UNIQUE_ID2, DESIG_UNIQUE_ID1 >> 16); // set actual device ID as serial // initialize USB - rcc_periph_reset_pulse(RST_USB); // reset USB peripheral - usb_disconnect(); // disconnect to force re-enumeration -#if defined(MAPLE_MINI) - // connect USB D+ using dedicated DISC line/circuit on PB9 - rcc_periph_clock_enable(RCC_GPIOB); - gpio_set_mode(GPIOB, GPIO_MODE_OUTPUT_2_MHZ, GPIO_CNF_OUTPUT_PUSHPULL, GPIO9); - gpio_clear(GPIOB, GPIO9); -#elif defined(BLASTER) - // enable USB D+ pull-up using GPIO - rcc_periph_clock_enable(RCC_GPIOB); - gpio_set_mode(GPIOB, GPIO_MODE_OUTPUT_2_MHZ, GPIO_CNF_OUTPUT_PUSHPULL, GPIO6); - gpio_set(GPIOB, GPIO6); -#endif rcc_periph_clock_enable(RCC_GPIOA); // enable clock for GPIO used for USB - rcc_periph_clock_enable(RCC_USB); // enable clock for USB domain - usb_device = usbd_init(&st_usbfs_v1_usb_driver, &usb_cdcacm_device_descriptor, &usb_cdcacm_configuration_descriptor, usb_strings, LENGTH(usb_strings), usbd_control_buffer, sizeof(usbd_control_buffer)); + gpio_mode_setup(GPIOA, GPIO_MODE_AF, GPIO_PUPD_NONE, GPIO11 | GPIO12); // set pin to alternate function + gpio_set_af(GPIOA, GPIO_AF10, GPIO11 | GPIO12); // set alternate function to USB + usb_device = usbd_init(&otgfs_usb_driver, &usb_cdcacm_device_descriptor, &usb_cdcacm_configuration_descriptor, usb_strings, LENGTH(usb_strings), usbd_control_buffer, sizeof(usbd_control_buffer)); usbd_register_set_config_callback(usb_device, usb_cdcacm_set_config); - nvic_enable_irq(NVIC_USB_LP_CAN_RX0_IRQ); // enable interrupts (to not have to poll all the time) + nvic_enable_irq(NVIC_OTG_FS_IRQ); // enable interrupts (to not have to poll all the time) // reset buffer states tx_i = 0; @@ -485,7 +444,7 @@ void usb_cdcacm_flush(void) } /** USB interrupt service routine called when data is received */ -void usb_lp_can_rx0_isr(void) +void otg_fs_isr(void) { usbd_poll(usb_device); } diff --git a/lib/usb_cdcacm.h b/lib/usb_cdcacm.h index 6fba418..87ce66d 100644 --- a/lib/usb_cdcacm.h +++ b/lib/usb_cdcacm.h @@ -2,10 +2,9 @@ * @file * @author King Kévin * @copyright SPDX-License-Identifier: GPL-3.0-or-later - * @date 2016-2019 + * @date 2016-2020 */ #pragma once -#error not converted for STM32F4 /** flag set to true when user is connected to USB CDC ACM port (e.g. when a terminal is opened) */ extern volatile bool usb_cdcacm_connecting;