From 4938128cccd3a76907caf546eacee41e53b989e7 Mon Sep 17 00:00:00 2001 From: Tinic Uro Date: Wed, 29 May 2024 12:54:15 -0700 Subject: Make it compile for STM32U545. --- src/portable/synopsys/dwc2/dwc2_stm32.h | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/portable/synopsys/dwc2/dwc2_stm32.h b/src/portable/synopsys/dwc2/dwc2_stm32.h index 3237a50f6..9957976a5 100644 --- a/src/portable/synopsys/dwc2/dwc2_stm32.h +++ b/src/portable/synopsys/dwc2/dwc2_stm32.h @@ -89,6 +89,12 @@ extern "C" { #define USB_OTG_FS_PERIPH_BASE USB_OTG_FS_BASE #define EP_MAX_FS 6 #define EP_FIFO_SIZE_FS 1280 + #define USB_OTG_FS_IRQN OTG_FS_IRQn + #elif defined(USB_DRD_FS) + #define USB_OTG_FS_PERIPH_BASE USB_DRD_BASE + #define EP_MAX_FS 6 + #define EP_FIFO_SIZE_FS 1280 + #define USB_OTG_FS_IRQN USB_IRQn #else #define USB_OTG_HS_PERIPH_BASE USB_OTG_HS_BASE #define EP_MAX_HS 9 @@ -109,7 +115,7 @@ extern "C" { // - Port0 to OTG_FS, and Port1 to OTG_HS static const dwc2_controller_t _dwc2_controller[] = { #ifdef USB_OTG_FS_PERIPH_BASE - { .reg_base = USB_OTG_FS_PERIPH_BASE, .irqnum = OTG_FS_IRQn, .ep_count = EP_MAX_FS, .ep_fifo_size = EP_FIFO_SIZE_FS }, + { .reg_base = USB_OTG_FS_PERIPH_BASE, .irqnum = USB_OTG_FS_IRQN, .ep_count = EP_MAX_FS, .ep_fifo_size = EP_FIFO_SIZE_FS }, #endif #ifdef USB_OTG_HS_PERIPH_BASE -- cgit v1.3.1 From 22e6b1130fa60b76ed0a1d9b6cc049179606c48c Mon Sep 17 00:00:00 2001 From: Tinic Uro Date: Wed, 29 May 2024 13:13:47 -0700 Subject: Cleaner approach. --- src/portable/synopsys/dwc2/dwc2_stm32.h | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/portable/synopsys/dwc2/dwc2_stm32.h b/src/portable/synopsys/dwc2/dwc2_stm32.h index 9957976a5..5743569db 100644 --- a/src/portable/synopsys/dwc2/dwc2_stm32.h +++ b/src/portable/synopsys/dwc2/dwc2_stm32.h @@ -84,17 +84,16 @@ extern "C" { #elif CFG_TUSB_MCU == OPT_MCU_STM32U5 #include "stm32u5xx.h" - // U59x/5Ax/5Fx/5Gx are highspeed with built-in HS PHY #ifdef USB_OTG_FS #define USB_OTG_FS_PERIPH_BASE USB_OTG_FS_BASE #define EP_MAX_FS 6 #define EP_FIFO_SIZE_FS 1280 - #define USB_OTG_FS_IRQN OTG_FS_IRQn + // U53x/U54x are fullspeed with built-in FS PHY but not OTG #elif defined(USB_DRD_FS) - #define USB_OTG_FS_PERIPH_BASE USB_DRD_BASE + #define USB_DRD_FS_PERIPH_BASE USB_DRD_BASE #define EP_MAX_FS 6 #define EP_FIFO_SIZE_FS 1280 - #define USB_OTG_FS_IRQN USB_IRQn + // U59x/5Ax/5Fx/5Gx are highspeed with built-in HS PHY #else #define USB_OTG_HS_PERIPH_BASE USB_OTG_HS_BASE #define EP_MAX_HS 9 @@ -114,6 +113,10 @@ extern "C" { // On STM32 for consistency we associate // - Port0 to OTG_FS, and Port1 to OTG_HS static const dwc2_controller_t _dwc2_controller[] = { + #ifdef USB_DRD_FS_PERIPH_BASE + { .reg_base = USB_DRD_FS_PERIPH_BASE, .irqnum = USB_IRQn, .ep_count = EP_MAX_FS, .ep_fifo_size = EP_FIFO_SIZE_FS }, + #endif + #ifdef USB_OTG_FS_PERIPH_BASE { .reg_base = USB_OTG_FS_PERIPH_BASE, .irqnum = USB_OTG_FS_IRQN, .ep_count = EP_MAX_FS, .ep_fifo_size = EP_FIFO_SIZE_FS }, #endif -- cgit v1.3.1 From 2e946ac77a8fda2b4b36c19df5294cd7213d46aa Mon Sep 17 00:00:00 2001 From: Tinic Uro Date: Wed, 29 May 2024 13:23:18 -0700 Subject: Use correct specs. --- src/portable/synopsys/dwc2/dwc2_stm32.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/portable/synopsys/dwc2/dwc2_stm32.h b/src/portable/synopsys/dwc2/dwc2_stm32.h index 5743569db..4f311782d 100644 --- a/src/portable/synopsys/dwc2/dwc2_stm32.h +++ b/src/portable/synopsys/dwc2/dwc2_stm32.h @@ -91,8 +91,8 @@ extern "C" { // U53x/U54x are fullspeed with built-in FS PHY but not OTG #elif defined(USB_DRD_FS) #define USB_DRD_FS_PERIPH_BASE USB_DRD_BASE - #define EP_MAX_FS 6 - #define EP_FIFO_SIZE_FS 1280 + #define EP_MAX_FS 8 + #define EP_FIFO_SIZE_FS 2048 // U59x/5Ax/5Fx/5Gx are highspeed with built-in HS PHY #else #define USB_OTG_HS_PERIPH_BASE USB_OTG_HS_BASE -- cgit v1.3.1 From 60d7fcb1ee8dcc4870221e97c1e3fba5463a9d45 Mon Sep 17 00:00:00 2001 From: Tinic Uro Date: Thu, 30 May 2024 13:26:14 -0700 Subject: Use correct backend. --- src/common/tusb_mcu.h | 25 +++++++++++++-------- src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c | 2 +- src/portable/st/stm32_fsdev/fsdev_stm32.h | 31 +++++++++++++++++++++++++++ src/portable/synopsys/dwc2/dwc2_stm32.h | 11 +--------- 4 files changed, 49 insertions(+), 20 deletions(-) (limited to 'src') diff --git a/src/common/tusb_mcu.h b/src/common/tusb_mcu.h index c66996c4f..0f4fca8d1 100644 --- a/src/common/tusb_mcu.h +++ b/src/common/tusb_mcu.h @@ -271,17 +271,24 @@ #define TUP_DCD_ENDPOINT_MAX 8 #elif TU_CHECK_MCU(OPT_MCU_STM32U5) - #define TUP_USBIP_DWC2 - #define TUP_USBIP_DWC2_STM32 + #ifdef USB_DRD_FS + #define TUP_USBIP_FSDEV + #define TUP_USBIP_FSDEV_STM32 + #define TUP_DCD_ENDPOINT_MAX 8 - // U59x/5Ax/5Fx/5Gx are highspeed with built-in HS PHY - #if defined(STM32U595xx) || defined(STM32U599xx) || defined(STM32U5A5xx) || defined(STM32U5A9xx) || \ - defined(STM32U5F7xx) || defined(STM32U5F9xx) || defined(STM32U5G7xx) || defined(STM32U5G9xx) - #define TUP_DCD_ENDPOINT_MAX 9 - #define TUP_RHPORT_HIGHSPEED 1 - #define TUP_USBIP_DWC2_TEST_MODE #else - #define TUP_DCD_ENDPOINT_MAX 6 + #define TUP_USBIP_DWC2 + #define TUP_USBIP_DWC2_STM32 + + // U59x/5Ax/5Fx/5Gx are highspeed with built-in HS PHY + #if defined(STM32U595xx) || defined(STM32U599xx) || defined(STM32U5A5xx) || defined(STM32U5A9xx) || \ + defined(STM32U5F7xx) || defined(STM32U5F9xx) || defined(STM32U5G7xx) || defined(STM32U5G9xx) + #define TUP_DCD_ENDPOINT_MAX 9 + #define TUP_RHPORT_HIGHSPEED 1 + #define TUP_USBIP_DWC2_TEST_MODE + #else + #define TUP_DCD_ENDPOINT_MAX 6 + #endif #endif #elif TU_CHECK_MCU(OPT_MCU_STM32L5) diff --git a/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c b/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c index 9ce37f992..5f230d86f 100644 --- a/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c +++ b/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c @@ -232,7 +232,7 @@ void dcd_init(uint8_t rhport) } USB->CNTR = 0; // Enable USB -#if !defined(STM32G0) && !defined(STM32H5) // BTABLE register does not exist any more on STM32G0, it is fixed to USB SRAM base address +#if !defined(STM32G0) && !defined(STM32H5) && !defined(STM32U5) // BTABLE register does not exist any more on STM32G0, it is fixed to USB SRAM base address USB->BTABLE = DCD_STM32_BTABLE_BASE; #endif USB->ISTR = 0; // Clear pending interrupts diff --git a/src/portable/st/stm32_fsdev/fsdev_stm32.h b/src/portable/st/stm32_fsdev/fsdev_stm32.h index b3fa11b88..a5199c9e3 100644 --- a/src/portable/st/stm32_fsdev/fsdev_stm32.h +++ b/src/portable/st/stm32_fsdev/fsdev_stm32.h @@ -159,6 +159,35 @@ #define USB_PMAADDR (USB_BASE + (USB_PMAADDR_NS - USB_BASE_NS)) #endif +#elif CFG_TUSB_MCU == OPT_MCU_STM32U5 + #include "stm32u5xx.h" + #define FSDEV_BUS_32BIT + + #define FSDEV_PMA_SIZE (2048u) + #undef USB_PMAADDR + #define USB_PMAADDR USB_DRD_PMAADDR + #define USB_TypeDef USB_DRD_TypeDef + #define EP0R CHEP0R + #define USB_EP_CTR_RX USB_EP_VTRX + #define USB_EP_CTR_TX USB_EP_VTTX + #define USB_EP_T_FIELD USB_CHEP_UTYPE + #define USB_EPREG_MASK USB_CHEP_REG_MASK + #define USB_EPTX_DTOGMASK USB_CHEP_TX_DTOGMASK + #define USB_EPRX_DTOGMASK USB_CHEP_RX_DTOGMASK + #define USB_EPTX_DTOG1 USB_CHEP_TX_DTOG1 + #define USB_EPTX_DTOG2 USB_CHEP_TX_DTOG2 + #define USB_EPRX_DTOG1 USB_CHEP_RX_DTOG1 + #define USB_EPRX_DTOG2 USB_CHEP_RX_DTOG2 + #define USB_EPRX_STAT USB_CH_RX_VALID + #define USB_EPKIND_MASK USB_EP_KIND_MASK + #define USB USB_DRD_FS + #define USB_CNTR_FRES USB_CNTR_USBRST + #define USB_CNTR_RESUME USB_CNTR_L2RES + #define USB_ISTR_EP_ID USB_ISTR_IDN + #define USB_EPADDR_FIELD USB_CHEP_ADDR + #define USB_CNTR_LPMODE USB_CNTR_SUSPRDY + #define USB_CNTR_FSUSP USB_CNTR_SUSPEN + #else #error You are using an untested or unimplemented STM32 variant. Please update the driver. // This includes L1x0, L1x1, L1x2, L4x2 and L4x3, G1x1, G1x3, and G1x4 @@ -211,6 +240,8 @@ static const IRQn_Type fsdev_irq[] = { #elif CFG_TUSB_MCU == OPT_MCU_STM32WB USB_HP_IRQn, USB_LP_IRQn, + #elif CFG_TUSB_MCU == OPT_MCU_STM32U5 + USB_IRQn, #else #error Unknown arch in USB driver #endif diff --git a/src/portable/synopsys/dwc2/dwc2_stm32.h b/src/portable/synopsys/dwc2/dwc2_stm32.h index 4f311782d..eaac2c44b 100644 --- a/src/portable/synopsys/dwc2/dwc2_stm32.h +++ b/src/portable/synopsys/dwc2/dwc2_stm32.h @@ -84,16 +84,11 @@ extern "C" { #elif CFG_TUSB_MCU == OPT_MCU_STM32U5 #include "stm32u5xx.h" + // U59x/5Ax/5Fx/5Gx are highspeed with built-in HS PHY #ifdef USB_OTG_FS #define USB_OTG_FS_PERIPH_BASE USB_OTG_FS_BASE #define EP_MAX_FS 6 #define EP_FIFO_SIZE_FS 1280 - // U53x/U54x are fullspeed with built-in FS PHY but not OTG - #elif defined(USB_DRD_FS) - #define USB_DRD_FS_PERIPH_BASE USB_DRD_BASE - #define EP_MAX_FS 8 - #define EP_FIFO_SIZE_FS 2048 - // U59x/5Ax/5Fx/5Gx are highspeed with built-in HS PHY #else #define USB_OTG_HS_PERIPH_BASE USB_OTG_HS_BASE #define EP_MAX_HS 9 @@ -113,10 +108,6 @@ extern "C" { // On STM32 for consistency we associate // - Port0 to OTG_FS, and Port1 to OTG_HS static const dwc2_controller_t _dwc2_controller[] = { - #ifdef USB_DRD_FS_PERIPH_BASE - { .reg_base = USB_DRD_FS_PERIPH_BASE, .irqnum = USB_IRQn, .ep_count = EP_MAX_FS, .ep_fifo_size = EP_FIFO_SIZE_FS }, - #endif - #ifdef USB_OTG_FS_PERIPH_BASE { .reg_base = USB_OTG_FS_PERIPH_BASE, .irqnum = USB_OTG_FS_IRQN, .ep_count = EP_MAX_FS, .ep_fifo_size = EP_FIFO_SIZE_FS }, #endif -- cgit v1.3.1 From 28c243337591f0ac7745f11737d907d47f0e6320 Mon Sep 17 00:00:00 2001 From: Tinic Uro Date: Wed, 12 Jun 2024 08:08:25 -0700 Subject: Add stm32u545nucleo board. --- hw/bsp/stm32u5/boards/stm32u575nucleo/board.mk | 1 + hw/bsp/stm32u5/boards/stm32u5a5nucleo/board.mk | 1 + hw/bsp/stm32u5/family.c | 17 ++++++++++++++++- hw/bsp/stm32u5/family.cmake | 14 ++++++++++---- hw/bsp/stm32u5/family.mk | 14 ++++++++++++-- src/portable/synopsys/dwc2/dwc2_stm32.h | 2 +- 6 files changed, 41 insertions(+), 8 deletions(-) (limited to 'src') diff --git a/hw/bsp/stm32u5/boards/stm32u575nucleo/board.mk b/hw/bsp/stm32u5/boards/stm32u575nucleo/board.mk index 1dd157a68..c83ec3999 100644 --- a/hw/bsp/stm32u5/boards/stm32u575nucleo/board.mk +++ b/hw/bsp/stm32u5/boards/stm32u575nucleo/board.mk @@ -6,5 +6,6 @@ LD_FILE = ${FAMILY_PATH}/linker/STM32U575xx_FLASH.ld SRC_S += $(ST_CMSIS)/Source/Templates/gcc/startup_stm32u575xx.s +MCU_VARIANT = stm32u575xx # For flash-jlink target JLINK_DEVICE = stm32u575zi diff --git a/hw/bsp/stm32u5/boards/stm32u5a5nucleo/board.mk b/hw/bsp/stm32u5/boards/stm32u5a5nucleo/board.mk index e759cec24..4bebe3330 100644 --- a/hw/bsp/stm32u5/boards/stm32u5a5nucleo/board.mk +++ b/hw/bsp/stm32u5/boards/stm32u5a5nucleo/board.mk @@ -7,5 +7,6 @@ LD_FILE = ${BOARD_PATH}/STM32U5A5ZJTXQ_FLASH.ld SRC_S += $(ST_CMSIS)/Source/Templates/gcc/startup_stm32u5a5xx.s +MCU_VARIANT = stm32u5a5xx # For flash-jlink target JLINK_DEVICE = stm32u575zi diff --git a/hw/bsp/stm32u5/family.c b/hw/bsp/stm32u5/family.c index d779b5c96..0f0868839 100644 --- a/hw/bsp/stm32u5/family.c +++ b/hw/bsp/stm32u5/family.c @@ -72,7 +72,9 @@ void board_init(void) { __HAL_RCC_GPIOC_CLK_ENABLE(); __HAL_RCC_GPIOD_CLK_ENABLE(); __HAL_RCC_GPIOE_CLK_ENABLE(); +#ifdef GPIOF __HAL_RCC_GPIOF_CLK_ENABLE(); +#endif __HAL_RCC_GPIOG_CLK_ENABLE(); __HAL_RCC_GPIOH_CLK_ENABLE(); @@ -140,6 +142,17 @@ void board_init(void) { GPIO_InitStruct.Alternate = GPIO_AF10_USB; HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); +#ifdef USB_OTG_HS + // STM32U535/STM32U545 + + /* Enable USB power on Pwrctrl CR2 register */ + HAL_PWREx_EnableVddUSB(); + + /* USB clock enable */ + __HAL_RCC_USB_FS_CLK_ENABLE(); + +#endif + #ifdef USB_OTG_FS #if CFG_TUSB_OS == OPT_OS_FREERTOS // If freeRTOS is used, IRQ priority is limit by max syscall ( smaller is higher ) @@ -170,7 +183,9 @@ void board_init(void) { /* USB clock enable */ __HAL_RCC_USB_OTG_FS_CLK_ENABLE(); -#else +#endif + +#ifdef USB_OTG_HS // STM59x/Ax/Fx/Gx only have 1 USB HS port #if CFG_TUSB_OS == OPT_OS_FREERTOS diff --git a/hw/bsp/stm32u5/family.cmake b/hw/bsp/stm32u5/family.cmake index 7402540b7..c19bce64b 100644 --- a/hw/bsp/stm32u5/family.cmake +++ b/hw/bsp/stm32u5/family.cmake @@ -102,10 +102,16 @@ function(family_configure_example TARGET RTOS) # Add TinyUSB target and port source family_add_tinyusb(${TARGET} OPT_MCU_STM32U5 ${RTOS}) - target_sources(${TARGET}-tinyusb PUBLIC - ${TOP}/src/portable/synopsys/dwc2/dcd_dwc2.c - #${TOP}/src/portable/st/typec/typec_stm32.c - ) + if ((${MCU_VARIANT} EQUAL "stm32u535xx") OR (${MCU_VARIANT} EQUAL "stm32u545xx")) + target_sources(${TARGET}-tinyusb PUBLIC + ${TOP}/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c + ) + else () + target_sources(${TARGET}-tinyusb PUBLIC + ${TOP}/src/portable/synopsys/dwc2/dcd_dwc2.c + #${TOP}/src/portable/st/typec/typec_stm32.c + ) + endif () target_link_libraries(${TARGET}-tinyusb PUBLIC board_${BOARD}) # Link dependencies diff --git a/hw/bsp/stm32u5/family.mk b/hw/bsp/stm32u5/family.mk index be5809340..45f9aa33e 100644 --- a/hw/bsp/stm32u5/family.mk +++ b/hw/bsp/stm32u5/family.mk @@ -27,18 +27,28 @@ LDFLAGS_GCC += \ --specs=nosys.specs --specs=nano.specs SRC_C += \ - src/portable/synopsys/dwc2/dcd_dwc2.c \ $(ST_CMSIS)/Source/Templates/system_stm32$(ST_FAMILY)xx.c \ $(ST_HAL_DRIVER)/Src/stm32$(ST_FAMILY)xx_hal.c \ $(ST_HAL_DRIVER)/Src/stm32$(ST_FAMILY)xx_hal_cortex.c \ $(ST_HAL_DRIVER)/Src/stm32$(ST_FAMILY)xx_hal_gpio.c \ - $(ST_HAL_DRIVER)/Src/stm32$(ST_FAMILY)xx_hal_icache.c \ + $(ST_HAL_DRIVER)/Src/stm32$(ST_FAMILY)xx_hal_icache.c \ $(ST_HAL_DRIVER)/Src/stm32$(ST_FAMILY)xx_hal_pwr.c \ $(ST_HAL_DRIVER)/Src/stm32$(ST_FAMILY)xx_hal_pwr_ex.c \ $(ST_HAL_DRIVER)/Src/stm32$(ST_FAMILY)xx_hal_rcc.c \ $(ST_HAL_DRIVER)/Src/stm32$(ST_FAMILY)xx_hal_rcc_ex.c \ $(ST_HAL_DRIVER)/Src/stm32$(ST_FAMILY)xx_hal_uart.c +ifeq ($(MCU_VARIANT),stm32u545xx) +SRC_C += \ + src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c +else ($(MCU_VARIANT),stm32u535xx) +SRC_C += \ + src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c +else +SRC_C += \ + src/portable/synopsys/dwc2/dcd_dwc2.c +endif + INC += \ $(TOP)/lib/CMSIS_5/CMSIS/Core/Include \ $(TOP)/$(ST_CMSIS)/Include \ diff --git a/src/portable/synopsys/dwc2/dwc2_stm32.h b/src/portable/synopsys/dwc2/dwc2_stm32.h index eaac2c44b..3237a50f6 100644 --- a/src/portable/synopsys/dwc2/dwc2_stm32.h +++ b/src/portable/synopsys/dwc2/dwc2_stm32.h @@ -109,7 +109,7 @@ extern "C" { // - Port0 to OTG_FS, and Port1 to OTG_HS static const dwc2_controller_t _dwc2_controller[] = { #ifdef USB_OTG_FS_PERIPH_BASE - { .reg_base = USB_OTG_FS_PERIPH_BASE, .irqnum = USB_OTG_FS_IRQN, .ep_count = EP_MAX_FS, .ep_fifo_size = EP_FIFO_SIZE_FS }, + { .reg_base = USB_OTG_FS_PERIPH_BASE, .irqnum = OTG_FS_IRQn, .ep_count = EP_MAX_FS, .ep_fifo_size = EP_FIFO_SIZE_FS }, #endif #ifdef USB_OTG_HS_PERIPH_BASE -- cgit v1.3.1 From bc576e7cee64fedfa977604f8e9e4043b3473ece Mon Sep 17 00:00:00 2001 From: Tinic Uro Date: Wed, 12 Jun 2024 08:33:10 -0700 Subject: Make it work. --- hw/bsp/stm32u5/boards/stm32u545nucleo/board.mk | 1 + hw/bsp/stm32u5/boards/stm32u575eval/board.mk | 1 + hw/bsp/stm32u5/family.mk | 2 +- src/common/tusb_mcu.h | 2 +- 4 files changed, 4 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/hw/bsp/stm32u5/boards/stm32u545nucleo/board.mk b/hw/bsp/stm32u5/boards/stm32u545nucleo/board.mk index 66cba0c2b..072c595fb 100644 --- a/hw/bsp/stm32u5/boards/stm32u545nucleo/board.mk +++ b/hw/bsp/stm32u5/boards/stm32u545nucleo/board.mk @@ -6,5 +6,6 @@ LD_FILE = ${FAMILY_PATH}/linker/STM32U545xx_FLASH.ld SRC_S += $(ST_CMSIS)/Source/Templates/gcc/startup_stm32u545xx.s +MCU_VARIANT = stm32u545xx # For flash-jlink target JLINK_DEVICE = stm32u545re diff --git a/hw/bsp/stm32u5/boards/stm32u575eval/board.mk b/hw/bsp/stm32u5/boards/stm32u575eval/board.mk index 922d67f83..fee56f2ba 100644 --- a/hw/bsp/stm32u5/boards/stm32u575eval/board.mk +++ b/hw/bsp/stm32u5/boards/stm32u575eval/board.mk @@ -6,5 +6,6 @@ LD_FILE = ${FAMILY_PATH}/linker/STM32U575xx_FLASH.ld SRC_S += $(ST_CMSIS)/Source/Templates/gcc/startup_stm32u575xx.s +MCU_VARIANT = stm32u575xx # For flash-jlink target JLINK_DEVICE = stm32u575ai diff --git a/hw/bsp/stm32u5/family.mk b/hw/bsp/stm32u5/family.mk index 45f9aa33e..9ab8992a8 100644 --- a/hw/bsp/stm32u5/family.mk +++ b/hw/bsp/stm32u5/family.mk @@ -41,7 +41,7 @@ SRC_C += \ ifeq ($(MCU_VARIANT),stm32u545xx) SRC_C += \ src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c -else ($(MCU_VARIANT),stm32u535xx) +else ifeq ($(MCU_VARIANT),stm32u535xx) SRC_C += \ src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c else diff --git a/src/common/tusb_mcu.h b/src/common/tusb_mcu.h index 0f4fca8d1..4b802138b 100644 --- a/src/common/tusb_mcu.h +++ b/src/common/tusb_mcu.h @@ -271,7 +271,7 @@ #define TUP_DCD_ENDPOINT_MAX 8 #elif TU_CHECK_MCU(OPT_MCU_STM32U5) - #ifdef USB_DRD_FS + #if defined (STM32U535xx) || defined (STM32U545xx) #define TUP_USBIP_FSDEV #define TUP_USBIP_FSDEV_STM32 #define TUP_DCD_ENDPOINT_MAX 8 -- cgit v1.3.1 From 2ed027f2bdedae81f20d7417ad7f018a6de9357a Mon Sep 17 00:00:00 2001 From: hathach Date: Fri, 14 Jun 2024 12:51:28 +0700 Subject: use stock core_riscv.h for ch32 v2 v3 --- hw/bsp/ch32v20x/core_riscv.h | 572 ------------------------------- hw/bsp/ch32v20x/family.c | 12 + hw/bsp/ch32v20x/family.cmake | 1 + hw/bsp/ch32v20x/family.mk | 4 + hw/bsp/ch32v307/core_riscv.h | 379 -------------------- hw/bsp/ch32v307/debug_uart.c | 9 + hw/bsp/ch32v307/family.c | 13 + hw/bsp/ch32v307/family.cmake | 1 + hw/bsp/ch32v307/family.mk | 4 + src/portable/st/stm32_fsdev/fsdev_ch32.h | 12 +- src/portable/wch/ch32_usbfs_reg.h | 11 + src/portable/wch/ch32_usbhs_reg.h | 12 + 12 files changed, 78 insertions(+), 952 deletions(-) delete mode 100644 hw/bsp/ch32v20x/core_riscv.h delete mode 100644 hw/bsp/ch32v307/core_riscv.h (limited to 'src') diff --git a/hw/bsp/ch32v20x/core_riscv.h b/hw/bsp/ch32v20x/core_riscv.h deleted file mode 100644 index be1b52a6c..000000000 --- a/hw/bsp/ch32v20x/core_riscv.h +++ /dev/null @@ -1,572 +0,0 @@ -/********************************** (C) COPYRIGHT ******************************* - * File Name : core_riscv.h - * Author : WCH - * Version : V1.0.0 - * Date : 2021/06/06 - * Description : RISC-V Core Peripheral Access Layer Header File for CH32V20x -********************************************************************************* -* Copyright (c) 2021 Nanjing Qinheng Microelectronics Co., Ltd. -* Attention: This software (modified or not) and binary are used for -* microcontroller manufactured by Nanjing Qinheng Microelectronics. -*******************************************************************************/ -#ifndef __CORE_RISCV_H__ -#define __CORE_RISCV_H__ - -#ifdef __cplusplus -extern "C" { -#endif - -/* IO definitions */ -#ifdef __cplusplus - #define __I volatile /* defines 'read only' permissions */ -#else - #define __I volatile const /* defines 'read only' permissions */ -#endif -#define __O volatile /* defines 'write only' permissions */ -#define __IO volatile /* defines 'read / write' permissions */ - -/* Standard Peripheral Library old types (maintained for legacy purpose) */ -typedef __I uint64_t vuc64; /* Read Only */ -typedef __I uint32_t vuc32; /* Read Only */ -typedef __I uint16_t vuc16; /* Read Only */ -typedef __I uint8_t vuc8; /* Read Only */ - -typedef const uint64_t uc64; /* Read Only */ -typedef const uint32_t uc32; /* Read Only */ -typedef const uint16_t uc16; /* Read Only */ -typedef const uint8_t uc8; /* Read Only */ - -typedef __I int64_t vsc64; /* Read Only */ -typedef __I int32_t vsc32; /* Read Only */ -typedef __I int16_t vsc16; /* Read Only */ -typedef __I int8_t vsc8; /* Read Only */ - -typedef const int64_t sc64; /* Read Only */ -typedef const int32_t sc32; /* Read Only */ -typedef const int16_t sc16; /* Read Only */ -typedef const int8_t sc8; /* Read Only */ - -typedef __IO uint64_t vu64; -typedef __IO uint32_t vu32; -typedef __IO uint16_t vu16; -typedef __IO uint8_t vu8; - -typedef uint64_t u64; -typedef uint32_t u32; -typedef uint16_t u16; -typedef uint8_t u8; - -typedef __IO int64_t vs64; -typedef __IO int32_t vs32; -typedef __IO int16_t vs16; -typedef __IO int8_t vs8; - -typedef int64_t s64; -typedef int32_t s32; -typedef int16_t s16; -typedef int8_t s8; - -typedef enum {NoREADY = 0, READY = !NoREADY} ErrorStatus; - -typedef enum {DISABLE = 0, ENABLE = !DISABLE} FunctionalState; - -typedef enum {RESET = 0, SET = !RESET} FlagStatus, ITStatus; - -#define RV_STATIC_INLINE static inline - -/* memory mapped structure for Program Fast Interrupt Controller (PFIC) */ -typedef struct{ - __I uint32_t ISR[8]; - __I uint32_t IPR[8]; - __IO uint32_t ITHRESDR; - __IO uint32_t RESERVED; - __IO uint32_t CFGR; - __I uint32_t GISR; - __IO uint8_t VTFIDR[4]; - uint8_t RESERVED0[12]; - __IO uint32_t VTFADDR[4]; - uint8_t RESERVED1[0x90]; - __O uint32_t IENR[8]; - uint8_t RESERVED2[0x60]; - __O uint32_t IRER[8]; - uint8_t RESERVED3[0x60]; - __O uint32_t IPSR[8]; - uint8_t RESERVED4[0x60]; - __O uint32_t IPRR[8]; - uint8_t RESERVED5[0x60]; - __IO uint32_t IACTR[8]; - uint8_t RESERVED6[0xE0]; - __IO uint8_t IPRIOR[256]; - uint8_t RESERVED7[0x810]; - __IO uint32_t SCTLR; -}PFIC_Type; - -/* memory mapped structure for SysTick */ -typedef struct -{ - __IO uint32_t CTLR; - __IO uint32_t SR; - __IO uint64_t CNT; - __IO uint64_t CMP; -}SysTick_Type; - -#define PFIC ((PFIC_Type *) 0xE000E000 ) -#define NVIC PFIC -#define NVIC_KEY1 ((uint32_t)0xFA050000) -#define NVIC_KEY2 ((uint32_t)0xBCAF0000) -#define NVIC_KEY3 ((uint32_t)0xBEEF0000) - -#define SysTick ((SysTick_Type *) 0xE000F000) - -/********************************************************************* - * @fn __enable_irq - * - * @brief Enable Global Interrupt - * - * @return none - */ -__attribute__( ( always_inline ) ) RV_STATIC_INLINE void __enable_irq(void) -{ - __asm volatile ("csrw 0x800, %0" : : "r" (0x6088) ); -} - -/********************************************************************* - * @fn __disable_irq - * - * @brief Disable Global Interrupt - * - * @return none - */ -__attribute__( ( always_inline ) ) RV_STATIC_INLINE void __disable_irq(void) -{ - __asm volatile ("csrw 0x800, %0" : : "r" (0x6000) ); -} - -/********************************************************************* - * @fn __NOP - * - * @brief nop - * - * @return none - */ -__attribute__( ( always_inline ) ) RV_STATIC_INLINE void __NOP(void) -{ - __asm volatile ("nop"); -} - -/********************************************************************* - * @fn NVIC_EnableIRQ - * - * @brief Disable Interrupt - * - * @param IRQn - Interrupt Numbers - * - * @return none - */ -__attribute__( ( always_inline ) ) RV_STATIC_INLINE void NVIC_EnableIRQ(IRQn_Type IRQn) -{ - NVIC->IENR[((uint32_t)(IRQn) >> 5)] = (1 << ((uint32_t)(IRQn) & 0x1F)); -} - -/********************************************************************* - * @fn NVIC_DisableIRQ - * - * @brief Disable Interrupt - * - * @param IRQn - Interrupt Numbers - * - * @return none - */ -__attribute__( ( always_inline ) ) RV_STATIC_INLINE void NVIC_DisableIRQ(IRQn_Type IRQn) -{ - NVIC->IRER[((uint32_t)(IRQn) >> 5)] = (1 << ((uint32_t)(IRQn) & 0x1F)); -} - -/********************************************************************* - * @fn NVIC_GetStatusIRQ - * - * @brief Get Interrupt Enable State - * - * @param IRQn - Interrupt Numbers - * - * @return 1 - Interrupt Pending Enable - * 0 - Interrupt Pending Disable - */ -__attribute__( ( always_inline ) ) RV_STATIC_INLINE uint32_t NVIC_GetStatusIRQ(IRQn_Type IRQn) -{ - return((uint32_t) ((NVIC->ISR[(uint32_t)(IRQn) >> 5] & (1 << ((uint32_t)(IRQn) & 0x1F)))?1:0)); -} - -/********************************************************************* - * @fn NVIC_GetPendingIRQ - * - * @brief Get Interrupt Pending State - * - * @param IRQn - Interrupt Numbers - * - * @return 1 - Interrupt Pending Enable - * 0 - Interrupt Pending Disable - */ -__attribute__( ( always_inline ) ) RV_STATIC_INLINE uint32_t NVIC_GetPendingIRQ(IRQn_Type IRQn) -{ - return((uint32_t) ((NVIC->IPR[(uint32_t)(IRQn) >> 5] & (1 << ((uint32_t)(IRQn) & 0x1F)))?1:0)); -} - -/********************************************************************* - * @fn NVIC_SetPendingIRQ - * - * @brief Set Interrupt Pending - * - * @param IRQn - Interrupt Numbers - * - * @return none - */ -__attribute__( ( always_inline ) ) RV_STATIC_INLINE void NVIC_SetPendingIRQ(IRQn_Type IRQn) -{ - NVIC->IPSR[((uint32_t)(IRQn) >> 5)] = (1 << ((uint32_t)(IRQn) & 0x1F)); -} - -/********************************************************************* - * @fn NVIC_ClearPendingIRQ - * - * @brief Clear Interrupt Pending - * - * @param IRQn - Interrupt Numbers - * - * @return none - */ -__attribute__( ( always_inline ) ) RV_STATIC_INLINE void NVIC_ClearPendingIRQ(IRQn_Type IRQn) -{ - NVIC->IPRR[((uint32_t)(IRQn) >> 5)] = (1 << ((uint32_t)(IRQn) & 0x1F)); -} - -/********************************************************************* - * @fn NVIC_GetActive - * - * @brief Get Interrupt Active State - * - * @param IRQn - Interrupt Numbers - * - * @return 1 - Interrupt Active - * 0 - Interrupt No Active - */ -__attribute__( ( always_inline ) ) RV_STATIC_INLINE uint32_t NVIC_GetActive(IRQn_Type IRQn) -{ - return((uint32_t)((NVIC->IACTR[(uint32_t)(IRQn) >> 5] & (1 << ((uint32_t)(IRQn) & 0x1F)))?1:0)); -} - -/********************************************************************* - * @fn NVIC_SetPriority - * - * @brief Set Interrupt Priority - * - * @param IRQn - Interrupt Numbers - * priority - bit7 - Pre-emption Priority - * bit[6:5] - Subpriority - * - * @return none - */ -__attribute__( ( always_inline ) ) RV_STATIC_INLINE void NVIC_SetPriority(IRQn_Type IRQn, uint8_t priority) -{ - NVIC->IPRIOR[(uint32_t)(IRQn)] = priority; -} - -/********************************************************************* - * @fn __WFI - * - * @brief Wait for Interrupt - * - * @return none - */ -__attribute__( ( always_inline ) ) RV_STATIC_INLINE void __WFI(void) -{ - NVIC->SCTLR &= ~(1<<3); // wfi - asm volatile ("wfi"); -} - -/********************************************************************* - * @fn _SEV - * - * @brief Set Event - * - * @return none - */ -__attribute__( ( always_inline ) ) RV_STATIC_INLINE void _SEV(void) -{ - uint32_t t; - - t = NVIC->SCTLR; - NVIC->SCTLR |= (1<<3)|(1<<5); - NVIC->SCTLR = (NVIC->SCTLR & ~(1<<5)) | ( t & (1<<5)); -} - -/********************************************************************* - * @fn _WFE - * - * @brief Wait for Events - * - * @return none - */ -__attribute__( ( always_inline ) ) RV_STATIC_INLINE void _WFE(void) -{ - NVIC->SCTLR |= (1<<3); - asm volatile ("wfi"); -} - -/********************************************************************* - * @fn __WFE - * - * @brief Wait for Events - * - * @return none - */ -__attribute__( ( always_inline ) ) RV_STATIC_INLINE void __WFE(void) -{ - _SEV(); - _WFE(); - _WFE(); -} - -/********************************************************************* - * @fn SetVTFIRQ - * - * @brief Set VTF Interrupt - * - * @param addr - VTF interrupt service function base address. - * IRQn - Interrupt Numbers - * num - VTF Interrupt Numbers - * NewState - DISABLE or ENABLE - * - * @return none - */ -__attribute__( ( always_inline ) ) RV_STATIC_INLINE void SetVTFIRQ(uint32_t addr, IRQn_Type IRQn, uint8_t num, FunctionalState NewState){ - if(num > 3) return ; - - if (NewState != DISABLE) - { - NVIC->VTFIDR[num] = IRQn; - NVIC->VTFADDR[num] = ((addr&0xFFFFFFFE)|0x1); - } - else{ - NVIC->VTFIDR[num] = IRQn; - NVIC->VTFADDR[num] = ((addr&0xFFFFFFFE)&(~0x1)); - } -} - -/********************************************************************* - * @fn NVIC_SystemReset - * - * @brief Initiate a system reset request - * - * @return none - */ -__attribute__( ( always_inline ) ) RV_STATIC_INLINE void NVIC_SystemReset(void) -{ - NVIC->CFGR = NVIC_KEY3|(1<<7); -} - -/********************************************************************* - * @fn __AMOADD_W - * - * @brief Atomic Add with 32bit value - * Atomically ADD 32bit value with value in memory using amoadd.d. - * - * @param addr - Address pointer to data, address need to be 4byte aligned - * value - value to be ADDed - * - * @return return memory value + add value - */ -__attribute__( ( always_inline ) ) RV_STATIC_INLINE int32_t __AMOADD_W(volatile int32_t *addr, int32_t value) -{ - int32_t result; - - __asm volatile ("amoadd.w %0, %2, %1" : \ - "=r"(result), "+A"(*addr) : "r"(value) : "memory"); - return *addr; -} - -/********************************************************************* - * @fn __AMOAND_W - * - * @brief Atomic And with 32bit value - * Atomically AND 32bit value with value in memory using amoand.d. - * - * @param addr - Address pointer to data, address need to be 4byte aligned - * value - value to be ANDed - * - * @return return memory value & and value - */ -__attribute__( ( always_inline ) ) RV_STATIC_INLINE int32_t __AMOAND_W(volatile int32_t *addr, int32_t value) -{ - int32_t result; - - __asm volatile ("amoand.w %0, %2, %1" : \ - "=r"(result), "+A"(*addr) : "r"(value) : "memory"); - return *addr; -} - -/********************************************************************* - * @fn __AMOMAX_W - * - * @brief Atomic signed MAX with 32bit value - * Atomically signed max compare 32bit value with value in memory using amomax.d. - * - * @param addr - Address pointer to data, address need to be 4byte aligned - * value - value to be compared - * - * @return the bigger value - */ -__attribute__( ( always_inline ) ) RV_STATIC_INLINE int32_t __AMOMAX_W(volatile int32_t *addr, int32_t value) -{ - int32_t result; - - __asm volatile ("amomax.w %0, %2, %1" : \ - "=r"(result), "+A"(*addr) : "r"(value) : "memory"); - return *addr; -} - -/********************************************************************* - * @fn __AMOMAXU_W - * - * @brief Atomic unsigned MAX with 32bit value - * Atomically unsigned max compare 32bit value with value in memory using amomaxu.d. - * - * @param addr - Address pointer to data, address need to be 4byte aligned - * value - value to be compared - * - * @return return the bigger value - */ -__attribute__( ( always_inline ) ) RV_STATIC_INLINE uint32_t __AMOMAXU_W(volatile uint32_t *addr, uint32_t value) -{ - uint32_t result; - - __asm volatile ("amomaxu.w %0, %2, %1" : \ - "=r"(result), "+A"(*addr) : "r"(value) : "memory"); - return *addr; -} - -/********************************************************************* - * @fn __AMOMIN_W - * - * @brief Atomic signed MIN with 32bit value - * Atomically signed min compare 32bit value with value in memory using amomin.d. - * - * @param addr - Address pointer to data, address need to be 4byte aligned - * value - value to be compared - * - * @return the smaller value - */ -__attribute__( ( always_inline ) ) RV_STATIC_INLINE int32_t __AMOMIN_W(volatile int32_t *addr, int32_t value) -{ - int32_t result; - - __asm volatile ("amomin.w %0, %2, %1" : \ - "=r"(result), "+A"(*addr) : "r"(value) : "memory"); - return *addr; -} - -/********************************************************************* - * @fn __AMOMINU_W - * - * @brief Atomic unsigned MIN with 32bit value - * Atomically unsigned min compare 32bit value with value in memory using amominu.d. - * - * @param addr - Address pointer to data, address need to be 4byte aligned - * value - value to be compared - * - * @return the smaller value - */ -__attribute__( ( always_inline ) ) RV_STATIC_INLINE uint32_t __AMOMINU_W(volatile uint32_t *addr, uint32_t value) -{ - uint32_t result; - - __asm volatile ("amominu.w %0, %2, %1" : \ - "=r"(result), "+A"(*addr) : "r"(value) : "memory"); - return *addr; -} - -/********************************************************************* - * @fn __AMOOR_W - * - * @brief Atomic OR with 32bit value - * Atomically OR 32bit value with value in memory using amoor.d. - * - * @param addr - Address pointer to data, address need to be 4byte aligned - * value - value to be ORed - * - * @return return memory value | and value - */ -__attribute__( ( always_inline ) ) RV_STATIC_INLINE int32_t __AMOOR_W(volatile int32_t *addr, int32_t value) -{ - int32_t result; - - __asm volatile ("amoor.w %0, %2, %1" : \ - "=r"(result), "+A"(*addr) : "r"(value) : "memory"); - return *addr; -} - -/********************************************************************* - * @fn __AMOSWAP_W - * - * @brief Atomically swap new 32bit value into memory using amoswap.d. - * - * @param addr - Address pointer to data, address need to be 4byte aligned - * newval - New value to be stored into the address - * - * @return return the original value in memory - */ -__attribute__( ( always_inline ) ) RV_STATIC_INLINE uint32_t __AMOSWAP_W(volatile uint32_t *addr, uint32_t newval) -{ - uint32_t result; - - __asm volatile ("amoswap.w %0, %2, %1" : \ - "=r"(result), "+A"(*addr) : "r"(newval) : "memory"); - return result; -} - -/********************************************************************* - * @fn __AMOXOR_W - * - * @brief Atomic XOR with 32bit value - * Atomically XOR 32bit value with value in memory using amoxor.d. - * - * @param addr - Address pointer to data, address need to be 4byte aligned - * value - value to be XORed - * - * @return return memory value ^ and value - */ -__attribute__( ( always_inline ) ) RV_STATIC_INLINE int32_t __AMOXOR_W(volatile int32_t *addr, int32_t value) -{ - int32_t result; - - __asm volatile ("amoxor.w %0, %2, %1" : \ - "=r"(result), "+A"(*addr) : "r"(value) : "memory"); - return *addr; -} - -/* Core_Exported_Functions */ -extern uint32_t __get_MSTATUS(void); -extern void __set_MSTATUS(uint32_t value); -extern uint32_t __get_MISA(void); -extern void __set_MISA(uint32_t value); -extern uint32_t __get_MTVEC(void); -extern void __set_MTVEC(uint32_t value); -extern uint32_t __get_MSCRATCH(void); -extern void __set_MSCRATCH(uint32_t value); -extern uint32_t __get_MEPC(void); -extern void __set_MEPC(uint32_t value); -extern uint32_t __get_MCAUSE(void); -extern void __set_MCAUSE(uint32_t value); -extern uint32_t __get_MTVAL(void); -extern void __set_MTVAL(uint32_t value); -extern uint32_t __get_MVENDORID(void); -extern uint32_t __get_MARCHID(void); -extern uint32_t __get_MIMPID(void); -extern uint32_t __get_MHARTID(void); -extern uint32_t __get_SP(void); - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/hw/bsp/ch32v20x/family.c b/hw/bsp/ch32v20x/family.c index c32cfd46e..8575f5699 100644 --- a/hw/bsp/ch32v20x/family.c +++ b/hw/bsp/ch32v20x/family.c @@ -1,6 +1,18 @@ #include + +// https://github.com/openwch/ch32v307/pull/90 +// https://github.com/openwch/ch32v20x/pull/12 +#ifdef __GNUC__ +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wstrict-prototypes" +#endif + #include "ch32v20x.h" +#ifdef __GNUC__ +#pragma GCC diagnostic pop +#endif + #include "bsp/board_api.h" #include "board.h" diff --git a/hw/bsp/ch32v20x/family.cmake b/hw/bsp/ch32v20x/family.cmake index 1d574fdf8..28fd13697 100644 --- a/hw/bsp/ch32v20x/family.cmake +++ b/hw/bsp/ch32v20x/family.cmake @@ -49,6 +49,7 @@ function(add_board_target BOARD_TARGET) ${STARTUP_FILE_${CMAKE_C_COMPILER_ID}} ) target_include_directories(${BOARD_TARGET} PUBLIC + ${SDK_SRC_DIR}/Core ${SDK_SRC_DIR}/Peripheral/inc ${CMAKE_CURRENT_FUNCTION_LIST_DIR} ) diff --git a/hw/bsp/ch32v20x/family.mk b/hw/bsp/ch32v20x/family.mk index 49d4d2feb..daf3148f8 100644 --- a/hw/bsp/ch32v20x/family.mk +++ b/hw/bsp/ch32v20x/family.mk @@ -24,6 +24,9 @@ CFLAGS += \ -DCH32V20x_${MCU_VARIANT} \ -DCFG_TUSB_MCU=OPT_MCU_CH32V20X +# https://github.com/openwch/ch32v20x/pull/12 +CFLAGS += -Wno-error=strict-prototypes + ifeq ($(PORT),0) $(info "Using FSDEV driver") CFLAGS += -DCFG_TUD_WCH_USBIP_FSDEV=1 @@ -51,6 +54,7 @@ SRC_S += $(SDK_SRC_DIR)/Startup/startup_ch32v20x_${MCU_VARIANT}.S INC += \ $(TOP)/$(BOARD_PATH) \ + $(TOP)/$(SDK_SRC_DIR)/Core \ $(TOP)/$(SDK_SRC_DIR)/Peripheral/inc \ FREERTOS_PORTABLE_SRC = $(FREERTOS_PORTABLE_PATH)/RISC-V diff --git a/hw/bsp/ch32v307/core_riscv.h b/hw/bsp/ch32v307/core_riscv.h deleted file mode 100644 index a7ce10a00..000000000 --- a/hw/bsp/ch32v307/core_riscv.h +++ /dev/null @@ -1,379 +0,0 @@ -/********************************** (C) COPYRIGHT ******************************* -* File Name : core_riscv.h -* Author : WCH -* Version : V1.0.0 -* Date : 2021/06/06 -* Description : RISC-V Core Peripheral Access Layer Header File for CH32V30x -* Copyright (c) 2021 Nanjing Qinheng Microelectronics Co., Ltd. -* SPDX-License-Identifier: Apache-2.0 -*******************************************************************************/ -#ifndef __CORE_RISCV_H__ -#define __CORE_RISCV_H__ - -/* IO definitions */ -#ifdef __cplusplus - #define __I volatile /* defines 'read only' permissions */ -#else - #define __I volatile const /* defines 'read only' permissions */ -#endif -#define __O volatile /* defines 'write only' permissions */ -#define __IO volatile /* defines 'read / write' permissions */ - -/* Standard Peripheral Library old types (maintained for legacy purpose) */ -typedef __I uint64_t vuc64; /* Read Only */ -typedef __I uint32_t vuc32; /* Read Only */ -typedef __I uint16_t vuc16; /* Read Only */ -typedef __I uint8_t vuc8; /* Read Only */ - -typedef const uint64_t uc64; /* Read Only */ -typedef const uint32_t uc32; /* Read Only */ -typedef const uint16_t uc16; /* Read Only */ -typedef const uint8_t uc8; /* Read Only */ - -typedef __I int64_t vsc64; /* Read Only */ -typedef __I int32_t vsc32; /* Read Only */ -typedef __I int16_t vsc16; /* Read Only */ -typedef __I int8_t vsc8; /* Read Only */ - -typedef const int64_t sc64; /* Read Only */ -typedef const int32_t sc32; /* Read Only */ -typedef const int16_t sc16; /* Read Only */ -typedef const int8_t sc8; /* Read Only */ - -typedef __IO uint64_t vu64; -typedef __IO uint32_t vu32; -typedef __IO uint16_t vu16; -typedef __IO uint8_t vu8; - -typedef uint64_t u64; -typedef uint32_t u32; -typedef uint16_t u16; -typedef uint8_t u8; - -typedef __IO int64_t vs64; -typedef __IO int32_t vs32; -typedef __IO int16_t vs16; -typedef __IO int8_t vs8; - -typedef int64_t s64; -typedef int32_t s32; -typedef int16_t s16; -typedef int8_t s8; - -typedef enum {ERROR = 0, SUCCESS = !ERROR} ErrorStatus; - -typedef enum {DISABLE = 0, ENABLE = !DISABLE} FunctionalState; - -typedef enum {RESET = 0, SET = !RESET} FlagStatus, ITStatus; - -#define RV_STATIC_INLINE static inline - -/* memory mapped structure for Program Fast Interrupt Controller (PFIC) */ -typedef struct{ - __I uint32_t ISR[8]; - __I uint32_t IPR[8]; - __IO uint32_t ITHRESDR; - __IO uint32_t RESERVED; - __IO uint32_t CFGR; - __I uint32_t GISR; - uint8_t VTFIDR[4]; - uint8_t RESERVED0[12]; - __IO uint32_t VTFADDR[4]; - uint8_t RESERVED1[0x90]; - __O uint32_t IENR[8]; - uint8_t RESERVED2[0x60]; - __O uint32_t IRER[8]; - uint8_t RESERVED3[0x60]; - __O uint32_t IPSR[8]; - uint8_t RESERVED4[0x60]; - __O uint32_t IPRR[8]; - uint8_t RESERVED5[0x60]; - __IO uint32_t IACTR[8]; - uint8_t RESERVED6[0xE0]; - __IO uint8_t IPRIOR[256]; - uint8_t RESERVED7[0x810]; - __IO uint32_t SCTLR; -}PFIC_Type; - -/* memory mapped structure for SysTick */ -typedef struct -{ - __IO u32 CTLR; - __IO u32 SR; - __IO u64 CNT; - __IO u64 CMP; -}SysTick_Type; - - -#define PFIC ((PFIC_Type *) 0xE000E000 ) -#define NVIC PFIC -#define NVIC_KEY1 ((uint32_t)0xFA050000) -#define NVIC_KEY2 ((uint32_t)0xBCAF0000) -#define NVIC_KEY3 ((uint32_t)0xBEEF0000) - -#define SysTick ((SysTick_Type *) 0xE000F000) - - -/********************************************************************* - * @fn __enable_irq - * - * @brief Enable Global Interrupt - * - * @return none - */ -RV_STATIC_INLINE void __enable_irq(void) -{ - __asm volatile ("csrw 0x800, %0" : : "r" (0x6088) ); -} - -/********************************************************************* - * @fn __disable_irq - * - * @brief Disable Global Interrupt - * - * @return none - */ -RV_STATIC_INLINE void __disable_irq(void) -{ - __asm volatile ("csrw 0x800, %0" : : "r" (0x6000) ); -} - -/********************************************************************* - * @fn __NOP - * - * @brief nop - * - * @return none - */ -RV_STATIC_INLINE void __NOP(void) -{ - __asm volatile ("nop"); -} - -/********************************************************************* - * @fn NVIC_EnableIRQ - * - * @brief Enable Interrupt - * - * @param IRQn: Interrupt Numbers - * - * @return none - */ -RV_STATIC_INLINE void NVIC_EnableIRQ(IRQn_Type IRQn) -{ - NVIC->IENR[((uint32_t)(IRQn) >> 5)] = (1 << ((uint32_t)(IRQn) & 0x1F)); -} - -/********************************************************************* - * @fn NVIC_DisableIRQ - * - * @brief Disable Interrupt - * - * @param IRQn: Interrupt Numbers - * - * @return none - */ -RV_STATIC_INLINE void NVIC_DisableIRQ(IRQn_Type IRQn) -{ - NVIC->IRER[((uint32_t)(IRQn) >> 5)] = (1 << ((uint32_t)(IRQn) & 0x1F)); -} - -/********************************************************************* - * @fn NVIC_GetStatusIRQ - * - * @brief Get Interrupt Enable State - * - * @param IRQn: Interrupt Numbers - * - * @return 1 - Interrupt Enable - * 0 - Interrupt Disable - */ -RV_STATIC_INLINE uint32_t NVIC_GetStatusIRQ(IRQn_Type IRQn) -{ - return((uint32_t) ((NVIC->ISR[(uint32_t)(IRQn) >> 5] & (1 << ((uint32_t)(IRQn) & 0x1F)))?1:0)); -} - -/********************************************************************* - * @fn NVIC_GetPendingIRQ - * - * @brief Get Interrupt Pending State - * - * @param IRQn: Interrupt Numbers - * - * @return 1 - Interrupt Pending Enable - * 0 - Interrupt Pending Disable - */ -RV_STATIC_INLINE uint32_t NVIC_GetPendingIRQ(IRQn_Type IRQn) -{ - return((uint32_t) ((NVIC->IPR[(uint32_t)(IRQn) >> 5] & (1 << ((uint32_t)(IRQn) & 0x1F)))?1:0)); -} - -/********************************************************************* - * @fn NVIC_SetPendingIRQ - * - * @brief Set Interrupt Pending - * - * @param IRQn: Interrupt Numbers - * - * @return None - */ -RV_STATIC_INLINE void NVIC_SetPendingIRQ(IRQn_Type IRQn) -{ - NVIC->IPSR[((uint32_t)(IRQn) >> 5)] = (1 << ((uint32_t)(IRQn) & 0x1F)); -} - -/********************************************************************* - * @fn NVIC_ClearPendingIRQ - * - * @brief Clear Interrupt Pending - * - * @param IRQn: Interrupt Numbers - * - * @return None - */ -RV_STATIC_INLINE void NVIC_ClearPendingIRQ(IRQn_Type IRQn) -{ - NVIC->IPRR[((uint32_t)(IRQn) >> 5)] = (1 << ((uint32_t)(IRQn) & 0x1F)); -} - -/********************************************************************* - * @fn NVIC_GetActive - * - * @brief Get Interrupt Active State - * - * @param IRQn: Interrupt Numbers - * - * @return 1 - Interrupt Active - * 0 - Interrupt No Active - */ -RV_STATIC_INLINE uint32_t NVIC_GetActive(IRQn_Type IRQn) -{ - return((uint32_t)((NVIC->IACTR[(uint32_t)(IRQn) >> 5] & (1 << ((uint32_t)(IRQn) & 0x1F)))?1:0)); -} - -/********************************************************************* - * @fn NVIC_SetPriority - * - * @brief Set Interrupt Priority - * - * @param IRQn - Interrupt Numbers - * priority - - * bit7 - pre-emption priority - * bit6~bit4 - subpriority - * @return None - */ -RV_STATIC_INLINE void NVIC_SetPriority(IRQn_Type IRQn, uint8_t priority) -{ - NVIC->IPRIOR[(uint32_t)(IRQn)] = priority; -} - -/********************************************************************* - * @fn __WFI - * - * @brief Wait for Interrupt - * - * @return None - */ -__attribute__( ( always_inline ) ) RV_STATIC_INLINE void __WFI(void) -{ - NVIC->SCTLR &= ~(1<<3); // wfi - asm volatile ("wfi"); -} - -/********************************************************************* - * @fn __WFE - * - * @brief Wait for Events - * - * @return None - */ -__attribute__( ( always_inline ) ) RV_STATIC_INLINE void __WFE(void) -{ - uint32_t t; - - t = NVIC->SCTLR; - NVIC->SCTLR |= (1<<3)|(1<<5); // (wfi->wfe)+(__sev) - NVIC->SCTLR = (NVIC->SCTLR & ~(1<<5)) | ( t & (1<<5)); - asm volatile ("wfi"); - asm volatile ("wfi"); -} - -/********************************************************************* - * @fn SetVTFIRQ - * - * @brief Set VTF Interrupt - * - * @param add - VTF interrupt service function base address. - * IRQn -Interrupt Numbers - * num - VTF Interrupt Numbers - * NewState - DISABLE or ENABLE - * @return None - */ -RV_STATIC_INLINE void SetVTFIRQ(uint32_t addr, IRQn_Type IRQn, uint8_t num, FunctionalState NewState){ - if(num > 3) return ; - - if (NewState != DISABLE) - { - NVIC->VTFIDR[num] = IRQn; - NVIC->VTFADDR[num] = ((addr&0xFFFFFFFE)|0x1); - } - else{ - NVIC->VTFIDR[num] = IRQn; - NVIC->VTFADDR[num] = ((addr&0xFFFFFFFE)&(~0x1)); - } -} - -/********************************************************************* - * @fn NVIC_SystemReset - * - * @brief Initiate a system reset request - * - * @return None - */ -RV_STATIC_INLINE void NVIC_SystemReset(void) -{ - NVIC->CFGR = NVIC_KEY3|(1<<7); -} - - -/* Core_Exported_Functions */ -extern uint32_t __get_FFLAGS(void); -extern void __set_FFLAGS(uint32_t value); -extern uint32_t __get_FRM(void); -extern void __set_FRM(uint32_t value); -extern uint32_t __get_FCSR(void); -extern void __set_FCSR(uint32_t value); -extern uint32_t __get_MSTATUS(void); -extern void __set_MSTATUS(uint32_t value); -extern uint32_t __get_MISA(void); -extern void __set_MISA(uint32_t value); -extern uint32_t __get_MIE(void); -extern void __set_MIE(uint32_t value); -extern uint32_t __get_MTVEC(void); -extern void __set_MTVEC(uint32_t value); -extern uint32_t __get_MSCRATCH(void); -extern void __set_MSCRATCH(uint32_t value); -extern uint32_t __get_MEPC(void); -extern void __set_MEPC(uint32_t value); -extern uint32_t __get_MCAUSE(void); -extern void __set_MCAUSE(uint32_t value); -extern uint32_t __get_MTVAL(void); -extern void __set_MTVAL(uint32_t value); -extern uint32_t __get_MIP(void); -extern void __set_MIP(uint32_t value); -extern uint32_t __get_MCYCLE(void); -extern void __set_MCYCLE(uint32_t value); -extern uint32_t __get_MCYCLEH(void); -extern void __set_MCYCLEH(uint32_t value); -extern uint32_t __get_MINSTRET(void); -extern void __set_MINSTRET(uint32_t value); -extern uint32_t __get_MINSTRETH(void); -extern void __set_MINSTRETH(uint32_t value); -extern uint32_t __get_MVENDORID(void); -extern uint32_t __get_MARCHID(void); -extern uint32_t __get_MIMPID(void); -extern uint32_t __get_MHARTID(void); -extern uint32_t __get_SP(void); - - -#endif diff --git a/hw/bsp/ch32v307/debug_uart.c b/hw/bsp/ch32v307/debug_uart.c index fbabeeadc..2fd3a9d64 100644 --- a/hw/bsp/ch32v307/debug_uart.c +++ b/hw/bsp/ch32v307/debug_uart.c @@ -25,8 +25,17 @@ */ #include "debug_uart.h" + +#ifdef __GNUC__ +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wstrict-prototypes" +#endif + #include +#ifdef __GNUC__ +#pragma GCC diagnostic pop +#endif #define UART_RINGBUFFER_SIZE_TX 128 #define UART_RINGBUFFER_MASK_TX (UART_RINGBUFFER_SIZE_TX-1) diff --git a/hw/bsp/ch32v307/family.c b/hw/bsp/ch32v307/family.c index 0846b10a9..adf2dbea5 100644 --- a/hw/bsp/ch32v307/family.c +++ b/hw/bsp/ch32v307/family.c @@ -25,9 +25,22 @@ */ #include "stdio.h" + +// https://github.com/openwch/ch32v307/pull/90 +// https://github.com/openwch/ch32v20x/pull/12 + +#ifdef __GNUC__ +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wstrict-prototypes" +#endif + #include "debug_uart.h" #include "ch32v30x.h" +#ifdef __GNUC__ +#pragma GCC diagnostic pop +#endif + #include "bsp/board_api.h" #include "board.h" diff --git a/hw/bsp/ch32v307/family.cmake b/hw/bsp/ch32v307/family.cmake index af26bfc31..d603af62d 100644 --- a/hw/bsp/ch32v307/family.cmake +++ b/hw/bsp/ch32v307/family.cmake @@ -49,6 +49,7 @@ function(add_board_target BOARD_TARGET) ${STARTUP_FILE_${CMAKE_C_COMPILER_ID}} ) target_include_directories(${BOARD_TARGET} PUBLIC + ${SDK_SRC_DIR}/Core ${SDK_SRC_DIR}/Peripheral/inc ${CMAKE_CURRENT_FUNCTION_LIST_DIR} ) diff --git a/hw/bsp/ch32v307/family.mk b/hw/bsp/ch32v307/family.mk index 30a070a9b..bf2732106 100644 --- a/hw/bsp/ch32v307/family.mk +++ b/hw/bsp/ch32v307/family.mk @@ -25,6 +25,9 @@ CFLAGS += \ -fsigned-char \ -DCFG_TUSB_MCU=OPT_MCU_CH32V307 \ +# https://github.com/openwch/ch32v307/pull/90 +CFLAGS += -Wno-error=strict-prototypes + ifeq ($(SPEED),high) $(info "Using USBHS driver for HighSpeed mode") CFLAGS += -DCFG_TUD_WCH_USBIP_USBHS=1 @@ -51,6 +54,7 @@ SRC_S += \ INC += \ $(TOP)/$(BOARD_PATH) \ + $(TOP)/$(SDK_SRC_DIR)/Core \ $(TOP)/$(SDK_SRC_DIR)/Peripheral/inc # For freeRTOS port source diff --git a/src/portable/st/stm32_fsdev/fsdev_ch32.h b/src/portable/st/stm32_fsdev/fsdev_ch32.h index 85fe3266c..dbf2a0289 100644 --- a/src/portable/st/stm32_fsdev/fsdev_ch32.h +++ b/src/portable/st/stm32_fsdev/fsdev_ch32.h @@ -36,13 +36,23 @@ #include "common/tusb_compiler.h" +// https://github.com/openwch/ch32v307/pull/90 +// https://github.com/openwch/ch32v20x/pull/12 +#ifdef __GNUC__ +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wstrict-prototypes" +#endif + #if CFG_TUSB_MCU == OPT_MCU_CH32V20X #include - #elif CFG_TUSB_MCU == OPT_MCU_CH32F20X #include #endif +#ifdef __GNUC__ +#pragma GCC diagnostic pop +#endif + #define FSDEV_PMA_SIZE (512u) // volatile 32-bit aligned diff --git a/src/portable/wch/ch32_usbfs_reg.h b/src/portable/wch/ch32_usbfs_reg.h index 0a50a6169..ef6ebf2dc 100644 --- a/src/portable/wch/ch32_usbfs_reg.h +++ b/src/portable/wch/ch32_usbfs_reg.h @@ -28,6 +28,13 @@ #ifndef USB_CH32_USBFS_REG_H #define USB_CH32_USBFS_REG_H +// https://github.com/openwch/ch32v307/pull/90 +// https://github.com/openwch/ch32v20x/pull/12 +#ifdef __GNUC__ +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wstrict-prototypes" +#endif + #if CFG_TUSB_MCU == OPT_MCU_CH32V307 #include #define USBHD_IRQn OTG_FS_IRQn @@ -39,6 +46,10 @@ #include #endif +#ifdef __GNUC__ +#pragma GCC diagnostic pop +#endif + // CTRL #define USBFS_CTRL_DMA_EN (1 << 0) #define USBFS_CTRL_CLR_ALL (1 << 1) diff --git a/src/portable/wch/ch32_usbhs_reg.h b/src/portable/wch/ch32_usbhs_reg.h index 130e4f223..87300b497 100644 --- a/src/portable/wch/ch32_usbhs_reg.h +++ b/src/portable/wch/ch32_usbhs_reg.h @@ -28,12 +28,24 @@ #ifndef USB_CH32_USBHS_REG_H #define USB_CH32_USBHS_REG_H +// https://github.com/openwch/ch32v307/pull/90 +// https://github.com/openwch/ch32v20x/pull/12 +#ifdef __GNUC__ +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wstrict-prototypes" +#endif + #if CFG_TUSB_MCU == OPT_MCU_CH32V307 #include #elif CFG_TUSB_MCU == OPT_MCU_CH32F20X #include #endif +#ifdef __GNUC__ +#pragma GCC diagnostic pop +#endif + + /******************* GLOBAL ******************/ // USB CONTROL -- cgit v1.3.1 From 969b06d77c8a37510c9bed8dde377ff7bf462a30 Mon Sep 17 00:00:00 2001 From: hathach Date: Fri, 14 Jun 2024 12:51:50 +0700 Subject: minor update --- src/class/hid/hid.h | 4 ++-- src/class/net/ncm_device.c | 2 ++ 2 files changed, 4 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/class/hid/hid.h b/src/class/hid/hid.h index 2fe922136..c2b5a8a48 100644 --- a/src/class/hid/hid.h +++ b/src/class/hid/hid.h @@ -762,7 +762,7 @@ enum { HID_USAGE_PAGE_ALPHA_DISPLAY = 0x14, HID_USAGE_PAGE_MEDICAL = 0x40, HID_USAGE_PAGE_LIGHTING_AND_ILLUMINATION = 0x59, - HID_USAGE_PAGE_MONITOR = 0x80, //0x80 - 0x83 + HID_USAGE_PAGE_MONITOR = 0x80, // 0x80 - 0x83 HID_USAGE_PAGE_POWER = 0x84, // 0x084 - 0x87 HID_USAGE_PAGE_BARCODE_SCANNER = 0x8c, HID_USAGE_PAGE_SCALE = 0x8d, @@ -770,7 +770,7 @@ enum { HID_USAGE_PAGE_CAMERA = 0x90, HID_USAGE_PAGE_ARCADE = 0x91, HID_USAGE_PAGE_FIDO = 0xF1D0, // FIDO alliance HID usage page - HID_USAGE_PAGE_VENDOR = 0xFF00 // 0xFF00 - 0xFFFF + HID_USAGE_PAGE_VENDOR = 0xFF00 // 0xFF00 - 0xFFFF }; /// HID Usage Table - Table 6: Generic Desktop Page diff --git a/src/class/net/ncm_device.c b/src/class/net/ncm_device.c index 64aba011a..44a6a0de9 100644 --- a/src/class/net/ncm_device.c +++ b/src/class/net/ncm_device.c @@ -1,6 +1,8 @@ /* * The MIT License (MIT) * + * Copyright (c) 2020 Jacob Berg Potter + * Copyright (c) 2020 Peter Lawrence * Copyright (c) 2019 Ha Thach (tinyusb.org) * Copyright (c) 2024 Hardy Griech * -- cgit v1.3.1 From 33f5547ed435f33259afc2a8e906eb7a258fbdd6 Mon Sep 17 00:00:00 2001 From: hathach Date: Fri, 14 Jun 2024 16:06:37 +0700 Subject: add ch32v103 bsp support, compile but does not run, probably due to compile/linker issue --- .../ch32v10x/boards/ch32v103r_r1_1v0/board.cmake | 8 + hw/bsp/ch32v10x/boards/ch32v103r_r1_1v0/board.h | 20 + hw/bsp/ch32v10x/boards/ch32v103r_r1_1v0/board.mk | 7 + hw/bsp/ch32v10x/ch32v10x_conf.h | 37 ++ hw/bsp/ch32v10x/ch32v10x_it.h | 15 + hw/bsp/ch32v10x/family.c | 147 +++++ hw/bsp/ch32v10x/family.cmake | 117 ++++ hw/bsp/ch32v10x/family.mk | 53 ++ hw/bsp/ch32v10x/linker/ch32v10x.ld | 165 ++++++ hw/bsp/ch32v10x/system_ch32v10x.c | 600 +++++++++++++++++++++ hw/bsp/ch32v10x/system_ch32v10x.h | 29 + hw/bsp/ch32v10x/wch-riscv.cfg | 17 + hw/bsp/ch32v20x/family.mk | 10 +- hw/bsp/family_support.cmake | 2 +- src/common/tusb_mcu.h | 9 + src/portable/wch/ch32_usbfs_reg.h | 67 ++- src/tusb_option.h | 6 +- tools/get_deps.py | 3 + 18 files changed, 1296 insertions(+), 16 deletions(-) create mode 100644 hw/bsp/ch32v10x/boards/ch32v103r_r1_1v0/board.cmake create mode 100644 hw/bsp/ch32v10x/boards/ch32v103r_r1_1v0/board.h create mode 100644 hw/bsp/ch32v10x/boards/ch32v103r_r1_1v0/board.mk create mode 100644 hw/bsp/ch32v10x/ch32v10x_conf.h create mode 100644 hw/bsp/ch32v10x/ch32v10x_it.h create mode 100644 hw/bsp/ch32v10x/family.c create mode 100644 hw/bsp/ch32v10x/family.cmake create mode 100644 hw/bsp/ch32v10x/family.mk create mode 100644 hw/bsp/ch32v10x/linker/ch32v10x.ld create mode 100644 hw/bsp/ch32v10x/system_ch32v10x.c create mode 100644 hw/bsp/ch32v10x/system_ch32v10x.h create mode 100644 hw/bsp/ch32v10x/wch-riscv.cfg (limited to 'src') diff --git a/hw/bsp/ch32v10x/boards/ch32v103r_r1_1v0/board.cmake b/hw/bsp/ch32v10x/boards/ch32v103r_r1_1v0/board.cmake new file mode 100644 index 000000000..f6e47ba30 --- /dev/null +++ b/hw/bsp/ch32v10x/boards/ch32v103r_r1_1v0/board.cmake @@ -0,0 +1,8 @@ +set(LD_FLASH_SIZE 64K) +set(LD_RAM_SIZE 20K) + +function(update_board TARGET) + target_compile_definitions(${TARGET} PUBLIC + CFG_EXAMPLE_MSC_DUAL_READONLY + ) +endfunction() diff --git a/hw/bsp/ch32v10x/boards/ch32v103r_r1_1v0/board.h b/hw/bsp/ch32v10x/boards/ch32v103r_r1_1v0/board.h new file mode 100644 index 000000000..3b1187c3a --- /dev/null +++ b/hw/bsp/ch32v10x/boards/ch32v103r_r1_1v0/board.h @@ -0,0 +1,20 @@ +#ifndef BOARD_H_ +#define BOARD_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +#define LED_PORT GPIOA +#define LED_PIN GPIO_Pin_10 +#define LED_STATE_ON 0 + +#define BUTTON_PORT GPIOA +#define BUTTON_PIN GPIO_Pin_1 +#define BUTTON_STATE_ACTIVE 0 + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/hw/bsp/ch32v10x/boards/ch32v103r_r1_1v0/board.mk b/hw/bsp/ch32v10x/boards/ch32v103r_r1_1v0/board.mk new file mode 100644 index 000000000..7d7462312 --- /dev/null +++ b/hw/bsp/ch32v10x/boards/ch32v103r_r1_1v0/board.mk @@ -0,0 +1,7 @@ +MCU_VARIANT = D6 + +CFLAGS += -DCFG_EXAMPLE_MSC_DUAL_READONLY + +LDFLAGS += \ + -Wl,--defsym=__flash_size=64K \ + -Wl,--defsym=__ram_size=20K \ diff --git a/hw/bsp/ch32v10x/ch32v10x_conf.h b/hw/bsp/ch32v10x/ch32v10x_conf.h new file mode 100644 index 000000000..939c0fbde --- /dev/null +++ b/hw/bsp/ch32v10x/ch32v10x_conf.h @@ -0,0 +1,37 @@ +/********************************** (C) COPYRIGHT ******************************* + * File Name : ch32v10x_conf.h + * Author : WCH + * Version : V1.0.0 + * Date : 2020/04/30 + * Description : Library configuration file. +********************************************************************************* +* Copyright (c) 2021 Nanjing Qinheng Microelectronics Co., Ltd. +* Attention: This software (modified or not) and binary are used for +* microcontroller manufactured by Nanjing Qinheng Microelectronics. +*******************************************************************************/ +#ifndef __CH32V10x_CONF_H +#define __CH32V10x_CONF_H + +#include "ch32v10x_adc.h" +#include "ch32v10x_bkp.h" +#include "ch32v10x_crc.h" +#include "ch32v10x_dbgmcu.h" +#include "ch32v10x_dma.h" +#include "ch32v10x_exti.h" +#include "ch32v10x_flash.h" +#include "ch32v10x_gpio.h" +#include "ch32v10x_i2c.h" +#include "ch32v10x_iwdg.h" +#include "ch32v10x_pwr.h" +#include "ch32v10x_rcc.h" +#include "ch32v10x_rtc.h" +#include "ch32v10x_spi.h" +#include "ch32v10x_tim.h" +#include "ch32v10x_usart.h" +#include "ch32v10x_wwdg.h" +#include "ch32v10x_usb.h" +#include "ch32v10x_usb_host.h" +#include "ch32v10x_it.h" +#include "ch32v10x_misc.h" + +#endif /* __CH32V10x_CONF_H */ diff --git a/hw/bsp/ch32v10x/ch32v10x_it.h b/hw/bsp/ch32v10x/ch32v10x_it.h new file mode 100644 index 000000000..13afc2412 --- /dev/null +++ b/hw/bsp/ch32v10x/ch32v10x_it.h @@ -0,0 +1,15 @@ +/********************************** (C) COPYRIGHT ******************************* + * File Name : ch32v10x_it.h + * Author : WCH + * Version : V1.0.0 + * Date : 2022/08/20 + * Description : This file contains the headers of the interrupt handlers. +********************************************************************************* +* Copyright (c) 2021 Nanjing Qinheng Microelectronics Co., Ltd. +* Attention: This software (modified or not) and binary are used for +* microcontroller manufactured by Nanjing Qinheng Microelectronics. +*******************************************************************************/ +#ifndef __CH32V10x_IT_H +#define __CH32V10x_IT_H + +#endif /* __CH32V10x_IT_H */ diff --git a/hw/bsp/ch32v10x/family.c b/hw/bsp/ch32v10x/family.c new file mode 100644 index 000000000..6de17521e --- /dev/null +++ b/hw/bsp/ch32v10x/family.c @@ -0,0 +1,147 @@ +#include + +// https://github.com/openwch/ch32v307/pull/90 +// https://github.com/openwch/ch32v20x/pull/12 +#ifdef __GNUC__ +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wstrict-prototypes" +#endif + +#include "ch32v10x.h" + +#ifdef __GNUC__ +#pragma GCC diagnostic pop +#endif + +#include "bsp/board_api.h" +#include "board.h" + +__attribute__((interrupt)) __attribute__((used)) +void USBHD_IRQHandler(void) { + #if CFG_TUD_WCH_USBIP_USBFS + tud_int_handler(0); + #endif +} + +__attribute__((interrupt)) __attribute__((used)) +void USBHDWakeUp_IRQHandler(void) { + #if CFG_TUD_WCH_USBIP_USBFS + tud_int_handler(0); + #endif +} + +#if CFG_TUSB_OS == OPT_OS_NONE +volatile uint32_t system_ticks = 0; + +__attribute__((interrupt)) __attribute__((used)) +void SysTick_Handler(void) { + SysTick->CNTL0 = SysTick->CNTL1 = SysTick->CNTL2 = SysTick->CNTL3 = 0; + SysTick->CNTH0 = SysTick->CNTH1 = SysTick->CNTH2 = SysTick->CNTH3 = 0; + system_ticks++; +} + +uint32_t SysTick_Config(uint32_t ticks) { + NVIC_EnableIRQ(SysTicK_IRQn); + SysTick->CTLR = 0; + SysTick->CNTL0 = SysTick->CNTL1 = SysTick->CNTL2 = SysTick->CNTL3 = 0; + SysTick->CNTH0 = SysTick->CNTH1 = SysTick->CNTH2 = SysTick->CNTH3 = 0; + + SysTick->CMPLR0 = (u8)(ticks & 0xFF); + SysTick->CMPLR1 = (u8)(ticks >> 8); + SysTick->CMPLR2 = (u8)(ticks >> 16); + SysTick->CMPLR3 = (u8)(ticks >> 24); + + SysTick->CMPHR0 = SysTick->CMPHR1 = SysTick->CMPHR2 = SysTick->CMPHR3 = 0; + SysTick->CTLR = 1; + return 0; +} + +uint32_t board_millis(void) { + return system_ticks; +} +#endif + +void board_init(void) { + __disable_irq(); + +#if CFG_TUSB_OS == OPT_OS_NONE + SysTick_Config(SystemCoreClock / 1000); +#endif + + uint8_t usb_div; + switch (SystemCoreClock) { + case 48000000: usb_div = RCC_USBCLKSource_PLLCLK_Div1; break; + case 72000000: usb_div = RCC_USBCLKSource_PLLCLK_1Div5; break; + default: TU_ASSERT(0,); break; + } + RCC_USBCLKConfig(usb_div); + RCC_APB1PeriphClockCmd(RCC_APB1Periph_USB, ENABLE); + + RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); + + #ifdef LED_PIN + GPIO_InitTypeDef led_init = { + .GPIO_Pin = LED_PIN, + .GPIO_Mode = GPIO_Mode_Out_OD, + .GPIO_Speed = GPIO_Speed_50MHz, + }; + GPIO_Init(LED_PORT, &led_init); + #endif + + #ifdef BUTTON_PIN + GPIO_InitTypeDef button_init = { + .GPIO_Pin = BUTTON_PIN, + .GPIO_Mode = GPIO_Mode_IPU, + .GPIO_Speed = GPIO_Speed_50MHz, + }; + GPIO_Init(BUTTON_PORT, &button_init); + #endif + + // UART TX is PA9 + RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE); + GPIO_InitTypeDef usart_init = { + .GPIO_Pin = GPIO_Pin_9, + .GPIO_Speed = GPIO_Speed_50MHz, + .GPIO_Mode = GPIO_Mode_AF_PP, + }; + GPIO_Init(GPIOA, &usart_init); + + USART_InitTypeDef usart = { + .USART_BaudRate = 115200, + .USART_WordLength = USART_WordLength_8b, + .USART_StopBits = USART_StopBits_1, + .USART_Parity = USART_Parity_No, + .USART_Mode = USART_Mode_Tx, + .USART_HardwareFlowControl = USART_HardwareFlowControl_None, + }; + USART_Init(USART1, &usart); + USART_Cmd(USART1, ENABLE); + + __enable_irq(); + + board_led_write(true); +} + +void board_led_write(bool state) { + GPIO_WriteBit(LED_PORT, LED_PIN, state ? LED_STATE_ON : (1-LED_STATE_ON)); +} + +uint32_t board_button_read(void) { + return BUTTON_STATE_ACTIVE == GPIO_ReadInputDataBit(BUTTON_PORT, BUTTON_PIN); +} + +int board_uart_read(uint8_t *buf, int len) { + (void) buf; + (void) len; + return 0; +} + +int board_uart_write(void const *buf, int len) { + const char *bufc = (const char *) buf; + for (int i = 0; i < len; i++) { + while (USART_GetFlagStatus(USART1, USART_FLAG_TC) == RESET); + USART_SendData(USART1, *bufc++); + } + + return len; +} diff --git a/hw/bsp/ch32v10x/family.cmake b/hw/bsp/ch32v10x/family.cmake new file mode 100644 index 000000000..b0d8241d3 --- /dev/null +++ b/hw/bsp/ch32v10x/family.cmake @@ -0,0 +1,117 @@ +include_guard() + +#set(UF2_FAMILY_ID 0x699b62ec) +set(CH32_FAMILY ch32v10x) +set(SDK_DIR ${TOP}/hw/mcu/wch/ch32v103) +set(SDK_SRC_DIR ${SDK_DIR}/EVT/EXAM/SRC) + +# include board specific +include(${CMAKE_CURRENT_LIST_DIR}/boards/${BOARD}/board.cmake) + +# toolchain set up +set(CMAKE_SYSTEM_PROCESSOR rv32imac-ilp32 CACHE INTERNAL "System Processor") +set(CMAKE_TOOLCHAIN_FILE ${TOP}/examples/build_system/cmake/toolchain/riscv_${TOOLCHAIN}.cmake) + +set(FAMILY_MCUS CH32V103 CACHE INTERNAL "") +set(OPENOCD_OPTION "-f ${CMAKE_CURRENT_LIST_DIR}/wch-riscv.cfg") + +#------------------------------------ +# BOARD_TARGET +#------------------------------------ +# only need to be built ONCE for all examples +function(add_board_target BOARD_TARGET) + if (TARGET ${BOARD_TARGET}) + return() + endif() + + if (NOT DEFINED LD_FILE_GNU) + set(LD_FILE_GNU ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/linker/${CH32_FAMILY}.ld) + endif () + set(LD_FILE_Clang ${LD_FILE_GNU}) + + if (NOT DEFINED STARTUP_FILE_GNU) + set(STARTUP_FILE_GNU ${SDK_SRC_DIR}/Startup/startup_${CH32_FAMILY}.S) + endif () + set(STARTUP_FILE_Clang ${STARTUP_FILE_GNU}) + + add_library(${BOARD_TARGET} STATIC + ${SDK_SRC_DIR}/Core/core_riscv.c + ${SDK_SRC_DIR}/Peripheral/src/${CH32_FAMILY}_gpio.c + ${SDK_SRC_DIR}/Peripheral/src/${CH32_FAMILY}_misc.c + ${SDK_SRC_DIR}/Peripheral/src/${CH32_FAMILY}_rcc.c + ${SDK_SRC_DIR}/Peripheral/src/${CH32_FAMILY}_usart.c + ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/system_${CH32_FAMILY}.c + ${STARTUP_FILE_${CMAKE_C_COMPILER_ID}} + ) + target_include_directories(${BOARD_TARGET} PUBLIC + ${SDK_SRC_DIR}/Core + ${SDK_SRC_DIR}/Peripheral/inc + ${CMAKE_CURRENT_FUNCTION_LIST_DIR} + ) + target_compile_definitions(${BOARD_TARGET} PUBLIC + ) + + update_board(${BOARD_TARGET}) + + if (CMAKE_C_COMPILER_ID STREQUAL "GNU") + target_compile_options(${BOARD_TARGET} PUBLIC + -mcmodel=medany + ) + target_link_options(${BOARD_TARGET} PUBLIC + "LINKER:--script=${LD_FILE_GNU}" + -Wl,--defsym=__flash_size=${LD_FLASH_SIZE} + -Wl,--defsym=__ram_size=${LD_RAM_SIZE} + -nostartfiles + --specs=nosys.specs --specs=nano.specs + ) + elseif (CMAKE_C_COMPILER_ID STREQUAL "Clang") + message(FATAL_ERROR "Clang is not supported for MSP432E4") + elseif (CMAKE_C_COMPILER_ID STREQUAL "IAR") + target_link_options(${BOARD_TARGET} PUBLIC + "LINKER:--config=${LD_FILE_IAR}" + ) + endif () +endfunction() + + +#------------------------------------ +# Functions +#------------------------------------ +function(family_configure_example TARGET RTOS) + family_configure_common(${TARGET} ${RTOS}) + + # Board target + add_board_target(board_${BOARD}) + + #---------- Port Specific ---------- + # These files are built for each example since it depends on example's tusb_config.h + target_sources(${TARGET} PUBLIC + # BSP + ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/family.c + ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/../board.c + ) + target_include_directories(${TARGET} PUBLIC + # family, hw, board + ${CMAKE_CURRENT_FUNCTION_LIST_DIR} + ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/../../ + ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/boards/${BOARD} + ) + + # Add TinyUSB target and port source + family_add_tinyusb(${TARGET} OPT_MCU_CH32V103 ${RTOS}) + + target_sources(${TARGET}-tinyusb PUBLIC + ${TOP}/src/portable/wch/dcd_ch32_usbfs.c + ) + target_link_libraries(${TARGET}-tinyusb PUBLIC board_${BOARD}) + + # Link dependencies + target_link_libraries(${TARGET} PUBLIC board_${BOARD} ${TARGET}-tinyusb) + + # Flashing + family_add_bin_hex(${TARGET}) + family_flash_openocd_wch(${TARGET}) + + #family_add_uf2(${TARGET} ${UF2_FAMILY_ID}) + #family_flash_uf2(${TARGET} ${UF2_FAMILY_ID}) +endfunction() diff --git a/hw/bsp/ch32v10x/family.mk b/hw/bsp/ch32v10x/family.mk new file mode 100644 index 000000000..d96d5012e --- /dev/null +++ b/hw/bsp/ch32v10x/family.mk @@ -0,0 +1,53 @@ +# https://www.embecosm.com/resources/tool-chain-downloads/#riscv-stable +#CROSS_COMPILE ?= riscv32-unknown-elf- + +# Toolchain from https://nucleisys.com/download.php +#CROSS_COMPILE ?= riscv-nuclei-elf- + +# Toolchain from https://github.com/xpack-dev-tools/riscv-none-elf-gcc-xpack +CROSS_COMPILE ?= riscv-none-elf- + +CH32_FAMILY = ch32v10x +SDK_DIR = hw/mcu/wch/ch32v103 +SDK_SRC_DIR = $(SDK_DIR)/EVT/EXAM/SRC + +include $(TOP)/$(BOARD_PATH)/board.mk +CPU_CORE ?= rv32imac-ilp32 + +# Port0 use FSDev, Port1 use USBFS +PORT ?= 0 + +CFLAGS += \ + -mcmodel=medany \ + -ffat-lto-objects \ + -flto \ + -DCFG_TUSB_MCU=OPT_MCU_CH32V103 + +# https://github.com/openwch/ch32v20x/pull/12 +CFLAGS += -Wno-error=strict-prototypes + +LDFLAGS_GCC += \ + -nostdlib -nostartfiles \ + --specs=nosys.specs --specs=nano.specs \ + +LD_FILE = $(FAMILY_PATH)/linker/${CH32_FAMILY}.ld + +SRC_C += \ + src/portable/wch/dcd_ch32_usbfs.c \ + $(SDK_SRC_DIR)/Core/core_riscv.c \ + $(SDK_SRC_DIR)/Peripheral/src/${CH32_FAMILY}_gpio.c \ + $(SDK_SRC_DIR)/Peripheral/src/${CH32_FAMILY}_misc.c \ + $(SDK_SRC_DIR)/Peripheral/src/${CH32_FAMILY}_rcc.c \ + $(SDK_SRC_DIR)/Peripheral/src/${CH32_FAMILY}_usart.c \ + +SRC_S += $(SDK_SRC_DIR)/Startup/startup_${CH32_FAMILY}.S + +INC += \ + $(TOP)/$(BOARD_PATH) \ + $(TOP)/$(SDK_SRC_DIR)/Core \ + $(TOP)/$(SDK_SRC_DIR)/Peripheral/inc \ + +FREERTOS_PORTABLE_SRC = $(FREERTOS_PORTABLE_PATH)/RISC-V + +OPENOCD_WCH_OPTION=-f $(TOP)/$(FAMILY_PATH)/wch-riscv.cfg +flash: flash-openocd-wch diff --git a/hw/bsp/ch32v10x/linker/ch32v10x.ld b/hw/bsp/ch32v10x/linker/ch32v10x.ld new file mode 100644 index 000000000..cd5c8dc17 --- /dev/null +++ b/hw/bsp/ch32v10x/linker/ch32v10x.ld @@ -0,0 +1,165 @@ +/* Define default values if not already defined */ +__FLASH_SIZE = DEFINED(__flash_size) ? __flash_size : 64K; +__RAM_SIZE = DEFINED(__ram_size) ? __ram_size : 20K; + +MEMORY +{ + FLASH (rx) : ORIGIN = 0x00000000, LENGTH = __FLASH_SIZE + RAM (xrw) : ORIGIN = 0x20000000, LENGTH = __RAM_SIZE +} + +ENTRY( _start ) + +__stack_size = 2048; + +PROVIDE( _stack_size = __stack_size ); + +SECTIONS +{ + .init : + { + _sinit = .; + . = ALIGN(4); + KEEP(*(SORT_NONE(.init))) + . = ALIGN(4); + _einit = .; + } >FLASH AT>FLASH + + .vector : + { + *(.vector); + . = ALIGN(64); + } >FLASH AT>FLASH + + .text : + { + . = ALIGN(4); + *(.text) + *(.text.*) + *(.rodata) + *(.rodata*) + *(.gnu.linkonce.t.*) + . = ALIGN(4); + } >FLASH AT>FLASH + + .fini : + { + KEEP(*(SORT_NONE(.fini))) + . = ALIGN(4); + } >FLASH AT>FLASH + + PROVIDE( _etext = . ); + PROVIDE( _eitcm = . ); + + .preinit_array : + { + PROVIDE_HIDDEN (__preinit_array_start = .); + KEEP (*(.preinit_array)) + PROVIDE_HIDDEN (__preinit_array_end = .); + } >FLASH AT>FLASH + + .init_array : + { + PROVIDE_HIDDEN (__init_array_start = .); + KEEP (*(SORT_BY_INIT_PRIORITY(.init_array.*) SORT_BY_INIT_PRIORITY(.ctors.*))) + KEEP (*(.init_array EXCLUDE_FILE (*crtbegin.o *crtbegin?.o *crtend.o *crtend?.o ) .ctors)) + PROVIDE_HIDDEN (__init_array_end = .); + } >FLASH AT>FLASH + + .fini_array : + { + PROVIDE_HIDDEN (__fini_array_start = .); + KEEP (*(SORT_BY_INIT_PRIORITY(.fini_array.*) SORT_BY_INIT_PRIORITY(.dtors.*))) + KEEP (*(.fini_array EXCLUDE_FILE (*crtbegin.o *crtbegin?.o *crtend.o *crtend?.o ) .dtors)) + PROVIDE_HIDDEN (__fini_array_end = .); + } >FLASH AT>FLASH + + .ctors : + { + /* gcc uses crtbegin.o to find the start of + the constructors, so we make sure it is + first. Because this is a wildcard, it + doesn't matter if the user does not + actually link against crtbegin.o; the + linker won't look for a file to match a + wildcard. The wildcard also means that it + doesn't matter which directory crtbegin.o + is in. */ + KEEP (*crtbegin.o(.ctors)) + KEEP (*crtbegin?.o(.ctors)) + /* We don't want to include the .ctor section from + the crtend.o file until after the sorted ctors. + The .ctor section from the crtend file contains the + end of ctors marker and it must be last */ + KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .ctors)) + KEEP (*(SORT(.ctors.*))) + KEEP (*(.ctors)) + } >FLASH AT>FLASH + + .dtors : + { + KEEP (*crtbegin.o(.dtors)) + KEEP (*crtbegin?.o(.dtors)) + KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .dtors)) + KEEP (*(SORT(.dtors.*))) + KEEP (*(.dtors)) + } >FLASH AT>FLASH + + .dalign : + { + . = ALIGN(4); + PROVIDE(_data_vma = .); + } >RAM AT>FLASH + + .dlalign : + { + . = ALIGN(4); + PROVIDE(_data_lma = .); + } >FLASH AT>FLASH + + .data : + { + *(.gnu.linkonce.r.*) + *(.data .data.*) + *(.gnu.linkonce.d.*) + . = ALIGN(8); + PROVIDE( __global_pointer$ = . + 0x800 ); + *(.sdata .sdata.*) + *(.sdata2.*) + *(.gnu.linkonce.s.*) + . = ALIGN(8); + *(.srodata.cst16) + *(.srodata.cst8) + *(.srodata.cst4) + *(.srodata.cst2) + *(.srodata .srodata.*) + . = ALIGN(4); + PROVIDE( _edata = .); + } >RAM AT>FLASH + + .bss : + { + . = ALIGN(4); + PROVIDE( _sbss = .); + *(.sbss*) + *(.gnu.linkonce.sb.*) + *(.bss*) + *(.gnu.linkonce.b.*) + *(COMMON*) + . = ALIGN(4); + PROVIDE( _ebss = .); + } >RAM AT>FLASH + + PROVIDE( _end = _ebss); + PROVIDE( end = . ); + + .stack ORIGIN(RAM) + LENGTH(RAM) - __stack_size : + { + PROVIDE( _heap_end = . ); + . = ALIGN(4); + PROVIDE(_susrstack = . ); + . = . + __stack_size; + PROVIDE( _eusrstack = .); + } >RAM + +} diff --git a/hw/bsp/ch32v10x/system_ch32v10x.c b/hw/bsp/ch32v10x/system_ch32v10x.c new file mode 100644 index 000000000..b083b83b4 --- /dev/null +++ b/hw/bsp/ch32v10x/system_ch32v10x.c @@ -0,0 +1,600 @@ +/********************************** (C) COPYRIGHT ******************************* + * File Name : system_ch32v10x.c + * Author : WCH + * Version : V1.0.0 + * Date : 2020/04/30 + * Description : CH32V10x Device Peripheral Access Layer System Source File. +********************************************************************************* +* Copyright (c) 2021 Nanjing Qinheng Microelectronics Co., Ltd. +* Attention: This software (modified or not) and binary are used for +* microcontroller manufactured by Nanjing Qinheng Microelectronics. +*******************************************************************************/ +#include "ch32v10x.h" + +/* + * Uncomment the line corresponding to the desired System clock (SYSCLK) frequency (after + * reset the HSI is used as SYSCLK source). + * If none of the define below is enabled, the HSI is used as System clock source. + */ +//#define SYSCLK_FREQ_HSE HSE_VALUE +//#define SYSCLK_FREQ_48MHz_HSE 48000000 +//#define SYSCLK_FREQ_56MHz_HSE 56000000 +#define SYSCLK_FREQ_72MHz_HSE 72000000 +//#define SYSCLK_FREQ_HSI HSI_VALUE +//#define SYSCLK_FREQ_48MHz_HSI 48000000 +//#define SYSCLK_FREQ_56MHz_HSI 56000000 +//#define SYSCLK_FREQ_72MHz_HSI 72000000 + +/* Clock Definitions */ +#ifdef SYSCLK_FREQ_HSE +uint32_t SystemCoreClock = SYSCLK_FREQ_HSE; /* System Clock Frequency (Core Clock) */ +#elif defined SYSCLK_FREQ_48MHz_HSE +uint32_t SystemCoreClock = SYSCLK_FREQ_48MHz_HSE; /* System Clock Frequency (Core Clock) */ +#elif defined SYSCLK_FREQ_56MHz_HSE +uint32_t SystemCoreClock = SYSCLK_FREQ_56MHz_HSE; /* System Clock Frequency (Core Clock) */ +#elif defined SYSCLK_FREQ_72MHz_HSE +uint32_t SystemCoreClock = SYSCLK_FREQ_72MHz_HSE; /* System Clock Frequency (Core Clock) */ +#elif defined SYSCLK_FREQ_48MHz_HSI +uint32_t SystemCoreClock = SYSCLK_FREQ_48MHz_HSI; /* System Clock Frequency (Core Clock) */ +#elif defined SYSCLK_FREQ_56MHz_HSI +uint32_t SystemCoreClock = SYSCLK_FREQ_56MHz_HSI; /* System Clock Frequency (Core Clock) */ +#elif defined SYSCLK_FREQ_72MHz_HSI +uint32_t SystemCoreClock = SYSCLK_FREQ_72MHz_HSI; /* System Clock Frequency (Core Clock) */ +#else +uint32_t SystemCoreClock = HSI_VALUE; /* System Clock Frequency (Core Clock) */ + +#endif + +__I uint8_t AHBPrescTable[16] = {0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 6, 7, 8, 9}; + +/* ch32v10x_system_private_function_proto_types */ +static void SetSysClock(void); + +#ifdef SYSCLK_FREQ_HSE +static void SetSysClockToHSE( void ); +#elif defined SYSCLK_FREQ_48MHz_HSE +static void SetSysClockTo48_HSE( void ); +#elif defined SYSCLK_FREQ_56MHz_HSE +static void SetSysClockTo56_HSE( void ); +#elif defined SYSCLK_FREQ_72MHz_HSE +static void SetSysClockTo72_HSE( void ); +#elif defined SYSCLK_FREQ_48MHz_HSI +static void SetSysClockTo48_HSI( void ); +#elif defined SYSCLK_FREQ_56MHz_HSI +static void SetSysClockTo56_HSI( void ); +#elif defined SYSCLK_FREQ_72MHz_HSI +static void SetSysClockTo72_HSI( void ); + +#endif + +/********************************************************************* + * @fn SystemInit + * + * @brief Setup the microcontroller system Initialize the Embedded Flash Interface, + * the PLL and update the SystemCoreClock variable. + * + * @return none + */ +void SystemInit(void) +{ + RCC->CTLR |= (uint32_t)0x00000001; + RCC->CFGR0 &= (uint32_t)0xF8FF0000; + RCC->CTLR &= (uint32_t)0xFEF6FFFF; + RCC->CTLR &= (uint32_t)0xFFFBFFFF; + RCC->CFGR0 &= (uint32_t)0xFF80FFFF; + RCC->INTR = 0x009F0000; + SetSysClock(); +} + +/********************************************************************* + * @fn SystemCoreClockUpdate + * + * @brief Update SystemCoreClock variable according to Clock Register Values. + * + * @return none + */ +void SystemCoreClockUpdate(void) +{ + uint32_t tmp = 0, pllmull = 0, pllsource = 0; + + tmp = RCC->CFGR0 & RCC_SWS; + + switch(tmp) + { + case 0x00: + SystemCoreClock = HSI_VALUE; + break; + case 0x04: + SystemCoreClock = HSE_VALUE; + break; + case 0x08: + pllmull = RCC->CFGR0 & RCC_PLLMULL; + pllsource = RCC->CFGR0 & RCC_PLLSRC; + pllmull = (pllmull >> 18) + 2; + if(pllsource == 0x00) + { + if( EXTEN->EXTEN_CTR & EXTEN_PLL_HSI_PRE ) + { + SystemCoreClock = ( HSI_VALUE ) * pllmull; + } + else + { + SystemCoreClock = ( HSI_VALUE >> 1 ) * pllmull; + } + } + else + { + if((RCC->CFGR0 & RCC_PLLXTPRE) != (uint32_t)RESET) + { + SystemCoreClock = (HSE_VALUE >> 1) * pllmull; + } + else + { + SystemCoreClock = HSE_VALUE * pllmull; + } + } + break; + default: + SystemCoreClock = HSI_VALUE; + break; + } + + tmp = AHBPrescTable[((RCC->CFGR0 & RCC_HPRE) >> 4)]; + SystemCoreClock >>= tmp; +} + +/********************************************************************* + * @fn SetSysClock + * + * @brief Configures the System clock frequency, HCLK, PCLK2 and PCLK1 prescalers. + * + * @return none + */ +static void SetSysClock(void) +{ + //GPIO_IPD_Unused(); +#ifdef SYSCLK_FREQ_HSE + SetSysClockToHSE(); +#elif defined SYSCLK_FREQ_48MHz_HSE + SetSysClockTo48_HSE(); +#elif defined SYSCLK_FREQ_56MHz_HSE + SetSysClockTo56_HSE(); +#elif defined SYSCLK_FREQ_72MHz_HSE + SetSysClockTo72_HSE(); +#elif defined SYSCLK_FREQ_48MHz_HSI + SetSysClockTo48_HSI(); +#elif defined SYSCLK_FREQ_56MHz_HSI + SetSysClockTo56_HSI(); +#elif defined SYSCLK_FREQ_72MHz_HSI + SetSysClockTo72_HSI(); + +#endif + + /* If none of the define above is enabled, the HSI is used as System clock + * source (default after reset) + */ +} + +#ifdef SYSCLK_FREQ_HSE + +/********************************************************************* + * @fn SetSysClockToHSE + * + * @brief Sets HSE as System clock source and configure HCLK, PCLK2 and PCLK1 prescalers. + * + * @return none + */ +static void SetSysClockToHSE(void) +{ + __IO uint32_t StartUpCounter = 0, HSEStatus = 0; + + RCC->CTLR |= ((uint32_t)RCC_HSEON); + + /* Wait till HSE is ready and if Time out is reached exit */ + do + { + HSEStatus = RCC->CTLR & RCC_HSERDY; + StartUpCounter++; + } while((HSEStatus == 0) && (StartUpCounter != HSE_STARTUP_TIMEOUT)); + + if((RCC->CTLR & RCC_HSERDY) != RESET) + { + HSEStatus = (uint32_t)0x01; + } + else + { + HSEStatus = (uint32_t)0x00; + } + + if(HSEStatus == (uint32_t)0x01) + { + FLASH->ACTLR |= FLASH_ACTLR_PRFTBE; + /* Flash 0 wait state */ + FLASH->ACTLR &= (uint32_t)((uint32_t)~FLASH_ACTLR_LATENCY); + FLASH->ACTLR |= (uint32_t)FLASH_ACTLR_LATENCY_0; + + /* HCLK = SYSCLK */ + RCC->CFGR0 |= (uint32_t)RCC_HPRE_DIV1; + /* PCLK2 = HCLK */ + RCC->CFGR0 |= (uint32_t)RCC_PPRE2_DIV1; + /* PCLK1 = HCLK */ + RCC->CFGR0 |= (uint32_t)RCC_PPRE1_DIV1; + + /* Select HSE as system clock source */ + RCC->CFGR0 &= (uint32_t)((uint32_t) ~(RCC_SW)); + RCC->CFGR0 |= (uint32_t)RCC_SW_HSE; + + /* Wait till HSE is used as system clock source */ + while((RCC->CFGR0 & (uint32_t)RCC_SWS) != (uint32_t)0x04) + { + } + } + else + { + /* If HSE fails to start-up, the application will have wrong clock + * configuration. User can add here some code to deal with this error + */ + } +} + + +#elif defined SYSCLK_FREQ_48MHz_HSE + +/********************************************************************* + * @fn SetSysClockTo48_HSE + * + * @brief Sets System clock frequency to 48MHz and configure HCLK, PCLK2 and PCLK1 prescalers. + * + * @return none + */ +static void SetSysClockTo48_HSE(void) +{ + __IO uint32_t StartUpCounter = 0, HSEStatus = 0; + + RCC->CTLR |= ((uint32_t)RCC_HSEON); + /* Wait till HSE is ready and if Time out is reached exit */ + do + { + HSEStatus = RCC->CTLR & RCC_HSERDY; + StartUpCounter++; + } while((HSEStatus == 0) && (StartUpCounter != HSE_STARTUP_TIMEOUT)); + + if((RCC->CTLR & RCC_HSERDY) != RESET) + { + HSEStatus = (uint32_t)0x01; + } + else + { + HSEStatus = (uint32_t)0x00; + } + + if(HSEStatus == (uint32_t)0x01) + { + /* Enable Prefetch Buffer */ + FLASH->ACTLR |= FLASH_ACTLR_PRFTBE; + + /* Flash 1 wait state */ + FLASH->ACTLR &= (uint32_t)((uint32_t)~FLASH_ACTLR_LATENCY); + FLASH->ACTLR |= (uint32_t)FLASH_ACTLR_LATENCY_1; + + /* HCLK = SYSCLK */ + RCC->CFGR0 |= (uint32_t)RCC_HPRE_DIV1; + /* PCLK2 = HCLK */ + RCC->CFGR0 |= (uint32_t)RCC_PPRE2_DIV1; + /* PCLK1 = HCLK */ + RCC->CFGR0 |= (uint32_t)RCC_PPRE1_DIV2; + + /* PLL configuration: PLLCLK = HSE * 6 = 48 MHz */ + RCC->CFGR0 &= (uint32_t)((uint32_t) ~(RCC_PLLSRC | RCC_PLLXTPRE | RCC_PLLMULL)); + RCC->CFGR0 |= (uint32_t)(RCC_PLLSRC_HSE | RCC_PLLMULL6); + + /* Enable PLL */ + RCC->CTLR |= RCC_PLLON; + /* Wait till PLL is ready */ + while((RCC->CTLR & RCC_PLLRDY) == 0) + { + } + /* Select PLL as system clock source */ + RCC->CFGR0 &= (uint32_t)((uint32_t) ~(RCC_SW)); + RCC->CFGR0 |= (uint32_t)RCC_SW_PLL; + /* Wait till PLL is used as system clock source */ + while((RCC->CFGR0 & (uint32_t)RCC_SWS) != (uint32_t)0x08) + { + } + } + else + { + /* + * If HSE fails to start-up, the application will have wrong clock + * configuration. User can add here some code to deal with this error + */ + } +} + +#elif defined SYSCLK_FREQ_56MHz_HSE + +/********************************************************************* + * @fn SetSysClockTo56_HSE + * + * @brief Sets System clock frequency to 56MHz and configure HCLK, PCLK2 and PCLK1 prescalers. + * + * @return none + */ +static void SetSysClockTo56_HSE(void) +{ + __IO uint32_t StartUpCounter = 0, HSEStatus = 0; + + RCC->CTLR |= ((uint32_t)RCC_HSEON); + + /* Wait till HSE is ready and if Time out is reached exit */ + do + { + HSEStatus = RCC->CTLR & RCC_HSERDY; + StartUpCounter++; + } while((HSEStatus == 0) && (StartUpCounter != HSE_STARTUP_TIMEOUT)); + + if((RCC->CTLR & RCC_HSERDY) != RESET) + { + HSEStatus = (uint32_t)0x01; + } + else + { + HSEStatus = (uint32_t)0x00; + } + + if(HSEStatus == (uint32_t)0x01) + { + /* Enable Prefetch Buffer */ + FLASH->ACTLR |= FLASH_ACTLR_PRFTBE; + + /* Flash 2 wait state */ + FLASH->ACTLR &= (uint32_t)((uint32_t)~FLASH_ACTLR_LATENCY); + FLASH->ACTLR |= (uint32_t)FLASH_ACTLR_LATENCY_2; + + /* HCLK = SYSCLK */ + RCC->CFGR0 |= (uint32_t)RCC_HPRE_DIV1; + /* PCLK2 = HCLK */ + RCC->CFGR0 |= (uint32_t)RCC_PPRE2_DIV1; + /* PCLK1 = HCLK */ + RCC->CFGR0 |= (uint32_t)RCC_PPRE1_DIV2; + + /* PLL configuration: PLLCLK = HSE * 7 = 56 MHz */ + RCC->CFGR0 &= (uint32_t)((uint32_t) ~(RCC_PLLSRC | RCC_PLLXTPRE | RCC_PLLMULL)); + RCC->CFGR0 |= (uint32_t)(RCC_PLLSRC_HSE | RCC_PLLMULL7); + /* Enable PLL */ + RCC->CTLR |= RCC_PLLON; + /* Wait till PLL is ready */ + while((RCC->CTLR & RCC_PLLRDY) == 0) + { + } + + /* Select PLL as system clock source */ + RCC->CFGR0 &= (uint32_t)((uint32_t) ~(RCC_SW)); + RCC->CFGR0 |= (uint32_t)RCC_SW_PLL; + /* Wait till PLL is used as system clock source */ + while((RCC->CFGR0 & (uint32_t)RCC_SWS) != (uint32_t)0x08) + { + } + } + else + { + /* + * If HSE fails to start-up, the application will have wrong clock + * configuration. User can add here some code to deal with this error + */ + } +} + +#elif defined SYSCLK_FREQ_72MHz_HSE + +/********************************************************************* + * @fn SetSysClockTo72_HSE + * + * @brief Sets System clock frequency to 72MHz and configure HCLK, PCLK2 and PCLK1 prescalers. + * + * @return none + */ +static void SetSysClockTo72_HSE(void) +{ + __IO uint32_t StartUpCounter = 0, HSEStatus = 0; + + RCC->CTLR |= ((uint32_t)RCC_HSEON); + + /* Wait till HSE is ready and if Time out is reached exit */ + do + { + HSEStatus = RCC->CTLR & RCC_HSERDY; + StartUpCounter++; + } while((HSEStatus == 0) && (StartUpCounter != HSE_STARTUP_TIMEOUT)); + + if((RCC->CTLR & RCC_HSERDY) != RESET) + { + HSEStatus = (uint32_t)0x01; + } + else + { + HSEStatus = (uint32_t)0x00; + } + + if(HSEStatus == (uint32_t)0x01) + { + /* Enable Prefetch Buffer */ + FLASH->ACTLR |= FLASH_ACTLR_PRFTBE; + + /* Flash 2 wait state */ + FLASH->ACTLR &= (uint32_t)((uint32_t)~FLASH_ACTLR_LATENCY); + FLASH->ACTLR |= (uint32_t)FLASH_ACTLR_LATENCY_2; + + /* HCLK = SYSCLK */ + RCC->CFGR0 |= (uint32_t)RCC_HPRE_DIV1; + /* PCLK2 = HCLK */ + RCC->CFGR0 |= (uint32_t)RCC_PPRE2_DIV1; + /* PCLK1 = HCLK */ + RCC->CFGR0 |= (uint32_t)RCC_PPRE1_DIV2; + + /* PLL configuration: PLLCLK = HSE * 9 = 72 MHz */ + RCC->CFGR0 &= (uint32_t)((uint32_t) ~(RCC_PLLSRC | RCC_PLLXTPRE | + RCC_PLLMULL)); + RCC->CFGR0 |= (uint32_t)(RCC_PLLSRC_HSE | RCC_PLLMULL9); + /* Enable PLL */ + RCC->CTLR |= RCC_PLLON; + /* Wait till PLL is ready */ + while((RCC->CTLR & RCC_PLLRDY) == 0) + { + } + /* Select PLL as system clock source */ + RCC->CFGR0 &= (uint32_t)((uint32_t) ~(RCC_SW)); + RCC->CFGR0 |= (uint32_t)RCC_SW_PLL; + /* Wait till PLL is used as system clock source */ + while((RCC->CFGR0 & (uint32_t)RCC_SWS) != (uint32_t)0x08) + { + } + } + else + { + /* + * If HSE fails to start-up, the application will have wrong clock + * configuration. User can add here some code to deal with this error + */ + } +} + +#elif defined SYSCLK_FREQ_48MHz_HSI + +/********************************************************************* + * @fn SetSysClockTo48_HSI + * + * @brief Sets System clock frequency to 48MHz and configure HCLK, PCLK2 and PCLK1 prescalers. + * + * @return none + */ +static void SetSysClockTo48_HSI(void) +{ + EXTEN->EXTEN_CTR |= EXTEN_PLL_HSI_PRE; + + /* Enable Prefetch Buffer */ + FLASH->ACTLR |= FLASH_ACTLR_PRFTBE; + + /* Flash 1 wait state */ + FLASH->ACTLR &= (uint32_t)((uint32_t)~FLASH_ACTLR_LATENCY); + FLASH->ACTLR |= (uint32_t)FLASH_ACTLR_LATENCY_1; + + /* HCLK = SYSCLK */ + RCC->CFGR0 |= (uint32_t)RCC_HPRE_DIV1; + /* PCLK2 = HCLK */ + RCC->CFGR0 |= (uint32_t)RCC_PPRE2_DIV1; + /* PCLK1 = HCLK */ + RCC->CFGR0 |= (uint32_t)RCC_PPRE1_DIV2; + + /* PLL configuration: PLLCLK = HSI * 6 = 48 MHz */ + RCC->CFGR0 &= (uint32_t)((uint32_t) ~(RCC_PLLSRC | RCC_PLLXTPRE | RCC_PLLMULL)); + RCC->CFGR0 |= (uint32_t)(RCC_PLLSRC_HSI_Div2 | RCC_PLLMULL6); + + /* Enable PLL */ + RCC->CTLR |= RCC_PLLON; + /* Wait till PLL is ready */ + while((RCC->CTLR & RCC_PLLRDY) == 0) + { + } + /* Select PLL as system clock source */ + RCC->CFGR0 &= (uint32_t)((uint32_t) ~(RCC_SW)); + RCC->CFGR0 |= (uint32_t)RCC_SW_PLL; + /* Wait till PLL is used as system clock source */ + while((RCC->CFGR0 & (uint32_t)RCC_SWS) != (uint32_t)0x08) + { + } +} + +#elif defined SYSCLK_FREQ_56MHz_HSI + +/********************************************************************* + * @fn SetSysClockTo56_HSI + * + * @brief Sets System clock frequency to 56MHz and configure HCLK, PCLK2 and PCLK1 prescalers. + * + * @return none + */ +static void SetSysClockTo56_HSI(void) +{ + EXTEN->EXTEN_CTR |= EXTEN_PLL_HSI_PRE; + + /* Enable Prefetch Buffer */ + FLASH->ACTLR |= FLASH_ACTLR_PRFTBE; + + /* Flash 1 wait state */ + FLASH->ACTLR &= (uint32_t)((uint32_t)~FLASH_ACTLR_LATENCY); + FLASH->ACTLR |= (uint32_t)FLASH_ACTLR_LATENCY_1; + + /* HCLK = SYSCLK */ + RCC->CFGR0 |= (uint32_t)RCC_HPRE_DIV1; + /* PCLK2 = HCLK */ + RCC->CFGR0 |= (uint32_t)RCC_PPRE2_DIV1; + /* PCLK1 = HCLK */ + RCC->CFGR0 |= (uint32_t)RCC_PPRE1_DIV2; + + /* PLL configuration: PLLCLK = HSI * 7 = 56 MHz */ + RCC->CFGR0 &= (uint32_t)((uint32_t) ~(RCC_PLLSRC | RCC_PLLXTPRE | RCC_PLLMULL)); + RCC->CFGR0 |= (uint32_t)(RCC_PLLSRC_HSI_Div2 | RCC_PLLMULL7); + + /* Enable PLL */ + RCC->CTLR |= RCC_PLLON; + /* Wait till PLL is ready */ + while((RCC->CTLR & RCC_PLLRDY) == 0) + { + } + /* Select PLL as system clock source */ + RCC->CFGR0 &= (uint32_t)((uint32_t) ~(RCC_SW)); + RCC->CFGR0 |= (uint32_t)RCC_SW_PLL; + /* Wait till PLL is used as system clock source */ + while((RCC->CFGR0 & (uint32_t)RCC_SWS) != (uint32_t)0x08) + { + } +} + +#elif defined SYSCLK_FREQ_72MHz_HSI + +/********************************************************************* + * @fn SetSysClockTo72_HSI + * + * @brief Sets System clock frequency to 72MHz and configure HCLK, PCLK2 and PCLK1 prescalers. + * + * @return none + */ +static void SetSysClockTo72_HSI(void) +{ + EXTEN->EXTEN_CTR |= EXTEN_PLL_HSI_PRE; + + /* Enable Prefetch Buffer */ + FLASH->ACTLR |= FLASH_ACTLR_PRFTBE; + + /* Flash 1 wait state */ + FLASH->ACTLR &= (uint32_t)((uint32_t)~FLASH_ACTLR_LATENCY); + FLASH->ACTLR |= (uint32_t)FLASH_ACTLR_LATENCY_1; + + /* HCLK = SYSCLK */ + RCC->CFGR0 |= (uint32_t)RCC_HPRE_DIV1; + /* PCLK2 = HCLK */ + RCC->CFGR0 |= (uint32_t)RCC_PPRE2_DIV1; + /* PCLK1 = HCLK */ + RCC->CFGR0 |= (uint32_t)RCC_PPRE1_DIV2; + + /* PLL configuration: PLLCLK = HSI * 9 = 72 MHz */ + RCC->CFGR0 &= (uint32_t)((uint32_t) ~(RCC_PLLSRC | RCC_PLLXTPRE | RCC_PLLMULL)); + RCC->CFGR0 |= (uint32_t)(RCC_PLLSRC_HSI_Div2 | RCC_PLLMULL9); + + /* Enable PLL */ + RCC->CTLR |= RCC_PLLON; + /* Wait till PLL is ready */ + while((RCC->CTLR & RCC_PLLRDY) == 0) + { + } + /* Select PLL as system clock source */ + RCC->CFGR0 &= (uint32_t)((uint32_t) ~(RCC_SW)); + RCC->CFGR0 |= (uint32_t)RCC_SW_PLL; + /* Wait till PLL is used as system clock source */ + while((RCC->CFGR0 & (uint32_t)RCC_SWS) != (uint32_t)0x08) + { + } +} + +#endif diff --git a/hw/bsp/ch32v10x/system_ch32v10x.h b/hw/bsp/ch32v10x/system_ch32v10x.h new file mode 100644 index 000000000..d15624520 --- /dev/null +++ b/hw/bsp/ch32v10x/system_ch32v10x.h @@ -0,0 +1,29 @@ +/********************************** (C) COPYRIGHT ******************************* + * File Name : system_ch32v10x.h + * Author : WCH + * Version : V1.0.0 + * Date : 2020/04/30 + * Description : CH32V10x Device Peripheral Access Layer System Header File. +********************************************************************************* +* Copyright (c) 2021 Nanjing Qinheng Microelectronics Co., Ltd. +* Attention: This software (modified or not) and binary are used for +* microcontroller manufactured by Nanjing Qinheng Microelectronics. +*******************************************************************************/ +#ifndef __SYSTEM_CH32V10x_H +#define __SYSTEM_CH32V10x_H + +#ifdef __cplusplus +extern "C" { +#endif + +extern uint32_t SystemCoreClock; /* System Clock Frequency (Core Clock) */ + +/* System_Exported_Functions */ +extern void SystemInit(void); +extern void SystemCoreClockUpdate(void); + +#ifdef __cplusplus +} +#endif + +#endif /*__CH32V10x_SYSTEM_H */ diff --git a/hw/bsp/ch32v10x/wch-riscv.cfg b/hw/bsp/ch32v10x/wch-riscv.cfg new file mode 100644 index 000000000..aa35aa9c5 --- /dev/null +++ b/hw/bsp/ch32v10x/wch-riscv.cfg @@ -0,0 +1,17 @@ +adapter driver wlinke +adapter speed 6000 +transport select sdi + +wlink_set_address 0x00000000 +set _CHIPNAME wch_riscv +sdi newtap $_CHIPNAME cpu -irlen 5 -expected-id 0x00001 + +set _TARGETNAME $_CHIPNAME.cpu + +target create $_TARGETNAME.0 wch_riscv -chain-position $_TARGETNAME +$_TARGETNAME.0 configure -work-area-phys 0x20000000 -work-area-size 10000 -work-area-backup 1 +set _FLASHNAME $_CHIPNAME.flash + +flash bank $_FLASHNAME wch_riscv 0x00000000 0 0 0 $_TARGETNAME.0 + +echo "Ready for Remote Connections" diff --git a/hw/bsp/ch32v20x/family.mk b/hw/bsp/ch32v20x/family.mk index daf3148f8..4485091dc 100644 --- a/hw/bsp/ch32v20x/family.mk +++ b/hw/bsp/ch32v20x/family.mk @@ -45,12 +45,12 @@ SRC_C += \ src/portable/wch/dcd_ch32_usbfs.c \ src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c \ $(SDK_SRC_DIR)/Core/core_riscv.c \ - $(SDK_SRC_DIR)/Peripheral/src/ch32v20x_gpio.c \ - $(SDK_SRC_DIR)/Peripheral/src/ch32v20x_misc.c \ - $(SDK_SRC_DIR)/Peripheral/src/ch32v20x_rcc.c \ - $(SDK_SRC_DIR)/Peripheral/src/ch32v20x_usart.c \ + $(SDK_SRC_DIR)/Peripheral/src/${CH32_FAMILY}_gpio.c \ + $(SDK_SRC_DIR)/Peripheral/src/${CH32_FAMILY}_misc.c \ + $(SDK_SRC_DIR)/Peripheral/src/${CH32_FAMILY}_rcc.c \ + $(SDK_SRC_DIR)/Peripheral/src/${CH32_FAMILY}_usart.c \ -SRC_S += $(SDK_SRC_DIR)/Startup/startup_ch32v20x_${MCU_VARIANT}.S +SRC_S += $(SDK_SRC_DIR)/Startup/startup_${CH32_FAMILY}_${MCU_VARIANT}.S INC += \ $(TOP)/$(BOARD_PATH) \ diff --git a/hw/bsp/family_support.cmake b/hw/bsp/family_support.cmake index d9443f811..94d55f04a 100644 --- a/hw/bsp/family_support.cmake +++ b/hw/bsp/family_support.cmake @@ -443,7 +443,7 @@ function(family_flash_openocd TARGET) # note skip verify since it has issue with rp2040 add_custom_target(${TARGET}-openocd DEPENDS ${TARGET} - COMMAND ${OPENOCD} ${OPTION_LIST} -c "program $ reset" ${OPTION_LIST2} -c exit + COMMAND ${OPENOCD} ${OPTION_LIST} -c init -c halt -c "program $ reset" ${OPTION_LIST2} -c exit VERBATIM ) endfunction() diff --git a/src/common/tusb_mcu.h b/src/common/tusb_mcu.h index c66996c4f..d9d11e96d 100644 --- a/src/common/tusb_mcu.h +++ b/src/common/tusb_mcu.h @@ -420,6 +420,15 @@ #define TUP_RHPORT_HIGHSPEED CFG_TUD_WCH_USBIP_USBHS #define TUP_DCD_ENDPOINT_MAX (CFG_TUD_WCH_USBIP_USBHS ? 16 : 8) +#elif TU_CHECK_MCU(OPT_MCU_CH32V103) + #define TUP_USBIP_WCH_USBFS + + #if !defined(CFG_TUD_WCH_USBIP_USBFS) + #define CFG_TUD_WCH_USBIP_USBFS 1 + #endif + + #define TUP_DCD_ENDPOINT_MAX 8 + #elif TU_CHECK_MCU(OPT_MCU_CH32V20X) // v20x support both FSDEV (USBD) and USBFS, default to FSDEV #define TUP_USBIP_WCH_USBFS diff --git a/src/portable/wch/ch32_usbfs_reg.h b/src/portable/wch/ch32_usbfs_reg.h index ef6ebf2dc..68be64f5e 100644 --- a/src/portable/wch/ch32_usbfs_reg.h +++ b/src/portable/wch/ch32_usbfs_reg.h @@ -35,15 +35,68 @@ #pragma GCC diagnostic ignored "-Wstrict-prototypes" #endif -#if CFG_TUSB_MCU == OPT_MCU_CH32V307 - #include - #define USBHD_IRQn OTG_FS_IRQn - +#if CFG_TUSB_MCU == OPT_MCU_CH32F20X + #include +#elif CFG_TUSB_MCU == OPT_MCU_CH32V103 + #include + typedef struct + { + __IO uint8_t BASE_CTRL; + __IO uint8_t UDEV_CTRL; + __IO uint8_t INT_EN; + __IO uint8_t DEV_ADDR; + __IO uint8_t Reserve0; + __IO uint8_t MIS_ST; + __IO uint8_t INT_FG; + __IO uint8_t INT_ST; + __IO uint32_t RX_LEN; + __IO uint8_t UEP4_1_MOD; + __IO uint8_t UEP2_3_MOD; + __IO uint8_t UEP5_6_MOD; + __IO uint8_t UEP7_MOD; + __IO uint32_t UEP0_DMA; + __IO uint32_t UEP1_DMA; + __IO uint32_t UEP2_DMA; + __IO uint32_t UEP3_DMA; + __IO uint32_t UEP4_DMA; + __IO uint32_t UEP5_DMA; + __IO uint32_t UEP6_DMA; + __IO uint32_t UEP7_DMA; + __IO uint16_t UEP0_TX_LEN; + __IO uint8_t UEP0_TX_CTRL; + __IO uint8_t UEP0_RX_CTRL; + __IO uint16_t UEP1_TX_LEN; + __IO uint8_t UEP1_TX_CTRL; + __IO uint8_t UEP1_RX_CTRL; + __IO uint16_t UEP2_TX_LEN; + __IO uint8_t UEP2_TX_CTRL; + __IO uint8_t UEP2_RX_CTRL; + __IO uint16_t UEP3_TX_LEN; + __IO uint8_t UEP3_TX_CTRL; + __IO uint8_t UEP3_RX_CTRL; + __IO uint16_t UEP4_TX_LEN; + __IO uint8_t UEP4_TX_CTRL; + __IO uint8_t UEP4_RX_CTRL; + __IO uint16_t UEP5_TX_LEN; + __IO uint8_t UEP5_TX_CTRL; + __IO uint8_t UEP5_RX_CTRL; + __IO uint16_t UEP6_TX_LEN; + __IO uint8_t UEP6_TX_CTRL; + __IO uint8_t UEP6_RX_CTRL; + __IO uint16_t UEP7_TX_LEN; + __IO uint8_t UEP7_TX_CTRL; + __IO uint8_t UEP7_RX_CTRL; + __IO uint32_t Reserve1; + __IO uint32_t OTG_CR; + __IO uint32_t OTG_SR; + } USBOTG_FS_TypeDef; + + #define USBOTG_FS ((USBOTG_FS_TypeDef *) 0x40023400) #elif CFG_TUSB_MCU == OPT_MCU_CH32V20X #include - -#elif CFG_TUSB_MCU == OPT_MCU_CH32F20X - #include +#elif CFG_TUSB_MCU == OPT_MCU_CH32V307 + #include + #define USBHD_IRQn OTG_FS_IRQn #endif #ifdef __GNUC__ diff --git a/src/tusb_option.h b/src/tusb_option.h index db8b94580..1ca09e902 100644 --- a/src/tusb_option.h +++ b/src/tusb_option.h @@ -24,8 +24,8 @@ * This file is part of the TinyUSB stack. */ -#ifndef _TUSB_OPTION_H_ -#define _TUSB_OPTION_H_ +#ifndef TUSB_OPTION_H_ +#define TUSB_OPTION_H_ #include "common/tusb_compiler.h" @@ -182,7 +182,7 @@ #define OPT_MCU_CH32V307 2200 ///< WCH CH32V307 #define OPT_MCU_CH32F20X 2210 ///< WCH CH32F20x #define OPT_MCU_CH32V20X 2220 ///< WCH CH32V20X - +#define OPT_MCU_CH32V103 2230 ///< WCH CH32V103 // NXP LPC MCX #define OPT_MCU_MCXN9 2300 ///< NXP MCX N9 Series diff --git a/tools/get_deps.py b/tools/get_deps.py index 50cc5c893..92bfb86a2 100644 --- a/tools/get_deps.py +++ b/tools/get_deps.py @@ -168,6 +168,9 @@ deps_optional = { 'hw/mcu/ti': ['https://github.com/hathach/ti_driver.git', '143ed6cc20a7615d042b03b21e070197d473e6e5', 'msp430 msp432e4 tm4c'], + 'hw/mcu/wch/ch32v103': ['https://github.com/openwch/ch32v103.git', + '7578cae0b21f86dd053a1f781b2fc6ab99d0ec17', + 'ch32v10x'], 'hw/mcu/wch/ch32v20x': ['https://github.com/openwch/ch32v20x.git', 'de6d68c654340d7f27b00cebbfc9aa2740a1abc2', 'ch32v20x'], -- cgit v1.3.1 From 9ae00535737f6f442a9ca7ad3167f686c0d557b1 Mon Sep 17 00:00:00 2001 From: hathach Date: Fri, 14 Jun 2024 16:08:26 +0700 Subject: newline --- src/portable/st/stm32_fsdev/fsdev_ch32.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/portable/st/stm32_fsdev/fsdev_ch32.h b/src/portable/st/stm32_fsdev/fsdev_ch32.h index dbf2a0289..f63a80d56 100644 --- a/src/portable/st/stm32_fsdev/fsdev_ch32.h +++ b/src/portable/st/stm32_fsdev/fsdev_ch32.h @@ -43,10 +43,10 @@ #pragma GCC diagnostic ignored "-Wstrict-prototypes" #endif -#if CFG_TUSB_MCU == OPT_MCU_CH32V20X - #include -#elif CFG_TUSB_MCU == OPT_MCU_CH32F20X +#if CFG_TUSB_MCU == OPT_MCU_CH32F20X #include +#elif CFG_TUSB_MCU == OPT_MCU_CH32V20X + #include #endif #ifdef __GNUC__ -- cgit v1.3.1 From f32851cf2ae6ec7aa3b39150c3f0f96d65af9b3a Mon Sep 17 00:00:00 2001 From: hathach Date: Fri, 14 Jun 2024 16:16:10 +0700 Subject: fix ci skip example for ch32v1 --- examples/device/audio_4_channel_mic_freertos/skip.txt | 1 + examples/device/audio_test_freertos/skip.txt | 1 + examples/device/cdc_msc_freertos/skip.txt | 1 + examples/device/hid_composite_freertos/skip.txt | 1 + examples/device/net_lwip_webserver/skip.txt | 1 + examples/device/video_capture/skip.txt | 1 + examples/device/video_capture_2ch/skip.txt | 1 + src/tusb_option.h | 4 ++-- 8 files changed, 9 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/examples/device/audio_4_channel_mic_freertos/skip.txt b/examples/device/audio_4_channel_mic_freertos/skip.txt index 4769af009..012ca4e74 100644 --- a/examples/device/audio_4_channel_mic_freertos/skip.txt +++ b/examples/device/audio_4_channel_mic_freertos/skip.txt @@ -1,3 +1,4 @@ +mcu:CH32V103 mcu:CH32V20X mcu:CH32V307 mcu:CXD56 diff --git a/examples/device/audio_test_freertos/skip.txt b/examples/device/audio_test_freertos/skip.txt index 6aaa27661..c13667f56 100644 --- a/examples/device/audio_test_freertos/skip.txt +++ b/examples/device/audio_test_freertos/skip.txt @@ -1,3 +1,4 @@ +mcu:CH32V103 mcu:CH32V20X mcu:CH32V307 mcu:CXD56 diff --git a/examples/device/cdc_msc_freertos/skip.txt b/examples/device/cdc_msc_freertos/skip.txt index 457ddb760..75a79aff4 100644 --- a/examples/device/cdc_msc_freertos/skip.txt +++ b/examples/device/cdc_msc_freertos/skip.txt @@ -1,3 +1,4 @@ +mcu:CH32V103 mcu:CH32V20X mcu:CH32V307 mcu:CXD56 diff --git a/examples/device/hid_composite_freertos/skip.txt b/examples/device/hid_composite_freertos/skip.txt index 6aaa27661..c13667f56 100644 --- a/examples/device/hid_composite_freertos/skip.txt +++ b/examples/device/hid_composite_freertos/skip.txt @@ -1,3 +1,4 @@ +mcu:CH32V103 mcu:CH32V20X mcu:CH32V307 mcu:CXD56 diff --git a/examples/device/net_lwip_webserver/skip.txt b/examples/device/net_lwip_webserver/skip.txt index 51af58667..85c450e82 100644 --- a/examples/device/net_lwip_webserver/skip.txt +++ b/examples/device/net_lwip_webserver/skip.txt @@ -1,3 +1,4 @@ +mcu:CH32V103 mcu:CH32V20X mcu:LPC11UXX mcu:LPC13XX diff --git a/examples/device/video_capture/skip.txt b/examples/device/video_capture/skip.txt index 714cabeec..cb0c7d2e6 100644 --- a/examples/device/video_capture/skip.txt +++ b/examples/device/video_capture/skip.txt @@ -1,3 +1,4 @@ +mcu:CH32V103 mcu:CH32V20X mcu:MSP430x5xx mcu:NUC121 diff --git a/examples/device/video_capture_2ch/skip.txt b/examples/device/video_capture_2ch/skip.txt index 1786297f9..af3b0de04 100644 --- a/examples/device/video_capture_2ch/skip.txt +++ b/examples/device/video_capture_2ch/skip.txt @@ -2,6 +2,7 @@ mcu:MSP430x5xx mcu:NUC121 mcu:SAMD11 mcu:GD32VF103 +mcu:CH32V103 mcu:CH32V20X mcu:CH32V307 mcu:STM32L0 diff --git a/src/tusb_option.h b/src/tusb_option.h index 1ca09e902..8990cf92b 100644 --- a/src/tusb_option.h +++ b/src/tusb_option.h @@ -24,8 +24,8 @@ * This file is part of the TinyUSB stack. */ -#ifndef TUSB_OPTION_H_ -#define TUSB_OPTION_H_ +#ifndef _TUSB_OPTION_H_ +#define _TUSB_OPTION_H_ #include "common/tusb_compiler.h" -- cgit v1.3.1 From 2be72a97b8fd4d08ca20a9b8815f2042c4ef7520 Mon Sep 17 00:00:00 2001 From: hathach Date: Fri, 14 Jun 2024 17:55:36 +0700 Subject: minor update --- hw/bsp/ch32v10x/boards/ch32v103r_r1_1v0/board.mk | 2 -- hw/bsp/ch32v10x/family.c | 2 +- src/class/net/ncm_device.c | 4 ++-- 3 files changed, 3 insertions(+), 5 deletions(-) (limited to 'src') diff --git a/hw/bsp/ch32v10x/boards/ch32v103r_r1_1v0/board.mk b/hw/bsp/ch32v10x/boards/ch32v103r_r1_1v0/board.mk index 7d7462312..70e65333c 100644 --- a/hw/bsp/ch32v10x/boards/ch32v103r_r1_1v0/board.mk +++ b/hw/bsp/ch32v10x/boards/ch32v103r_r1_1v0/board.mk @@ -1,5 +1,3 @@ -MCU_VARIANT = D6 - CFLAGS += -DCFG_EXAMPLE_MSC_DUAL_READONLY LDFLAGS += \ diff --git a/hw/bsp/ch32v10x/family.c b/hw/bsp/ch32v10x/family.c index c41b207e0..15f754e11 100644 --- a/hw/bsp/ch32v10x/family.c +++ b/hw/bsp/ch32v10x/family.c @@ -24,7 +24,7 @@ void USBHD_IRQHandler(void) { } __attribute__((interrupt)) __attribute__((used)) -void USBHDWakeUp_IRQHandler(void) { +void USBWakeUp_IRQHandler(void) { #if CFG_TUD_WCH_USBIP_USBFS tud_int_handler(0); #endif diff --git a/src/class/net/ncm_device.c b/src/class/net/ncm_device.c index 44a6a0de9..90d747185 100644 --- a/src/class/net/ncm_device.c +++ b/src/class/net/ncm_device.c @@ -1,10 +1,10 @@ /* * The MIT License (MIT) * - * Copyright (c) 2020 Jacob Berg Potter - * Copyright (c) 2020 Peter Lawrence * Copyright (c) 2019 Ha Thach (tinyusb.org) * Copyright (c) 2024 Hardy Griech + * Copyright (c) 2020 Jacob Berg Potter + * Copyright (c) 2020 Peter Lawrence * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal -- cgit v1.3.1 From 00062ddb0cda4e46750c7df09aa31026cc03b5ee Mon Sep 17 00:00:00 2001 From: Okarss <104319900+Okarss@users.noreply.github.com> Date: Fri, 14 Jun 2024 18:16:09 +0300 Subject: [STM32 FSDEV] Simplify toggle bit logic --- src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c | 12 ++++++------ src/portable/st/stm32_fsdev/fsdev_common.h | 24 ++---------------------- 2 files changed, 8 insertions(+), 28 deletions(-) (limited to 'src') diff --git a/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c b/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c index 9ce37f992..b5b89c577 100644 --- a/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c +++ b/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c @@ -215,20 +215,20 @@ void dcd_init(uint8_t rhport) /* The RM mentions to use a special ordering of PDWN and FRES, but this isn't done in HAL. * Here, the RM is followed. */ - for (uint32_t i = 0; i < 200; i++) { // should be a few us - asm("NOP"); + for (volatile uint32_t i = 0; i < 200; i++) { // should be a few us + __DSB(); } // Perform USB peripheral reset USB->CNTR = USB_CNTR_FRES | USB_CNTR_PDWN; - for (uint32_t i = 0; i < 200; i++) { // should be a few us - asm("NOP"); + for (volatile uint32_t i = 0; i < 200; i++) { // should be a few us + __DSB(); } USB->CNTR &= ~USB_CNTR_PDWN; // Wait startup time, for F042 and F070, this is <= 1 us. - for (uint32_t i = 0; i < 200; i++) { // should be a few us - asm("NOP"); + for (volatile uint32_t i = 0; i < 200; i++) { // should be a few us + __DSB(); } USB->CNTR = 0; // Enable USB diff --git a/src/portable/st/stm32_fsdev/fsdev_common.h b/src/portable/st/stm32_fsdev/fsdev_common.h index af5d8afab..e8a6af8cb 100644 --- a/src/portable/st/stm32_fsdev/fsdev_common.h +++ b/src/portable/st/stm32_fsdev/fsdev_common.h @@ -295,18 +295,7 @@ TU_ATTR_ALWAYS_INLINE static inline void pcd_set_ep_rx_cnt(USB_TypeDef * USBx, u TU_ATTR_ALWAYS_INLINE static inline void pcd_set_ep_tx_status(USB_TypeDef * USBx, uint32_t bEpIdx, uint32_t wState) { uint32_t regVal = pcd_get_endpoint(USBx, bEpIdx); regVal &= USB_EPTX_DTOGMASK; - - /* toggle first bit ? */ - if((USB_EPTX_DTOG1 & (wState))!= 0U) - { - regVal ^= USB_EPTX_DTOG1; - } - /* toggle second bit ? */ - if((USB_EPTX_DTOG2 & ((uint32_t)(wState)))!= 0U) - { - regVal ^= USB_EPTX_DTOG2; - } - + regVal ^= wState; regVal |= USB_EP_CTR_RX|USB_EP_CTR_TX; pcd_set_endpoint(USBx, bEpIdx, regVal); } @@ -322,16 +311,7 @@ TU_ATTR_ALWAYS_INLINE static inline void pcd_set_ep_tx_status(USB_TypeDef * USBx TU_ATTR_ALWAYS_INLINE static inline void pcd_set_ep_rx_status(USB_TypeDef * USBx, uint32_t bEpIdx, uint32_t wState) { uint32_t regVal = pcd_get_endpoint(USBx, bEpIdx); regVal &= USB_EPRX_DTOGMASK; - - /* toggle first bit ? */ - if((USB_EPRX_DTOG1 & wState)!= 0U) { - regVal ^= USB_EPRX_DTOG1; - } - /* toggle second bit ? */ - if((USB_EPRX_DTOG2 & wState)!= 0U) { - regVal ^= USB_EPRX_DTOG2; - } - + regVal ^= wState; regVal |= USB_EP_CTR_RX|USB_EP_CTR_TX; pcd_set_endpoint(USBx, bEpIdx, regVal); } -- cgit v1.3.1 From fb6a6acbff81a98e37b86a0dc3370d4076bb356c Mon Sep 17 00:00:00 2001 From: Okarss <104319900+Okarss@users.noreply.github.com> Date: Fri, 14 Jun 2024 18:39:48 +0300 Subject: Revert the DSB because of RISC-V --- src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c b/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c index b5b89c577..4e31c99fa 100644 --- a/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c +++ b/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c @@ -216,19 +216,19 @@ void dcd_init(uint8_t rhport) * Here, the RM is followed. */ for (volatile uint32_t i = 0; i < 200; i++) { // should be a few us - __DSB(); + asm("NOP"); } // Perform USB peripheral reset USB->CNTR = USB_CNTR_FRES | USB_CNTR_PDWN; for (volatile uint32_t i = 0; i < 200; i++) { // should be a few us - __DSB(); + asm("NOP"); } USB->CNTR &= ~USB_CNTR_PDWN; // Wait startup time, for F042 and F070, this is <= 1 us. for (volatile uint32_t i = 0; i < 200; i++) { // should be a few us - __DSB(); + asm("NOP"); } USB->CNTR = 0; // Enable USB -- cgit v1.3.1 From 5f060a357d34257f5a742ebf78c5e4e0873c7a13 Mon Sep 17 00:00:00 2001 From: Okarss <104319900+Okarss@users.noreply.github.com> Date: Fri, 14 Jun 2024 21:23:17 +0300 Subject: Update the STM32 documentation --- README.rst | 5 +++-- docs/reference/supported.rst | 20 +++++++++++++++++--- src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c | 10 ++++++++-- src/portable/st/stm32_fsdev/fsdev_stm32.h | 2 +- 4 files changed, 29 insertions(+), 8 deletions(-) (limited to 'src') diff --git a/README.rst b/README.rst index b5f9fc149..1ae8c5375 100644 --- a/README.rst +++ b/README.rst @@ -151,8 +151,9 @@ Following CPUs are supported, check out `Supported Devices`_ for comprehensive l +--------------+------------------------------------------------------------+ | Sony | CXD56 | +--------------+------------------------------------------------------------+ -| ST STM32 | F0, F1, F2, F3, F4, F7, H5, H7, G0, G4, L0, L1, L4, L4+, | -| | U5, WB | +| ST STM32 | F0, F1, F2, F3, F4, F7, G0, G4, H5, H7, | +| | | +| | L0, L1, L4, L4+, L5, U5, WB | +--------------+------------------------------------------------------------+ | TI | MSP430, MSP432E4, TM4C123 | +--------------+------------------------------------------------------------+ diff --git a/docs/reference/supported.rst b/docs/reference/supported.rst index 3ca203e88..d0e0bf1af 100644 --- a/docs/reference/supported.rst +++ b/docs/reference/supported.rst @@ -104,11 +104,17 @@ Supported MCUs | +-----------------------+--------+------+-----------+-------------------+--------------+ | | F7 | ✔ | | ✔ | dwc2 | | | +-----------------------+--------+------+-----------+-------------------+--------------+ -| | H7 | ✔ | | ✔ | dwc2 | | +| | G0 | ✔ | ✖ | ✖ | stm32_fsdev | | | +-----------------------+--------+------+-----------+-------------------+--------------+ | | G4 | ✔ | ✖ | ✖ | stm32_fsdev | | | +-----------------------+--------+------+-----------+-------------------+--------------+ -| | L0, L1 | ✔ | ✖ | ✖ | stm32_fsdev | | +| | H5 | ✔ | ✖ | ✖ | stm32_fsdev | | +| +-----------------------+--------+------+-----------+-------------------+--------------+ +| | H7 | ✔ | | ✔ | dwc2 | | +| +-----------------------+--------+------+-----------+-------------------+--------------+ +| | L0 | ✔ | ✖ | ✖ | stm32_fsdev | | +| +-----------------------+--------+------+-----------+-------------------+--------------+ +| | L1 | ✔ | ✖ | ✖ | stm32_fsdev | | | +----+------------------+--------+------+-----------+-------------------+--------------+ | | L4 | 4x2, 4x3 | ✔ | ✖ | ✖ | stm32_fsdev | | | | +------------------+--------+------+-----------+-------------------+--------------+ @@ -116,8 +122,14 @@ Supported MCUs | +----+------------------+--------+------+-----------+-------------------+--------------+ | | L4+ | ✔ | | | dwc2 | | | +-----------------------+--------+------+-----------+-------------------+--------------+ -| | U5 | ✔ | | ✔ | dwc2 | | +| | L5 | ✔ | ✖ | ✖ | stm32_fsdev | | | +-----------------------+--------+------+-----------+-------------------+--------------+ +| | U5 | 535, 545 | ✔ | ✖ | ✖ | stm32_fsdev | | +| | +------------------+--------+------+-----------+-------------------+--------------+ +| | | 575, 585 | ✔ | | ✖ | dwc2 | | +| | +------------------+--------+------+-----------+-------------------+--------------+ +| | | 59x,5Ax,5Fx,5Gx | ✔ | | ✔ | dwc2 | | +| +----+------------------+--------+------+-----------+-------------------+--------------+ | | WBx5 | ✔ | | | stm32_fsdev | | +--------------+-----------------------+--------+------+-----------+-------------------+--------------+ | TI | MSP430 | ✔ | ✖ | ✖ | msp430x5xx | | @@ -129,7 +141,9 @@ Supported MCUs | ValentyUSB | eptri | ✔ | ✖ | ✖ | eptri | | +--------------+-----------------------+--------+------+-----------+-------------------+--------------+ | WCH | CH32F20x | ✔ | | ✔ | ch32f205 | | +| +-----------------------+--------+------+-----------+-------------------+--------------+ | | CH32V20x | ✔ | | ✖ | ch32v20x | | +| +-----------------------+--------+------+-----------+-------------------+--------------+ | | CH32V307 | ✔ | | ✔ | ch32v307 | | +--------------+-----------------------+--------+------+-----------+-------------------+--------------+ diff --git a/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c b/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c index 9ce37f992..0ecb6ea05 100644 --- a/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c +++ b/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c @@ -37,14 +37,20 @@ * It also should work with minimal changes for any ST MCU with an "USB A"/"PCD"/"HCD" peripheral. This * covers: * - * F04x, F072, F078, 070x6/B 1024 byte buffer + * F04x, F072, F078, F070x6/B 1024 byte buffer * F102, F103 512 byte buffer; no internal D+ pull-up (maybe many more changes?) * F302xB/C, F303xB/C, F373 512 byte buffer; no internal D+ pull-up * F302x6/8, F302xD/E2, F303xD/E 1024 byte buffer; no internal D+ pull-up + * G0 2048 byte buffer; 32-bit bus + * G4 1024 byte buffer + * H5 2048 byte buffer; 32-bit bus * L0x2, L0x3 1024 byte buffer * L1 512 byte buffer * L4x2, L4x3 1024 byte buffer - * G0 2048 byte buffer + * L5 1024 byte buffer + * U0 1024 byte buffer; 32-bit bus + * U535, U545 2048 byte buffer; 32-bit bus + * WB35, WB55 1024 byte buffer * * To use this driver, you must: * - If you are using a device with crystal-less USB, set up the clock recovery system (CRS) diff --git a/src/portable/st/stm32_fsdev/fsdev_stm32.h b/src/portable/st/stm32_fsdev/fsdev_stm32.h index b3fa11b88..524efc75f 100644 --- a/src/portable/st/stm32_fsdev/fsdev_stm32.h +++ b/src/portable/st/stm32_fsdev/fsdev_stm32.h @@ -161,7 +161,7 @@ #else #error You are using an untested or unimplemented STM32 variant. Please update the driver. - // This includes L1x0, L1x1, L1x2, L4x2 and L4x3, G1x1, G1x3, and G1x4 + // This includes U0 #endif // This checks if the device has "LPM" -- cgit v1.3.1 From d52d659261bd2bd680bdb5194bfd11349a2ed994 Mon Sep 17 00:00:00 2001 From: Ryzee119 Date: Tue, 18 Jun 2024 14:02:36 +0930 Subject: usbh: Set interface recipient should be interface --- src/host/usbh.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/host/usbh.c b/src/host/usbh.c index 7a47f5056..a94c22c4c 100644 --- a/src/host/usbh.c +++ b/src/host/usbh.c @@ -1113,7 +1113,7 @@ bool tuh_interface_set(uint8_t daddr, uint8_t itf_num, uint8_t itf_alt, TU_LOG_USBH("Set Interface %u Alternate %u\r\n", itf_num, itf_alt); tusb_control_request_t const request = { .bmRequestType_bit = { - .recipient = TUSB_REQ_RCPT_DEVICE, + .recipient = TUSB_REQ_RCPT_INTERFACE, .type = TUSB_REQ_TYPE_STANDARD, .direction = TUSB_DIR_OUT }, -- cgit v1.3.1 From d945261aef7e2c922153e2a85d00791dd1930740 Mon Sep 17 00:00:00 2001 From: hathach Date: Tue, 18 Jun 2024 12:53:02 +0700 Subject: LOG3 in isr --- examples/host/device_info/src/tusb_config.h | 2 +- src/portable/nordic/nrf5x/dcd_nrf5x.c | 4 ++-- src/portable/nxp/khci/dcd_khci.c | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/examples/host/device_info/src/tusb_config.h b/examples/host/device_info/src/tusb_config.h index 484f651b1..2e9731eaf 100644 --- a/examples/host/device_info/src/tusb_config.h +++ b/examples/host/device_info/src/tusb_config.h @@ -70,7 +70,7 @@ #define CFG_TUH_ENABLED 1 #if CFG_TUSB_MCU == OPT_MCU_RP2040 - #define CFG_TUH_RPI_PIO_USB 1 // use pio-usb as host controller + // #define CFG_TUH_RPI_PIO_USB 1 // use pio-usb as host controller // #define CFG_TUH_MAX3421 1 // use max3421 as host controller // host roothub port is 1 if using either pio-usb or max3421 diff --git a/src/portable/nordic/nrf5x/dcd_nrf5x.c b/src/portable/nordic/nrf5x/dcd_nrf5x.c index abce35245..1cc5c1836 100644 --- a/src/portable/nordic/nrf5x/dcd_nrf5x.c +++ b/src/portable/nordic/nrf5x/dcd_nrf5x.c @@ -907,9 +907,9 @@ void tusb_hal_nrf_power_event(uint32_t event) { USB_EVT_READY = 2 }; -#if CFG_TUSB_DEBUG >= 2 +#if CFG_TUSB_DEBUG >= 3 const char* const power_evt_str[] = {"Detected", "Removed", "Ready"}; - TU_LOG(2, "Power USB event: %s\r\n", power_evt_str[event]); + TU_LOG(3, "Power USB event: %s\r\n", power_evt_str[event]); #endif switch (event) { diff --git a/src/portable/nxp/khci/dcd_khci.c b/src/portable/nxp/khci/dcd_khci.c index dc71117b3..ef61146aa 100644 --- a/src/portable/nxp/khci/dcd_khci.c +++ b/src/portable/nxp/khci/dcd_khci.c @@ -540,7 +540,7 @@ void dcd_int_handler(uint8_t rhport) } if (is & USB_ISTAT_SLEEP_MASK) { - // TU_LOG2("Suspend: "); TU_LOG2_HEX(is); + // TU_LOG3("Suspend: "); TU_LOG2_HEX(is); // Note Host usually has extra delay after bus reset (without SOF), which could falsely // detected as Sleep event. Though usbd has debouncing logic so we are good -- cgit v1.3.1 From 5083d1eb3399d605d64b3e30a784731f330e7774 Mon Sep 17 00:00:00 2001 From: Okarss <104319900+Okarss@users.noreply.github.com> Date: Tue, 18 Jun 2024 12:12:44 +0300 Subject: Update Host mode information for FSDEV devices --- docs/reference/supported.rst | 13 +++++++------ src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c | 6 +++--- 2 files changed, 10 insertions(+), 9 deletions(-) (limited to 'src') diff --git a/docs/reference/supported.rst b/docs/reference/supported.rst index d0e0bf1af..441c885ac 100644 --- a/docs/reference/supported.rst +++ b/docs/reference/supported.rst @@ -104,11 +104,11 @@ Supported MCUs | +-----------------------+--------+------+-----------+-------------------+--------------+ | | F7 | ✔ | | ✔ | dwc2 | | | +-----------------------+--------+------+-----------+-------------------+--------------+ -| | G0 | ✔ | ✖ | ✖ | stm32_fsdev | | +| | G0 | ✔ | | ✖ | stm32_fsdev | | | +-----------------------+--------+------+-----------+-------------------+--------------+ | | G4 | ✔ | ✖ | ✖ | stm32_fsdev | | | +-----------------------+--------+------+-----------+-------------------+--------------+ -| | H5 | ✔ | ✖ | ✖ | stm32_fsdev | | +| | H5 | ✔ | | ✖ | stm32_fsdev | | | +-----------------------+--------+------+-----------+-------------------+--------------+ | | H7 | ✔ | | ✔ | dwc2 | | | +-----------------------+--------+------+-----------+-------------------+--------------+ @@ -124,13 +124,13 @@ Supported MCUs | +-----------------------+--------+------+-----------+-------------------+--------------+ | | L5 | ✔ | ✖ | ✖ | stm32_fsdev | | | +-----------------------+--------+------+-----------+-------------------+--------------+ -| | U5 | 535, 545 | ✔ | ✖ | ✖ | stm32_fsdev | | +| | U5 | 535, 545 | ✔ | | ✖ | stm32_fsdev | | | | +------------------+--------+------+-----------+-------------------+--------------+ | | | 575, 585 | ✔ | | ✖ | dwc2 | | | | +------------------+--------+------+-----------+-------------------+--------------+ | | | 59x,5Ax,5Fx,5Gx | ✔ | | ✔ | dwc2 | | | +----+------------------+--------+------+-----------+-------------------+--------------+ -| | WBx5 | ✔ | | | stm32_fsdev | | +| | WBx5 | ✔ | ✖ | ✖ | stm32_fsdev | | +--------------+-----------------------+--------+------+-----------+-------------------+--------------+ | TI | MSP430 | ✔ | ✖ | ✖ | msp430x5xx | | | +-----------------------+--------+------+-----------+-------------------+--------------+ @@ -153,8 +153,9 @@ Table Legend = =================== ✔ Supported -⚠ WIP/partial support -✖ Not supported +⚠ Partial support +✖ Not supported by hardware +[empty] Unknown = =================== Supported Boards diff --git a/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c b/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c index 0ecb6ea05..fb499fa18 100644 --- a/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c +++ b/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c @@ -41,15 +41,15 @@ * F102, F103 512 byte buffer; no internal D+ pull-up (maybe many more changes?) * F302xB/C, F303xB/C, F373 512 byte buffer; no internal D+ pull-up * F302x6/8, F302xD/E2, F303xD/E 1024 byte buffer; no internal D+ pull-up - * G0 2048 byte buffer; 32-bit bus + * G0 2048 byte buffer; 32-bit bus; host mode * G4 1024 byte buffer - * H5 2048 byte buffer; 32-bit bus + * H5 2048 byte buffer; 32-bit bus; host mode * L0x2, L0x3 1024 byte buffer * L1 512 byte buffer * L4x2, L4x3 1024 byte buffer * L5 1024 byte buffer * U0 1024 byte buffer; 32-bit bus - * U535, U545 2048 byte buffer; 32-bit bus + * U535, U545 2048 byte buffer; 32-bit bus; host mode * WB35, WB55 1024 byte buffer * * To use this driver, you must: -- cgit v1.3.1 From 5e58ec127ff30ce48a9fcb819acfc05edc92f332 Mon Sep 17 00:00:00 2001 From: Ryzee119 Date: Thu, 20 Jun 2024 09:33:01 +0930 Subject: usbh: Add set address recovery time Ref USB Spec 9.2.6.3 --- src/host/usbh.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'src') diff --git a/src/host/usbh.c b/src/host/usbh.c index a94c22c4c..8c488aaa2 100644 --- a/src/host/usbh.c +++ b/src/host/usbh.c @@ -1421,6 +1421,9 @@ static void process_enumeration(tuh_xfer_t* xfer) { break; case ENUM_GET_DEVICE_DESC: { + // Allow 2ms for address recovery time, Ref USB Spec 9.2.6.3 + osal_task_delay(2); + uint8_t const new_addr = (uint8_t) tu_le16toh(xfer->setup->wValue); usbh_device_t* new_dev = get_device(new_addr); -- cgit v1.3.1 From 0d79da37e79b8abd04f7f9ba9c15114d84e9810a Mon Sep 17 00:00:00 2001 From: Andrew Leech Date: Thu, 20 Jun 2024 15:15:51 +1000 Subject: synopsys/dwc2_esp32: Add header for vTaskDelay. --- src/portable/synopsys/dwc2/dwc2_esp32.h | 1 + 1 file changed, 1 insertion(+) (limited to 'src') diff --git a/src/portable/synopsys/dwc2/dwc2_esp32.h b/src/portable/synopsys/dwc2/dwc2_esp32.h index c50dd66b8..932f52f40 100644 --- a/src/portable/synopsys/dwc2/dwc2_esp32.h +++ b/src/portable/synopsys/dwc2/dwc2_esp32.h @@ -35,6 +35,7 @@ #include "esp_intr_alloc.h" #include "soc/periph_defs.h" //#include "soc/usb_periph.h" +#include "freertos/task.h" #define DWC2_REG_BASE 0x60080000UL #define DWC2_EP_MAX 6 // USB_OUT_EP_NUM. TODO ESP32Sx only has 5 tx fifo (5 endpoint IN) -- cgit v1.3.1 From 85e1f423bf67776bf2c7113f3f287297f6e81404 Mon Sep 17 00:00:00 2001 From: Davide Gerhard Date: Thu, 27 Jun 2024 21:30:16 +0200 Subject: remove double semicolon since ISO C not allow it ISO C does not allow extra ';' outside of a function [-Werror=pedantic] --- src/osal/osal_freertos.h | 2 +- src/typec/tcd.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/osal/osal_freertos.h b/src/osal/osal_freertos.h index f1f05f353..a3a0f3a3f 100644 --- a/src/osal/osal_freertos.h +++ b/src/osal/osal_freertos.h @@ -78,7 +78,7 @@ typedef struct // _int_set is not used with an RTOS #define OSAL_QUEUE_DEF(_int_set, _name, _depth, _type) \ static _type _name##_##buf[_depth];\ - osal_queue_def_t _name = { .depth = _depth, .item_sz = sizeof(_type), .buf = _name##_##buf, _OSAL_Q_NAME(_name) }; + osal_queue_def_t _name = { .depth = _depth, .item_sz = sizeof(_type), .buf = _name##_##buf, _OSAL_Q_NAME(_name) } //--------------------------------------------------------------------+ // TASK API diff --git a/src/typec/tcd.h b/src/typec/tcd.h index 86499c951..bcbdab8ed 100644 --- a/src/typec/tcd.h +++ b/src/typec/tcd.h @@ -63,7 +63,7 @@ typedef struct TU_ATTR_PACKED { } xfer_complete; }; -} tcd_event_t;; +} tcd_event_t; //--------------------------------------------------------------------+ // -- cgit v1.3.1 From 8f699023f3ff2434efa4433ddc92a9c01756d1f1 Mon Sep 17 00:00:00 2001 From: Davide Gerhard Date: Fri, 28 Jun 2024 10:55:43 +0200 Subject: audio_device.c: fix strict-overflow warning with gcc >= 12 Fix the following error ~/libs/tinyusb/src/class/audio/audio_device.c:1493:23: error: assuming pointer wraparound does not occur when comparing P +- C1 with P +- C2 [-Werror=strict-overflow] 1493 | while (p_desc < p_desc_end) | ~~~~~~~^~~~~~~~~~~~ compilation terminated due to -Wfatal-errors. --- src/class/audio/audio_device.c | 26 ++++++++++++++++---------- 1 file changed, 16 insertions(+), 10 deletions(-) (limited to 'src') diff --git a/src/class/audio/audio_device.c b/src/class/audio/audio_device.c index 46db96ea9..65cac2fd5 100644 --- a/src/class/audio/audio_device.c +++ b/src/class/audio/audio_device.c @@ -1490,7 +1490,8 @@ uint16_t audiod_open(uint8_t rhport, tusb_desc_interface_t const * itf_desc, uin #endif uint8_t const *p_desc = _audiod_fct[i].p_desc; uint8_t const *p_desc_end = p_desc + _audiod_fct[i].desc_length - TUD_AUDIO_DESC_IAD_LEN; - while (p_desc < p_desc_end) + // Condition modified from p_desc < p_desc_end to prevent gcc>=12 strict-overflow warning + while (p_desc_end - p_desc > 0) { if (tu_desc_type(p_desc) == TUSB_DESC_ENDPOINT) { @@ -1740,7 +1741,8 @@ static bool audiod_set_interface(uint8_t rhport, tusb_control_request_t const * uint8_t const *p_desc_end = audio->p_desc + audio->desc_length - TUD_AUDIO_DESC_IAD_LEN; // p_desc starts at required interface with alternate setting zero - while (p_desc < p_desc_end) + // Condition modified from p_desc < p_desc_end to prevent gcc>=12 strict-overflow warning + while (p_desc_end - p_desc > 0) { // Find correct interface if (tu_desc_type(p_desc) == TUSB_DESC_INTERFACE && ((tusb_desc_interface_t const * )p_desc)->bInterfaceNumber == itf && ((tusb_desc_interface_t const * )p_desc)->bAlternateSetting == alt) @@ -1750,7 +1752,8 @@ static bool audiod_set_interface(uint8_t rhport, tusb_control_request_t const * #endif // From this point forward follow the EP descriptors associated to the current alternate setting interface - Open EPs if necessary uint8_t foundEPs = 0, nEps = ((tusb_desc_interface_t const * )p_desc)->bNumEndpoints; - while (foundEPs < nEps && p_desc < p_desc_end) + // Condition modified from p_desc < p_desc_end to prevent gcc>=12 strict-overflow warning + while (foundEPs < nEps && (p_desc_end - p_desc > 0)) { if (tu_desc_type(p_desc) == TUSB_DESC_ENDPOINT) { @@ -2394,7 +2397,8 @@ static bool audiod_get_AS_interface_index(uint8_t itf, audiod_function_t * audio p_desc += ((audio_desc_cs_ac_interface_t const *)p_desc)->wTotalLength; uint8_t tmp = 0; - while (p_desc < p_desc_end) + // Condition modified from p_desc < p_desc_end to prevent gcc>=12 strict-overflow warning + while (p_desc_end - p_desc > 0) { // We assume the number of alternate settings is increasing thus we return the index of alternate setting zero! if (tu_desc_type(p_desc) == TUSB_DESC_INTERFACE && ((tusb_desc_interface_t const * )p_desc)->bAlternateSetting == 0) @@ -2447,7 +2451,8 @@ static bool audiod_verify_entity_exists(uint8_t itf, uint8_t entityID, uint8_t * uint8_t const *p_desc_end = ((audio_desc_cs_ac_interface_t const *)p_desc)->wTotalLength + p_desc; p_desc = tu_desc_next(p_desc); // Get past CS AC descriptor - while (p_desc < p_desc_end) + // Condition modified from p_desc < p_desc_end to prevent gcc>=12 strict-overflow warning + while (p_desc_end - p_desc > 0) { if (p_desc[3] == entityID) // Entity IDs are always at offset 3 { @@ -2471,8 +2476,8 @@ static bool audiod_verify_itf_exists(uint8_t itf, uint8_t *func_id) // Get pointer at beginning and end uint8_t const *p_desc = _audiod_fct[i].p_desc; uint8_t const *p_desc_end = _audiod_fct[i].p_desc + _audiod_fct[i].desc_length - TUD_AUDIO_DESC_IAD_LEN; - - while (p_desc < p_desc_end) + // Condition modified from p_desc < p_desc_end to prevent gcc>=12 strict-overflow warning + while (p_desc_end - p_desc > 0) { if (tu_desc_type(p_desc) == TUSB_DESC_INTERFACE && ((tusb_desc_interface_t const *)_audiod_fct[i].p_desc)->bInterfaceNumber == itf) { @@ -2500,7 +2505,8 @@ static bool audiod_verify_ep_exists(uint8_t ep, uint8_t *func_id) uint8_t const *p_desc = tu_desc_next(_audiod_fct[i].p_desc); p_desc += ((audio_desc_cs_ac_interface_t const *)p_desc)->wTotalLength; - while (p_desc < p_desc_end) + // Condition modified from p_desc < p_desc_end to prevent gcc>=12 strict-overflow warning + while (p_desc_end - p_desc > 0) { if (tu_desc_type(p_desc) == TUSB_DESC_ENDPOINT && ((tusb_desc_endpoint_t const * )p_desc)->bEndpointAddress == ep) { @@ -2531,8 +2537,8 @@ static void audiod_parse_for_AS_params(audiod_function_t* audio, uint8_t const * #endif p_desc = tu_desc_next(p_desc); // Exclude standard AS interface descriptor of current alternate interface descriptor - - while (p_desc < p_desc_end) + // Condition modified from p_desc < p_desc_end to prevent gcc>=12 strict-overflow warning + while (p_desc_end - p_desc > 0) { // Abort if follow up descriptor is a new standard interface descriptor - indicates the last AS descriptor was already finished if (tu_desc_type(p_desc) == TUSB_DESC_INTERFACE) break; -- cgit v1.3.1 From 8f9a57636c9ae6b51e272274ea79f01a7a2631c1 Mon Sep 17 00:00:00 2001 From: Davide Gerhard Date: Fri, 28 Jun 2024 19:57:59 +0200 Subject: audio.h: fix error ISO C restricts enumerator values to range of 'int' fix error ~/dsp/libs/tinyusb/src/class/audio/audio.h:643:53: error: ISO C restricts enumerator values to range of 'int' before C23 [-Werror=pedantic] 643 | AUDIO_CHANNEL_CONFIG_RAW_DATA = 0x80000000, // TODO | ^~~~~~~~~~ compilation terminated due to -Wfatal-errors. Closes: https://github.com/hathach/tinyusb/issues/2690 --- src/class/audio/audio.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/class/audio/audio.h b/src/class/audio/audio.h index d6f3e22e2..49ccbe863 100644 --- a/src/class/audio/audio.h +++ b/src/class/audio/audio.h @@ -489,7 +489,7 @@ typedef enum AUDIO_DATA_FORMAT_TYPE_I_IEEE_FLOAT = (uint32_t) (1 << 2), AUDIO_DATA_FORMAT_TYPE_I_ALAW = (uint32_t) (1 << 3), AUDIO_DATA_FORMAT_TYPE_I_MULAW = (uint32_t) (1 << 4), - AUDIO_DATA_FORMAT_TYPE_I_RAW_DATA = 0x80000000, + AUDIO_DATA_FORMAT_TYPE_I_RAW_DATA = (int)(1U << 31U), } audio_data_format_type_I_t; /// All remaining definitions are taken from the descriptor descriptions in the UAC2 main specification @@ -640,7 +640,7 @@ typedef enum AUDIO_CHANNEL_CONFIG_BOTTOM_CENTER = 0x01000000, AUDIO_CHANNEL_CONFIG_BACK_LEFT_OF_CENTER = 0x02000000, AUDIO_CHANNEL_CONFIG_BACK_RIGHT_OF_CENTER = 0x04000000, - AUDIO_CHANNEL_CONFIG_RAW_DATA = 0x80000000, + AUDIO_CHANNEL_CONFIG_RAW_DATA = (int)(1U << 31U), } audio_channel_config_t; /// AUDIO Channel Cluster Descriptor (4.1) -- cgit v1.3.1 From bd562e418080d4d9e4213d38a123b93f30250c48 Mon Sep 17 00:00:00 2001 From: Ha Thach Date: Fri, 5 Jul 2024 15:15:00 +0700 Subject: Revert "audio.h: fix error ISO C restricts enumerator values to range of 'int'" --- src/class/audio/audio.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/class/audio/audio.h b/src/class/audio/audio.h index 49ccbe863..d6f3e22e2 100644 --- a/src/class/audio/audio.h +++ b/src/class/audio/audio.h @@ -489,7 +489,7 @@ typedef enum AUDIO_DATA_FORMAT_TYPE_I_IEEE_FLOAT = (uint32_t) (1 << 2), AUDIO_DATA_FORMAT_TYPE_I_ALAW = (uint32_t) (1 << 3), AUDIO_DATA_FORMAT_TYPE_I_MULAW = (uint32_t) (1 << 4), - AUDIO_DATA_FORMAT_TYPE_I_RAW_DATA = (int)(1U << 31U), + AUDIO_DATA_FORMAT_TYPE_I_RAW_DATA = 0x80000000, } audio_data_format_type_I_t; /// All remaining definitions are taken from the descriptor descriptions in the UAC2 main specification @@ -640,7 +640,7 @@ typedef enum AUDIO_CHANNEL_CONFIG_BOTTOM_CENTER = 0x01000000, AUDIO_CHANNEL_CONFIG_BACK_LEFT_OF_CENTER = 0x02000000, AUDIO_CHANNEL_CONFIG_BACK_RIGHT_OF_CENTER = 0x04000000, - AUDIO_CHANNEL_CONFIG_RAW_DATA = (int)(1U << 31U), + AUDIO_CHANNEL_CONFIG_RAW_DATA = 0x80000000, } audio_channel_config_t; /// AUDIO Channel Cluster Descriptor (4.1) -- cgit v1.3.1 From ca12a579020184c0e3f6d66d8081d5bb927cb4b2 Mon Sep 17 00:00:00 2001 From: hathach Date: Fri, 5 Jul 2024 15:19:16 +0700 Subject: add u for unsigned --- src/class/audio/audio.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/class/audio/audio.h b/src/class/audio/audio.h index d6f3e22e2..2f97c0f23 100644 --- a/src/class/audio/audio.h +++ b/src/class/audio/audio.h @@ -489,7 +489,7 @@ typedef enum AUDIO_DATA_FORMAT_TYPE_I_IEEE_FLOAT = (uint32_t) (1 << 2), AUDIO_DATA_FORMAT_TYPE_I_ALAW = (uint32_t) (1 << 3), AUDIO_DATA_FORMAT_TYPE_I_MULAW = (uint32_t) (1 << 4), - AUDIO_DATA_FORMAT_TYPE_I_RAW_DATA = 0x80000000, + AUDIO_DATA_FORMAT_TYPE_I_RAW_DATA = 0x80000000u, } audio_data_format_type_I_t; /// All remaining definitions are taken from the descriptor descriptions in the UAC2 main specification @@ -640,7 +640,7 @@ typedef enum AUDIO_CHANNEL_CONFIG_BOTTOM_CENTER = 0x01000000, AUDIO_CHANNEL_CONFIG_BACK_LEFT_OF_CENTER = 0x02000000, AUDIO_CHANNEL_CONFIG_BACK_RIGHT_OF_CENTER = 0x04000000, - AUDIO_CHANNEL_CONFIG_RAW_DATA = 0x80000000, + AUDIO_CHANNEL_CONFIG_RAW_DATA = 0x80000000u, } audio_channel_config_t; /// AUDIO Channel Cluster Descriptor (4.1) -- cgit v1.3.1 From 1f590c36287e26b6d189bf41f9b7704e957bf8af Mon Sep 17 00:00:00 2001 From: hathach Date: Fri, 12 Jul 2024 16:53:21 +0700 Subject: - add tud_cdc_configure_fifo() to replace CFG_TUD_CDC_PERSISTENT_TX_BUFF - new line, and code format --- src/class/cdc/cdc_device.c | 237 ++++++++++++++++++--------------------------- src/class/cdc/cdc_device.h | 195 ++++++++++++++----------------------- 2 files changed, 168 insertions(+), 264 deletions(-) (limited to 'src') diff --git a/src/class/cdc/cdc_device.c b/src/class/cdc/cdc_device.c index f36725eba..681a1b852 100644 --- a/src/class/cdc/cdc_device.c +++ b/src/class/cdc/cdc_device.c @@ -45,8 +45,7 @@ //--------------------------------------------------------------------+ #define BULK_PACKET_SIZE (TUD_OPT_HIGH_SPEED ? 512 : 64) -typedef struct -{ +typedef struct { uint8_t itf_num; uint8_t ep_notif; uint8_t ep_in; @@ -56,7 +55,7 @@ typedef struct uint8_t line_state; /*------------- From this point, data is not cleared by bus reset -------------*/ - char wanted_char; + char wanted_char; TU_ATTR_ALIGNED(4) cdc_line_coding_t line_coding; // FIFO @@ -72,18 +71,17 @@ typedef struct // Endpoint Transfer buffer CFG_TUSB_MEM_ALIGN uint8_t epout_buf[CFG_TUD_CDC_EP_BUFSIZE]; CFG_TUSB_MEM_ALIGN uint8_t epin_buf[CFG_TUD_CDC_EP_BUFSIZE]; - -}cdcd_interface_t; +} cdcd_interface_t; #define ITF_MEM_RESET_SIZE offsetof(cdcd_interface_t, wanted_char) //--------------------------------------------------------------------+ // INTERNAL OBJECT & FUNCTION DECLARATION //--------------------------------------------------------------------+ -CFG_TUD_MEM_SECTION tu_static cdcd_interface_t _cdcd_itf[CFG_TUD_CDC]; +CFG_TUD_MEM_SECTION static cdcd_interface_t _cdcd_itf[CFG_TUD_CDC]; +static tud_cdc_configure_fifo_t _cdcd_fifo_cfg; -static bool _prep_out_transaction (cdcd_interface_t* p_cdc) -{ +static bool _prep_out_transaction (cdcd_interface_t* p_cdc) { uint8_t const rhport = 0; uint16_t available = tu_fifo_remaining(&p_cdc->rx_ff); @@ -99,14 +97,11 @@ static bool _prep_out_transaction (cdcd_interface_t* p_cdc) // fifo can be changed before endpoint is claimed available = tu_fifo_remaining(&p_cdc->rx_ff); - if ( available >= sizeof(p_cdc->epout_buf) ) - { + if ( available >= sizeof(p_cdc->epout_buf) ) { return usbd_edpt_xfer(rhport, p_cdc->ep_out, p_cdc->epout_buf, sizeof(p_cdc->epout_buf)); - }else - { + }else { // Release endpoint since we don't make any transfer usbd_edpt_release(rhport, p_cdc->ep_out); - return false; } } @@ -114,51 +109,49 @@ static bool _prep_out_transaction (cdcd_interface_t* p_cdc) //--------------------------------------------------------------------+ // APPLICATION API //--------------------------------------------------------------------+ -bool tud_cdc_n_connected(uint8_t itf) -{ + +bool tud_cdc_configure_fifo(tud_cdc_configure_fifo_t const* cfg) { + TU_VERIFY(cfg); + _cdcd_fifo_cfg = (*cfg); + return true; +} + +bool tud_cdc_n_connected(uint8_t itf) { // DTR (bit 0) active is considered as connected return tud_ready() && tu_bit_test(_cdcd_itf[itf].line_state, 0); } -uint8_t tud_cdc_n_get_line_state (uint8_t itf) -{ +uint8_t tud_cdc_n_get_line_state(uint8_t itf) { return _cdcd_itf[itf].line_state; } -void tud_cdc_n_get_line_coding (uint8_t itf, cdc_line_coding_t* coding) -{ +void tud_cdc_n_get_line_coding(uint8_t itf, cdc_line_coding_t* coding) { (*coding) = _cdcd_itf[itf].line_coding; } -void tud_cdc_n_set_wanted_char (uint8_t itf, char wanted) -{ +void tud_cdc_n_set_wanted_char(uint8_t itf, char wanted) { _cdcd_itf[itf].wanted_char = wanted; } - //--------------------------------------------------------------------+ // READ API //--------------------------------------------------------------------+ -uint32_t tud_cdc_n_available(uint8_t itf) -{ +uint32_t tud_cdc_n_available(uint8_t itf) { return tu_fifo_count(&_cdcd_itf[itf].rx_ff); } -uint32_t tud_cdc_n_read(uint8_t itf, void* buffer, uint32_t bufsize) -{ +uint32_t tud_cdc_n_read(uint8_t itf, void* buffer, uint32_t bufsize) { cdcd_interface_t* p_cdc = &_cdcd_itf[itf]; uint32_t num_read = tu_fifo_read_n(&p_cdc->rx_ff, buffer, (uint16_t) TU_MIN(bufsize, UINT16_MAX)); _prep_out_transaction(p_cdc); return num_read; } -bool tud_cdc_n_peek(uint8_t itf, uint8_t* chr) -{ +bool tud_cdc_n_peek(uint8_t itf, uint8_t* chr) { return tu_fifo_peek(&_cdcd_itf[itf].rx_ff, chr); } -void tud_cdc_n_read_flush (uint8_t itf) -{ +void tud_cdc_n_read_flush(uint8_t itf) { cdcd_interface_t* p_cdc = &_cdcd_itf[itf]; tu_fifo_clear(&p_cdc->rx_ff); _prep_out_transaction(p_cdc); @@ -167,16 +160,15 @@ void tud_cdc_n_read_flush (uint8_t itf) //--------------------------------------------------------------------+ // WRITE API //--------------------------------------------------------------------+ -uint32_t tud_cdc_n_write(uint8_t itf, void const* buffer, uint32_t bufsize) -{ +uint32_t tud_cdc_n_write(uint8_t itf, void const* buffer, uint32_t bufsize) { cdcd_interface_t* p_cdc = &_cdcd_itf[itf]; uint16_t ret = tu_fifo_write_n(&p_cdc->tx_ff, buffer, (uint16_t) TU_MIN(bufsize, UINT16_MAX)); // flush if queue more than packet size - if ( tu_fifo_count(&p_cdc->tx_ff) >= BULK_PACKET_SIZE - #if CFG_TUD_CDC_TX_BUFSIZE < BULK_PACKET_SIZE - || tu_fifo_full(&p_cdc->tx_ff) // check full if fifo size is less than packet size - #endif + if (tu_fifo_count(&p_cdc->tx_ff) >= BULK_PACKET_SIZE + #if CFG_TUD_CDC_TX_BUFSIZE < BULK_PACKET_SIZE + || tu_fifo_full(&p_cdc->tx_ff) // check full if fifo size is less than packet size + #endif ) { tud_cdc_n_write_flush(itf); } @@ -184,30 +176,27 @@ uint32_t tud_cdc_n_write(uint8_t itf, void const* buffer, uint32_t bufsize) return ret; } -uint32_t tud_cdc_n_write_flush (uint8_t itf) -{ +uint32_t tud_cdc_n_write_flush(uint8_t itf) { cdcd_interface_t* p_cdc = &_cdcd_itf[itf]; // Skip if usb is not ready yet - TU_VERIFY( tud_ready(), 0 ); + TU_VERIFY(tud_ready(), 0); // No data to send - if ( !tu_fifo_count(&p_cdc->tx_ff) ) return 0; + if (!tu_fifo_count(&p_cdc->tx_ff)) return 0; uint8_t const rhport = 0; // Claim the endpoint - TU_VERIFY( usbd_edpt_claim(rhport, p_cdc->ep_in), 0 ); + TU_VERIFY(usbd_edpt_claim(rhport, p_cdc->ep_in), 0); // Pull data from FIFO uint16_t const count = tu_fifo_read_n(&p_cdc->tx_ff, p_cdc->epin_buf, sizeof(p_cdc->epin_buf)); - if ( count ) - { - TU_ASSERT( usbd_edpt_xfer(rhport, p_cdc->ep_in, p_cdc->epin_buf, count), 0 ); + if (count) { + TU_ASSERT(usbd_edpt_xfer(rhport, p_cdc->ep_in, p_cdc->epin_buf, count), 0); return count; - }else - { + } else { // Release endpoint since we don't make any transfer // Note: data is dropped if terminal is not connected usbd_edpt_release(rhport, p_cdc->ep_in); @@ -215,33 +204,30 @@ uint32_t tud_cdc_n_write_flush (uint8_t itf) } } -uint32_t tud_cdc_n_write_available (uint8_t itf) -{ +uint32_t tud_cdc_n_write_available(uint8_t itf) { return tu_fifo_remaining(&_cdcd_itf[itf].tx_ff); } -bool tud_cdc_n_write_clear (uint8_t itf) -{ +bool tud_cdc_n_write_clear(uint8_t itf) { return tu_fifo_clear(&_cdcd_itf[itf].tx_ff); } //--------------------------------------------------------------------+ // USBD Driver API //--------------------------------------------------------------------+ -void cdcd_init(void) -{ +void cdcd_init(void) { tu_memclr(_cdcd_itf, sizeof(_cdcd_itf)); + tu_memclr(&_cdcd_fifo_cfg, sizeof(_cdcd_fifo_cfg)); - for(uint8_t i=0; iwanted_char = (char) -1; // default line coding is : stop bit = 1, parity = none, data bits = 8 - p_cdc->line_coding.bit_rate = 115200; + p_cdc->line_coding.bit_rate = 115200; p_cdc->line_coding.stop_bits = 0; - p_cdc->line_coding.parity = 0; + p_cdc->line_coding.parity = 0; p_cdc->line_coding.data_bits = 8; // Config RX fifo @@ -285,35 +271,28 @@ bool cdcd_deinit(void) { return true; } -void cdcd_reset(uint8_t rhport) -{ +void cdcd_reset(uint8_t rhport) { (void) rhport; - for(uint8_t i=0; irx_ff); - #if !CFG_TUD_CDC_PERSISTENT_TX_BUFF - tu_fifo_clear(&p_cdc->tx_ff); - #endif + if (!_cdcd_fifo_cfg.rx_persistent) tu_fifo_clear(&p_cdc->rx_ff); + if (!_cdcd_fifo_cfg.tx_persistent) tu_fifo_clear(&p_cdc->tx_ff); tu_fifo_set_overwritable(&p_cdc->tx_ff, true); } } -uint16_t cdcd_open(uint8_t rhport, tusb_desc_interface_t const * itf_desc, uint16_t max_len) -{ +uint16_t cdcd_open(uint8_t rhport, tusb_desc_interface_t const * itf_desc, uint16_t max_len) { // Only support ACM subclass TU_VERIFY( TUSB_CLASS_CDC == itf_desc->bInterfaceClass && CDC_COMM_SUBCLASS_ABSTRACT_CONTROL_MODEL == itf_desc->bInterfaceSubClass, 0); // Find available interface - cdcd_interface_t * p_cdc = NULL; - for(uint8_t cdc_id=0; cdc_iditf_num = itf_desc->bInterfaceNumber; uint16_t drv_len = sizeof(tusb_desc_interface_t); - uint8_t const * p_desc = tu_desc_next( itf_desc ); + uint8_t const* p_desc = tu_desc_next(itf_desc); // Communication Functional Descriptors - while ( TUSB_DESC_CS_INTERFACE == tu_desc_type(p_desc) && drv_len <= max_len ) - { + while (TUSB_DESC_CS_INTERFACE == tu_desc_type(p_desc) && drv_len <= max_len) { drv_len += tu_desc_len(p_desc); - p_desc = tu_desc_next(p_desc); + p_desc = tu_desc_next(p_desc); } - if ( TUSB_DESC_ENDPOINT == tu_desc_type(p_desc) ) - { + if (TUSB_DESC_ENDPOINT == tu_desc_type(p_desc)) { // notification endpoint - tusb_desc_endpoint_t const * desc_ep = (tusb_desc_endpoint_t const *) p_desc; + tusb_desc_endpoint_t const* desc_ep = (tusb_desc_endpoint_t const*) p_desc; - TU_ASSERT( usbd_edpt_open(rhport, desc_ep), 0 ); + TU_ASSERT(usbd_edpt_open(rhport, desc_ep), 0); p_cdc->ep_notif = desc_ep->bEndpointAddress; drv_len += tu_desc_len(p_desc); - p_desc = tu_desc_next(p_desc); + p_desc = tu_desc_next(p_desc); } //------------- Data Interface (if any) -------------// - if ( (TUSB_DESC_INTERFACE == tu_desc_type(p_desc)) && - (TUSB_CLASS_CDC_DATA == ((tusb_desc_interface_t const *) p_desc)->bInterfaceClass) ) - { + if ((TUSB_DESC_INTERFACE == tu_desc_type(p_desc)) && + (TUSB_CLASS_CDC_DATA == ((tusb_desc_interface_t const*) p_desc)->bInterfaceClass)) { // next to endpoint descriptor drv_len += tu_desc_len(p_desc); - p_desc = tu_desc_next(p_desc); + p_desc = tu_desc_next(p_desc); // Open endpoint pair - TU_ASSERT( usbd_open_edpt_pair(rhport, p_desc, 2, TUSB_XFER_BULK, &p_cdc->ep_out, &p_cdc->ep_in), 0 ); + TU_ASSERT(usbd_open_edpt_pair(rhport, p_desc, 2, TUSB_XFER_BULK, &p_cdc->ep_out, &p_cdc->ep_in), 0); - drv_len += 2*sizeof(tusb_desc_endpoint_t); + drv_len += 2 * sizeof(tusb_desc_endpoint_t); } // Prepare for incoming data @@ -368,8 +344,7 @@ uint16_t cdcd_open(uint8_t rhport, tusb_desc_interface_t const * itf_desc, uint1 // Invoked when a control transfer occurred on an interface of this class // Driver response accordingly to the request and the transfer stage (setup/data/ack) // return false to stall control endpoint (e.g unsupported request) -bool cdcd_control_xfer_cb(uint8_t rhport, uint8_t stage, tusb_control_request_t const * request) -{ +bool cdcd_control_xfer_cb(uint8_t rhport, uint8_t stage, tusb_control_request_t const* request) { // Handle class request only TU_VERIFY(request->bmRequestType_bit.type == TUSB_REQ_TYPE_CLASS); @@ -377,42 +352,33 @@ bool cdcd_control_xfer_cb(uint8_t rhport, uint8_t stage, tusb_control_request_t cdcd_interface_t* p_cdc = _cdcd_itf; // Identify which interface to use - for ( ; ; itf++, p_cdc++) - { + for (;; itf++, p_cdc++) { if (itf >= TU_ARRAY_SIZE(_cdcd_itf)) return false; - if ( p_cdc->itf_num == request->wIndex ) break; + if (p_cdc->itf_num == request->wIndex) break; } - switch ( request->bRequest ) - { + switch (request->bRequest) { case CDC_REQUEST_SET_LINE_CODING: - if (stage == CONTROL_STAGE_SETUP) - { + if (stage == CONTROL_STAGE_SETUP) { TU_LOG_DRV(" Set Line Coding\r\n"); tud_control_xfer(rhport, request, &p_cdc->line_coding, sizeof(cdc_line_coding_t)); + } else if (stage == CONTROL_STAGE_ACK) { + if (tud_cdc_line_coding_cb) tud_cdc_line_coding_cb(itf, &p_cdc->line_coding); } - else if ( stage == CONTROL_STAGE_ACK) - { - if ( tud_cdc_line_coding_cb ) tud_cdc_line_coding_cb(itf, &p_cdc->line_coding); - } - break; + break; case CDC_REQUEST_GET_LINE_CODING: - if (stage == CONTROL_STAGE_SETUP) - { + if (stage == CONTROL_STAGE_SETUP) { TU_LOG_DRV(" Get Line Coding\r\n"); tud_control_xfer(rhport, request, &p_cdc->line_coding, sizeof(cdc_line_coding_t)); } - break; + break; case CDC_REQUEST_SET_CONTROL_LINE_STATE: - if (stage == CONTROL_STAGE_SETUP) - { + if (stage == CONTROL_STAGE_SETUP) { tud_control_status(rhport, request); - } - else if (stage == CONTROL_STAGE_ACK) - { + } else if (stage == CONTROL_STAGE_ACK) { // CDC PSTN v1.2 section 6.3.12 // Bit 0: Indicates if DTE is present or not. // This signal corresponds to V.24 signal 108/2 and RS-232 signal DTR (Data Terminal Ready) @@ -429,61 +395,54 @@ bool cdcd_control_xfer_cb(uint8_t rhport, uint8_t stage, tusb_control_request_t TU_LOG_DRV(" Set Control Line State: DTR = %d, RTS = %d\r\n", dtr, rts); // Invoke callback - if ( tud_cdc_line_state_cb ) tud_cdc_line_state_cb(itf, dtr, rts); + if (tud_cdc_line_state_cb) tud_cdc_line_state_cb(itf, dtr, rts); } - break; + break; + case CDC_REQUEST_SEND_BREAK: - if (stage == CONTROL_STAGE_SETUP) - { + if (stage == CONTROL_STAGE_SETUP) { tud_control_status(rhport, request); - } - else if (stage == CONTROL_STAGE_ACK) - { + } else if (stage == CONTROL_STAGE_ACK) { TU_LOG_DRV(" Send Break\r\n"); - if ( tud_cdc_send_break_cb ) tud_cdc_send_break_cb(itf, request->wValue); + if (tud_cdc_send_break_cb) tud_cdc_send_break_cb(itf, request->wValue); } - break; + break; - default: return false; // stall unsupported request + default: + return false; // stall unsupported request } return true; } -bool cdcd_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t result, uint32_t xferred_bytes) -{ +bool cdcd_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t result, uint32_t xferred_bytes) { (void) result; uint8_t itf; cdcd_interface_t* p_cdc; // Identify which interface to use - for (itf = 0; itf < CFG_TUD_CDC; itf++) - { + for (itf = 0; itf < CFG_TUD_CDC; itf++) { p_cdc = &_cdcd_itf[itf]; - if ( ( ep_addr == p_cdc->ep_out ) || ( ep_addr == p_cdc->ep_in ) ) break; + if ((ep_addr == p_cdc->ep_out) || (ep_addr == p_cdc->ep_in)) break; } TU_ASSERT(itf < CFG_TUD_CDC); // Received new data - if ( ep_addr == p_cdc->ep_out ) - { + if (ep_addr == p_cdc->ep_out) { tu_fifo_write_n(&p_cdc->rx_ff, p_cdc->epout_buf, (uint16_t) xferred_bytes); // Check for wanted char and invoke callback if needed - if ( tud_cdc_rx_wanted_cb && (((signed char) p_cdc->wanted_char) != -1) ) - { - for ( uint32_t i = 0; i < xferred_bytes; i++ ) - { - if ( (p_cdc->wanted_char == p_cdc->epout_buf[i]) && !tu_fifo_empty(&p_cdc->rx_ff) ) - { + if (tud_cdc_rx_wanted_cb && (((signed char) p_cdc->wanted_char) != -1)) { + for (uint32_t i = 0; i < xferred_bytes; i++) { + if ((p_cdc->wanted_char == p_cdc->epout_buf[i]) && !tu_fifo_empty(&p_cdc->rx_ff)) { tud_cdc_rx_wanted_cb(itf, p_cdc->wanted_char); } } } // invoke receive callback (if there is still data) - if (tud_cdc_rx_cb && !tu_fifo_empty(&p_cdc->rx_ff) ) tud_cdc_rx_cb(itf); + if (tud_cdc_rx_cb && !tu_fifo_empty(&p_cdc->rx_ff)) tud_cdc_rx_cb(itf); // prepare for OUT transaction _prep_out_transaction(p_cdc); @@ -492,19 +451,15 @@ bool cdcd_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t result, uint32_ // Data sent to host, we continue to fetch from tx fifo to send. // Note: This will cause incorrect baudrate set in line coding. // Though maybe the baudrate is not really important !!! - if ( ep_addr == p_cdc->ep_in ) - { + if (ep_addr == p_cdc->ep_in) { // invoke transmit callback to possibly refill tx fifo - if ( tud_cdc_tx_complete_cb ) tud_cdc_tx_complete_cb(itf); + if (tud_cdc_tx_complete_cb) tud_cdc_tx_complete_cb(itf); - if ( 0 == tud_cdc_n_write_flush(itf) ) - { + if (0 == tud_cdc_n_write_flush(itf)) { // If there is no data left, a ZLP should be sent if // xferred_bytes is multiple of EP Packet size and not zero - if ( !tu_fifo_count(&p_cdc->tx_ff) && xferred_bytes && (0 == (xferred_bytes & (BULK_PACKET_SIZE-1))) ) - { - if ( usbd_edpt_claim(rhport, p_cdc->ep_in) ) - { + if (!tu_fifo_count(&p_cdc->tx_ff) && xferred_bytes && (0 == (xferred_bytes & (BULK_PACKET_SIZE - 1)))) { + if (usbd_edpt_claim(rhport, p_cdc->ep_in)) { usbd_edpt_xfer(rhport, p_cdc->ep_in, NULL, 0); } } diff --git a/src/class/cdc/cdc_device.h b/src/class/cdc/cdc_device.h index db709b3bc..5c2d07c5b 100644 --- a/src/class/cdc/cdc_device.h +++ b/src/class/cdc/cdc_device.h @@ -24,8 +24,8 @@ * This file is part of the TinyUSB stack. */ -#ifndef _TUSB_CDC_DEVICE_H_ -#define _TUSB_CDC_DEVICE_H_ +#ifndef TUSB_CDC_DEVICE_H_ +#define TUSB_CDC_DEVICE_H_ #include "cdc.h" @@ -41,213 +41,162 @@ #define CFG_TUD_CDC_EP_BUFSIZE (TUD_OPT_HIGH_SPEED ? 512 : 64) #endif -// By default the TX fifo buffer is cleared on connect / bus reset. -// Enable this to persist any data in the fifo instead. -#ifndef CFG_TUD_CDC_PERSISTENT_TX_BUFF - #define CFG_TUD_CDC_PERSISTENT_TX_BUFF (0) -#endif - #ifdef __cplusplus extern "C" { #endif -/** \addtogroup CDC_Serial Serial - * @{ - * \defgroup CDC_Serial_Device Device - * @{ */ +//--------------------------------------------------------------------+ +// Driver Configuration +//--------------------------------------------------------------------+ + +typedef struct TU_ATTR_PACKED { + uint8_t rx_persistent : 1; // keep rx fifo on bus reset or disconnect + uint8_t tx_persistent : 1; // keep tx fifo on bus reset or disconnect +} tud_cdc_configure_fifo_t; + +// Configure CDC FIFOs behavior +bool tud_cdc_configure_fifo(tud_cdc_configure_fifo_t const* cfg); //--------------------------------------------------------------------+ -// Application API (Multiple Ports) -// CFG_TUD_CDC > 1 +// Application API (Multiple Ports) i.e CFG_TUD_CDC > 1 //--------------------------------------------------------------------+ // Check if terminal is connected to this port -bool tud_cdc_n_connected (uint8_t itf); +bool tud_cdc_n_connected(uint8_t itf); // Get current line state. Bit 0: DTR (Data Terminal Ready), Bit 1: RTS (Request to Send) -uint8_t tud_cdc_n_get_line_state (uint8_t itf); +uint8_t tud_cdc_n_get_line_state(uint8_t itf); // Get current line encoding: bit rate, stop bits parity etc .. -void tud_cdc_n_get_line_coding (uint8_t itf, cdc_line_coding_t* coding); +void tud_cdc_n_get_line_coding(uint8_t itf, cdc_line_coding_t* coding); // Set special character that will trigger tud_cdc_rx_wanted_cb() callback on receiving -void tud_cdc_n_set_wanted_char (uint8_t itf, char wanted); +void tud_cdc_n_set_wanted_char(uint8_t itf, char wanted); // Get the number of bytes available for reading -uint32_t tud_cdc_n_available (uint8_t itf); +uint32_t tud_cdc_n_available(uint8_t itf); // Read received bytes -uint32_t tud_cdc_n_read (uint8_t itf, void* buffer, uint32_t bufsize); +uint32_t tud_cdc_n_read(uint8_t itf, void* buffer, uint32_t bufsize); // Read a byte, return -1 if there is none -static inline -int32_t tud_cdc_n_read_char (uint8_t itf); +TU_ATTR_ALWAYS_INLINE static inline int32_t tud_cdc_n_read_char(uint8_t itf) { + uint8_t ch; + return tud_cdc_n_read(itf, &ch, 1) ? (int32_t) ch : -1; +} // Clear the received FIFO -void tud_cdc_n_read_flush (uint8_t itf); +void tud_cdc_n_read_flush(uint8_t itf); // Get a byte from FIFO without removing it -bool tud_cdc_n_peek (uint8_t itf, uint8_t* ui8); +bool tud_cdc_n_peek(uint8_t itf, uint8_t* ui8); // Write bytes to TX FIFO, data may remain in the FIFO for a while -uint32_t tud_cdc_n_write (uint8_t itf, void const* buffer, uint32_t bufsize); +uint32_t tud_cdc_n_write(uint8_t itf, void const* buffer, uint32_t bufsize); // Write a byte -static inline -uint32_t tud_cdc_n_write_char (uint8_t itf, char ch); +TU_ATTR_ALWAYS_INLINE static inline uint32_t tud_cdc_n_write_char(uint8_t itf, char ch) { + return tud_cdc_n_write(itf, &ch, 1); +} // Write a null-terminated string -static inline -uint32_t tud_cdc_n_write_str (uint8_t itf, char const* str); +TU_ATTR_ALWAYS_INLINE static inline uint32_t tud_cdc_n_write_str(uint8_t itf, char const* str) { + return tud_cdc_n_write(itf, str, strlen(str)); +} // Force sending data if possible, return number of forced bytes -uint32_t tud_cdc_n_write_flush (uint8_t itf); +uint32_t tud_cdc_n_write_flush(uint8_t itf); // Return the number of bytes (characters) available for writing to TX FIFO buffer in a single n_write operation. -uint32_t tud_cdc_n_write_available (uint8_t itf); +uint32_t tud_cdc_n_write_available(uint8_t itf); // Clear the transmit FIFO -bool tud_cdc_n_write_clear (uint8_t itf); +bool tud_cdc_n_write_clear(uint8_t itf); //--------------------------------------------------------------------+ // Application API (Single Port) //--------------------------------------------------------------------+ -static inline bool tud_cdc_connected (void); -static inline uint8_t tud_cdc_get_line_state (void); -static inline void tud_cdc_get_line_coding (cdc_line_coding_t* coding); -static inline void tud_cdc_set_wanted_char (char wanted); - -static inline uint32_t tud_cdc_available (void); -static inline int32_t tud_cdc_read_char (void); -static inline uint32_t tud_cdc_read (void* buffer, uint32_t bufsize); -static inline void tud_cdc_read_flush (void); -static inline bool tud_cdc_peek (uint8_t* ui8); - -static inline uint32_t tud_cdc_write_char (char ch); -static inline uint32_t tud_cdc_write (void const* buffer, uint32_t bufsize); -static inline uint32_t tud_cdc_write_str (char const* str); -static inline uint32_t tud_cdc_write_flush (void); -static inline uint32_t tud_cdc_write_available (void); -static inline bool tud_cdc_write_clear (void); - -//--------------------------------------------------------------------+ -// Application Callback API (weak is optional) -//--------------------------------------------------------------------+ - -// Invoked when received new data -TU_ATTR_WEAK void tud_cdc_rx_cb(uint8_t itf); - -// Invoked when received `wanted_char` -TU_ATTR_WEAK void tud_cdc_rx_wanted_cb(uint8_t itf, char wanted_char); - -// Invoked when a TX is complete and therefore space becomes available in TX buffer -TU_ATTR_WEAK void tud_cdc_tx_complete_cb(uint8_t itf); - -// Invoked when line state DTR & RTS are changed via SET_CONTROL_LINE_STATE -TU_ATTR_WEAK void tud_cdc_line_state_cb(uint8_t itf, bool dtr, bool rts); - -// Invoked when line coding is change via SET_LINE_CODING -TU_ATTR_WEAK void tud_cdc_line_coding_cb(uint8_t itf, cdc_line_coding_t const* p_line_coding); - -// Invoked when received send break -TU_ATTR_WEAK void tud_cdc_send_break_cb(uint8_t itf, uint16_t duration_ms); - -//--------------------------------------------------------------------+ -// Inline Functions -//--------------------------------------------------------------------+ -static inline int32_t tud_cdc_n_read_char (uint8_t itf) -{ - uint8_t ch; - return tud_cdc_n_read(itf, &ch, 1) ? (int32_t) ch : -1; -} - -static inline uint32_t tud_cdc_n_write_char(uint8_t itf, char ch) -{ - return tud_cdc_n_write(itf, &ch, 1); -} - -static inline uint32_t tud_cdc_n_write_str (uint8_t itf, char const* str) -{ - return tud_cdc_n_write(itf, str, strlen(str)); -} - -static inline bool tud_cdc_connected (void) -{ +TU_ATTR_ALWAYS_INLINE static inline bool tud_cdc_connected(void) { return tud_cdc_n_connected(0); } -static inline uint8_t tud_cdc_get_line_state (void) -{ +TU_ATTR_ALWAYS_INLINE static inline uint8_t tud_cdc_get_line_state(void) { return tud_cdc_n_get_line_state(0); } -static inline void tud_cdc_get_line_coding (cdc_line_coding_t* coding) -{ +TU_ATTR_ALWAYS_INLINE static inline void tud_cdc_get_line_coding(cdc_line_coding_t* coding) { tud_cdc_n_get_line_coding(0, coding); } -static inline void tud_cdc_set_wanted_char (char wanted) -{ +TU_ATTR_ALWAYS_INLINE static inline void tud_cdc_set_wanted_char(char wanted) { tud_cdc_n_set_wanted_char(0, wanted); } -static inline uint32_t tud_cdc_available (void) -{ +TU_ATTR_ALWAYS_INLINE static inline uint32_t tud_cdc_available(void) { return tud_cdc_n_available(0); } -static inline int32_t tud_cdc_read_char (void) -{ +TU_ATTR_ALWAYS_INLINE static inline int32_t tud_cdc_read_char(void) { return tud_cdc_n_read_char(0); } -static inline uint32_t tud_cdc_read (void* buffer, uint32_t bufsize) -{ +TU_ATTR_ALWAYS_INLINE static inline uint32_t tud_cdc_read(void* buffer, uint32_t bufsize) { return tud_cdc_n_read(0, buffer, bufsize); } -static inline void tud_cdc_read_flush (void) -{ +TU_ATTR_ALWAYS_INLINE static inline void tud_cdc_read_flush(void) { tud_cdc_n_read_flush(0); } -static inline bool tud_cdc_peek (uint8_t* ui8) -{ +TU_ATTR_ALWAYS_INLINE static inline bool tud_cdc_peek(uint8_t* ui8) { return tud_cdc_n_peek(0, ui8); } -static inline uint32_t tud_cdc_write_char (char ch) -{ +TU_ATTR_ALWAYS_INLINE static inline uint32_t tud_cdc_write_char(char ch) { return tud_cdc_n_write_char(0, ch); } -static inline uint32_t tud_cdc_write (void const* buffer, uint32_t bufsize) -{ +TU_ATTR_ALWAYS_INLINE static inline uint32_t tud_cdc_write(void const* buffer, uint32_t bufsize) { return tud_cdc_n_write(0, buffer, bufsize); } -static inline uint32_t tud_cdc_write_str (char const* str) -{ +TU_ATTR_ALWAYS_INLINE static inline uint32_t tud_cdc_write_str(char const* str) { return tud_cdc_n_write_str(0, str); } -static inline uint32_t tud_cdc_write_flush (void) -{ +TU_ATTR_ALWAYS_INLINE static inline uint32_t tud_cdc_write_flush(void) { return tud_cdc_n_write_flush(0); } -static inline uint32_t tud_cdc_write_available(void) -{ +TU_ATTR_ALWAYS_INLINE static inline uint32_t tud_cdc_write_available(void) { return tud_cdc_n_write_available(0); } -static inline bool tud_cdc_write_clear(void) -{ +TU_ATTR_ALWAYS_INLINE static inline bool tud_cdc_write_clear(void) { return tud_cdc_n_write_clear(0); } -/** @} */ -/** @} */ +//--------------------------------------------------------------------+ +// Application Callback API (weak is optional) +//--------------------------------------------------------------------+ + +// Invoked when received new data +TU_ATTR_WEAK void tud_cdc_rx_cb(uint8_t itf); + +// Invoked when received `wanted_char` +TU_ATTR_WEAK void tud_cdc_rx_wanted_cb(uint8_t itf, char wanted_char); + +// Invoked when a TX is complete and therefore space becomes available in TX buffer +TU_ATTR_WEAK void tud_cdc_tx_complete_cb(uint8_t itf); + +// Invoked when line state DTR & RTS are changed via SET_CONTROL_LINE_STATE +TU_ATTR_WEAK void tud_cdc_line_state_cb(uint8_t itf, bool dtr, bool rts); + +// Invoked when line coding is change via SET_LINE_CODING +TU_ATTR_WEAK void tud_cdc_line_coding_cb(uint8_t itf, cdc_line_coding_t const* p_line_coding); + +// Invoked when received send break +TU_ATTR_WEAK void tud_cdc_send_break_cb(uint8_t itf, uint16_t duration_ms); //--------------------------------------------------------------------+ // INTERNAL USBD-CLASS DRIVER API -- cgit v1.3.1 From 4ce1cce40a01dce56cab2c73745f4f2c9d212b25 Mon Sep 17 00:00:00 2001 From: hathach Date: Fri, 12 Jul 2024 20:17:14 +0700 Subject: simplify dwc2 test mode - all dwc2 ip seems to support test mode in both fs/hs -> remove TUP_USBIP_DWC2_TEST_MODE - remove dcd_check_test_mode_support(), all should be supported - move enum tusb_feature_test_mode_t to tusb_types.h --- src/common/tusb_mcu.h | 3 -- src/common/tusb_types.h | 9 ++++++ src/device/dcd.h | 13 +------- src/device/usbd.c | 56 +++++++++++------------------------ src/portable/synopsys/dwc2/dcd_dwc2.c | 20 +++---------- src/tusb_option.h | 2 +- 6 files changed, 32 insertions(+), 71 deletions(-) (limited to 'src') diff --git a/src/common/tusb_mcu.h b/src/common/tusb_mcu.h index 80826c895..637281bfc 100644 --- a/src/common/tusb_mcu.h +++ b/src/common/tusb_mcu.h @@ -195,7 +195,6 @@ #elif TU_CHECK_MCU(OPT_MCU_STM32F4) #define TUP_USBIP_DWC2 #define TUP_USBIP_DWC2_STM32 - #define TUP_USBIP_DWC2_TEST_MODE // For most mcu, FS has 4, HS has 6. TODO 446/469/479 HS has 9 #define TUP_DCD_ENDPOINT_MAX 6 @@ -210,7 +209,6 @@ // MCU with on-chip HS Phy #if defined(STM32F723xx) || defined(STM32F730xx) || defined(STM32F733xx) #define TUP_RHPORT_HIGHSPEED 1 // Port0: FS, Port1: HS - #define TUP_USBIP_DWC2_TEST_MODE #endif #elif TU_CHECK_MCU(OPT_MCU_STM32H7) @@ -285,7 +283,6 @@ defined(STM32U5F7xx) || defined(STM32U5F9xx) || defined(STM32U5G7xx) || defined(STM32U5G9xx) #define TUP_DCD_ENDPOINT_MAX 9 #define TUP_RHPORT_HIGHSPEED 1 - #define TUP_USBIP_DWC2_TEST_MODE #else #define TUP_DCD_ENDPOINT_MAX 6 #endif diff --git a/src/common/tusb_types.h b/src/common/tusb_types.h index b571f9b72..1501a5af6 100644 --- a/src/common/tusb_types.h +++ b/src/common/tusb_types.h @@ -214,6 +214,15 @@ enum { #define TUSB_DESC_CONFIG_POWER_MA(x) ((x)/2) +// USB 2.0 Spec Table 9-7: Test Mode Selectors +typedef enum { + TUSB_FEATURE_TEST_J = 1, + TUSB_FEATURE_TEST_K, + TUSB_FEATURE_TEST_SE0_NAK, + TUSB_FEATURE_TEST_PACKET, + TUSB_FEATURE_TEST_FORCE_ENABLE, +} tusb_feature_test_mode_t; + //--------------------------------------------------------------------+ // //--------------------------------------------------------------------+ diff --git a/src/device/dcd.h b/src/device/dcd.h index f6735b077..5356e9be1 100644 --- a/src/device/dcd.h +++ b/src/device/dcd.h @@ -89,14 +89,6 @@ typedef struct TU_ATTR_ALIGNED(4) { }; } dcd_event_t; -typedef enum { - TEST_J = 1, - TEST_K, - TEST_SE0_NAK, - TEST_PACKET, - TEST_FORCE_ENABLE, -} test_mode_t; - //TU_VERIFY_STATIC(sizeof(dcd_event_t) <= 12, "size is not correct"); //--------------------------------------------------------------------+ @@ -150,11 +142,8 @@ void dcd_disconnect(uint8_t rhport); void dcd_sof_enable(uint8_t rhport, bool en); #if CFG_TUD_TEST_MODE -// Check if the test mode is supported, returns true is test mode selector is supported -bool dcd_check_test_mode_support(test_mode_t test_selector) TU_ATTR_WEAK; - // Put device into a test mode (needs power cycle to quit) -void dcd_enter_test_mode(uint8_t rhport, test_mode_t test_selector) TU_ATTR_WEAK; +void dcd_enter_test_mode(uint8_t rhport, tusb_feature_test_mode_t test_selector); #endif //--------------------------------------------------------------------+ // Endpoint API diff --git a/src/device/usbd.c b/src/device/usbd.c index 800d9c824..4105a71a4 100644 --- a/src/device/usbd.c +++ b/src/device/usbd.c @@ -321,9 +321,17 @@ TU_ATTR_ALWAYS_INLINE static inline bool queue_event(dcd_event_t const * event, static bool process_control_request(uint8_t rhport, tusb_control_request_t const * p_request); static bool process_set_config(uint8_t rhport, uint8_t cfg_num); static bool process_get_descriptor(uint8_t rhport, tusb_control_request_t const * p_request); + #if CFG_TUD_TEST_MODE -static bool process_test_mode_cb(uint8_t rhport, uint8_t stage, tusb_control_request_t const * request); +static bool process_test_mode_cb(uint8_t rhport, uint8_t stage, tusb_control_request_t const * request) { + TU_VERIFY(CONTROL_STAGE_ACK == stage); + uint8_t const selector = tu_u16_high(request->wIndex); + TU_LOG_USBD(" Enter Test Mode (test selector index: %d)\r\n", selector); + dcd_enter_test_mode(rhport, (tusb_feature_test_mode_t) selector); + return true; +} #endif + // from usbd_control.c void usbd_control_reset(void); void usbd_control_set_request(tusb_control_request_t const *request); @@ -695,7 +703,7 @@ static bool process_control_request(uint8_t rhport, tusb_control_request_t const } if ( TUSB_REQ_TYPE_STANDARD != p_request->bmRequestType_bit.type ) { - // Non standard request is not supported + // Non-standard request is not supported TU_BREAKPOINT(); return false; } @@ -759,43 +767,27 @@ static bool process_control_request(uint8_t rhport, tusb_control_request_t const break; case TUSB_REQ_SET_FEATURE: - // Handle the feature selector - switch(p_request->wValue) - { - // Support for remote wakeup + switch(p_request->wValue) { case TUSB_REQ_FEATURE_REMOTE_WAKEUP: TU_LOG_USBD(" Enable Remote Wakeup\r\n"); - // Host may enable remote wake up before suspending especially HID device _usbd_dev.remote_wakeup_en = true; tud_control_status(rhport, p_request); break; -#if CFG_TUD_TEST_MODE - // Support for TEST_MODE + #if CFG_TUD_TEST_MODE case TUSB_REQ_FEATURE_TEST_MODE: { // Only handle the test mode if supported and valid - TU_VERIFY(dcd_enter_test_mode && dcd_check_test_mode_support && 0 == tu_u16_low(p_request->wIndex)); - - uint8_t selector = tu_u16_high(p_request->wIndex); - - // Stall request if the selected test mode isn't supported - if (!dcd_check_test_mode_support((test_mode_t)selector)) - { - TU_LOG_USBD(" Unsupported Test Mode (test selector index: %d)\r\n", selector); + TU_VERIFY(0 == tu_u16_low(p_request->wIndex)); - return false; - } - - // Acknowledge request - tud_control_status(rhport, p_request); - - TU_LOG_USBD(" Enter Test Mode (test selector index: %d)\r\n", selector); + uint8_t const selector = tu_u16_high(p_request->wIndex); + TU_VERIFY(TUSB_FEATURE_TEST_J <= selector && selector <= TUSB_FEATURE_TEST_FORCE_ENABLE); usbd_control_set_complete_callback(process_test_mode_cb); + tud_control_status(rhport, p_request); break; } -#endif /* CFG_TUD_TEST_MODE */ + #endif /* CFG_TUD_TEST_MODE */ // Stall unsupported feature selector default: return false; @@ -1127,20 +1119,6 @@ static bool process_get_descriptor(uint8_t rhport, tusb_control_request_t const } } -#if CFG_TUD_TEST_MODE -static bool process_test_mode_cb(uint8_t rhport, uint8_t stage, tusb_control_request_t const * request) -{ - // At this point it should already be ensured that dcd_enter_test_mode() is defined - - // Only enter the test mode after the request for it has completed - TU_VERIFY(CONTROL_STAGE_ACK == stage); - - dcd_enter_test_mode(rhport, (test_mode_t)tu_u16_high(request->wIndex)); - - return true; -} -#endif /* CFG_TUD_TEST_MODE */ - //--------------------------------------------------------------------+ // DCD Event Handler //--------------------------------------------------------------------+ diff --git a/src/portable/synopsys/dwc2/dcd_dwc2.c b/src/portable/synopsys/dwc2/dcd_dwc2.c index dbcd586c5..9a38b46dc 100644 --- a/src/portable/synopsys/dwc2/dcd_dwc2.c +++ b/src/portable/synopsys/dwc2/dcd_dwc2.c @@ -1195,25 +1195,13 @@ void dcd_int_handler(uint8_t rhport) { // } } -#if defined(TUP_USBIP_DWC2_TEST_MODE) && CFG_TUD_TEST_MODE - -bool dcd_check_test_mode_support(test_mode_t test_selector) { - // Check if test mode selector is unsupported - if (TEST_FORCE_ENABLE < test_selector || TEST_J > test_selector) { - return false; - } - - return true; -} - -void dcd_enter_test_mode(uint8_t rhport, test_mode_t test_selector) { - // Get port address... +#if CFG_TUD_TEST_MODE +void dcd_enter_test_mode(uint8_t rhport, tusb_feature_test_mode_t test_selector) { dwc2_regs_t* dwc2 = DWC2_REG(rhport); // Enable the test mode - dwc2->dctl = (dwc2->dctl & ~DCTL_TCTL_Msk) | (test_selector << DCTL_TCTL_Pos); + dwc2->dctl = (dwc2->dctl & ~DCTL_TCTL_Msk) | (((uint8_t) test_selector) << DCTL_TCTL_Pos); } - -#endif /* TUP_USBIP_DWC2_TEST_MODE && CFG_TUD_TEST_MODE */ +#endif #endif diff --git a/src/tusb_option.h b/src/tusb_option.h index 8990cf92b..f2cc284dc 100644 --- a/src/tusb_option.h +++ b/src/tusb_option.h @@ -381,7 +381,7 @@ #error "CFG_TUD_ENDPPOINT_MAX must be less than or equal to TUP_DCD_ENDPOINT_MAX" #endif -// USB 2.0 compliance test mode support +// USB 2.0 7.1.20: compliance test mode support #ifndef CFG_TUD_TEST_MODE #define CFG_TUD_TEST_MODE 0 #endif -- cgit v1.3.1 From 0ecf15bc61b2684e53250437d295d6c43682a724 Mon Sep 17 00:00:00 2001 From: hathach Date: Wed, 17 Jul 2024 14:35:23 +0700 Subject: follow up to #2253 - rename tud_hid_report_fail_cb() to tud_hid_report_failed_cb() and change its signature - use default implementation for hid callbacks to be compatible with keil compiler - code format --- src/class/cdc/cdc_device.h | 2 +- src/class/hid/hid_device.c | 268 +++++++++++++++++++++++---------------------- src/class/hid/hid_device.h | 106 +++++++----------- 3 files changed, 180 insertions(+), 196 deletions(-) (limited to 'src') diff --git a/src/class/cdc/cdc_device.h b/src/class/cdc/cdc_device.h index 5c2d07c5b..34670517a 100644 --- a/src/class/cdc/cdc_device.h +++ b/src/class/cdc/cdc_device.h @@ -58,7 +58,7 @@ typedef struct TU_ATTR_PACKED { bool tud_cdc_configure_fifo(tud_cdc_configure_fifo_t const* cfg); //--------------------------------------------------------------------+ -// Application API (Multiple Ports) i.e CFG_TUD_CDC > 1 +// Application API (Multiple Ports) i.e. CFG_TUD_CDC > 1 //--------------------------------------------------------------------+ // Check if terminal is connected to this port diff --git a/src/class/hid/hid_device.c b/src/class/hid/hid_device.c index ada01582e..7168ab3d5 100644 --- a/src/class/hid/hid_device.c +++ b/src/class/hid/hid_device.c @@ -61,28 +61,53 @@ typedef struct { CFG_TUD_MEM_SECTION tu_static hidd_interface_t _hidd_itf[CFG_TUD_HID]; /*------------- Helpers -------------*/ -static inline uint8_t get_index_by_itfnum(uint8_t itf_num) -{ +TU_ATTR_ALWAYS_INLINE static inline uint8_t get_index_by_itfnum(uint8_t itf_num) { for (uint8_t i = 0; i < CFG_TUD_HID; i++) { - if (itf_num == _hidd_itf[i].itf_num) + if (itf_num == _hidd_itf[i].itf_num) { return i; + } } - return 0xFF; } +//--------------------------------------------------------------------+ +// Weak stubs: invoked if no strong implementation is available +//--------------------------------------------------------------------+ +TU_ATTR_WEAK void tud_hid_set_protocol_cb(uint8_t instance, uint8_t protocol) { + (void) instance; + (void) protocol; +} + +TU_ATTR_WEAK bool tud_hid_set_idle_cb(uint8_t instance, uint8_t idle_rate) { + (void) instance; + (void) idle_rate; + return true; +} + +TU_ATTR_WEAK void tud_hid_report_complete_cb(uint8_t instance, uint8_t const* report, uint16_t len) { + (void) instance; + (void) report; + (void) len; +} + +// Invoked when a transfer wasn't successful +TU_ATTR_WEAK void tud_hid_report_failed_cb(uint8_t instance, hid_report_type_t report_type, uint8_t const* report, uint16_t xferred_bytes) { + (void) instance; + (void) report_type; + (void) report; + (void) xferred_bytes; +} + //--------------------------------------------------------------------+ // APPLICATION API //--------------------------------------------------------------------+ -bool tud_hid_n_ready(uint8_t instance) -{ +bool tud_hid_n_ready(uint8_t instance) { uint8_t const rhport = 0; uint8_t const ep_in = _hidd_itf[instance].ep_in; return tud_ready() && (ep_in != 0) && !usbd_edpt_busy(rhport, ep_in); } -bool tud_hid_n_report(uint8_t instance, uint8_t report_id, void const *report, uint16_t len) -{ +bool tud_hid_n_report(uint8_t instance, uint8_t report_id, void const *report, uint16_t len) { uint8_t const rhport = 0; hidd_interface_t *p_hid = &_hidd_itf[instance]; @@ -101,14 +126,16 @@ bool tud_hid_n_report(uint8_t instance, uint8_t report_id, void const *report, u return usbd_edpt_xfer(rhport, p_hid->ep_in, p_hid->epin_buf, len); } -uint8_t tud_hid_n_interface_protocol(uint8_t instance) { return _hidd_itf[instance].itf_protocol; } +uint8_t tud_hid_n_interface_protocol(uint8_t instance) { + return _hidd_itf[instance].itf_protocol; +} -uint8_t tud_hid_n_get_protocol(uint8_t instance) { return _hidd_itf[instance].protocol_mode; } +uint8_t tud_hid_n_get_protocol(uint8_t instance) { + return _hidd_itf[instance].protocol_mode; +} -bool tud_hid_n_keyboard_report(uint8_t instance, uint8_t report_id, uint8_t modifier, uint8_t keycode[6]) -{ +bool tud_hid_n_keyboard_report(uint8_t instance, uint8_t report_id, uint8_t modifier, uint8_t keycode[6]) { hid_keyboard_report_t report; - report.modifier = modifier; report.reserved = 0; @@ -121,8 +148,8 @@ bool tud_hid_n_keyboard_report(uint8_t instance, uint8_t report_id, uint8_t modi return tud_hid_n_report(instance, report_id, &report, sizeof(report)); } -bool tud_hid_n_mouse_report(uint8_t instance, uint8_t report_id, uint8_t buttons, int8_t x, int8_t y, int8_t vertical, int8_t horizontal) -{ +bool tud_hid_n_mouse_report(uint8_t instance, uint8_t report_id, + uint8_t buttons, int8_t x, int8_t y, int8_t vertical, int8_t horizontal) { hid_mouse_report_t report = { .buttons = buttons, .x = x, @@ -134,8 +161,8 @@ bool tud_hid_n_mouse_report(uint8_t instance, uint8_t report_id, uint8_t buttons return tud_hid_n_report(instance, report_id, &report, sizeof(report)); } -bool tud_hid_n_abs_mouse_report(uint8_t instance, uint8_t report_id, uint8_t buttons, int16_t x, int16_t y, int8_t vertical, int8_t horizontal) -{ +bool tud_hid_n_abs_mouse_report(uint8_t instance, uint8_t report_id, + uint8_t buttons, int16_t x, int16_t y, int8_t vertical, int8_t horizontal) { hid_abs_mouse_report_t report = { .buttons = buttons, .x = x, @@ -146,8 +173,8 @@ bool tud_hid_n_abs_mouse_report(uint8_t instance, uint8_t report_id, uint8_t but return tud_hid_n_report(instance, report_id, &report, sizeof(report)); } -bool tud_hid_n_gamepad_report(uint8_t instance, uint8_t report_id, int8_t x, int8_t y, int8_t z, int8_t rz, int8_t rx, int8_t ry, uint8_t hat, uint32_t buttons) -{ +bool tud_hid_n_gamepad_report(uint8_t instance, uint8_t report_id, + int8_t x, int8_t y, int8_t z, int8_t rz, int8_t rx, int8_t ry, uint8_t hat, uint32_t buttons) { hid_gamepad_report_t report = { .x = x, .y = y, @@ -165,28 +192,25 @@ bool tud_hid_n_gamepad_report(uint8_t instance, uint8_t report_id, int8_t x, int //--------------------------------------------------------------------+ // USBD-CLASS API //--------------------------------------------------------------------+ -void hidd_init(void) -{ +void hidd_init(void) { hidd_reset(0); } -bool hidd_deinit(void) -{ +bool hidd_deinit(void) { return true; } -void hidd_reset(uint8_t rhport) -{ +void hidd_reset(uint8_t rhport) { (void)rhport; tu_memclr(_hidd_itf, sizeof(_hidd_itf)); } -uint16_t hidd_open(uint8_t rhport, tusb_desc_interface_t const *desc_itf, uint16_t max_len) -{ +uint16_t hidd_open(uint8_t rhport, tusb_desc_interface_t const *desc_itf, uint16_t max_len) { TU_VERIFY(TUSB_CLASS_HID == desc_itf->bInterfaceClass, 0); // len = interface + hid + n*endpoints - uint16_t const drv_len = (uint16_t)(sizeof(tusb_desc_interface_t) + sizeof(tusb_hid_descriptor_hid_t) + desc_itf->bNumEndpoints * sizeof(tusb_desc_endpoint_t)); + uint16_t const drv_len = (uint16_t) (sizeof(tusb_desc_interface_t) + sizeof(tusb_hid_descriptor_hid_t) + + desc_itf->bNumEndpoints * sizeof(tusb_desc_endpoint_t)); TU_ASSERT(max_len >= drv_len, 0); // Find available interface @@ -211,8 +235,9 @@ uint16_t hidd_open(uint8_t rhport, tusb_desc_interface_t const *desc_itf, uint16 p_desc = tu_desc_next(p_desc); TU_ASSERT(usbd_open_edpt_pair(rhport, p_desc, desc_itf->bNumEndpoints, TUSB_XFER_INTERRUPT, &p_hid->ep_out, &p_hid->ep_in), 0); - if (desc_itf->bInterfaceSubClass == HID_SUBCLASS_BOOT) + if (desc_itf->bInterfaceSubClass == HID_SUBCLASS_BOOT) { p_hid->itf_protocol = desc_itf->bInterfaceProtocol; + } p_hid->protocol_mode = HID_PROTOCOL_REPORT; // Per Specs: default is report mode p_hid->itf_num = desc_itf->bInterfaceNumber; @@ -234,8 +259,7 @@ uint16_t hidd_open(uint8_t rhport, tusb_desc_interface_t const *desc_itf, uint16 // Invoked when a control transfer occurred on an interface of this class // Driver response accordingly to the request and the transfer stage (setup/data/ack) // return false to stall control endpoint (e.g unsupported request) -bool hidd_control_xfer_cb(uint8_t rhport, uint8_t stage, tusb_control_request_t const *request) -{ +bool hidd_control_xfer_cb(uint8_t rhport, uint8_t stage, tusb_control_request_t const *request) { TU_VERIFY(request->bmRequestType_bit.recipient == TUSB_REQ_RCPT_INTERFACE); uint8_t const hid_itf = get_index_by_itfnum((uint8_t)request->wIndex); @@ -262,90 +286,82 @@ bool hidd_control_xfer_cb(uint8_t rhport, uint8_t stage, tusb_control_request_t } else if (request->bmRequestType_bit.type == TUSB_REQ_TYPE_CLASS) { //------------- Class Specific Request -------------// switch (request->bRequest) { - case HID_REQ_CONTROL_GET_REPORT: - if (stage == CONTROL_STAGE_SETUP) { - uint8_t const report_type = tu_u16_high(request->wValue); - uint8_t const report_id = tu_u16_low(request->wValue); - - uint8_t *report_buf = p_hid->ctrl_buf; - uint16_t req_len = tu_min16(request->wLength, CFG_TUD_HID_EP_BUFSIZE); - - uint16_t xferlen = 0; - - // If host request a specific Report ID, add ID to as 1 byte of response - if ((report_id != HID_REPORT_TYPE_INVALID) && (req_len > 1)) { - *report_buf++ = report_id; - req_len--; - - xferlen++; + case HID_REQ_CONTROL_GET_REPORT: + if (stage == CONTROL_STAGE_SETUP) { + uint8_t const report_type = tu_u16_high(request->wValue); + uint8_t const report_id = tu_u16_low(request->wValue); + + uint8_t* report_buf = p_hid->ctrl_buf; + uint16_t req_len = tu_min16(request->wLength, CFG_TUD_HID_EP_BUFSIZE); + uint16_t xferlen = 0; + + // If host request a specific Report ID, add ID to as 1 byte of response + if ((report_id != HID_REPORT_TYPE_INVALID) && (req_len > 1)) { + *report_buf++ = report_id; + req_len--; + xferlen++; + } + + xferlen += tud_hid_get_report_cb(hid_itf, report_id, (hid_report_type_t) report_type, report_buf, req_len); + TU_ASSERT(xferlen > 0); + + tud_control_xfer(rhport, request, p_hid->ctrl_buf, xferlen); } - - xferlen += tud_hid_get_report_cb(hid_itf, report_id, (hid_report_type_t)report_type, report_buf, req_len); - TU_ASSERT(xferlen > 0); - - tud_control_xfer(rhport, request, p_hid->ctrl_buf, xferlen); - } - break; - - case HID_REQ_CONTROL_SET_REPORT: - if (stage == CONTROL_STAGE_SETUP) { - TU_VERIFY(request->wLength <= sizeof(p_hid->ctrl_buf)); - tud_control_xfer(rhport, request, p_hid->ctrl_buf, request->wLength); - } else if (stage == CONTROL_STAGE_ACK) { - uint8_t const report_type = tu_u16_high(request->wValue); - uint8_t const report_id = tu_u16_low(request->wValue); - - uint8_t const *report_buf = p_hid->ctrl_buf; - uint16_t report_len = tu_min16(request->wLength, CFG_TUD_HID_EP_BUFSIZE); - - // If host request a specific Report ID, extract report ID in buffer before invoking callback - if ((report_id != HID_REPORT_TYPE_INVALID) && (report_len > 1) && (report_id == report_buf[0])) { - report_buf++; - report_len--; + break; + + case HID_REQ_CONTROL_SET_REPORT: + if (stage == CONTROL_STAGE_SETUP) { + TU_VERIFY(request->wLength <= sizeof(p_hid->ctrl_buf)); + tud_control_xfer(rhport, request, p_hid->ctrl_buf, request->wLength); + } else if (stage == CONTROL_STAGE_ACK) { + uint8_t const report_type = tu_u16_high(request->wValue); + uint8_t const report_id = tu_u16_low(request->wValue); + + uint8_t const* report_buf = p_hid->ctrl_buf; + uint16_t report_len = tu_min16(request->wLength, CFG_TUD_HID_EP_BUFSIZE); + + // If host request a specific Report ID, extract report ID in buffer before invoking callback + if ((report_id != HID_REPORT_TYPE_INVALID) && (report_len > 1) && (report_id == report_buf[0])) { + report_buf++; + report_len--; + } + + tud_hid_set_report_cb(hid_itf, report_id, (hid_report_type_t) report_type, report_buf, report_len); } + break; - tud_hid_set_report_cb(hid_itf, report_id, (hid_report_type_t)report_type, report_buf, report_len); - } - break; - - case HID_REQ_CONTROL_SET_IDLE: - if (stage == CONTROL_STAGE_SETUP) { - p_hid->idle_rate = tu_u16_high(request->wValue); - if (tud_hid_set_idle_cb) { - // stall request if callback return false - TU_VERIFY(tud_hid_set_idle_cb(hid_itf, p_hid->idle_rate)); + case HID_REQ_CONTROL_SET_IDLE: + if (stage == CONTROL_STAGE_SETUP) { + p_hid->idle_rate = tu_u16_high(request->wValue); + TU_VERIFY(tud_hid_set_idle_cb(hid_itf, p_hid->idle_rate)); // stall if false + tud_control_status(rhport, request); } + break; - tud_control_status(rhport, request); - } - break; - - case HID_REQ_CONTROL_GET_IDLE: - if (stage == CONTROL_STAGE_SETUP) { - // TODO idle rate of report - tud_control_xfer(rhport, request, &p_hid->idle_rate, 1); - } - break; + case HID_REQ_CONTROL_GET_IDLE: + if (stage == CONTROL_STAGE_SETUP) { + // TODO idle rate of report + tud_control_xfer(rhport, request, &p_hid->idle_rate, 1); + } + break; - case HID_REQ_CONTROL_GET_PROTOCOL: - if (stage == CONTROL_STAGE_SETUP) { - tud_control_xfer(rhport, request, &p_hid->protocol_mode, 1); - } - break; + case HID_REQ_CONTROL_GET_PROTOCOL: + if (stage == CONTROL_STAGE_SETUP) { + tud_control_xfer(rhport, request, &p_hid->protocol_mode, 1); + } + break; - case HID_REQ_CONTROL_SET_PROTOCOL: - if (stage == CONTROL_STAGE_SETUP) { - tud_control_status(rhport, request); - } else if (stage == CONTROL_STAGE_ACK) { - p_hid->protocol_mode = (uint8_t)request->wValue; - if (tud_hid_set_protocol_cb) { + case HID_REQ_CONTROL_SET_PROTOCOL: + if (stage == CONTROL_STAGE_SETUP) { + tud_control_status(rhport, request); + } else if (stage == CONTROL_STAGE_ACK) { + p_hid->protocol_mode = (uint8_t) request->wValue; tud_hid_set_protocol_cb(hid_itf, p_hid->protocol_mode); } - } - break; + break; - default: - return false; // stall unsupported request + default: + return false; // stall unsupported request } } else { return false; // stall unsupported request @@ -354,45 +370,35 @@ bool hidd_control_xfer_cb(uint8_t rhport, uint8_t stage, tusb_control_request_t return true; } -bool hidd_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t result, uint32_t xferred_bytes) -{ - (void)result; - +bool hidd_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t result, uint32_t xferred_bytes) { uint8_t instance = 0; hidd_interface_t *p_hid = _hidd_itf; // Identify which interface to use for (instance = 0; instance < CFG_TUD_HID; instance++) { p_hid = &_hidd_itf[instance]; - if ((ep_addr == p_hid->ep_out) || (ep_addr == p_hid->ep_in)) + if ((ep_addr == p_hid->ep_out) || (ep_addr == p_hid->ep_in)) { break; + } } TU_ASSERT(instance < CFG_TUD_HID); - // Check if there was a problem - if (XFER_RESULT_SUCCESS != result) { // Inform application about the issue - if (tud_hid_report_fail_cb) { - tud_hid_report_fail_cb(instance, ep_addr, (uint16_t)xferred_bytes); + if (ep_addr == p_hid->ep_in) { + // Input report + if (XFER_RESULT_SUCCESS == result) { + tud_hid_report_complete_cb(instance, p_hid->epin_buf, (uint16_t) xferred_bytes); + } else { + tud_hid_report_failed_cb(instance, HID_REPORT_TYPE_INPUT, p_hid->epin_buf, (uint16_t) xferred_bytes); } - - // Allow a new transfer to be received if issue happened on an OUT endpoint - if (ep_addr == p_hid->ep_out) { - // Prepare the OUT endpoint to be able to receive a new transfer - TU_ASSERT(usbd_edpt_xfer(rhport, p_hid->ep_out, p_hid->epout_buf, sizeof(p_hid->epout_buf))); + } else { + // Output report + if (XFER_RESULT_SUCCESS == result) { + tud_hid_set_report_cb(instance, 0, HID_REPORT_TYPE_OUTPUT, p_hid->epout_buf, (uint16_t)xferred_bytes); + } else { + tud_hid_report_failed_cb(instance, HID_REPORT_TYPE_OUTPUT, p_hid->epout_buf, (uint16_t) xferred_bytes); } - return true; - } - - // Sent report successfully - if (ep_addr == p_hid->ep_in) { - if (tud_hid_report_complete_cb) { - tud_hid_report_complete_cb(instance, p_hid->epin_buf, (uint16_t)xferred_bytes); - } - } - // Received report successfully - else if (ep_addr == p_hid->ep_out) { - tud_hid_set_report_cb(instance, 0, HID_REPORT_TYPE_OUTPUT, p_hid->epout_buf, (uint16_t)xferred_bytes); + // prepare for new transfer TU_ASSERT(usbd_edpt_xfer(rhport, p_hid->ep_out, p_hid->epout_buf, sizeof(p_hid->epout_buf))); } diff --git a/src/class/hid/hid_device.h b/src/class/hid/hid_device.h index fcbf161c4..89c28e061 100644 --- a/src/class/hid/hid_device.h +++ b/src/class/hid/hid_device.h @@ -24,8 +24,8 @@ * This file is part of the TinyUSB stack. */ -#ifndef _TUSB_HID_DEVICE_H_ -#define _TUSB_HID_DEVICE_H_ +#ifndef TUSB_HID_DEVICE_H_ +#define TUSB_HID_DEVICE_H_ #include "hid.h" @@ -48,8 +48,7 @@ #endif //--------------------------------------------------------------------+ -// Application API (Multiple Instances) -// CFG_TUD_HID > 1 +// Application API (Multiple Instances) i.e. CFG_TUD_HID > 1 //--------------------------------------------------------------------+ // Check if the interface is ready to use @@ -76,12 +75,6 @@ bool tud_hid_n_mouse_report(uint8_t instance, uint8_t report_id, uint8_t buttons // use template layout report as defined by hid_abs_mouse_report_t bool tud_hid_n_abs_mouse_report(uint8_t instance, uint8_t report_id, uint8_t buttons, int16_t x, int16_t y, int8_t vertical, int8_t horizontal); - -static inline bool tud_hid_abs_mouse_report(uint8_t report_id, uint8_t buttons, int16_t x, int16_t y, int8_t vertical, int8_t horizontal) -{ - return tud_hid_n_abs_mouse_report(0, report_id, buttons, x, y, vertical, horizontal); -} - // Gamepad: convenient helper to send gamepad report if application // use template layout report TUD_HID_REPORT_DESC_GAMEPAD bool tud_hid_n_gamepad_report(uint8_t instance, uint8_t report_id, int8_t x, int8_t y, int8_t z, int8_t rz, int8_t rx, int8_t ry, uint8_t hat, uint32_t buttons); @@ -89,16 +82,40 @@ bool tud_hid_n_gamepad_report(uint8_t instance, uint8_t report_id, int8_t x, int //--------------------------------------------------------------------+ // Application API (Single Port) //--------------------------------------------------------------------+ -static inline bool tud_hid_ready(void); -static inline uint8_t tud_hid_interface_protocol(void); -static inline uint8_t tud_hid_get_protocol(void); -static inline bool tud_hid_report(uint8_t report_id, void const* report, uint16_t len); -static inline bool tud_hid_keyboard_report(uint8_t report_id, uint8_t modifier, uint8_t keycode[6]); -static inline bool tud_hid_mouse_report(uint8_t report_id, uint8_t buttons, int8_t x, int8_t y, int8_t vertical, int8_t horizontal); -static inline bool tud_hid_gamepad_report(uint8_t report_id, int8_t x, int8_t y, int8_t z, int8_t rz, int8_t rx, int8_t ry, uint8_t hat, uint32_t buttons); +TU_ATTR_ALWAYS_INLINE static inline bool tud_hid_ready(void) { + return tud_hid_n_ready(0); +} + +TU_ATTR_ALWAYS_INLINE static inline uint8_t tud_hid_interface_protocol(void) { + return tud_hid_n_interface_protocol(0); +} + +TU_ATTR_ALWAYS_INLINE static inline uint8_t tud_hid_get_protocol(void) { + return tud_hid_n_get_protocol(0); +} + +TU_ATTR_ALWAYS_INLINE static inline bool tud_hid_report(uint8_t report_id, void const* report, uint16_t len) { + return tud_hid_n_report(0, report_id, report, len); +} + +TU_ATTR_ALWAYS_INLINE static inline bool tud_hid_keyboard_report(uint8_t report_id, uint8_t modifier, uint8_t keycode[6]) { + return tud_hid_n_keyboard_report(0, report_id, modifier, keycode); +} + +TU_ATTR_ALWAYS_INLINE static inline bool tud_hid_mouse_report(uint8_t report_id, uint8_t buttons, int8_t x, int8_t y, int8_t vertical, int8_t horizontal) { + return tud_hid_n_mouse_report(0, report_id, buttons, x, y, vertical, horizontal); +} + +TU_ATTR_ALWAYS_INLINE static inline bool tud_hid_abs_mouse_report(uint8_t report_id, uint8_t buttons, int16_t x, int16_t y, int8_t vertical, int8_t horizontal) { + return tud_hid_n_abs_mouse_report(0, report_id, buttons, x, y, vertical, horizontal); +} + +TU_ATTR_ALWAYS_INLINE static inline bool tud_hid_gamepad_report(uint8_t report_id, int8_t x, int8_t y, int8_t z, int8_t rz, int8_t rx, int8_t ry, uint8_t hat, uint32_t buttons) { + return tud_hid_n_gamepad_report(0, report_id, x, y, z, rz, rx, ry, hat, buttons); +} //--------------------------------------------------------------------+ -// Callbacks (Weak is optional) +// Application Callbacks //--------------------------------------------------------------------+ // Invoked when received GET HID REPORT DESCRIPTOR request @@ -111,63 +128,25 @@ uint8_t const * tud_hid_descriptor_report_cb(uint8_t instance); uint16_t tud_hid_get_report_cb(uint8_t instance, uint8_t report_id, hid_report_type_t report_type, uint8_t* buffer, uint16_t reqlen); // Invoked when received SET_REPORT control request or -// received data on OUT endpoint ( Report ID = 0, Type = 0 ) +// received data on OUT endpoint (Report ID = 0, Type = OUTPUT) void tud_hid_set_report_cb(uint8_t instance, uint8_t report_id, hid_report_type_t report_type, uint8_t const* buffer, uint16_t bufsize); // Invoked when received SET_PROTOCOL request // protocol is either HID_PROTOCOL_BOOT (0) or HID_PROTOCOL_REPORT (1) -TU_ATTR_WEAK void tud_hid_set_protocol_cb(uint8_t instance, uint8_t protocol); +void tud_hid_set_protocol_cb(uint8_t instance, uint8_t protocol); // Invoked when received SET_IDLE request. return false will stall the request -// - Idle Rate = 0 : only send report if there is changes, i.e skip duplication +// - Idle Rate = 0 : only send report if there is changes, i.e. skip duplication // - Idle Rate > 0 : skip duplication, but send at least 1 report every idle rate (in unit of 4 ms). -TU_ATTR_WEAK bool tud_hid_set_idle_cb(uint8_t instance, uint8_t idle_rate); +bool tud_hid_set_idle_cb(uint8_t instance, uint8_t idle_rate); // Invoked when sent REPORT successfully to host // Application can use this to send the next report // Note: For composite reports, report[0] is report ID -TU_ATTR_WEAK void tud_hid_report_complete_cb(uint8_t instance, uint8_t const* report, uint16_t len); +void tud_hid_report_complete_cb(uint8_t instance, uint8_t const* report, uint16_t len); // Invoked when a transfer wasn't successful -TU_ATTR_WEAK void tud_hid_report_fail_cb(uint8_t instance, uint8_t ep_addr, uint16_t len); - -//--------------------------------------------------------------------+ -// Inline Functions -//--------------------------------------------------------------------+ -static inline bool tud_hid_ready(void) -{ - return tud_hid_n_ready(0); -} - -static inline uint8_t tud_hid_interface_protocol(void) -{ - return tud_hid_n_interface_protocol(0); -} - -static inline uint8_t tud_hid_get_protocol(void) -{ - return tud_hid_n_get_protocol(0); -} - -static inline bool tud_hid_report(uint8_t report_id, void const* report, uint16_t len) -{ - return tud_hid_n_report(0, report_id, report, len); -} - -static inline bool tud_hid_keyboard_report(uint8_t report_id, uint8_t modifier, uint8_t keycode[6]) -{ - return tud_hid_n_keyboard_report(0, report_id, modifier, keycode); -} - -static inline bool tud_hid_mouse_report(uint8_t report_id, uint8_t buttons, int8_t x, int8_t y, int8_t vertical, int8_t horizontal) -{ - return tud_hid_n_mouse_report(0, report_id, buttons, x, y, vertical, horizontal); -} - -static inline bool tud_hid_gamepad_report(uint8_t report_id, int8_t x, int8_t y, int8_t z, int8_t rz, int8_t rx, int8_t ry, uint8_t hat, uint32_t buttons) -{ - return tud_hid_n_gamepad_report(0, report_id, x, y, z, rz, rx, ry, hat, buttons); -} +void tud_hid_report_failed_cb(uint8_t instance, hid_report_type_t report_type, uint8_t const* report, uint16_t xferred_bytes); /* --------------------------------------------------------------------+ * HID Report Descriptor Template @@ -645,9 +624,8 @@ uint16_t hidd_open (uint8_t rhport, tusb_desc_interface_t const * itf bool hidd_control_xfer_cb (uint8_t rhport, uint8_t stage, tusb_control_request_t const * request); bool hidd_xfer_cb (uint8_t rhport, uint8_t ep_addr, xfer_result_t event, uint32_t xferred_bytes); - #ifdef __cplusplus } #endif -#endif /* _TUSB_HID_DEVICE_H_ */ +#endif -- cgit v1.3.1 From 0004faca83f3fa3128fa69b6f97ac711f30d2d20 Mon Sep 17 00:00:00 2001 From: hathach Date: Wed, 17 Jul 2024 19:29:21 +0700 Subject: minor update hid device --- src/class/hid/hid_device.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'src') diff --git a/src/class/hid/hid_device.c b/src/class/hid/hid_device.c index 7168ab3d5..00f6fc474 100644 --- a/src/class/hid/hid_device.c +++ b/src/class/hid/hid_device.c @@ -46,16 +46,16 @@ typedef struct { uint8_t itf_protocol; // Boot mouse or keyboard uint16_t report_desc_len; - CFG_TUSB_MEM_ALIGN uint8_t protocol_mode; // Boot (0) or Report protocol (1) - CFG_TUSB_MEM_ALIGN uint8_t idle_rate; // up to application to handle idle rate - - CFG_TUSB_MEM_ALIGN uint8_t epin_buf[CFG_TUD_HID_EP_BUFSIZE]; - CFG_TUSB_MEM_ALIGN uint8_t epout_buf[CFG_TUD_HID_EP_BUFSIZE]; - CFG_TUSB_MEM_ALIGN uint8_t ctrl_buf[CFG_TUD_HID_EP_BUFSIZE]; + uint8_t protocol_mode; // Boot (0) or Report protocol (1) + uint8_t idle_rate; // up to application to handle idle rate // TODO save hid descriptor since host can specifically request this after enumeration // Note: HID descriptor may be not available from application after enumeration tusb_hid_descriptor_hid_t const *hid_descriptor; + + uint8_t ctrl_buf[CFG_TUD_HID_EP_BUFSIZE]; + CFG_TUSB_MEM_ALIGN uint8_t epin_buf[CFG_TUD_HID_EP_BUFSIZE]; + CFG_TUSB_MEM_ALIGN uint8_t epout_buf[CFG_TUD_HID_EP_BUFSIZE]; } hidd_interface_t; CFG_TUD_MEM_SECTION tu_static hidd_interface_t _hidd_itf[CFG_TUD_HID]; -- cgit v1.3.1 From 770efd9b46db0f8723beebe4bfa4d6694bac2901 Mon Sep 17 00:00:00 2001 From: Liam Fraser Date: Wed, 17 Jul 2024 13:03:09 +0100 Subject: RP2040: Use our own unaligned memcpy to avoid alignment faults with some memcpy implementations --- src/portable/raspberrypi/rp2040/rp2040_usb.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/portable/raspberrypi/rp2040/rp2040_usb.c b/src/portable/raspberrypi/rp2040/rp2040_usb.c index 1ca711c77..c5d1ba3ce 100644 --- a/src/portable/raspberrypi/rp2040/rp2040_usb.c +++ b/src/portable/raspberrypi/rp2040/rp2040_usb.c @@ -53,6 +53,14 @@ TU_ATTR_ALWAYS_INLINE static inline bool is_host_mode(void) { //--------------------------------------------------------------------+ // Implementation //--------------------------------------------------------------------+ +// Provide own byte by byte memcpy as not all copies are aligned +static void unaligned_memcpy(void *dst, const void *src, size_t n) { + uint8_t *dst_byte = (uint8_t*)dst; + const uint8_t *src_byte = (const uint8_t*)src; + while (n--) { + *dst_byte++ = *src_byte++; + } +} void rp2040_usb_init(void) { // Reset usb controller @@ -125,7 +133,7 @@ static uint32_t __tusb_irq_path_func(prepare_ep_buffer)(struct hw_endpoint* ep, if (!ep->rx) { // Copy data from user buffer to hw buffer - memcpy(ep->hw_data_buf + buf_id * 64, ep->user_buf, buflen); + unaligned_memcpy(ep->hw_data_buf + buf_id * 64, ep->user_buf, buflen); ep->user_buf += buflen; // Mark as full @@ -230,7 +238,7 @@ static uint16_t __tusb_irq_path_func(sync_ep_buffer)(struct hw_endpoint* ep, uin // we have received AFTER we have copied it to the user buffer at the appropriate offset assert(buf_ctrl & USB_BUF_CTRL_FULL); - memcpy(ep->user_buf, ep->hw_data_buf + buf_id * 64, xferred_bytes); + unaligned_memcpy(ep->user_buf, ep->hw_data_buf + buf_id * 64, xferred_bytes); ep->xferred_len = (uint16_t) (ep->xferred_len + xferred_bytes); ep->user_buf += xferred_bytes; } -- cgit v1.3.1 From 3804ab9a67737732fe6bcc8e0b016ea00d47ff12 Mon Sep 17 00:00:00 2001 From: Liam Fraser Date: Wed, 17 Jul 2024 15:40:34 +0100 Subject: RP2040: no need to clear usb_hw (usb registers) as they are reset to default state by a hardware reset --- src/portable/raspberrypi/rp2040/rp2040_usb.c | 1 - 1 file changed, 1 deletion(-) (limited to 'src') diff --git a/src/portable/raspberrypi/rp2040/rp2040_usb.c b/src/portable/raspberrypi/rp2040/rp2040_usb.c index c5d1ba3ce..43f48da39 100644 --- a/src/portable/raspberrypi/rp2040/rp2040_usb.c +++ b/src/portable/raspberrypi/rp2040/rp2040_usb.c @@ -75,7 +75,6 @@ void rp2040_usb_init(void) { #pragma GCC diagnostic ignored "-Wstringop-overflow" #endif #endif - memset(usb_hw, 0, sizeof(*usb_hw)); memset(usb_dpram, 0, sizeof(*usb_dpram)); #ifdef __GNUC__ #pragma GCC diagnostic pop -- cgit v1.3.1 From 0d72f153cf1614aaff0b5859d00fb5c0e1711f51 Mon Sep 17 00:00:00 2001 From: graham sanderson Date: Wed, 17 Jul 2024 15:46:35 -0500 Subject: fix arguable bug caught as warning by LLVM embedded toolchain for ARM 14.0.0 --- src/tusb.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/tusb.c b/src/tusb.c index 0092267a1..860e8ac35 100644 --- a/src/tusb.c +++ b/src/tusb.c @@ -398,7 +398,7 @@ static void dump_str_line(uint8_t const* buf, uint16_t count) { tu_printf(" |"); // each line is 16 bytes for (uint16_t i = 0; i < count; i++) { - const char ch = buf[i]; + int ch = buf[i]; tu_printf("%c", isprint(ch) ? ch : '.'); } tu_printf("|\r\n"); -- cgit v1.3.1 From 31a979a6cccc2d4dc0a86474643710ae3b7f34fe Mon Sep 17 00:00:00 2001 From: graham sanderson Date: Wed, 17 Jul 2024 21:08:55 -0500 Subject: fix some clang compiler warnings --- examples/host/cdc_msc_hid/src/hid_app.c | 1 + examples/host/hid_controller/src/hid_app.c | 1 + src/class/hid/hid_host.c | 4 +++- 3 files changed, 5 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/examples/host/cdc_msc_hid/src/hid_app.c b/examples/host/cdc_msc_hid/src/hid_app.c index f0d42a08f..6bb3a2072 100644 --- a/examples/host/cdc_msc_hid/src/hid_app.c +++ b/examples/host/cdc_msc_hid/src/hid_app.c @@ -235,6 +235,7 @@ static void process_mouse_report(hid_mouse_report_t const * report) static void process_generic_report(uint8_t dev_addr, uint8_t instance, uint8_t const* report, uint16_t len) { (void) dev_addr; + (void) len; uint8_t const rpt_count = hid_info[instance].report_count; tuh_hid_report_info_t* rpt_info_arr = hid_info[instance].report_info; diff --git a/examples/host/hid_controller/src/hid_app.c b/examples/host/hid_controller/src/hid_app.c index bff830ca2..6ffe0b6d4 100644 --- a/examples/host/hid_controller/src/hid_app.c +++ b/examples/host/hid_controller/src/hid_app.c @@ -253,6 +253,7 @@ bool diff_report(sony_ds4_report_t const* rpt1, sony_ds4_report_t const* rpt2) void process_sony_ds4(uint8_t const* report, uint16_t len) { + (void)len; const char* dpad_str[] = { "N", "NE", "E", "SE", "S", "SW", "W", "NW", "none" }; // previous report used to compare for changes diff --git a/src/class/hid/hid_host.c b/src/class/hid/hid_host.c index 115a8a4df..7639a8fc6 100644 --- a/src/class/hid/hid_host.c +++ b/src/class/hid/hid_host.c @@ -657,7 +657,9 @@ uint8_t tuh_hid_parse_report_descriptor(tuh_hid_report_info_t* report_info_arr, uint8_t const data8 = desc_report[0]; TU_LOG(3, "tag = %d, type = %d, size = %d, data = ", tag, type, size); - for (uint32_t i = 0; i < size; i++) TU_LOG(3, "%02X ", desc_report[i]); + for (uint32_t i = 0; i < size; i++) { + TU_LOG(3, "%02X ", desc_report[i]); + } TU_LOG(3, "\r\n"); switch (type) { -- cgit v1.3.1 From ffe1d0664b6abe942c14ca540833e1e86a797184 Mon Sep 17 00:00:00 2001 From: HiFiPhile Date: Thu, 18 Jul 2024 20:02:57 +0200 Subject: UAC2: Fix memclr on driver reset. --- src/class/audio/audio_device.c | 94 ++++++++++++++++++++++-------------------- 1 file changed, 50 insertions(+), 44 deletions(-) (limited to 'src') diff --git a/src/class/audio/audio_device.c b/src/class/audio/audio_device.c index 65cac2fd5..ed380424f 100644 --- a/src/class/audio/audio_device.c +++ b/src/class/audio/audio_device.c @@ -304,19 +304,6 @@ typedef struct uint16_t desc_length; // Length of audio function descriptor - // Buffer for control requests - uint8_t * ctrl_buf; - uint8_t ctrl_buf_sz; - - // Current active alternate settings - uint8_t * alt_setting; // We need to save the current alternate setting this way, because it is possible that there are AS interfaces which do not have an EP! - - // EP Transfer buffers and FIFOs -#if CFG_TUD_AUDIO_ENABLE_EP_OUT -#if !CFG_TUD_AUDIO_ENABLE_DECODING - tu_fifo_t ep_out_ff; -#endif - #if CFG_TUD_AUDIO_ENABLE_FEEDBACK_EP struct { CFG_TUSB_MEM_ALIGN uint32_t value; // Feedback value for asynchronous mode (in 16.16 format). @@ -346,17 +333,6 @@ typedef struct } feedback; #endif // CFG_TUD_AUDIO_ENABLE_FEEDBACK_EP -#endif // CFG_TUD_AUDIO_ENABLE_EP_OUT - -#if CFG_TUD_AUDIO_ENABLE_EP_IN && !CFG_TUD_AUDIO_ENABLE_ENCODING - tu_fifo_t ep_in_ff; -#endif - - // Audio control interrupt buffer - no FIFO - 6 Bytes according to UAC 2 specification (p. 74) -#if CFG_TUD_AUDIO_ENABLE_INTERRUPT_EP - CFG_TUSB_MEM_ALIGN uint8_t ep_int_buf[6]; -#endif - // Decoding parameters - parameters are set when alternate AS interface is set by host // Coding is currently only supported for EP. Software coding corresponding to AS interfaces without EPs are not supported currently. #if CFG_TUD_AUDIO_ENABLE_EP_OUT && CFG_TUD_AUDIO_ENABLE_DECODING @@ -365,8 +341,7 @@ typedef struct #if CFG_TUD_AUDIO_ENABLE_TYPE_I_DECODING audio_data_format_type_I_t format_type_I_rx; - uint8_t n_bytes_per_sampe_rx; - uint8_t n_channels_per_ff_rx; + uint8_t n_bytes_per_sample_rx; uint8_t n_ff_used_rx; #endif #endif @@ -382,26 +357,57 @@ typedef struct #if CFG_TUD_AUDIO_ENABLE_EP_IN && (CFG_TUD_AUDIO_ENABLE_ENCODING || CFG_TUD_AUDIO_EP_IN_FLOW_CONTROL) audio_format_type_t format_type_tx; uint8_t n_channels_tx; - uint8_t n_bytes_per_sampe_tx; + uint8_t n_bytes_per_sample_tx; #if CFG_TUD_AUDIO_ENABLE_TYPE_I_ENCODING audio_data_format_type_I_t format_type_I_tx; - uint8_t n_channels_per_ff_tx; uint8_t n_ff_used_tx; #endif #endif + // Buffer for control requests + uint8_t * ctrl_buf; + uint8_t ctrl_buf_sz; + + // Current active alternate settings + uint8_t * alt_setting; // We need to save the current alternate setting this way, because it is possible that there are AS interfaces which do not have an EP! + + // EP Transfer buffers and FIFOs +#if CFG_TUD_AUDIO_ENABLE_EP_OUT +#if !CFG_TUD_AUDIO_ENABLE_DECODING + tu_fifo_t ep_out_ff; +#endif + + +#endif // CFG_TUD_AUDIO_ENABLE_EP_OUT + +#if CFG_TUD_AUDIO_ENABLE_EP_IN && !CFG_TUD_AUDIO_ENABLE_ENCODING + tu_fifo_t ep_in_ff; +#endif + + // Audio control interrupt buffer - no FIFO - 6 Bytes according to UAC 2 specification (p. 74) +#if CFG_TUD_AUDIO_ENABLE_INTERRUPT_EP + CFG_TUSB_MEM_ALIGN uint8_t ep_int_buf[6]; +#endif + + // Support FIFOs for software encoding and decoding #if CFG_TUD_AUDIO_ENABLE_EP_OUT && CFG_TUD_AUDIO_ENABLE_DECODING tu_fifo_t * rx_supp_ff; uint8_t n_rx_supp_ff; uint16_t rx_supp_ff_sz_max; +#if CFG_TUD_AUDIO_ENABLE_TYPE_I_DECODING + uint8_t n_channels_per_ff_rx; +#endif #endif #if CFG_TUD_AUDIO_ENABLE_EP_IN && CFG_TUD_AUDIO_ENABLE_ENCODING tu_fifo_t * tx_supp_ff; uint8_t n_tx_supp_ff; uint16_t tx_supp_ff_sz_max; +#if CFG_TUD_AUDIO_ENABLE_TYPE_I_ENCODING + uint8_t n_channels_per_ff_tx; +#endif #endif // Linear buffer in case target MCU is not capable of handling a ring buffer FIFO e.g. no hardware buffer is available or driver is would need to be changed dramatically OR the support FIFOs are used @@ -707,16 +713,16 @@ static bool audiod_decode_type_I_pcm(uint8_t rhport, audiod_function_t* audio, u if (info.len_lin != 0) { info.len_lin = tu_min16(nBytesPerFFToRead, info.len_lin); - src = &audio->lin_buf_out[cnt_ff*audio->n_channels_per_ff_rx * audio->n_bytes_per_sampe_rx]; + src = &audio->lin_buf_out[cnt_ff*audio->n_channels_per_ff_rx * audio->n_bytes_per_sample_rx]; dst_end = info.ptr_lin + info.len_lin; - src = audiod_interleaved_copy_bytes_fast_decode(audio->n_bytes_per_sampe_rx, info.ptr_lin, dst_end, src, n_ff_used); + src = audiod_interleaved_copy_bytes_fast_decode(audio->n_bytes_per_sample_rx, info.ptr_lin, dst_end, src, n_ff_used); // Handle wrapped part of FIFO info.len_wrap = tu_min16(nBytesPerFFToRead - info.len_lin, info.len_wrap); if (info.len_wrap != 0) { dst_end = info.ptr_wrap + info.len_wrap; - audiod_interleaved_copy_bytes_fast_decode(audio->n_bytes_per_sampe_rx, info.ptr_wrap, dst_end, src, n_ff_used); + audiod_interleaved_copy_bytes_fast_decode(audio->n_bytes_per_sample_rx, info.ptr_wrap, dst_end, src, n_ff_used); } tu_fifo_advance_write_pointer(&audio->rx_supp_ff[cnt_ff], info.len_lin + info.len_wrap); } @@ -1024,7 +1030,7 @@ static uint16_t audiod_encode_type_I_pcm(uint8_t rhport, audiod_function_t* audi // Limit to maximum sample number - THIS IS A POSSIBLE ERROR SOURCE IF TOO MANY SAMPLE WOULD NEED TO BE SENT BUT CAN NOT! nBytesPerFFToSend = tu_min16(nBytesPerFFToSend, audio->ep_in_sz / n_ff_used); // Round to full number of samples (flooring) - uint16_t const nSlotSize = audio->n_channels_per_ff_tx * audio->n_bytes_per_sampe_tx; + uint16_t const nSlotSize = audio->n_channels_per_ff_tx * audio->n_bytes_per_sample_tx; nBytesPerFFToSend = (nBytesPerFFToSend / nSlotSize) * nSlotSize; #endif @@ -1036,7 +1042,7 @@ static uint16_t audiod_encode_type_I_pcm(uint8_t rhport, audiod_function_t* audi for (cnt_ff = 0; cnt_ff < n_ff_used; cnt_ff++) { - dst = &audio->lin_buf_in[cnt_ff*audio->n_channels_per_ff_tx*audio->n_bytes_per_sampe_tx]; + dst = &audio->lin_buf_in[cnt_ff*audio->n_channels_per_ff_tx*audio->n_bytes_per_sample_tx]; tu_fifo_get_read_info(&audio->tx_supp_ff[cnt_ff], &info); @@ -1044,7 +1050,7 @@ static uint16_t audiod_encode_type_I_pcm(uint8_t rhport, audiod_function_t* audi { info.len_lin = tu_min16(nBytesPerFFToSend, info.len_lin); // Limit up to desired length src_end = (uint8_t *)info.ptr_lin + info.len_lin; - dst = audiod_interleaved_copy_bytes_fast_encode(audio->n_bytes_per_sampe_tx, info.ptr_lin, src_end, dst, n_ff_used); + dst = audiod_interleaved_copy_bytes_fast_encode(audio->n_bytes_per_sample_tx, info.ptr_lin, src_end, dst, n_ff_used); // Limit up to desired length info.len_wrap = tu_min16(nBytesPerFFToSend - info.len_lin, info.len_wrap); @@ -1053,7 +1059,7 @@ static uint16_t audiod_encode_type_I_pcm(uint8_t rhport, audiod_function_t* audi if (info.len_wrap != 0) { src_end = (uint8_t *)info.ptr_wrap + info.len_wrap; - audiod_interleaved_copy_bytes_fast_encode(audio->n_bytes_per_sampe_tx, info.ptr_wrap, src_end, dst, n_ff_used); + audiod_interleaved_copy_bytes_fast_encode(audio->n_bytes_per_sample_tx, info.ptr_wrap, src_end, dst, n_ff_used); } tu_fifo_advance_read_pointer(&audio->tx_supp_ff[cnt_ff], info.len_lin + info.len_wrap); @@ -1782,8 +1788,8 @@ static bool audiod_set_interface(uint8_t rhport, tusb_control_request_t const * // Reconfigure size of support FIFOs - this is necessary to avoid samples to get split in case of a wrap #if CFG_TUD_AUDIO_ENABLE_ENCODING && CFG_TUD_AUDIO_ENABLE_TYPE_I_ENCODING - const uint16_t active_fifo_depth = (uint16_t) ((audio->tx_supp_ff_sz_max / (audio->n_channels_per_ff_tx * audio->n_bytes_per_sampe_tx)) - * (audio->n_channels_per_ff_tx * audio->n_bytes_per_sampe_tx)); + const uint16_t active_fifo_depth = (uint16_t) ((audio->tx_supp_ff_sz_max / (audio->n_channels_per_ff_tx * audio->n_bytes_per_sample_tx)) + * (audio->n_channels_per_ff_tx * audio->n_bytes_per_sample_tx)); for (uint8_t cnt = 0; cnt < audio->n_tx_supp_ff; cnt++) { tu_fifo_config(&audio->tx_supp_ff[cnt], audio->tx_supp_ff[cnt].buffer, active_fifo_depth, 1, true); @@ -1813,7 +1819,7 @@ static bool audiod_set_interface(uint8_t rhport, tusb_control_request_t const * // Reconfigure size of support FIFOs - this is necessary to avoid samples to get split in case of a wrap #if CFG_TUD_AUDIO_ENABLE_TYPE_I_DECODING - const uint16_t active_fifo_depth = (audio->rx_supp_ff_sz_max / audio->n_bytes_per_sampe_rx) * audio->n_bytes_per_sampe_rx; + const uint16_t active_fifo_depth = (audio->rx_supp_ff_sz_max / audio->n_bytes_per_sample_rx) * audio->n_bytes_per_sample_rx; for (uint8_t cnt = 0; cnt < audio->n_rx_supp_ff; cnt++) { tu_fifo_config(&audio->rx_supp_ff[cnt], audio->rx_supp_ff[cnt].buffer, active_fifo_depth, 1, true); @@ -2587,14 +2593,14 @@ static void audiod_parse_for_AS_params(audiod_function_t* audio, uint8_t const * #if CFG_TUD_AUDIO_ENABLE_EP_IN if (as_itf == audio->ep_in_as_intf_num) { - audio->n_bytes_per_sampe_tx = ((audio_desc_type_I_format_t const * )p_desc)->bSubslotSize; + audio->n_bytes_per_sample_tx = ((audio_desc_type_I_format_t const * )p_desc)->bSubslotSize; } #endif #if CFG_TUD_AUDIO_ENABLE_EP_OUT && CFG_TUD_AUDIO_ENABLE_DECODING if (as_itf == audio->ep_out_as_intf_num) { - audio->n_bytes_per_sampe_rx = ((audio_desc_type_I_format_t const * )p_desc)->bSubslotSize; + audio->n_bytes_per_sample_rx = ((audio_desc_type_I_format_t const * )p_desc)->bSubslotSize; } #endif } @@ -2613,7 +2619,7 @@ static bool audiod_calc_tx_packet_sz(audiod_function_t* audio) { TU_VERIFY(audio->format_type_tx == AUDIO_FORMAT_TYPE_I); TU_VERIFY(audio->n_channels_tx); - TU_VERIFY(audio->n_bytes_per_sampe_tx); + TU_VERIFY(audio->n_bytes_per_sample_tx); TU_VERIFY(audio->interval_tx); TU_VERIFY(audio->sample_rate_tx); @@ -2622,9 +2628,9 @@ static bool audiod_calc_tx_packet_sz(audiod_function_t* audio) const uint16_t sample_normimal = (uint16_t)(audio->sample_rate_tx * interval / ((tud_speed_get() == TUSB_SPEED_FULL) ? 1000 : 8000)); const uint16_t sample_reminder = (uint16_t)(audio->sample_rate_tx * interval % ((tud_speed_get() == TUSB_SPEED_FULL) ? 1000 : 8000)); - const uint16_t packet_sz_tx_min = (uint16_t)((sample_normimal - 1) * audio->n_channels_tx * audio->n_bytes_per_sampe_tx); - const uint16_t packet_sz_tx_norm = (uint16_t)(sample_normimal * audio->n_channels_tx * audio->n_bytes_per_sampe_tx); - const uint16_t packet_sz_tx_max = (uint16_t)((sample_normimal + 1) * audio->n_channels_tx * audio->n_bytes_per_sampe_tx); + const uint16_t packet_sz_tx_min = (uint16_t)((sample_normimal - 1) * audio->n_channels_tx * audio->n_bytes_per_sample_tx); + const uint16_t packet_sz_tx_norm = (uint16_t)(sample_normimal * audio->n_channels_tx * audio->n_bytes_per_sample_tx); + const uint16_t packet_sz_tx_max = (uint16_t)((sample_normimal + 1) * audio->n_channels_tx * audio->n_bytes_per_sample_tx); // Endpoint size must larger than packet size TU_ASSERT(packet_sz_tx_max <= audio->ep_in_sz); -- cgit v1.3.1 From 60b3d14d1979b4a281f999e3a1861b44477f57b1 Mon Sep 17 00:00:00 2001 From: HiFiPhile Date: Wed, 8 May 2024 14:05:58 +0200 Subject: Check tud ready check for OUT xfer. --- src/class/cdc/cdc_device.c | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) (limited to 'src') diff --git a/src/class/cdc/cdc_device.c b/src/class/cdc/cdc_device.c index 681a1b852..792aedf26 100644 --- a/src/class/cdc/cdc_device.c +++ b/src/class/cdc/cdc_device.c @@ -81,8 +81,13 @@ typedef struct { CFG_TUD_MEM_SECTION static cdcd_interface_t _cdcd_itf[CFG_TUD_CDC]; static tud_cdc_configure_fifo_t _cdcd_fifo_cfg; -static bool _prep_out_transaction (cdcd_interface_t* p_cdc) { +static bool _prep_out_transaction (cdcd_interface_t* p_cdc, bool itf_open) +{ uint8_t const rhport = 0; + + // Skip if usb is not ready yet + TU_VERIFY(tud_ready() || itf_open); + uint16_t available = tu_fifo_remaining(&p_cdc->rx_ff); // Prepare for incoming data but only allow what we can store in the ring buffer. @@ -143,7 +148,7 @@ uint32_t tud_cdc_n_available(uint8_t itf) { uint32_t tud_cdc_n_read(uint8_t itf, void* buffer, uint32_t bufsize) { cdcd_interface_t* p_cdc = &_cdcd_itf[itf]; uint32_t num_read = tu_fifo_read_n(&p_cdc->rx_ff, buffer, (uint16_t) TU_MIN(bufsize, UINT16_MAX)); - _prep_out_transaction(p_cdc); + _prep_out_transaction(p_cdc, false); return num_read; } @@ -154,7 +159,7 @@ bool tud_cdc_n_peek(uint8_t itf, uint8_t* chr) { void tud_cdc_n_read_flush(uint8_t itf) { cdcd_interface_t* p_cdc = &_cdcd_itf[itf]; tu_fifo_clear(&p_cdc->rx_ff); - _prep_out_transaction(p_cdc); + _prep_out_transaction(p_cdc, false); } //--------------------------------------------------------------------+ @@ -336,7 +341,7 @@ uint16_t cdcd_open(uint8_t rhport, tusb_desc_interface_t const * itf_desc, uint1 } // Prepare for incoming data - _prep_out_transaction(p_cdc); + _prep_out_transaction(p_cdc, true); return drv_len; } @@ -445,7 +450,7 @@ bool cdcd_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t result, uint32_ if (tud_cdc_rx_cb && !tu_fifo_empty(&p_cdc->rx_ff)) tud_cdc_rx_cb(itf); // prepare for OUT transaction - _prep_out_transaction(p_cdc); + _prep_out_transaction(p_cdc, false); } // Data sent to host, we continue to fetch from tx fifo to send. -- cgit v1.3.1 From a1fd43ebaf0a36683c0437ea258e2a024341ef6d Mon Sep 17 00:00:00 2001 From: HiFiPhile Date: Wed, 8 May 2024 14:07:32 +0200 Subject: Clear _usbd_dev prior to driver reset. --- src/device/usbd.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/device/usbd.c b/src/device/usbd.c index 4105a71a4..b2fd54575 100644 --- a/src/device/usbd.c +++ b/src/device/usbd.c @@ -495,15 +495,16 @@ bool tud_deinit(uint8_t rhport) { } static void configuration_reset(uint8_t rhport) { + // Clear mounted status first to ensure tud_ready() return false before driver clean up. + tu_varclr(&_usbd_dev); + memset(_usbd_dev.itf2drv, DRVID_INVALID, sizeof(_usbd_dev.itf2drv)); // invalid mapping + memset(_usbd_dev.ep2drv, DRVID_INVALID, sizeof(_usbd_dev.ep2drv)); // invalid mapping + for (uint8_t i = 0; i < TOTAL_DRIVER_COUNT; i++) { usbd_class_driver_t const* driver = get_driver(i); TU_ASSERT(driver,); driver->reset(rhport); } - - tu_varclr(&_usbd_dev); - memset(_usbd_dev.itf2drv, DRVID_INVALID, sizeof(_usbd_dev.itf2drv)); // invalid mapping - memset(_usbd_dev.ep2drv, DRVID_INVALID, sizeof(_usbd_dev.ep2drv)); // invalid mapping } static void usbd_reset(uint8_t rhport) { -- cgit v1.3.1 From 772398f6ead893e6eb69399e11c725919c2f1e1a Mon Sep 17 00:00:00 2001 From: HiFiPhile Date: Wed, 8 May 2024 20:03:45 +0200 Subject: Save setup_count on bus reset. --- src/device/usbd.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'src') diff --git a/src/device/usbd.c b/src/device/usbd.c index b2fd54575..2735e35fd 100644 --- a/src/device/usbd.c +++ b/src/device/usbd.c @@ -495,10 +495,13 @@ bool tud_deinit(uint8_t rhport) { } static void configuration_reset(uint8_t rhport) { + // Save setup_count for restore + uint8_t setup_count = _usbd_dev.setup_count; // Clear mounted status first to ensure tud_ready() return false before driver clean up. tu_varclr(&_usbd_dev); memset(_usbd_dev.itf2drv, DRVID_INVALID, sizeof(_usbd_dev.itf2drv)); // invalid mapping memset(_usbd_dev.ep2drv, DRVID_INVALID, sizeof(_usbd_dev.ep2drv)); // invalid mapping + _usbd_dev.setup_count = setup_count; for (uint8_t i = 0; i < TOTAL_DRIVER_COUNT; i++) { usbd_class_driver_t const* driver = get_driver(i); -- cgit v1.3.1 From be18af823591389a12e246f65784646f93443882 Mon Sep 17 00:00:00 2001 From: hathach Date: Fri, 19 Jul 2024 17:10:53 +0700 Subject: revert changes to usbds configuration_reset() (deal with it in separated PR) --- src/class/cdc/cdc_device.c | 3 +-- src/device/usbd.c | 12 ++++-------- 2 files changed, 5 insertions(+), 10 deletions(-) (limited to 'src') diff --git a/src/class/cdc/cdc_device.c b/src/class/cdc/cdc_device.c index 792aedf26..570c825ab 100644 --- a/src/class/cdc/cdc_device.c +++ b/src/class/cdc/cdc_device.c @@ -81,8 +81,7 @@ typedef struct { CFG_TUD_MEM_SECTION static cdcd_interface_t _cdcd_itf[CFG_TUD_CDC]; static tud_cdc_configure_fifo_t _cdcd_fifo_cfg; -static bool _prep_out_transaction (cdcd_interface_t* p_cdc, bool itf_open) -{ +static bool _prep_out_transaction (cdcd_interface_t* p_cdc, bool itf_open) { uint8_t const rhport = 0; // Skip if usb is not ready yet diff --git a/src/device/usbd.c b/src/device/usbd.c index 2735e35fd..4105a71a4 100644 --- a/src/device/usbd.c +++ b/src/device/usbd.c @@ -495,19 +495,15 @@ bool tud_deinit(uint8_t rhport) { } static void configuration_reset(uint8_t rhport) { - // Save setup_count for restore - uint8_t setup_count = _usbd_dev.setup_count; - // Clear mounted status first to ensure tud_ready() return false before driver clean up. - tu_varclr(&_usbd_dev); - memset(_usbd_dev.itf2drv, DRVID_INVALID, sizeof(_usbd_dev.itf2drv)); // invalid mapping - memset(_usbd_dev.ep2drv, DRVID_INVALID, sizeof(_usbd_dev.ep2drv)); // invalid mapping - _usbd_dev.setup_count = setup_count; - for (uint8_t i = 0; i < TOTAL_DRIVER_COUNT; i++) { usbd_class_driver_t const* driver = get_driver(i); TU_ASSERT(driver,); driver->reset(rhport); } + + tu_varclr(&_usbd_dev); + memset(_usbd_dev.itf2drv, DRVID_INVALID, sizeof(_usbd_dev.itf2drv)); // invalid mapping + memset(_usbd_dev.ep2drv, DRVID_INVALID, sizeof(_usbd_dev.ep2drv)); // invalid mapping } static void usbd_reset(uint8_t rhport) { -- cgit v1.3.1 From 6fb6602a097b2d2e026f150d6fde387803606f88 Mon Sep 17 00:00:00 2001 From: hathach Date: Fri, 19 Jul 2024 18:08:04 +0700 Subject: - add tud_cdc_n_ready() though not used - usbd now change _usbd_dev.cfg_num before calling driver's open() --- src/class/cdc/cdc_device.c | 16 ++++++++++------ src/class/cdc/cdc_device.h | 8 ++++++++ src/common/tusb_verify.h | 10 +++++----- src/device/usbd.c | 10 ++++++++-- 4 files changed, 31 insertions(+), 13 deletions(-) (limited to 'src') diff --git a/src/class/cdc/cdc_device.c b/src/class/cdc/cdc_device.c index 570c825ab..ebc408f5a 100644 --- a/src/class/cdc/cdc_device.c +++ b/src/class/cdc/cdc_device.c @@ -81,11 +81,11 @@ typedef struct { CFG_TUD_MEM_SECTION static cdcd_interface_t _cdcd_itf[CFG_TUD_CDC]; static tud_cdc_configure_fifo_t _cdcd_fifo_cfg; -static bool _prep_out_transaction (cdcd_interface_t* p_cdc, bool itf_open) { +static bool _prep_out_transaction (cdcd_interface_t* p_cdc) { uint8_t const rhport = 0; // Skip if usb is not ready yet - TU_VERIFY(tud_ready() || itf_open); + TU_VERIFY(tud_ready() && p_cdc->ep_out); uint16_t available = tu_fifo_remaining(&p_cdc->rx_ff); @@ -120,6 +120,10 @@ bool tud_cdc_configure_fifo(tud_cdc_configure_fifo_t const* cfg) { return true; } +bool tud_cdc_n_ready(uint8_t itf) { + return tud_ready() && _cdcd_itf[itf].ep_in != 0 && _cdcd_itf[itf].ep_out != 0; +} + bool tud_cdc_n_connected(uint8_t itf) { // DTR (bit 0) active is considered as connected return tud_ready() && tu_bit_test(_cdcd_itf[itf].line_state, 0); @@ -147,7 +151,7 @@ uint32_t tud_cdc_n_available(uint8_t itf) { uint32_t tud_cdc_n_read(uint8_t itf, void* buffer, uint32_t bufsize) { cdcd_interface_t* p_cdc = &_cdcd_itf[itf]; uint32_t num_read = tu_fifo_read_n(&p_cdc->rx_ff, buffer, (uint16_t) TU_MIN(bufsize, UINT16_MAX)); - _prep_out_transaction(p_cdc, false); + _prep_out_transaction(p_cdc); return num_read; } @@ -158,7 +162,7 @@ bool tud_cdc_n_peek(uint8_t itf, uint8_t* chr) { void tud_cdc_n_read_flush(uint8_t itf) { cdcd_interface_t* p_cdc = &_cdcd_itf[itf]; tu_fifo_clear(&p_cdc->rx_ff); - _prep_out_transaction(p_cdc, false); + _prep_out_transaction(p_cdc); } //--------------------------------------------------------------------+ @@ -340,7 +344,7 @@ uint16_t cdcd_open(uint8_t rhport, tusb_desc_interface_t const * itf_desc, uint1 } // Prepare for incoming data - _prep_out_transaction(p_cdc, true); + _prep_out_transaction(p_cdc); return drv_len; } @@ -449,7 +453,7 @@ bool cdcd_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t result, uint32_ if (tud_cdc_rx_cb && !tu_fifo_empty(&p_cdc->rx_ff)) tud_cdc_rx_cb(itf); // prepare for OUT transaction - _prep_out_transaction(p_cdc, false); + _prep_out_transaction(p_cdc); } // Data sent to host, we continue to fetch from tx fifo to send. diff --git a/src/class/cdc/cdc_device.h b/src/class/cdc/cdc_device.h index 34670517a..3ad7c8baf 100644 --- a/src/class/cdc/cdc_device.h +++ b/src/class/cdc/cdc_device.h @@ -61,6 +61,9 @@ bool tud_cdc_configure_fifo(tud_cdc_configure_fifo_t const* cfg); // Application API (Multiple Ports) i.e. CFG_TUD_CDC > 1 //--------------------------------------------------------------------+ +// Check if interface is ready +bool tud_cdc_n_ready(uint8_t itf); + // Check if terminal is connected to this port bool tud_cdc_n_connected(uint8_t itf); @@ -116,6 +119,11 @@ bool tud_cdc_n_write_clear(uint8_t itf); //--------------------------------------------------------------------+ // Application API (Single Port) //--------------------------------------------------------------------+ + +TU_ATTR_ALWAYS_INLINE static inline bool tud_cdc_ready(void) { + return tud_cdc_n_ready(0); +} + TU_ATTR_ALWAYS_INLINE static inline bool tud_cdc_connected(void) { return tud_cdc_n_connected(0); } diff --git a/src/common/tusb_verify.h b/src/common/tusb_verify.h index dde0550d3..4344575b7 100644 --- a/src/common/tusb_verify.h +++ b/src/common/tusb_verify.h @@ -56,8 +56,8 @@ * #define TU_VERIFY(cond) if(cond) return false; * #define TU_VERIFY(cond,ret) if(cond) return ret; * - * #define TU_ASSERT(cond) if(cond) {_MESS_FAILED(); TU_BREAKPOINT(), return false;} - * #define TU_ASSERT(cond,ret) if(cond) {_MESS_FAILED(); TU_BREAKPOINT(), return ret;} + * #define TU_ASSERT(cond) if(cond) {TU_MESS_FAILED(); TU_BREAKPOINT(), return false;} + * #define TU_ASSERT(cond,ret) if(cond) {TU_MESS_FAILED(); TU_BREAKPOINT(), return ret;} *------------------------------------------------------------------*/ #ifdef __cplusplus @@ -70,9 +70,9 @@ #if CFG_TUSB_DEBUG #include - #define _MESS_FAILED() tu_printf("%s %d: ASSERT FAILED\r\n", __func__, __LINE__) + #define TU_MESS_FAILED() tu_printf("%s %d: ASSERT FAILED\r\n", __func__, __LINE__) #else - #define _MESS_FAILED() do {} while (0) + #define TU_MESS_FAILED() do {} while (0) #endif // Halt CPU (breakpoint) when hitting error, only apply for Cortex M3, M4, M7, M33. M55 @@ -119,7 +119,7 @@ *------------------------------------------------------------------*/ #define TU_ASSERT_DEFINE(_cond, _ret) \ do { \ - if ( !(_cond) ) { _MESS_FAILED(); TU_BREAKPOINT(); return _ret; } \ + if ( !(_cond) ) { TU_MESS_FAILED(); TU_BREAKPOINT(); return _ret; } \ } while(0) #define TU_ASSERT_1ARGS(_cond) TU_ASSERT_DEFINE(_cond, false) diff --git a/src/device/usbd.c b/src/device/usbd.c index 4105a71a4..4e723c8b9 100644 --- a/src/device/usbd.c +++ b/src/device/usbd.c @@ -747,17 +747,23 @@ static bool process_control_request(uint8_t rhport, tusb_control_request_t const _usbd_dev.speed = speed; // restore speed } + _usbd_dev.cfg_num = cfg_num; + // Handle the new configuration and execute the corresponding callback if ( cfg_num ) { // switch to new configuration if not zero - TU_ASSERT( process_set_config(rhport, cfg_num) ); + if (!process_set_config(rhport, cfg_num)) { + TU_MESS_FAILED(); + TU_BREAKPOINT(); + _usbd_dev.cfg_num = 0; + return false; + } if ( tud_mount_cb ) tud_mount_cb(); } else { if ( tud_umount_cb ) tud_umount_cb(); } } - _usbd_dev.cfg_num = cfg_num; tud_control_status(rhport, p_request); } break; -- cgit v1.3.1 From d040644b6cb055532de7d3da3477e20067f1f15f Mon Sep 17 00:00:00 2001 From: Frank Voorburg Date: Sat, 29 Jun 2024 14:25:02 +0200 Subject: Additional fix related to issue #1018. Corrects the usage of TU_ATTR_WEAK for the Keil compiler for the callback functions: * tud_descriptor_bos_cb() * tud_vendor_control_xfer_cb() * tud_mount_cb() * tud_umount_cb() * tud_suspend_cb() * tud_resume_cb() Without the fix for the first two functions, the USB device won't enumerate properly, if the device makes use of a BOS description. For example when using a Microsoft OS 2.0 platform capability descriptor to set a specific Device Interface GUID for WinUSB. The fix for the other four functions were added, because it's probably just a matter of time before someone runs into the same problem with those callback functions. --- src/device/usbd.c | 34 +++++++++++++++++++++++++++++----- src/device/usbd.h | 12 ++++++------ 2 files changed, 35 insertions(+), 11 deletions(-) (limited to 'src') diff --git a/src/device/usbd.c b/src/device/usbd.c index 4e723c8b9..719183521 100644 --- a/src/device/usbd.c +++ b/src/device/usbd.c @@ -55,6 +55,30 @@ TU_ATTR_WEAK void tud_sof_cb(uint32_t frame_count) { (void)frame_count; } +TU_ATTR_WEAK uint8_t const * tud_descriptor_bos_cb(void) { + return NULL; +} + +TU_ATTR_WEAK void tud_mount_cb(void) { +} + +TU_ATTR_WEAK void tud_umount_cb(void) { +} + +TU_ATTR_WEAK void tud_suspend_cb(bool remote_wakeup_en) { + (void)remote_wakeup_en; +} + +TU_ATTR_WEAK void tud_resume_cb(void) { +} + +TU_ATTR_WEAK bool tud_vendor_control_xfer_cb(uint8_t rhport, uint8_t stage, tusb_control_request_t const * request) { + (void)rhport; + (void)stage; + (void)request; + return false; +} + TU_ATTR_WEAK bool dcd_deinit(uint8_t rhport) { (void) rhport; return false; @@ -557,7 +581,7 @@ void tud_task_ext(uint32_t timeout_ms, bool in_isr) { case DCD_EVENT_UNPLUGGED: TU_LOG_USBD("\r\n"); usbd_reset(event.rhport); - if (tud_umount_cb) tud_umount_cb(); + tud_umount_cb(); break; case DCD_EVENT_SETUP_RECEIVED: @@ -617,7 +641,7 @@ void tud_task_ext(uint32_t timeout_ms, bool in_isr) { // e.g suspend -> resume -> unplug/plug. Skip suspend/resume if not connected if (_usbd_dev.connected) { TU_LOG_USBD(": Remote Wakeup = %u\r\n", _usbd_dev.remote_wakeup_en); - if (tud_suspend_cb) tud_suspend_cb(_usbd_dev.remote_wakeup_en); + tud_suspend_cb(_usbd_dev.remote_wakeup_en); } else { TU_LOG_USBD(" Skipped\r\n"); } @@ -626,7 +650,7 @@ void tud_task_ext(uint32_t timeout_ms, bool in_isr) { case DCD_EVENT_RESUME: if (_usbd_dev.connected) { TU_LOG_USBD("\r\n"); - if (tud_resume_cb) tud_resume_cb(); + tud_resume_cb(); } else { TU_LOG_USBD(" Skipped\r\n"); } @@ -758,9 +782,9 @@ static bool process_control_request(uint8_t rhport, tusb_control_request_t const _usbd_dev.cfg_num = 0; return false; } - if ( tud_mount_cb ) tud_mount_cb(); + tud_mount_cb(); } else { - if ( tud_umount_cb ) tud_umount_cb(); + tud_umount_cb(); } } diff --git a/src/device/usbd.h b/src/device/usbd.h index e47f674ea..042f2b089 100644 --- a/src/device/usbd.h +++ b/src/device/usbd.h @@ -126,7 +126,7 @@ uint16_t const* tud_descriptor_string_cb(uint8_t index, uint16_t langid); // Invoked when received GET BOS DESCRIPTOR request // Application return pointer to descriptor -TU_ATTR_WEAK uint8_t const * tud_descriptor_bos_cb(void); +uint8_t const * tud_descriptor_bos_cb(void); // Invoked when received GET DEVICE QUALIFIER DESCRIPTOR request // Application return pointer to descriptor, whose contents must exist long enough for transfer to complete. @@ -140,17 +140,17 @@ TU_ATTR_WEAK uint8_t const* tud_descriptor_device_qualifier_cb(void); TU_ATTR_WEAK uint8_t const* tud_descriptor_other_speed_configuration_cb(uint8_t index); // Invoked when device is mounted (configured) -TU_ATTR_WEAK void tud_mount_cb(void); +void tud_mount_cb(void); // Invoked when device is unmounted -TU_ATTR_WEAK void tud_umount_cb(void); +void tud_umount_cb(void); // Invoked when usb bus is suspended // Within 7ms, device must draw an average of current less than 2.5 mA from bus -TU_ATTR_WEAK void tud_suspend_cb(bool remote_wakeup_en); +void tud_suspend_cb(bool remote_wakeup_en); // Invoked when usb bus is resumed -TU_ATTR_WEAK void tud_resume_cb(void); +void tud_resume_cb(void); // Invoked when there is a new usb event, which need to be processed by tud_task()/tud_task_ext() void tud_event_hook_cb(uint8_t rhport, uint32_t eventid, bool in_isr); @@ -159,7 +159,7 @@ void tud_event_hook_cb(uint8_t rhport, uint32_t eventid, bool in_isr); void tud_sof_cb(uint32_t frame_count); // Invoked when received control request with VENDOR TYPE -TU_ATTR_WEAK bool tud_vendor_control_xfer_cb(uint8_t rhport, uint8_t stage, tusb_control_request_t const * request); +bool tud_vendor_control_xfer_cb(uint8_t rhport, uint8_t stage, tusb_control_request_t const * request); //--------------------------------------------------------------------+ // Binary Device Object Store (BOS) Descriptor Templates -- cgit v1.3.1 From e92acf0a91b071a723c408385add083dfe337e8b Mon Sep 17 00:00:00 2001 From: hathach Date: Fri, 19 Jul 2024 20:53:23 +0700 Subject: also migrate tud_descriptor_device_qualifier_cb() / tud_descriptor_other_speed_configuration_cb() --- src/device/usbd.c | 58 ++++++++++++++++++++++++++----------------------------- src/device/usbd.h | 6 +++--- 2 files changed, 30 insertions(+), 34 deletions(-) (limited to 'src') diff --git a/src/device/usbd.c b/src/device/usbd.c index 719183521..f0d7c45b1 100644 --- a/src/device/usbd.c +++ b/src/device/usbd.c @@ -46,16 +46,25 @@ // Weak stubs: invoked if no strong implementation is available //--------------------------------------------------------------------+ TU_ATTR_WEAK void tud_event_hook_cb(uint8_t rhport, uint32_t eventid, bool in_isr) { - (void)rhport; - (void)eventid; - (void)in_isr; + (void) rhport; + (void) eventid; + (void) in_isr; } TU_ATTR_WEAK void tud_sof_cb(uint32_t frame_count) { - (void)frame_count; + (void) frame_count; +} + +TU_ATTR_WEAK uint8_t const* tud_descriptor_bos_cb(void) { + return NULL; +} + +TU_ATTR_WEAK uint8_t const* tud_descriptor_device_qualifier_cb(void) { + return NULL; } -TU_ATTR_WEAK uint8_t const * tud_descriptor_bos_cb(void) { +TU_ATTR_WEAK uint8_t const* tud_descriptor_other_speed_configuration_cb(uint8_t index) { + (void) index; return NULL; } @@ -66,16 +75,16 @@ TU_ATTR_WEAK void tud_umount_cb(void) { } TU_ATTR_WEAK void tud_suspend_cb(bool remote_wakeup_en) { - (void)remote_wakeup_en; + (void) remote_wakeup_en; } TU_ATTR_WEAK void tud_resume_cb(void) { } -TU_ATTR_WEAK bool tud_vendor_control_xfer_cb(uint8_t rhport, uint8_t stage, tusb_control_request_t const * request) { - (void)rhport; - (void)stage; - (void)request; +TU_ATTR_WEAK bool tud_vendor_control_xfer_cb(uint8_t rhport, uint8_t stage, tusb_control_request_t const* request) { + (void) rhport; + (void) stage; + (void) request; return false; } @@ -1075,15 +1084,12 @@ static bool process_get_descriptor(uint8_t rhport, tusb_control_request_t const } // break; // unreachable - case TUSB_DESC_BOS: - { + case TUSB_DESC_BOS: { TU_LOG_USBD(" BOS\r\n"); // requested by host if USB > 2.0 ( i.e 2.1 or 3.x ) - if (!tud_descriptor_bos_cb) return false; - uintptr_t desc_bos = (uintptr_t) tud_descriptor_bos_cb(); - TU_ASSERT(desc_bos); + TU_VERIFY(desc_bos); // Use offsetof to avoid pointer to the odd/misaligned address uint16_t const total_len = tu_le16toh( tu_unaligned_read16((const void*) (desc_bos + offsetof(tusb_desc_bos_t, wTotalLength))) ); @@ -1093,24 +1099,20 @@ static bool process_get_descriptor(uint8_t rhport, tusb_control_request_t const // break; // unreachable case TUSB_DESC_CONFIGURATION: - case TUSB_DESC_OTHER_SPEED_CONFIG: - { + case TUSB_DESC_OTHER_SPEED_CONFIG: { uintptr_t desc_config; - if ( desc_type == TUSB_DESC_CONFIGURATION ) - { + if ( desc_type == TUSB_DESC_CONFIGURATION ) { TU_LOG_USBD(" Configuration[%u]\r\n", desc_index); desc_config = (uintptr_t) tud_descriptor_configuration_cb(desc_index); - }else - { + TU_ASSERT(desc_config); + }else { // Host only request this after getting Device Qualifier descriptor TU_LOG_USBD(" Other Speed Configuration\r\n"); - TU_VERIFY( tud_descriptor_other_speed_configuration_cb ); desc_config = (uintptr_t) tud_descriptor_other_speed_configuration_cb(desc_index); + TU_VERIFY(desc_config); } - TU_ASSERT(desc_config); - // Use offsetof to avoid pointer to the odd/misaligned address uint16_t const total_len = tu_le16toh( tu_unaligned_read16((const void*) (desc_config + offsetof(tusb_desc_configuration_t, wTotalLength))) ); @@ -1131,16 +1133,10 @@ static bool process_get_descriptor(uint8_t rhport, tusb_control_request_t const } // break; // unreachable - case TUSB_DESC_DEVICE_QUALIFIER: - { + case TUSB_DESC_DEVICE_QUALIFIER: { TU_LOG_USBD(" Device Qualifier\r\n"); - - TU_VERIFY( tud_descriptor_device_qualifier_cb ); - uint8_t const* desc_qualifier = tud_descriptor_device_qualifier_cb(); TU_VERIFY(desc_qualifier); - - // first byte of descriptor is its size return tud_control_xfer(rhport, p_request, (void*) (uintptr_t) desc_qualifier, tu_desc_len(desc_qualifier)); } // break; // unreachable diff --git a/src/device/usbd.h b/src/device/usbd.h index 042f2b089..3d3e83f41 100644 --- a/src/device/usbd.h +++ b/src/device/usbd.h @@ -109,7 +109,7 @@ bool tud_control_xfer(uint8_t rhport, tusb_control_request_t const * request, vo bool tud_control_status(uint8_t rhport, tusb_control_request_t const * request); //--------------------------------------------------------------------+ -// Application Callbacks (WEAK is optional) +// Application Callbacks //--------------------------------------------------------------------+ // Invoked when received GET DEVICE DESCRIPTOR request @@ -132,12 +132,12 @@ uint8_t const * tud_descriptor_bos_cb(void); // Application return pointer to descriptor, whose contents must exist long enough for transfer to complete. // device_qualifier descriptor describes information about a high-speed capable device that would // change if the device were operating at the other speed. If not highspeed capable stall this request. -TU_ATTR_WEAK uint8_t const* tud_descriptor_device_qualifier_cb(void); +uint8_t const* tud_descriptor_device_qualifier_cb(void); // Invoked when received GET OTHER SEED CONFIGURATION DESCRIPTOR request // Application return pointer to descriptor, whose contents must exist long enough for transfer to complete // Configuration descriptor in the other speed e.g if high speed then this is for full speed and vice versa -TU_ATTR_WEAK uint8_t const* tud_descriptor_other_speed_configuration_cb(uint8_t index); +uint8_t const* tud_descriptor_other_speed_configuration_cb(uint8_t index); // Invoked when device is mounted (configured) void tud_mount_cb(void); -- cgit v1.3.1 From 8183433600a675a54964d0a36efb814f77f38a54 Mon Sep 17 00:00:00 2001 From: hathach Date: Fri, 19 Jul 2024 21:05:10 +0700 Subject: fix compile with tud_vendor_control_xfer_cb() and check tud_descriptor_device_cb() --- src/device/usbd.c | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) (limited to 'src') diff --git a/src/device/usbd.c b/src/device/usbd.c index f0d7c45b1..b93216006 100644 --- a/src/device/usbd.c +++ b/src/device/usbd.c @@ -708,8 +708,6 @@ static bool process_control_request(uint8_t rhport, tusb_control_request_t const // Vendor request if ( p_request->bmRequestType_bit.type == TUSB_REQ_TYPE_VENDOR ) { - TU_VERIFY(tud_vendor_control_xfer_cb); - usbd_control_set_complete_callback(tud_vendor_control_xfer_cb); return tud_vendor_control_xfer_cb(rhport, CONTROL_STAGE_SETUP, p_request); } @@ -1060,25 +1058,23 @@ static bool process_get_descriptor(uint8_t rhport, tusb_control_request_t const switch(desc_type) { - case TUSB_DESC_DEVICE: - { + case TUSB_DESC_DEVICE: { TU_LOG_USBD(" Device\r\n"); void* desc_device = (void*) (uintptr_t) tud_descriptor_device_cb(); + TU_ASSERT(desc_device); // Only response with exactly 1 Packet if: not addressed and host requested more data than device descriptor has. // This only happens with the very first get device descriptor and EP0 size = 8 or 16. if ((CFG_TUD_ENDPOINT0_SIZE < sizeof(tusb_desc_device_t)) && !_usbd_dev.addressed && - ((tusb_control_request_t const*) p_request)->wLength > sizeof(tusb_desc_device_t)) - { + ((tusb_control_request_t const*) p_request)->wLength > sizeof(tusb_desc_device_t)) { // Hack here: we modify the request length to prevent usbd_control response with zlp // since we are responding with 1 packet & less data than wLength. tusb_control_request_t mod_request = *p_request; mod_request.wLength = CFG_TUD_ENDPOINT0_SIZE; return tud_control_xfer(rhport, &mod_request, desc_device, CFG_TUD_ENDPOINT0_SIZE); - }else - { + }else { return tud_control_xfer(rhport, p_request, desc_device, sizeof(tusb_desc_device_t)); } } -- cgit v1.3.1 From 4de46fcf975d57983192874feea9d94427f5de50 Mon Sep 17 00:00:00 2001 From: hathach Date: Mon, 22 Jul 2024 16:01:39 +0700 Subject: fix a bug in fsdev introduced by #1942 --- hw/bsp/ch32v20x/boards/ch32v203c_r0_1v0/board.cmake | 1 - hw/bsp/ch32v20x/boards/ch32v203g_r0_1v0/board.cmake | 1 - hw/bsp/ch32v20x/boards/nanoch32v203/board.cmake | 1 - hw/bsp/ch32v20x/family.cmake | 6 ++++++ src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c | 2 +- 5 files changed, 7 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/hw/bsp/ch32v20x/boards/ch32v203c_r0_1v0/board.cmake b/hw/bsp/ch32v20x/boards/ch32v203c_r0_1v0/board.cmake index adb0ea741..4aae6bdc2 100644 --- a/hw/bsp/ch32v20x/boards/ch32v203c_r0_1v0/board.cmake +++ b/hw/bsp/ch32v20x/boards/ch32v203c_r0_1v0/board.cmake @@ -10,7 +10,6 @@ set(LD_RAM_SIZE 20K) function(update_board TARGET) target_compile_definitions(${TARGET} PUBLIC SYSCLK_FREQ_144MHz_HSE=144000000 - CH32_FLASH_ENHANCE_READ_MODE=1 CFG_EXAMPLE_MSC_DUAL_READONLY ) endfunction() diff --git a/hw/bsp/ch32v20x/boards/ch32v203g_r0_1v0/board.cmake b/hw/bsp/ch32v20x/boards/ch32v203g_r0_1v0/board.cmake index 6fe3e05b2..ecb8b378f 100644 --- a/hw/bsp/ch32v20x/boards/ch32v203g_r0_1v0/board.cmake +++ b/hw/bsp/ch32v20x/boards/ch32v203g_r0_1v0/board.cmake @@ -8,7 +8,6 @@ set(LD_RAM_SIZE 10K) function(update_board TARGET) target_compile_definitions(${TARGET} PUBLIC SYSCLK_FREQ_144MHz_HSI=144000000 - CH32_FLASH_ENHANCE_READ_MODE=1 CFG_EXAMPLE_MSC_DUAL_READONLY ) endfunction() diff --git a/hw/bsp/ch32v20x/boards/nanoch32v203/board.cmake b/hw/bsp/ch32v20x/boards/nanoch32v203/board.cmake index ed7365797..a0bf12b5c 100644 --- a/hw/bsp/ch32v20x/boards/nanoch32v203/board.cmake +++ b/hw/bsp/ch32v20x/boards/nanoch32v203/board.cmake @@ -8,7 +8,6 @@ set(LD_RAM_SIZE 20K) function(update_board TARGET) target_compile_definitions(${TARGET} PUBLIC SYSCLK_FREQ_144MHz_HSE=144000000 - CH32_FLASH_ENHANCE_READ_MODE=1 CFG_EXAMPLE_MSC_DUAL_READONLY ) endfunction() diff --git a/hw/bsp/ch32v20x/family.cmake b/hw/bsp/ch32v20x/family.cmake index bf929b862..380ef190d 100644 --- a/hw/bsp/ch32v20x/family.cmake +++ b/hw/bsp/ch32v20x/family.cmake @@ -72,6 +72,12 @@ function(add_board_target BOARD_TARGET) update_board(${BOARD_TARGET}) + if (LD_FLASH_SIZE STREQUAL 224K) + target_compile_definitions(${BOARD_TARGET} PUBLIC + CH32_FLASH_ENHANCE_READ_MODE=1 + ) + endif() + if (CMAKE_C_COMPILER_ID STREQUAL "GNU") target_compile_options(${BOARD_TARGET} PUBLIC -mcmodel=medany diff --git a/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c b/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c index 8bfb899ca..39f33bc34 100644 --- a/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c +++ b/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c @@ -1004,7 +1004,7 @@ static bool dcd_write_packet_memory(uint16_t dst, const void *__restrict src, ui srcVal++; } - if (wNBytes) { + if (wNBytes & 0x01) { temp1 = (uint16_t) *srcVal; *pdwVal = temp1; } -- cgit v1.3.1