stm32: Add support for USB on L0 MCUs.
This commit is contained in:
parent
788e7f50f2
commit
4c1ad1f691
|
@ -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
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue