diff --git a/cores/arduino/USBCore.cpp b/cores/arduino/USBCore.cpp index 691a7a96..5f88ef51 100644 --- a/cores/arduino/USBCore.cpp +++ b/cores/arduino/USBCore.cpp @@ -54,8 +54,17 @@ bool USBDeviceClass::begin() { #if defined(USB_CLASS) + #if defined(STM32L0_CONFIG_PIN_VBUS_HAS_DIVIDER) + // On boards with an external divider (to allow measuring + // voltage rather than just on/off), do not enable the pulldown + // since that influences the divider (and the divider works as + // an external pulldown too). + bool needs_pulldown = false; + #else + bool needs_pulldown = true; + #endif return USBD_Initialize(USB_VID, USB_PID, (const uint8_t*)USB_MANUFACTURER, (const uint8_t*)USB_PRODUCT, USB_CLASS, - STM32L0_CONFIG_PIN_VBUS, STM32L0_USB_IRQ_PRIORITY, + STM32L0_CONFIG_PIN_VBUS, needs_pulldown, STM32L0_USB_IRQ_PRIORITY, &USBDeviceClass::connectCallback, &USBDeviceClass::disconnectCallback, &USBDeviceClass::suspendCallback, &USBDeviceClass::resumeCallback); #endif return false; diff --git a/cores/arduino/wiring.c b/cores/arduino/wiring.c index 594695a5..0d593a78 100644 --- a/cores/arduino/wiring.c +++ b/cores/arduino/wiring.c @@ -64,12 +64,6 @@ void init( void ) stm32l0_dma_configure(STM32L0_ADC_IRQ_PRIORITY, STM32L0_UART_IRQ_PRIORITY, STM32L0_UART_IRQ_PRIORITY); -#if defined(STM32L0_CONFIG_PIN_VBUS) - if (STM32L0_CONFIG_PIN_VBUS != STM32L0_GPIO_PIN_NONE) { - stm32l0_gpio_pin_configure(STM32L0_CONFIG_PIN_VBUS, (STM32L0_GPIO_PARK_HIZ | STM32L0_GPIO_PUPD_PULLDOWN | STM32L0_GPIO_OSPEED_LOW | STM32L0_GPIO_OTYPE_PUSHPULL | STM32L0_GPIO_MODE_INPUT)); - } -#endif - #if defined(STM32L0_CONFIG_PIN_VBAT) stm32l0_gpio_pin_configure(STM32L0_CONFIG_PIN_VBAT, (STM32L0_GPIO_PARK_NONE | STM32L0_GPIO_MODE_ANALOG)); #endif diff --git a/cores/arduino/wiring_private.h b/cores/arduino/wiring_private.h index 8af973de..be299c9b 100644 --- a/cores/arduino/wiring_private.h +++ b/cores/arduino/wiring_private.h @@ -59,7 +59,7 @@ extern void USBD_CDC_Initialize(void *); extern void USBD_CDC_MSC_Initialize(void *); extern bool USBD_Initialize(uint16_t vid, uint16_t pid, const uint8_t *manufacturer, const uint8_t *product, void(*initialize)(void *), - unsigned int pin_vbus, unsigned int priority, + unsigned int pin_vbus, bool pin_vbus_needs_pulldown, unsigned int priority, void(*connect_callback)(void), void(*disconnect_callback)(void), void(*suspend_callback)(void), void(*resume_callback)(void)); extern void USBD_Teardown(void); extern void USBD_Attach(void); diff --git a/system/STM32L0xx/Lib/libstm32l052xx.a b/system/STM32L0xx/Lib/libstm32l052xx.a index 49a774bd..a69a9074 100644 Binary files a/system/STM32L0xx/Lib/libstm32l052xx.a and b/system/STM32L0xx/Lib/libstm32l052xx.a differ diff --git a/system/STM32L0xx/Lib/libstm32l072xx.a b/system/STM32L0xx/Lib/libstm32l072xx.a index 210bb454..0f27b4e9 100644 Binary files a/system/STM32L0xx/Lib/libstm32l072xx.a and b/system/STM32L0xx/Lib/libstm32l072xx.a differ diff --git a/system/STM32L0xx/Lib/libstm32l082xx.a b/system/STM32L0xx/Lib/libstm32l082xx.a index 8d7b8ace..724ceef1 100644 Binary files a/system/STM32L0xx/Lib/libstm32l082xx.a and b/system/STM32L0xx/Lib/libstm32l082xx.a differ diff --git a/system/STM32L0xx/Source/USB/usbd_conf.c b/system/STM32L0xx/Source/USB/usbd_conf.c index eaf5d6fe..c7ba3f6f 100644 --- a/system/STM32L0xx/Source/USB/usbd_conf.c +++ b/system/STM32L0xx/Source/USB/usbd_conf.c @@ -182,7 +182,7 @@ static void USBD_VBUSChangedIrq(void) } bool USBD_Initialize(uint16_t vid, uint16_t pid, const uint8_t *manufacturer, const uint8_t *product, void(*initialize)(struct _USBD_HandleTypeDef *), - unsigned int pin_vbus, unsigned int priority, + unsigned int pin_vbus, bool pin_vbus_needs_pulldown, unsigned int priority, void(*connect_callback)(void), void(*disconnect_callback)(void), void(*suspend_callback)(void), void(*resume_callback)(void)) { if (stm32l0_system_pclk1() < 10000000) @@ -198,9 +198,6 @@ bool USBD_Initialize(uint16_t vid, uint16_t pid, const uint8_t *manufacturer, co USBD_ProductString = product; USBD_ClassInitialize = initialize; - usbd_pin_vbus = pin_vbus; - usbd_mask_vbus = 1 << ((pin_vbus & STM32L0_GPIO_PIN_INDEX_MASK) >> STM32L0_GPIO_PIN_INDEX_SHIFT); - /* Set USB Interrupt priority */ NVIC_SetPriority(USB_IRQn, priority); @@ -209,19 +206,32 @@ bool USBD_Initialize(uint16_t vid, uint16_t pid, const uint8_t *manufacturer, co usbd_suspend_callback = suspend_callback; usbd_resume_callback = resume_callback; - stm32l0_lptim_timeout_create(&USBD_VBUSTimeout); - /* Configure USB FS GPIOs */ - stm32l0_gpio_pin_configure(usbd_pin_vbus, (STM32L0_GPIO_PARK_HIZ | STM32L0_GPIO_PUPD_PULLDOWN | STM32L0_GPIO_OSPEED_LOW | STM32L0_GPIO_OTYPE_PUSHPULL | STM32L0_GPIO_MODE_INPUT)); + usbd_pin_vbus = pin_vbus; + if (pin_vbus != STM32L0_GPIO_PIN_NONE) { + usbd_mask_vbus = 1 << ((pin_vbus & STM32L0_GPIO_PIN_INDEX_MASK) >> STM32L0_GPIO_PIN_INDEX_SHIFT); - if (stm32l0_gpio_pin_read(usbd_pin_vbus)) - { - stm32l0_lptim_timeout_start(&USBD_VBUSTimeout, stm32l0_lptim_millis_to_ticks(40), (stm32l0_lptim_callback_t)USBD_VBUSTimeoutIrq); /* 40ms */ + stm32l0_lptim_timeout_create(&USBD_VBUSTimeout); + + uint32_t mode = (STM32L0_GPIO_PARK_HIZ | STM32L0_GPIO_OSPEED_LOW | STM32L0_GPIO_OTYPE_PUSHPULL | STM32L0_GPIO_MODE_INPUT); + if (pin_vbus_needs_pulldown) + mode |= STM32L0_GPIO_PUPD_PULLDOWN; + stm32l0_gpio_pin_configure(usbd_pin_vbus, mode); + + if (stm32l0_gpio_pin_read(usbd_pin_vbus)) + { + stm32l0_lptim_timeout_start(&USBD_VBUSTimeout, stm32l0_lptim_millis_to_ticks(40), (stm32l0_lptim_callback_t)USBD_VBUSTimeoutIrq); /* 40ms */ + } + + stm32l0_exti_attach(usbd_pin_vbus, + (STM32L0_EXTI_CONTROL_NOWAKEUP | STM32L0_EXTI_CONTROL_PRIORITY_LOW | STM32L0_EXTI_CONTROL_EDGE_RISING | STM32L0_EXTI_CONTROL_EDGE_FALLING), + (stm32l0_exti_callback_t)USBD_VBUSChangedIrq, NULL); + } else { + // No VBUS pin, assume VBUS is always present + usbd_attached = true; + usbd_mask_vbus = 0; } - - stm32l0_exti_attach(usbd_pin_vbus, - (STM32L0_EXTI_CONTROL_NOWAKEUP | STM32L0_EXTI_CONTROL_PRIORITY_LOW | STM32L0_EXTI_CONTROL_EDGE_RISING | STM32L0_EXTI_CONTROL_EDGE_FALLING), - (stm32l0_exti_callback_t)USBD_VBUSChangedIrq, NULL); + return true; } @@ -230,11 +240,13 @@ void USBD_Teardown() { USBD_Detach(); - stm32l0_exti_detach(usbd_pin_vbus); + if (usbd_pin_vbus != STM32L0_GPIO_PIN_NONE) { + stm32l0_exti_detach(usbd_pin_vbus); - stm32l0_lptim_timeout_stop(&USBD_VBUSTimeout); + stm32l0_lptim_timeout_stop(&USBD_VBUSTimeout); - stm32l0_gpio_pin_configure(usbd_pin_vbus, STM32L0_GPIO_MODE_ANALOG); + stm32l0_gpio_pin_configure(usbd_pin_vbus, STM32L0_GPIO_MODE_ANALOG); + } usbd_wakeup = false; usbd_enabled = false; @@ -370,16 +382,18 @@ void USBD_SetupVBUS(bool wakeup) { usbd_wakeup = wakeup; - stm32l0_exti_detach(usbd_pin_vbus); - - stm32l0_gpio_pin_configure(usbd_pin_vbus, - (usbd_wakeup ? STM32L0_GPIO_PARK_NONE : STM32L0_GPIO_PARK_HIZ) | - (STM32L0_GPIO_PUPD_PULLDOWN | STM32L0_GPIO_OSPEED_LOW | STM32L0_GPIO_OTYPE_PUSHPULL | STM32L0_GPIO_MODE_INPUT)); - - stm32l0_exti_attach(usbd_pin_vbus, - ((usbd_wakeup ? 0 : STM32L0_EXTI_CONTROL_NOWAKEUP) | - (STM32L0_EXTI_CONTROL_PRIORITY_LOW | STM32L0_EXTI_CONTROL_EDGE_RISING | STM32L0_EXTI_CONTROL_EDGE_FALLING)), - (stm32l0_exti_callback_t)USBD_VBUSChangedIrq, NULL); + if (usbd_pin_vbus != STM32L0_GPIO_PIN_NONE) { + stm32l0_exti_detach(usbd_pin_vbus); + + stm32l0_gpio_pin_configure(usbd_pin_vbus, + (usbd_wakeup ? STM32L0_GPIO_PARK_NONE : STM32L0_GPIO_PARK_HIZ) | + (STM32L0_GPIO_PUPD_PULLDOWN | STM32L0_GPIO_OSPEED_LOW | STM32L0_GPIO_OTYPE_PUSHPULL | STM32L0_GPIO_MODE_INPUT)); + + stm32l0_exti_attach(usbd_pin_vbus, + ((usbd_wakeup ? 0 : STM32L0_EXTI_CONTROL_NOWAKEUP) | + (STM32L0_EXTI_CONTROL_PRIORITY_LOW | STM32L0_EXTI_CONTROL_EDGE_RISING | STM32L0_EXTI_CONTROL_EDGE_FALLING)), + (stm32l0_exti_callback_t)USBD_VBUSChangedIrq, NULL); + } } }