1
0
mirror of https://github.com/RIOT-OS/RIOT.git synced 2025-12-15 09:33:50 +01:00

Merge pull request #18680 from gschorcht/drivers/usbdev_stm32f3

cpu/stm32/periph/usbdev_fs: add support for STM32F3 family
This commit is contained in:
Dylan Laduranty 2022-10-05 18:35:53 +02:00 committed by GitHub
commit d7d91935a4
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 72 additions and 16 deletions

View File

@ -21,6 +21,7 @@ config BOARD_NUCLEO_F303ZE
select HAS_PERIPH_SPI
select HAS_PERIPH_TIMER
select HAS_PERIPH_UART
select HAS_PERIPH_USBDEV
# Put other features for this board (in alphabetical order)
select HAS_RIOTBOOT

View File

@ -8,6 +8,7 @@ FEATURES_PROVIDED += periph_rtc
FEATURES_PROVIDED += periph_spi
FEATURES_PROVIDED += periph_timer
FEATURES_PROVIDED += periph_uart
FEATURES_PROVIDED += periph_usbdev
# Put other features for this board (in alphabetical order)
FEATURES_PROVIDED += riotboot

View File

@ -173,6 +173,32 @@ static const spi_conf_t spi_config[] = {
#define SPI_NUMOF ARRAY_SIZE(spi_config)
/** @} */
/**
* @brief USB device FS configuration
*/
static const stm32_usbdev_fs_config_t stm32_usbdev_fs_config[] = {
{
.base_addr = (uintptr_t)USB,
.rcc_mask = RCC_APB1ENR_USBEN,
.irqn = USB_LP_CAN_RX0_IRQn,
.apb = APB1,
.dm = GPIO_PIN(PORT_A, 11),
.dp = GPIO_PIN(PORT_A, 12),
.af = GPIO_AF14,
.disconn = GPIO_PIN(PORT_G, 6),
},
};
/**
* @brief Interrupt function name mapping
*/
#define USBDEV_ISR isr_usb_lp_can_rx0
/**
* @brief Number of available USB device FS peripherals
*/
#define USBDEV_NUMOF ARRAY_SIZE(stm32_usbdev_fs_config)
#ifdef __cplusplus
}
#endif

View File

@ -116,6 +116,7 @@ static const stm32_usbdev_fs_config_t stm32_usbdev_fs_config[] = {
.dm = GPIO_PIN(PORT_A, 11),
.dp = GPIO_PIN(PORT_A, 12),
.af = GPIO_AF10,
.disconn = GPIO_UNDEF,
},
};

View File

@ -4,7 +4,7 @@
USEMODULE += periph stm32_clk stm32_vectors
ifneq (,$(filter periph_usbdev,$(FEATURES_USED)))
ifneq (wb,$(CPU_FAM))
ifeq (,$(filter f3 wb,$(CPU_FAM)))
USEMODULE += usbdev_synopsys_dwc2
endif
USEMODULE += ztimer

View File

@ -50,6 +50,7 @@ typedef struct {
gpio_t dm; /**< Data- gpio */
gpio_t dp; /**< Data+ gpio */
gpio_af_t af; /**< Alternative function */
gpio_t disconn; /**< GPIO if used for USB disconnect */
} stm32_usbdev_fs_config_t;
#ifdef __cplusplus

View File

@ -51,7 +51,7 @@ endif
# Select the correct implementation for `periph_usbdev`
ifneq (,$(filter periph_usbdev,$(USEMODULE)))
ifeq (wb,$(CPU_FAM))
ifneq (,$(filter f3 wb,$(CPU_FAM)))
SRC += usbdev_fs.c
endif
endif

View File

