From 7ca3c1d8920fc0a9ceef0a1d725009d1716e41fa Mon Sep 17 00:00:00 2001 From: Yuuki NAGAO Date: Tue, 20 Jun 2023 16:13:19 +0900 Subject: [PATCH] stm32: Add USB support for STM32L1 MCUs. Signed-off-by: Yuuki NAGAO --- ports/stm32/Makefile | 2 +- .../boards/NUCLEO_L152RE/mpconfigboard.h | 9 ++++++ ports/stm32/boards/stm32l1xx_hal_conf_base.h | 5 ++++ ports/stm32/mpconfigboard_common.h | 2 +- ports/stm32/powerctrlboot.c | 21 ++----------- ports/stm32/stm32_it.c | 2 +- ports/stm32/usb.c | 2 +- ports/stm32/usbd_conf.c | 30 ++++++++++++++++++- 8 files changed, 49 insertions(+), 24 deletions(-) diff --git a/ports/stm32/Makefile b/ports/stm32/Makefile index d5030b7e46..81a48249e8 100644 --- a/ports/stm32/Makefile +++ b/ports/stm32/Makefile @@ -404,7 +404,7 @@ HAL_SRC_C += $(addprefix $(STM32LIB_HAL_BASE)/Src/stm32$(MCU_SERIES)xx_,\ ll_utils.c \ ) -ifeq ($(MCU_SERIES),$(filter $(MCU_SERIES),f4 f7 g0 g4 h5 h7 l0 l4 wb)) +ifeq ($(MCU_SERIES),$(filter $(MCU_SERIES),f4 f7 g0 g4 h5 h7 l0 l1 l4 wb)) HAL_SRC_C += $(addprefix $(STM32LIB_HAL_BASE)/Src/stm32$(MCU_SERIES)xx_,\ hal_pcd.c \ hal_pcd_ex.c \ diff --git a/ports/stm32/boards/NUCLEO_L152RE/mpconfigboard.h b/ports/stm32/boards/NUCLEO_L152RE/mpconfigboard.h index 3609955893..5b83a980ce 100644 --- a/ports/stm32/boards/NUCLEO_L152RE/mpconfigboard.h +++ b/ports/stm32/boards/NUCLEO_L152RE/mpconfigboard.h @@ -7,6 +7,7 @@ #define MICROPY_HW_RTC_USE_LSE (1) #define MICROPY_HW_ENABLE_SERVO (1) #define MICROPY_HW_ENABLE_DAC (1) +#define MICROPY_HW_ENABLE_USB (0) // HSE is 8MHz, HSI is 16MHz CPU freq set to 32MHz // Default source for the clock is HSI. @@ -72,3 +73,11 @@ #define MICROPY_HW_LED_OFF(pin) (mp_hal_pin_low(pin)) #define MICROPY_HW_FLASH_LATENCY FLASH_LATENCY_1 + +// USB config +#if MICROPY_HW_ENABLE_USB +#if MICROPY_HW_CLK_USE_HSI +#error STM32L152RE cannot use USB feature with HSI clock. Use HSE. +#endif +#define MICROPY_HW_USB_FS (1) +#endif diff --git a/ports/stm32/boards/stm32l1xx_hal_conf_base.h b/ports/stm32/boards/stm32l1xx_hal_conf_base.h index b839fd29f0..5871e8a45a 100644 --- a/ports/stm32/boards/stm32l1xx_hal_conf_base.h +++ b/ports/stm32/boards/stm32l1xx_hal_conf_base.h @@ -26,6 +26,9 @@ #ifndef MICROPY_INCLUDED_STM32L1XX_HAL_CONF_BASE_H #define MICROPY_INCLUDED_STM32L1XX_HAL_CONF_BASE_H +// Needs to be defined before ll_usb.h is included +#define HAL_PCD_MODULE_ENABLED + // Include various HAL modules for convenience #include "stm32l1xx_hal_rcc.h" #include "stm32l1xx_hal_gpio.h" @@ -38,6 +41,7 @@ #include "stm32l1xx_hal_flash.h" #include "stm32l1xx_hal_i2c.h" #include "stm32l1xx_hal_iwdg.h" +#include "stm32l1xx_hal_pcd.h" #include "stm32l1xx_hal_pwr.h" #include "stm32l1xx_hal_rtc.h" #include "stm32l1xx_hal_spi.h" @@ -50,6 +54,7 @@ #include "stm32l1xx_ll_pwr.h" #include "stm32l1xx_ll_rtc.h" #include "stm32l1xx_ll_usart.h" +#include "stm32l1xx_ll_usb.h" // Enable various HAL modules #define HAL_MODULE_ENABLED diff --git a/ports/stm32/mpconfigboard_common.h b/ports/stm32/mpconfigboard_common.h index 8f2a6e530a..149d2ae73a 100644 --- a/ports/stm32/mpconfigboard_common.h +++ b/ports/stm32/mpconfigboard_common.h @@ -586,7 +586,7 @@ // Whether the USB peripheral is device-only, or multiple OTG // For STM32G0 and STM32H5 the USB peripheral supports device and host mode, // but otherwise acts like a non-multi-OTG peripheral. -#if defined(STM32G0) || defined(STM32G4) || defined(STM32H5) || defined(STM32L0) || defined(STM32L432xx) || defined(STM32WB) +#if defined(STM32G0) || defined(STM32G4) || defined(STM32H5) || defined(STM32L0) || defined(STM32L1) || defined(STM32L432xx) || defined(STM32WB) #define MICROPY_HW_USB_IS_MULTI_OTG (0) #else #define MICROPY_HW_USB_IS_MULTI_OTG (1) diff --git a/ports/stm32/powerctrlboot.c b/ports/stm32/powerctrlboot.c index 149c34ae63..1721f6c7ec 100644 --- a/ports/stm32/powerctrlboot.c +++ b/ports/stm32/powerctrlboot.c @@ -348,6 +348,8 @@ void SystemClock_Config(void) { #elif defined(STM32L1) void SystemClock_Config(void) { + // Enable SYSCFG clock + __HAL_RCC_SYSCFG_CLK_ENABLE(); // Enable power control peripheral __HAL_RCC_PWR_CLK_ENABLE(); @@ -388,25 +390,6 @@ void SystemClock_Config(void) { SystemCoreClockUpdate(); powerctrl_config_systick(); - #if MICROPY_HW_ENABLE_USB - // Enable the 48MHz internal oscillator - RCC->CRRCR |= RCC_CRRCR_HSI48ON; - RCC->APB2ENR |= RCC_APB2ENR_SYSCFGEN; - SYSCFG->CFGR3 |= SYSCFG_CFGR3_ENREF_HSI48; - while (!(RCC->CRRCR & RCC_CRRCR_HSI48RDY)) { - // Wait for HSI48 to be ready - } - - // Select RC48 as HSI48 for USB and RNG - RCC->CCIPR |= RCC_CCIPR_HSI48SEL; - - // Synchronise HSI48 with 1kHz USB SoF - __HAL_RCC_CRS_CLK_ENABLE(); - CRS->CR = 0x20 << CRS_CR_TRIM_Pos; - CRS->CFGR = 2 << CRS_CFGR_SYNCSRC_Pos | 0x22 << CRS_CFGR_FELIM_Pos - | __HAL_RCC_CRS_RELOADVALUE_CALCULATE(48000000, 1000) << CRS_CFGR_RELOAD_Pos; - #endif - // Disable the Debug Module in low-power mode due to prevent // unexpected HardFault after __WFI(). #if !defined(NDEBUG) diff --git a/ports/stm32/stm32_it.c b/ports/stm32/stm32_it.c index 84c05602b5..483537b649 100644 --- a/ports/stm32/stm32_it.c +++ b/ports/stm32/stm32_it.c @@ -320,7 +320,7 @@ void USB_IRQHandler(void) { } #endif -#elif defined(STM32G4) || defined(STM32WB) +#elif defined(STM32G4) || defined(STM32L1) || defined(STM32WB) #if MICROPY_HW_USB_FS void USB_LP_IRQHandler(void) { diff --git a/ports/stm32/usb.c b/ports/stm32/usb.c index 94d62f7625..c3b8544417 100644 --- a/ports/stm32/usb.c +++ b/ports/stm32/usb.c @@ -59,7 +59,7 @@ #endif // Maximum number of endpoints (excluding EP0) -#if defined(STM32G0) || defined(STM32G4) || defined(STM32H5) || defined(STM32L0) || defined(STM32WB) +#if defined(STM32G0) || defined(STM32G4) || defined(STM32H5) || defined(STM32L0) || defined(STM32L1) || defined(STM32WB) #define MAX_ENDPOINT(dev_id) (7) #elif defined(STM32L4) #define MAX_ENDPOINT(dev_id) (5) diff --git a/ports/stm32/usbd_conf.c b/ports/stm32/usbd_conf.c index 9f187fc08b..5d9e7177de 100644 --- a/ports/stm32/usbd_conf.c +++ b/ports/stm32/usbd_conf.c @@ -75,6 +75,16 @@ void HAL_PCD_MspInit(PCD_HandleTypeDef *hpcd) { mp_hal_pin_config(pin_A12, MP_HAL_PIN_MODE_ANALOG, MP_HAL_PIN_PULL_NONE, 0); mp_hal_pin_config_speed(pin_A12, GPIO_SPEED_FREQ_VERY_HIGH); + #elif defined(STM32L1) + + // STM32L1 doesn't have an alternate function for USB. + // To be disconnected from all peripherals, put in input mode. + + mp_hal_pin_config(pin_A11, MP_HAL_PIN_MODE_INPUT, MP_HAL_PIN_PULL_NONE, 0); + mp_hal_pin_config_speed(pin_A11, GPIO_SPEED_FREQ_VERY_HIGH); + mp_hal_pin_config(pin_A12, MP_HAL_PIN_MODE_INPUT, MP_HAL_PIN_PULL_NONE, 0); + mp_hal_pin_config_speed(pin_A12, GPIO_SPEED_FREQ_VERY_HIGH); + #else // Other MCUs have an alternate function for GPIO's to be in USB mode. @@ -149,7 +159,7 @@ void HAL_PCD_MspInit(PCD_HandleTypeDef *hpcd) { #elif defined(STM32L432xx) NVIC_SetPriority(USB_FS_IRQn, IRQ_PRI_OTG_FS); HAL_NVIC_EnableIRQ(USB_FS_IRQn); - #elif defined(STM32G4) || defined(STM32WB) + #elif defined(STM32G4) || defined(STM32L1) || defined(STM32WB) NVIC_SetPriority(USB_LP_IRQn, IRQ_PRI_OTG_FS); HAL_NVIC_EnableIRQ(USB_LP_IRQn); #else @@ -708,6 +718,24 @@ void USBD_LL_Delay(uint32_t Delay) { HAL_Delay(Delay); } +#if defined(STM32L1) +/** + * @brief Software Device Connection + * @param hpcd: PCD handle + * @param state: Connection state (0: disconnected / 1: connected) + * @retval None + */ +void HAL_PCDEx_SetConnectionState(PCD_HandleTypeDef *hpcd, uint8_t state) { + if (state == 1) { + /* DP Pull-Down is Internal */ + __HAL_SYSCFG_USBPULLUP_ENABLE(); + } else { + /* DP Pull-Down is Internal */ + __HAL_SYSCFG_USBPULLUP_DISABLE(); + } +} +#endif + #endif // MICROPY_HW_USB_FS || MICROPY_HW_USB_HS /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/