summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ports/stm32/Makefile7
-rw-r--r--ports/stm32/irq.h11
-rw-r--r--ports/stm32/powerctrlboot.c21
-rw-r--r--ports/stm32/stm32_it.c12
-rw-r--r--ports/stm32/usbd_cdc_interface.c13
-rw-r--r--ports/stm32/usbd_conf.c42
6 files changed, 100 insertions, 6 deletions
diff --git a/ports/stm32/Makefile b/ports/stm32/Makefile
index 84ce01e8f..d2ca4122a 100644
--- a/ports/stm32/Makefile
+++ b/ports/stm32/Makefile
@@ -331,12 +331,17 @@ SRC_HAL = $(addprefix $(HAL_DIR)/Src/stm32$(MCU_SERIES)xx_,\
hal_uart.c \
)
+ifeq ($(MCU_SERIES),$(filter $(MCU_SERIES),f4 f7 h7 l0 l4))
+SRC_HAL += $(addprefix $(HAL_DIR)/Src/stm32$(MCU_SERIES)xx_,\
+ ll_usb.c \
+ )
+endif
+
ifeq ($(MCU_SERIES),$(filter $(MCU_SERIES),f4 f7 h7 l4))
SRC_HAL += $(addprefix $(HAL_DIR)/Src/stm32$(MCU_SERIES)xx_,\
hal_sd.c \
ll_sdmmc.c \
ll_fmc.c \
- ll_usb.c \
)
endif
diff --git a/ports/stm32/irq.h b/ports/stm32/irq.h
index 075791357..78ba46ced 100644
--- a/ports/stm32/irq.h
+++ b/ports/stm32/irq.h
@@ -79,6 +79,17 @@ static inline void restore_irq_pri(uint32_t basepri) {
__set_BASEPRI(basepri);
}
+#else
+
+static inline uint32_t raise_irq_pri(uint32_t pri) {
+ return disable_irq();
+}
+
+// "state" should be the value returned from raise_irq_pri
+static inline void restore_irq_pri(uint32_t state) {
+ enable_irq(state);
+}
+
#endif
MP_DECLARE_CONST_FUN_OBJ_0(pyb_wfi_obj);
diff --git a/ports/stm32/powerctrlboot.c b/ports/stm32/powerctrlboot.c
index 527118ba8..e320cc4db 100644
--- a/ports/stm32/powerctrlboot.c
+++ b/ports/stm32/powerctrlboot.c
@@ -98,6 +98,27 @@ void SystemClock_Config(void) {
HAL_SYSTICK_Config(HAL_RCC_GetHCLKFreq() / 1000);
HAL_SYSTICK_CLKSourceConfig(SYSTICK_CLKSOURCE_HCLK);
+
+ #if MICROPY_HW_ENABLE_RNG || 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;
+
+ #if MICROPY_HW_ENABLE_USB
+ // 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
+ #endif
}
#endif
diff --git a/ports/stm32/stm32_it.c b/ports/stm32/stm32_it.c
index fd3aea6c1..1e2712b05 100644
--- a/ports/stm32/stm32_it.c
+++ b/ports/stm32/stm32_it.c
@@ -298,6 +298,16 @@ void DebugMon_Handler(void) {
/* file (startup_stm32f4xx.s). */
/******************************************************************************/
+#if defined(STM32L0)
+
+#if MICROPY_HW_USB_FS
+void USB_IRQHandler(void) {
+ HAL_PCD_IRQHandler(&pcd_fs_handle);
+}
+#endif
+
+#else
+
/**
* @brief This function handles USB-On-The-Go FS global interrupt request.
* @param None
@@ -405,6 +415,8 @@ void OTG_HS_WKUP_IRQHandler(void) {
}
#endif
+#endif // !defined(STM32L0)
+
/**
* @brief This function handles PPP interrupt request.
* @param None
diff --git a/ports/stm32/usbd_cdc_interface.c b/ports/stm32/usbd_cdc_interface.c
index 49f0deec7..b27ea51d8 100644
--- a/ports/stm32/usbd_cdc_interface.c
+++ b/ports/stm32/usbd_cdc_interface.c
@@ -140,11 +140,14 @@ int8_t usbd_cdc_control(usbd_cdc_state_t *cdc_in, uint8_t cmd, uint8_t* pbuf, ui
if (length & 1) {
// The actual connection state is delayed to give the host a chance to
// configure its serial port (in most cases to disable local echo)
- PCD_HandleTypeDef *hpcd = cdc->base.usbd->pdev->pData;
- USB_OTG_GlobalTypeDef *USBx = hpcd->Instance;
cdc->connect_state = USBD_CDC_CONNECT_STATE_CONNECTING;
usbd_cdc_connect_tx_timer = 8; // wait for 8 SOF IRQs
- USBx->GINTMSK |= USB_OTG_GINTMSK_SOFM;
+ #if defined(STM32L0)
+ USB->CNTR |= USB_CNTR_SOFM;
+ #else
+ PCD_HandleTypeDef *hpcd = cdc->base.usbd->pdev->pData;
+ hpcd->Instance->GINTMSK |= USB_OTG_GINTMSK_SOFM;
+ #endif
} else {
cdc->connect_state = USBD_CDC_CONNECT_STATE_DISCONNECTED;
}
@@ -216,7 +219,11 @@ void HAL_PCD_SOFCallback(PCD_HandleTypeDef *hpcd) {
--usbd_cdc_connect_tx_timer;
} else {
usbd_cdc_msc_hid_state_t *usbd = ((USBD_HandleTypeDef*)hpcd->pData)->pClassData;
+ #if defined(STM32L0)
+ USB->CNTR &= ~USB_CNTR_SOFM;
+ #else
hpcd->Instance->GINTMSK &= ~USB_OTG_GINTMSK_SOFM;
+ #endif
for (int i = 0; i < MICROPY_HW_USB_CDC_NUM; ++i) {
usbd_cdc_itf_t *cdc = (usbd_cdc_itf_t*)usbd->cdc[i];
if (cdc->connect_state == USBD_CDC_CONNECT_STATE_CONNECTING) {
diff --git a/ports/stm32/usbd_conf.c b/ports/stm32/usbd_conf.c
index ed99700e9..8e62a9cc8 100644
--- a/ports/stm32/usbd_conf.c
+++ b/ports/stm32/usbd_conf.c
@@ -44,6 +44,11 @@ PCD_HandleTypeDef pcd_fs_handle;
PCD_HandleTypeDef pcd_hs_handle;
#endif
+#if defined(STM32L0)
+// The STM32L0xx has a single USB device-only instance
+#define USB_OTG_FS USB
+#endif
+
/*******************************************************************************
PCD BSP Routines
*******************************************************************************/
@@ -57,6 +62,8 @@ void HAL_PCD_MspInit(PCD_HandleTypeDef *hpcd) {
if (hpcd->Instance == USB_OTG_FS) {
#if defined(STM32H7)
const uint32_t otg_alt = GPIO_AF10_OTG1_FS;
+ #elif defined(STM32L0)
+ const uint32_t otg_alt = GPIO_AF0_USB;
#else
const uint32_t otg_alt = GPIO_AF10_OTG_FS;
#endif
@@ -83,7 +90,11 @@ void HAL_PCD_MspInit(PCD_HandleTypeDef *hpcd) {
#endif
// Enable USB FS Clocks
+ #if defined(STM32L0)
+ __HAL_RCC_USB_CLK_ENABLE();
+ #else
__USB_OTG_FS_CLK_ENABLE();
+ #endif
#if defined(STM32L4)
// Enable VDDUSB
@@ -97,8 +108,13 @@ void HAL_PCD_MspInit(PCD_HandleTypeDef *hpcd) {
#endif
// Configure and enable USB FS interrupt
+ #if defined(STM32L0)
+ NVIC_SetPriority(USB_IRQn, IRQ_PRI_OTG_FS);
+ HAL_NVIC_EnableIRQ(USB_IRQn);
+ #else
NVIC_SetPriority(OTG_FS_IRQn, IRQ_PRI_OTG_FS);
HAL_NVIC_EnableIRQ(OTG_FS_IRQn);
+ #endif
}
#if MICROPY_HW_USB_HS
else if (hpcd->Instance == USB_OTG_HS) {
@@ -174,6 +190,10 @@ void HAL_PCD_MspInit(PCD_HandleTypeDef *hpcd) {
* @retval None
*/
void HAL_PCD_MspDeInit(PCD_HandleTypeDef *hpcd) {
+ #if defined(STM32L0)
+ __HAL_RCC_USB_CLK_DISABLE();
+ #else
+
if (hpcd->Instance == USB_OTG_FS) {
/* Disable USB FS Clocks */
__USB_OTG_FS_CLK_DISABLE();
@@ -186,6 +206,8 @@ void HAL_PCD_MspDeInit(PCD_HandleTypeDef *hpcd) {
__SYSCFG_CLK_DISABLE();
}
#endif
+
+ #endif
}
/*******************************************************************************
@@ -339,9 +361,7 @@ USBD_StatusTypeDef USBD_LL_Init(USBD_HandleTypeDef *pdev, int high_speed) {
#else
pcd_fs_handle.Init.dev_endpoints = 4;
#endif
- pcd_fs_handle.Init.use_dedicated_ep1 = 0;
pcd_fs_handle.Init.ep0_mps = 0x40;
- pcd_fs_handle.Init.dma_enable = 0;
pcd_fs_handle.Init.low_power_enable = 0;
pcd_fs_handle.Init.phy_itface = PCD_PHY_EMBEDDED;
pcd_fs_handle.Init.Sof_enable = 0;
@@ -350,11 +370,15 @@ USBD_StatusTypeDef USBD_LL_Init(USBD_HandleTypeDef *pdev, int high_speed) {
pcd_fs_handle.Init.lpm_enable = DISABLE;
pcd_fs_handle.Init.battery_charging_enable = DISABLE;
#endif
+ #if !defined(STM32L0)
+ pcd_fs_handle.Init.use_dedicated_ep1 = 0;
+ pcd_fs_handle.Init.dma_enable = 0;
#if !defined(MICROPY_HW_USB_VBUS_DETECT_PIN)
pcd_fs_handle.Init.vbus_sensing_enable = 0; // No VBUS Sensing on USB0
#else
pcd_fs_handle.Init.vbus_sensing_enable = 1;
#endif
+ #endif
// Link The driver to the stack
pcd_fs_handle.pData = pdev;
@@ -363,6 +387,18 @@ USBD_StatusTypeDef USBD_LL_Init(USBD_HandleTypeDef *pdev, int high_speed) {
// Initialize LL Driver
HAL_PCD_Init(&pcd_fs_handle);
+ #if defined(STM32L0)
+ // We have 512 16-bit words it total to use here (when using PCD_SNG_BUF)
+ HAL_PCDEx_PMAConfig(&pcd_fs_handle, 0x00, PCD_SNG_BUF, 64); // EP0
+ HAL_PCDEx_PMAConfig(&pcd_fs_handle, 0x80, PCD_SNG_BUF, 128); // EP0
+ HAL_PCDEx_PMAConfig(&pcd_fs_handle, 0x01, PCD_SNG_BUF, 192); // MSC / HID
+ HAL_PCDEx_PMAConfig(&pcd_fs_handle, 0x81, PCD_SNG_BUF, 256); // MSC / HID
+ HAL_PCDEx_PMAConfig(&pcd_fs_handle, 0x02, PCD_SNG_BUF, 320); // unused
+ HAL_PCDEx_PMAConfig(&pcd_fs_handle, 0x82, PCD_SNG_BUF, 320); // CDC CMD
+ HAL_PCDEx_PMAConfig(&pcd_fs_handle, 0x03, PCD_SNG_BUF, 384); // CDC DATA
+ HAL_PCDEx_PMAConfig(&pcd_fs_handle, 0x83, PCD_SNG_BUF, 448); // CDC DATA
+ #else
+
// We have 320 32-bit words in total to use here
#if MICROPY_HW_USB_CDC_NUM == 2
HAL_PCD_SetRxFiFo(&pcd_fs_handle, 128);
@@ -379,6 +415,8 @@ USBD_StatusTypeDef USBD_LL_Init(USBD_HandleTypeDef *pdev, int high_speed) {
HAL_PCD_SetTxFiFo(&pcd_fs_handle, 2, 32); // CDC CMD
HAL_PCD_SetTxFiFo(&pcd_fs_handle, 3, 64); // CDC DATA
#endif
+
+ #endif
}
#endif
#if MICROPY_HW_USB_HS