@ -135,20 +135,30 @@ static void _enable_usb_clk(void)
#if defined(RCC_APB1SMENR_USBSMEN)
RCC->APB1SMENR |= RCC_APB1SMENR_USBSMEN;
#elif defined(RCC_APB1SMENR_USBSMEN)
#elif defined(RCC_APB1SMENR1_USBSMEN)
RCC->APB1SMENR1 |= RCC_APB1SMENR1_USBSMEN;
#endif
#if defined(CRS_CR_AUTOTRIMEN) && defined(CRS_CR_CEN)
/* Enable CRS with auto trim enabled */
CRS->CR |= (CRS_CR_AUTOTRIMEN | CRS_CR_CEN);
#endif
}
static void _enable_gpio(const stm32_usbdev_fs_config_t *conf)
{
gpio_init(conf->dp, GPIO_IN);
gpio_init(conf->dm, GPIO_IN);
/* Configure AF for the pins */
gpio_init_af(conf->dp, conf->af);
gpio_init_af(conf->dm, conf->af);
if (conf->af != GPIO_AF_UNDEF) {
/* Configure AF for the pins */
gpio_init_af(conf->dp, conf->af);
gpio_init_af(conf->dm, conf->af);
}
if (conf->disconn != GPIO_UNDEF) {
/* In case the MCU has no internal D+ pullup, a GPIO is used to
* connect/disconnect from USB bus */
gpio_init(conf->disconn, GPIO_OUT);
gpio_clear(conf->disconn);
}
}
static void _set_ep_in_status(uint16_t *val, uint16_t mask)
@ -179,28 +189,36 @@ static void _set_ep_out_status(uint16_t *val, uint16_t mask)
static inline void _usb_attach(stm32_usbdev_fs_t *usbdev)
{
const stm32_usbdev_fs_config_t *conf = usbdev->config;
/* Some ST USB IP doesn't have this feature */
#ifdef USB_BCDR_DPPU
const stm32_usbdev_fs_config_t *conf = usbdev->config;
/* Enable DP pullup to signal connection */
_global_regs(conf)->BCDR |= USB_BCDR_DPPU;
while (!(CRS->ISR & CRS_ISR_ESYNCF));
while (!(CRS->ISR & CRS_ISR_ESYNCF)) {}
#else
(void)usbdev;
/* If configuration uses a GPIO for USB connect/disconnect */
if (conf->disconn != GPIO_UNDEF) {
gpio_set(conf->disconn);
}
#endif /* USB_BCDR_DPPU */
}
static inline void _usb_detach(stm32_usbdev_fs_t *usbdev)
{
const stm32_usbdev_fs_config_t *conf = usbdev->config;
/* Some ST USB IP doesn't have this feature */
#ifdef USB_BCDR_DPPU
const stm32_usbdev_fs_config_t *conf = usbdev->config;
DEBUG_PUTS("usbdev_fs: Detaching from host");
/* Disable DP pullup to signal disconnection */
CLRBIT(_global_regs(conf)->BCDR, USB_BCDR_DPPU);
#else
(void)usbdev;
/* If configuration uses a GPIO for USB connect/disconnect */
if (conf->disconn != GPIO_UNDEF) {
gpio_clear(conf->disconn);
}
#endif
}
@ -261,10 +279,12 @@ static void _usbdev_init(usbdev_t *dev)
/* Configure GPIOs */
_enable_gpio(conf);
/* Reset USB IP */
_global_regs(conf)->CNTR = USB_CNTR_FRES;
/* Reset and power down USB IP */
_global_regs(conf)->CNTR = USB_CNTR_FRES | USB_CNTR_PDWN;
/* Clear power down */
_global_regs(conf)->CNTR &= ~USB_CNTR_PDWN;
/* Clear reset */
_global_regs(conf)->CNTR = 0;
_global_regs(conf)->CNTR &= ~USB_CNTR_FRES;
/* Clear interrupt register */
_global_regs(conf)->ISTR = 0x0000;
/* Set BTABLE at start of USB SRAM */
@ -273,6 +293,12 @@ static void _usbdev_init(usbdev_t *dev)
_global_regs(conf)->DADDR = USB_DADDR_EF;
/* Unmask the interrupt in the NVIC */
_enable_irq();
/* Disable remapping of USB IRQs if remapping defined */
#ifdef SYSCFG_CFGR1_USB_IT_RMP
SYSCFG->CFGR1 &= ~SYSCFG_CFGR1_USB_IT_RMP;
#endif
/* Enable USB IRQ */
NVIC_EnableIRQ(conf->irqn);
/* fill USB SRAM with zeroes */