mirror of
https://github.com/hathach/tinyusb.git
synced 2026-02-04 14:15:40 +00:00
fsdev: reorganize functions
Signed-off-by: HiFiPhile <admin@hifiphile.com>
This commit is contained in:
@ -13,6 +13,7 @@ mcu:MSP432E4
|
|||||||
mcu:RX65X
|
mcu:RX65X
|
||||||
mcu:RAXXX
|
mcu:RAXXX
|
||||||
mcu:MAX3421
|
mcu:MAX3421
|
||||||
|
mcu:STM32C0
|
||||||
mcu:STM32F4
|
mcu:STM32F4
|
||||||
mcu:STM32F7
|
mcu:STM32F7
|
||||||
mcu:STM32H7
|
mcu:STM32H7
|
||||||
|
|||||||
@ -13,6 +13,7 @@ mcu:MSP432E4
|
|||||||
mcu:RX65X
|
mcu:RX65X
|
||||||
mcu:RAXXX
|
mcu:RAXXX
|
||||||
mcu:MAX3421
|
mcu:MAX3421
|
||||||
|
mcu:STM32C0
|
||||||
mcu:STM32F4
|
mcu:STM32F4
|
||||||
mcu:STM32F7
|
mcu:STM32F7
|
||||||
mcu:STM32H7
|
mcu:STM32H7
|
||||||
|
|||||||
@ -9,6 +9,7 @@ mcu:MIMXRT11XX
|
|||||||
mcu:MSP432E4
|
mcu:MSP432E4
|
||||||
mcu:RX65X
|
mcu:RX65X
|
||||||
mcu:MAX3421
|
mcu:MAX3421
|
||||||
|
mcu:STM32C0
|
||||||
mcu:STM32F4
|
mcu:STM32F4
|
||||||
mcu:STM32F7
|
mcu:STM32F7
|
||||||
mcu:STM32H7
|
mcu:STM32H7
|
||||||
|
|||||||
@ -61,6 +61,7 @@ function(family_configure_example TARGET RTOS)
|
|||||||
${CMAKE_CURRENT_FUNCTION_LIST_DIR}/${AT32_FAMILY}_clock.c
|
${CMAKE_CURRENT_FUNCTION_LIST_DIR}/${AT32_FAMILY}_clock.c
|
||||||
${CMAKE_CURRENT_FUNCTION_LIST_DIR}/${AT32_FAMILY}_int.c
|
${CMAKE_CURRENT_FUNCTION_LIST_DIR}/${AT32_FAMILY}_int.c
|
||||||
${TOP}/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c
|
${TOP}/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c
|
||||||
|
${TOP}/src/portable/st/stm32_fsdev/fsdev_common.c
|
||||||
${STARTUP_FILE_${CMAKE_C_COMPILER_ID}}
|
${STARTUP_FILE_${CMAKE_C_COMPILER_ID}}
|
||||||
)
|
)
|
||||||
target_include_directories(${TARGET} PUBLIC
|
target_include_directories(${TARGET} PUBLIC
|
||||||
|
|||||||
@ -16,6 +16,7 @@ LDFLAGS_GCC += \
|
|||||||
|
|
||||||
SRC_C += \
|
SRC_C += \
|
||||||
src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c \
|
src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c \
|
||||||
|
src/portable/st/stm32_fsdev/fsdev_common.c \
|
||||||
$(AT32_SDK_LIB)/drivers/src/${AT32_FAMILY}_gpio.c \
|
$(AT32_SDK_LIB)/drivers/src/${AT32_FAMILY}_gpio.c \
|
||||||
$(AT32_SDK_LIB)/drivers/src/${AT32_FAMILY}_misc.c \
|
$(AT32_SDK_LIB)/drivers/src/${AT32_FAMILY}_misc.c \
|
||||||
$(AT32_SDK_LIB)/drivers/src/${AT32_FAMILY}_usart.c \
|
$(AT32_SDK_LIB)/drivers/src/${AT32_FAMILY}_usart.c \
|
||||||
|
|||||||
@ -61,6 +61,7 @@ function(family_configure_example TARGET RTOS)
|
|||||||
${CMAKE_CURRENT_FUNCTION_LIST_DIR}/${AT32_FAMILY}_clock.c
|
${CMAKE_CURRENT_FUNCTION_LIST_DIR}/${AT32_FAMILY}_clock.c
|
||||||
${CMAKE_CURRENT_FUNCTION_LIST_DIR}/${AT32_FAMILY}_int.c
|
${CMAKE_CURRENT_FUNCTION_LIST_DIR}/${AT32_FAMILY}_int.c
|
||||||
${TOP}/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c
|
${TOP}/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c
|
||||||
|
${TOP}/src/portable/st/stm32_fsdev/fsdev_common.c
|
||||||
${STARTUP_FILE_${CMAKE_C_COMPILER_ID}}
|
${STARTUP_FILE_${CMAKE_C_COMPILER_ID}}
|
||||||
)
|
)
|
||||||
target_include_directories(${TARGET} PUBLIC
|
target_include_directories(${TARGET} PUBLIC
|
||||||
|
|||||||
@ -16,6 +16,7 @@ LDFLAGS_GCC += \
|
|||||||
|
|
||||||
SRC_C += \
|
SRC_C += \
|
||||||
src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c \
|
src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c \
|
||||||
|
src/portable/st/stm32_fsdev/fsdev_common.c \
|
||||||
$(AT32_SDK_LIB)/drivers/src/${AT32_FAMILY}_gpio.c \
|
$(AT32_SDK_LIB)/drivers/src/${AT32_FAMILY}_gpio.c \
|
||||||
$(AT32_SDK_LIB)/drivers/src/${AT32_FAMILY}_misc.c \
|
$(AT32_SDK_LIB)/drivers/src/${AT32_FAMILY}_misc.c \
|
||||||
$(AT32_SDK_LIB)/drivers/src/${AT32_FAMILY}_usart.c \
|
$(AT32_SDK_LIB)/drivers/src/${AT32_FAMILY}_usart.c \
|
||||||
|
|||||||
@ -93,6 +93,7 @@ function(family_configure_example TARGET RTOS)
|
|||||||
${TOP}/src/portable/wch/dcd_ch32_usbfs.c
|
${TOP}/src/portable/wch/dcd_ch32_usbfs.c
|
||||||
${TOP}/src/portable/wch/hcd_ch32_usbfs.c
|
${TOP}/src/portable/wch/hcd_ch32_usbfs.c
|
||||||
${TOP}/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c
|
${TOP}/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c
|
||||||
|
${TOP}/src/portable/st/stm32_fsdev/fsdev_common.c
|
||||||
${STARTUP_FILE_${CMAKE_C_COMPILER_ID}}
|
${STARTUP_FILE_${CMAKE_C_COMPILER_ID}}
|
||||||
)
|
)
|
||||||
target_include_directories(${TARGET} PUBLIC
|
target_include_directories(${TARGET} PUBLIC
|
||||||
|
|||||||
@ -47,6 +47,7 @@ SRC_C += \
|
|||||||
src/portable/wch/dcd_ch32_usbfs.c \
|
src/portable/wch/dcd_ch32_usbfs.c \
|
||||||
src/portable/wch/hcd_ch32_usbfs.c \
|
src/portable/wch/hcd_ch32_usbfs.c \
|
||||||
src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c \
|
src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c \
|
||||||
|
src/portable/st/stm32_fsdev/fsdev_common.c \
|
||||||
$(SDK_SRC_DIR)/Core/core_riscv.c \
|
$(SDK_SRC_DIR)/Core/core_riscv.c \
|
||||||
$(SDK_SRC_DIR)/Peripheral/src/${CH32_FAMILY}_gpio.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}_misc.c \
|
||||||
|
|||||||
@ -67,6 +67,7 @@ function(family_configure_example TARGET RTOS)
|
|||||||
${CMAKE_CURRENT_FUNCTION_LIST_DIR}/../board.c
|
${CMAKE_CURRENT_FUNCTION_LIST_DIR}/../board.c
|
||||||
${TOP}/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c
|
${TOP}/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c
|
||||||
${TOP}/src/portable/st/stm32_fsdev/hcd_stm32_fsdev.c
|
${TOP}/src/portable/st/stm32_fsdev/hcd_stm32_fsdev.c
|
||||||
|
${TOP}/src/portable/st/stm32_fsdev/fsdev_common.c
|
||||||
${TOP}/src/portable/st/typec/typec_stm32.c
|
${TOP}/src/portable/st/typec/typec_stm32.c
|
||||||
${STARTUP_FILE_${CMAKE_C_COMPILER_ID}}
|
${STARTUP_FILE_${CMAKE_C_COMPILER_ID}}
|
||||||
)
|
)
|
||||||
|
|||||||
@ -30,6 +30,7 @@ LDFLAGS_GCC += \
|
|||||||
SRC_C += \
|
SRC_C += \
|
||||||
src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c \
|
src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c \
|
||||||
src/portable/st/stm32_fsdev/hcd_stm32_fsdev.c \
|
src/portable/st/stm32_fsdev/hcd_stm32_fsdev.c \
|
||||||
|
src/portable/st/stm32_fsdev/fsdev_common.c \
|
||||||
$(ST_CMSIS)/Source/Templates/system_stm32$(ST_FAMILY)xx.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.c \
|
||||||
$(ST_HAL_DRIVER)/Src/stm32$(ST_FAMILY)xx_hal_cortex.c \
|
$(ST_HAL_DRIVER)/Src/stm32$(ST_FAMILY)xx_hal_cortex.c \
|
||||||
|
|||||||
@ -65,6 +65,7 @@ function(family_configure_example TARGET RTOS)
|
|||||||
${CMAKE_CURRENT_FUNCTION_LIST_DIR}/family.c
|
${CMAKE_CURRENT_FUNCTION_LIST_DIR}/family.c
|
||||||
${CMAKE_CURRENT_FUNCTION_LIST_DIR}/../board.c
|
${CMAKE_CURRENT_FUNCTION_LIST_DIR}/../board.c
|
||||||
${TOP}/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c
|
${TOP}/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c
|
||||||
|
${TOP}/src/portable/st/stm32_fsdev/fsdev_common.c
|
||||||
${STARTUP_FILE_${CMAKE_C_COMPILER_ID}}
|
${STARTUP_FILE_${CMAKE_C_COMPILER_ID}}
|
||||||
)
|
)
|
||||||
target_include_directories(${TARGET} PUBLIC
|
target_include_directories(${TARGET} PUBLIC
|
||||||
|
|||||||
@ -30,6 +30,7 @@ LDFLAGS_GCC += \
|
|||||||
|
|
||||||
SRC_C += \
|
SRC_C += \
|
||||||
src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c \
|
src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c \
|
||||||
|
src/portable/st/stm32_fsdev/fsdev_common.c \
|
||||||
$(ST_CMSIS)/Source/Templates/system_stm32$(ST_FAMILY)xx.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.c \
|
||||||
$(ST_HAL_DRIVER)/Src/stm32$(ST_FAMILY)xx_hal_cortex.c \
|
$(ST_HAL_DRIVER)/Src/stm32$(ST_FAMILY)xx_hal_cortex.c \
|
||||||
|
|||||||
@ -62,6 +62,7 @@ function(family_configure_example TARGET RTOS)
|
|||||||
${CMAKE_CURRENT_FUNCTION_LIST_DIR}/family.c
|
${CMAKE_CURRENT_FUNCTION_LIST_DIR}/family.c
|
||||||
${CMAKE_CURRENT_FUNCTION_LIST_DIR}/../board.c
|
${CMAKE_CURRENT_FUNCTION_LIST_DIR}/../board.c
|
||||||
${TOP}/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c
|
${TOP}/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c
|
||||||
|
${TOP}/src/portable/st/stm32_fsdev/fsdev_common.c
|
||||||
${STARTUP_FILE_${CMAKE_C_COMPILER_ID}}
|
${STARTUP_FILE_${CMAKE_C_COMPILER_ID}}
|
||||||
)
|
)
|
||||||
target_include_directories(${TARGET} PUBLIC
|
target_include_directories(${TARGET} PUBLIC
|
||||||
|
|||||||
@ -27,6 +27,7 @@ LDFLAGS_GCC += \
|
|||||||
# ------------------------
|
# ------------------------
|
||||||
SRC_C += \
|
SRC_C += \
|
||||||
src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c \
|
src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c \
|
||||||
|
src/portable/st/stm32_fsdev/fsdev_common.c \
|
||||||
${ST_CMSIS}/Source/Templates/system_stm32${ST_FAMILY}xx.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.c \
|
||||||
${ST_HAL_DRIVER}/Src/stm32${ST_FAMILY}xx_hal_cortex.c \
|
${ST_HAL_DRIVER}/Src/stm32${ST_FAMILY}xx_hal_cortex.c \
|
||||||
|
|||||||
@ -62,6 +62,7 @@ function(family_configure_example TARGET RTOS)
|
|||||||
${CMAKE_CURRENT_FUNCTION_LIST_DIR}/family.c
|
${CMAKE_CURRENT_FUNCTION_LIST_DIR}/family.c
|
||||||
${CMAKE_CURRENT_FUNCTION_LIST_DIR}/../board.c
|
${CMAKE_CURRENT_FUNCTION_LIST_DIR}/../board.c
|
||||||
${TOP}/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c
|
${TOP}/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c
|
||||||
|
${TOP}/src/portable/st/stm32_fsdev/fsdev_common.c
|
||||||
${STARTUP_FILE_${CMAKE_C_COMPILER_ID}}
|
${STARTUP_FILE_${CMAKE_C_COMPILER_ID}}
|
||||||
)
|
)
|
||||||
target_include_directories(${TARGET} PUBLIC
|
target_include_directories(${TARGET} PUBLIC
|
||||||
|
|||||||
@ -19,6 +19,7 @@ LDFLAGS_GCC += \
|
|||||||
|
|
||||||
SRC_C += \
|
SRC_C += \
|
||||||
src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c \
|
src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c \
|
||||||
|
src/portable/st/stm32_fsdev/fsdev_common.c \
|
||||||
$(ST_CMSIS)/Source/Templates/system_stm32$(ST_FAMILY)xx.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.c \
|
||||||
$(ST_HAL_DRIVER)/Src/stm32$(ST_FAMILY)xx_hal_cortex.c \
|
$(ST_HAL_DRIVER)/Src/stm32$(ST_FAMILY)xx_hal_cortex.c \
|
||||||
|
|||||||
@ -64,6 +64,7 @@ function(family_configure_example TARGET RTOS)
|
|||||||
${CMAKE_CURRENT_FUNCTION_LIST_DIR}/family.c
|
${CMAKE_CURRENT_FUNCTION_LIST_DIR}/family.c
|
||||||
${CMAKE_CURRENT_FUNCTION_LIST_DIR}/../board.c
|
${CMAKE_CURRENT_FUNCTION_LIST_DIR}/../board.c
|
||||||
${TOP}/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c
|
${TOP}/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c
|
||||||
|
${TOP}/src/portable/st/stm32_fsdev/fsdev_common.c
|
||||||
${TOP}/src/portable/st/typec/typec_stm32.c
|
${TOP}/src/portable/st/typec/typec_stm32.c
|
||||||
${STARTUP_FILE_${CMAKE_C_COMPILER_ID}}
|
${STARTUP_FILE_${CMAKE_C_COMPILER_ID}}
|
||||||
)
|
)
|
||||||
|
|||||||
@ -29,6 +29,8 @@ LDFLAGS_GCC += \
|
|||||||
|
|
||||||
SRC_C += \
|
SRC_C += \
|
||||||
src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c \
|
src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c \
|
||||||
|
src/portable/st/stm32_fsdev/hcd_stm32_fsdev.c \
|
||||||
|
src/portable/st/stm32_fsdev/fsdev_common.c \
|
||||||
$(ST_CMSIS)/Source/Templates/system_stm32$(ST_FAMILY)xx.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.c \
|
||||||
$(ST_HAL_DRIVER)/Src/stm32$(ST_FAMILY)xx_hal_cortex.c \
|
$(ST_HAL_DRIVER)/Src/stm32$(ST_FAMILY)xx_hal_cortex.c \
|
||||||
|
|||||||
@ -62,6 +62,7 @@ function(family_configure_example TARGET RTOS)
|
|||||||
${CMAKE_CURRENT_FUNCTION_LIST_DIR}/family.c
|
${CMAKE_CURRENT_FUNCTION_LIST_DIR}/family.c
|
||||||
${CMAKE_CURRENT_FUNCTION_LIST_DIR}/../board.c
|
${CMAKE_CURRENT_FUNCTION_LIST_DIR}/../board.c
|
||||||
${TOP}/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c
|
${TOP}/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c
|
||||||
|
${TOP}/src/portable/st/stm32_fsdev/fsdev_common.c
|
||||||
${TOP}/src/portable/st/typec/typec_stm32.c
|
${TOP}/src/portable/st/typec/typec_stm32.c
|
||||||
${STARTUP_FILE_${CMAKE_C_COMPILER_ID}}
|
${STARTUP_FILE_${CMAKE_C_COMPILER_ID}}
|
||||||
)
|
)
|
||||||
|
|||||||
@ -29,6 +29,7 @@ LDFLAGS_GCC += \
|
|||||||
|
|
||||||
SRC_C += \
|
SRC_C += \
|
||||||
src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c \
|
src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c \
|
||||||
|
src/portable/st/stm32_fsdev/fsdev_common.c \
|
||||||
src/portable/st/typec/typec_stm32.c \
|
src/portable/st/typec/typec_stm32.c \
|
||||||
$(ST_CMSIS)/Source/Templates/system_stm32$(ST_FAMILY)xx.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.c \
|
||||||
|
|||||||
@ -66,6 +66,7 @@ function(family_configure_example TARGET RTOS)
|
|||||||
${CMAKE_CURRENT_FUNCTION_LIST_DIR}/family.c
|
${CMAKE_CURRENT_FUNCTION_LIST_DIR}/family.c
|
||||||
${CMAKE_CURRENT_FUNCTION_LIST_DIR}/../board.c
|
${CMAKE_CURRENT_FUNCTION_LIST_DIR}/../board.c
|
||||||
${TOP}/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c
|
${TOP}/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c
|
||||||
|
${TOP}/src/portable/st/stm32_fsdev/fsdev_common.c
|
||||||
${TOP}/src/portable/st/typec/typec_stm32.c
|
${TOP}/src/portable/st/typec/typec_stm32.c
|
||||||
${STARTUP_FILE_${CMAKE_C_COMPILER_ID}}
|
${STARTUP_FILE_${CMAKE_C_COMPILER_ID}}
|
||||||
)
|
)
|
||||||
|
|||||||
@ -36,6 +36,8 @@ LDFLAGS_GCC += \
|
|||||||
|
|
||||||
SRC_C += \
|
SRC_C += \
|
||||||
src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c \
|
src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c \
|
||||||
|
src/portable/st/stm32_fsdev/hcd_stm32_fsdev.c \
|
||||||
|
src/portable/st/stm32_fsdev/fsdev_common.c \
|
||||||
$(ST_CMSIS)/Source/Templates/system_stm32$(ST_FAMILY)xx.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.c \
|
||||||
$(ST_HAL_DRIVER)/Src/stm32$(ST_FAMILY)xx_hal_cortex.c \
|
$(ST_HAL_DRIVER)/Src/stm32$(ST_FAMILY)xx_hal_cortex.c \
|
||||||
|
|||||||
@ -66,6 +66,7 @@ function(family_configure_example TARGET RTOS)
|
|||||||
${CMAKE_CURRENT_FUNCTION_LIST_DIR}/family.c
|
${CMAKE_CURRENT_FUNCTION_LIST_DIR}/family.c
|
||||||
${CMAKE_CURRENT_FUNCTION_LIST_DIR}/../board.c
|
${CMAKE_CURRENT_FUNCTION_LIST_DIR}/../board.c
|
||||||
${TOP}/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c
|
${TOP}/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c
|
||||||
|
${TOP}/src/portable/st/stm32_fsdev/fsdev_common.c
|
||||||
${STARTUP_FILE_${CMAKE_C_COMPILER_ID}}
|
${STARTUP_FILE_${CMAKE_C_COMPILER_ID}}
|
||||||
)
|
)
|
||||||
target_include_directories(${TARGET} PUBLIC
|
target_include_directories(${TARGET} PUBLIC
|
||||||
|
|||||||
@ -27,6 +27,7 @@ LDFLAGS_GCC += \
|
|||||||
|
|
||||||
SRC_C += \
|
SRC_C += \
|
||||||
src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c \
|
src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c \
|
||||||
|
src/portable/st/stm32_fsdev/fsdev_common.c \
|
||||||
$(ST_CMSIS)/Source/Templates/system_stm32$(ST_FAMILY)xx.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.c \
|
||||||
$(ST_HAL_DRIVER)/Src/stm32$(ST_FAMILY)xx_hal_cortex.c \
|
$(ST_HAL_DRIVER)/Src/stm32$(ST_FAMILY)xx_hal_cortex.c \
|
||||||
|
|||||||
@ -67,6 +67,7 @@ function(family_configure_example TARGET RTOS)
|
|||||||
${TOP}/src/portable/synopsys/dwc2/hcd_dwc2.c
|
${TOP}/src/portable/synopsys/dwc2/hcd_dwc2.c
|
||||||
${TOP}/src/portable/synopsys/dwc2/dwc2_common.c
|
${TOP}/src/portable/synopsys/dwc2/dwc2_common.c
|
||||||
${TOP}/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c
|
${TOP}/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c
|
||||||
|
${TOP}/src/portable/st/stm32_fsdev/fsdev_common.c
|
||||||
${STARTUP_FILE_${CMAKE_C_COMPILER_ID}}
|
${STARTUP_FILE_${CMAKE_C_COMPILER_ID}}
|
||||||
)
|
)
|
||||||
target_include_directories(${TARGET} PUBLIC
|
target_include_directories(${TARGET} PUBLIC
|
||||||
|
|||||||
@ -34,6 +34,7 @@ SRC_C += \
|
|||||||
src/portable/synopsys/dwc2/hcd_dwc2.c \
|
src/portable/synopsys/dwc2/hcd_dwc2.c \
|
||||||
src/portable/synopsys/dwc2/dwc2_common.c \
|
src/portable/synopsys/dwc2/dwc2_common.c \
|
||||||
src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c \
|
src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c \
|
||||||
|
src/portable/st/stm32_fsdev/fsdev_common.c \
|
||||||
$(ST_CMSIS)/Source/Templates/system_stm32$(ST_FAMILY)xx.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.c \
|
||||||
$(ST_HAL_DRIVER)/Src/stm32$(ST_FAMILY)xx_hal_cortex.c \
|
$(ST_HAL_DRIVER)/Src/stm32$(ST_FAMILY)xx_hal_cortex.c \
|
||||||
|
|||||||
@ -67,6 +67,7 @@ function(family_configure_example TARGET RTOS)
|
|||||||
${CMAKE_CURRENT_FUNCTION_LIST_DIR}/family.c
|
${CMAKE_CURRENT_FUNCTION_LIST_DIR}/family.c
|
||||||
${CMAKE_CURRENT_FUNCTION_LIST_DIR}/../board.c
|
${CMAKE_CURRENT_FUNCTION_LIST_DIR}/../board.c
|
||||||
${TOP}/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c
|
${TOP}/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c
|
||||||
|
${TOP}/src/portable/st/stm32_fsdev/fsdev_common.c
|
||||||
${STARTUP_FILE_${CMAKE_C_COMPILER_ID}}
|
${STARTUP_FILE_${CMAKE_C_COMPILER_ID}}
|
||||||
)
|
)
|
||||||
target_include_directories(${TARGET} PUBLIC
|
target_include_directories(${TARGET} PUBLIC
|
||||||
|
|||||||
@ -27,6 +27,7 @@ LDFLAGS_GCC += \
|
|||||||
|
|
||||||
SRC_C += \
|
SRC_C += \
|
||||||
src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c \
|
src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c \
|
||||||
|
src/portable/st/stm32_fsdev/fsdev_common.c \
|
||||||
$(ST_CMSIS)/Source/Templates/system_stm32$(ST_FAMILY)xx.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.c \
|
||||||
$(ST_HAL_DRIVER)/Src/stm32$(ST_FAMILY)xx_hal_cortex.c \
|
$(ST_HAL_DRIVER)/Src/stm32$(ST_FAMILY)xx_hal_cortex.c \
|
||||||
|
|||||||
@ -66,6 +66,8 @@ function(family_configure_example TARGET RTOS)
|
|||||||
${CMAKE_CURRENT_FUNCTION_LIST_DIR}/family.c
|
${CMAKE_CURRENT_FUNCTION_LIST_DIR}/family.c
|
||||||
${CMAKE_CURRENT_FUNCTION_LIST_DIR}/../board.c
|
${CMAKE_CURRENT_FUNCTION_LIST_DIR}/../board.c
|
||||||
${TOP}/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c
|
${TOP}/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c
|
||||||
|
${TOP}/src/portable/st/stm32_fsdev/hcd_stm32_fsdev.c
|
||||||
|
${TOP}/src/portable/st/stm32_fsdev/fsdev_common.c
|
||||||
${TOP}/src/portable/synopsys/dwc2/dcd_dwc2.c
|
${TOP}/src/portable/synopsys/dwc2/dcd_dwc2.c
|
||||||
${TOP}/src/portable/synopsys/dwc2/hcd_dwc2.c
|
${TOP}/src/portable/synopsys/dwc2/hcd_dwc2.c
|
||||||
${TOP}/src/portable/synopsys/dwc2/dwc2_common.c
|
${TOP}/src/portable/synopsys/dwc2/dwc2_common.c
|
||||||
|
|||||||
@ -39,10 +39,12 @@ SRC_C += \
|
|||||||
|
|
||||||
ifeq ($(MCU_VARIANT),stm32u545xx)
|
ifeq ($(MCU_VARIANT),stm32u545xx)
|
||||||
SRC_C += \
|
SRC_C += \
|
||||||
src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c
|
src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c \
|
||||||
|
src/portable/st/stm32_fsdev/fsdev_common.c
|
||||||
else ifeq ($(MCU_VARIANT),stm32u535xx)
|
else ifeq ($(MCU_VARIANT),stm32u535xx)
|
||||||
SRC_C += \
|
SRC_C += \
|
||||||
src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c
|
src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c \
|
||||||
|
src/portable/st/stm32_fsdev/fsdev_common.c
|
||||||
else
|
else
|
||||||
SRC_C += \
|
SRC_C += \
|
||||||
src/portable/synopsys/dwc2/dcd_dwc2.c \
|
src/portable/synopsys/dwc2/dcd_dwc2.c \
|
||||||
|
|||||||
@ -67,6 +67,7 @@ function(family_configure_example TARGET RTOS)
|
|||||||
${CMAKE_CURRENT_FUNCTION_LIST_DIR}/family.c
|
${CMAKE_CURRENT_FUNCTION_LIST_DIR}/family.c
|
||||||
${CMAKE_CURRENT_FUNCTION_LIST_DIR}/../board.c
|
${CMAKE_CURRENT_FUNCTION_LIST_DIR}/../board.c
|
||||||
${TOP}/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c
|
${TOP}/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c
|
||||||
|
${TOP}/src/portable/st/stm32_fsdev/fsdev_common.c
|
||||||
${STARTUP_FILE_${CMAKE_C_COMPILER_ID}}
|
${STARTUP_FILE_${CMAKE_C_COMPILER_ID}}
|
||||||
)
|
)
|
||||||
target_include_directories(${TARGET} PUBLIC
|
target_include_directories(${TARGET} PUBLIC
|
||||||
|
|||||||
@ -20,6 +20,7 @@ LDFLAGS_GCC += -specs=nosys.specs -specs=nano.specs
|
|||||||
|
|
||||||
SRC_C += \
|
SRC_C += \
|
||||||
src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c \
|
src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c \
|
||||||
|
src/portable/st/stm32_fsdev/fsdev_common.c \
|
||||||
$(ST_CMSIS)/Source/Templates/system_${ST_PREFIX}.c \
|
$(ST_CMSIS)/Source/Templates/system_${ST_PREFIX}.c \
|
||||||
$(ST_HAL_DRIVER)/Src/${ST_PREFIX}_hal.c \
|
$(ST_HAL_DRIVER)/Src/${ST_PREFIX}_hal.c \
|
||||||
$(ST_HAL_DRIVER)/Src/${ST_PREFIX}_hal_cortex.c \
|
$(ST_HAL_DRIVER)/Src/${ST_PREFIX}_hal_cortex.c \
|
||||||
|
|||||||
@ -18,7 +18,8 @@ if GetDepend(["PKG_TINYUSB_DEVICE_ENABLE"]):
|
|||||||
# BSP
|
# BSP
|
||||||
if GetDepend(["SOC_FAMILY_STM32"]):
|
if GetDepend(["SOC_FAMILY_STM32"]):
|
||||||
src += ["../../src/portable/synopsys/dwc2/dcd_dwc2.c",
|
src += ["../../src/portable/synopsys/dwc2/dcd_dwc2.c",
|
||||||
"../../src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c"]
|
"../../src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c",
|
||||||
|
"../../src/portable/st/stm32_fsdev/fsdev_common.c"]
|
||||||
|
|
||||||
if GetDepend(["SOC_NRF52840"]):
|
if GetDepend(["SOC_NRF52840"]):
|
||||||
src += ["../../src/portable/nordic/nrf5x/dcd_nrf5x.c"]
|
src += ["../../src/portable/nordic/nrf5x/dcd_nrf5x.c"]
|
||||||
|
|||||||
@ -112,16 +112,7 @@
|
|||||||
!(defined(TUP_USBIP_FSDEV_CH32) && CFG_TUD_WCH_USBIP_FSDEV == 0)
|
!(defined(TUP_USBIP_FSDEV_CH32) && CFG_TUD_WCH_USBIP_FSDEV == 0)
|
||||||
|
|
||||||
#include "device/dcd.h"
|
#include "device/dcd.h"
|
||||||
|
#include "fsdev_common.h"
|
||||||
#if defined(TUP_USBIP_FSDEV_STM32)
|
|
||||||
#include "fsdev_stm32.h"
|
|
||||||
#elif defined(TUP_USBIP_FSDEV_CH32)
|
|
||||||
#include "fsdev_ch32.h"
|
|
||||||
#elif defined(TUP_USBIP_FSDEV_AT32)
|
|
||||||
#include "fsdev_at32.h"
|
|
||||||
#else
|
|
||||||
#error "Unknown USB IP"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
//--------------------------------------------------------------------+
|
//--------------------------------------------------------------------+
|
||||||
// MACRO CONSTANT TYPEDEF
|
// MACRO CONSTANT TYPEDEF
|
||||||
@ -162,11 +153,6 @@ static bool edpt_xfer(uint8_t rhport, uint8_t ep_num, tusb_dir_t dir);
|
|||||||
static uint16_t ep_buf_ptr; ///< Points to first free memory location
|
static uint16_t ep_buf_ptr; ///< Points to first free memory location
|
||||||
static uint32_t dcd_pma_alloc(uint16_t len, bool dbuf);
|
static uint32_t dcd_pma_alloc(uint16_t len, bool dbuf);
|
||||||
static uint8_t dcd_ep_alloc(uint8_t ep_addr, uint8_t ep_type);
|
static uint8_t dcd_ep_alloc(uint8_t ep_addr, uint8_t ep_type);
|
||||||
static bool dcd_write_packet_memory(uint16_t dst, const void *__restrict src, uint16_t nbytes);
|
|
||||||
static bool dcd_read_packet_memory(void *__restrict dst, uint16_t src, uint16_t nbytes);
|
|
||||||
|
|
||||||
static bool dcd_write_packet_memory_ff(tu_fifo_t *ff, uint16_t dst, uint16_t wNBytes);
|
|
||||||
static bool dcd_read_packet_memory_ff(tu_fifo_t *ff, uint16_t src, uint16_t wNBytes);
|
|
||||||
|
|
||||||
static void edpt0_open(uint8_t rhport);
|
static void edpt0_open(uint8_t rhport);
|
||||||
|
|
||||||
@ -307,7 +293,7 @@ static void handle_ctr_setup(uint32_t ep_id) {
|
|||||||
uint16_t rx_addr = btable_get_addr(ep_id, BTABLE_BUF_RX);
|
uint16_t rx_addr = btable_get_addr(ep_id, BTABLE_BUF_RX);
|
||||||
uint8_t setup_packet[8] TU_ATTR_ALIGNED(4);
|
uint8_t setup_packet[8] TU_ATTR_ALIGNED(4);
|
||||||
|
|
||||||
dcd_read_packet_memory(setup_packet, rx_addr, rx_count);
|
fsdev_read_packet_memory(setup_packet, rx_addr, rx_count);
|
||||||
|
|
||||||
// Clear CTR RX if another setup packet arrived before this, it will be discarded
|
// Clear CTR RX if another setup packet arrived before this, it will be discarded
|
||||||
ep_write_clear_ctr(ep_id, TUSB_DIR_OUT);
|
ep_write_clear_ctr(ep_id, TUSB_DIR_OUT);
|
||||||
@ -345,9 +331,9 @@ static void handle_ctr_rx(uint32_t ep_id) {
|
|||||||
uint16_t pma_addr = (uint16_t) btable_get_addr(ep_id, buf_id);
|
uint16_t pma_addr = (uint16_t) btable_get_addr(ep_id, buf_id);
|
||||||
|
|
||||||
if (xfer->ff) {
|
if (xfer->ff) {
|
||||||
dcd_read_packet_memory_ff(xfer->ff, pma_addr, rx_count);
|
fsdev_read_packet_memory_ff(xfer->ff, pma_addr, rx_count);
|
||||||
} else {
|
} else {
|
||||||
dcd_read_packet_memory(xfer->buffer + xfer->queued_len, pma_addr, rx_count);
|
fsdev_read_packet_memory(xfer->buffer + xfer->queued_len, pma_addr, rx_count);
|
||||||
}
|
}
|
||||||
xfer->queued_len += rx_count;
|
xfer->queued_len += rx_count;
|
||||||
|
|
||||||
@ -742,9 +728,9 @@ static void dcd_transmit_packet(xfer_ctl_t *xfer, uint16_t ep_ix) {
|
|||||||
uint16_t addr_ptr = (uint16_t) btable_get_addr(ep_ix, buf_id);
|
uint16_t addr_ptr = (uint16_t) btable_get_addr(ep_ix, buf_id);
|
||||||
|
|
||||||
if (xfer->ff) {
|
if (xfer->ff) {
|
||||||
dcd_write_packet_memory_ff(xfer->ff, addr_ptr, len);
|
fsdev_write_packet_memory_ff(xfer->ff, addr_ptr, len);
|
||||||
} else {
|
} else {
|
||||||
dcd_write_packet_memory(addr_ptr, &(xfer->buffer[xfer->queued_len]), len);
|
fsdev_write_packet_memory(addr_ptr, &(xfer->buffer[xfer->queued_len]), len);
|
||||||
}
|
}
|
||||||
xfer->queued_len += len;
|
xfer->queued_len += len;
|
||||||
|
|
||||||
@ -864,168 +850,4 @@ void dcd_disconnect(uint8_t rhport) {
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
//--------------------------------------------------------------------+
|
|
||||||
// PMA read/write
|
|
||||||
//--------------------------------------------------------------------+
|
|
||||||
|
|
||||||
// Write to packet memory area (PMA) from user memory
|
|
||||||
// - Packet memory must be either strictly 16-bit or 32-bit depending on FSDEV_BUS_32BIT
|
|
||||||
// - Uses unaligned for RAM (since M0 cannot access unaligned address)
|
|
||||||
static bool dcd_write_packet_memory(uint16_t dst, const void *__restrict src, uint16_t nbytes) {
|
|
||||||
if (nbytes == 0) return true;
|
|
||||||
uint32_t n_write = nbytes / FSDEV_BUS_SIZE;
|
|
||||||
|
|
||||||
fsdev_pma_buf_t* pma_buf = PMA_BUF_AT(dst);
|
|
||||||
const uint8_t *src8 = src;
|
|
||||||
|
|
||||||
while (n_write--) {
|
|
||||||
pma_buf->value = fsdevbus_unaligned_read(src8);
|
|
||||||
src8 += FSDEV_BUS_SIZE;
|
|
||||||
pma_buf++;
|
|
||||||
}
|
|
||||||
|
|
||||||
// odd bytes e.g 1 for 16-bit or 1-3 for 32-bit
|
|
||||||
uint16_t odd = nbytes & (FSDEV_BUS_SIZE - 1);
|
|
||||||
if (odd) {
|
|
||||||
fsdev_bus_t temp = 0;
|
|
||||||
for(uint16_t i = 0; i < odd; i++) {
|
|
||||||
temp |= *src8++ << (i * 8);
|
|
||||||
}
|
|
||||||
pma_buf->value = temp;
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Read from packet memory area (PMA) to user memory.
|
|
||||||
// - Packet memory must be either strictly 16-bit or 32-bit depending on FSDEV_BUS_32BIT
|
|
||||||
// - Uses unaligned for RAM (since M0 cannot access unaligned address)
|
|
||||||
static bool dcd_read_packet_memory(void *__restrict dst, uint16_t src, uint16_t nbytes) {
|
|
||||||
if (nbytes == 0) return true;
|
|
||||||
uint32_t n_read = nbytes / FSDEV_BUS_SIZE;
|
|
||||||
|
|
||||||
fsdev_pma_buf_t* pma_buf = PMA_BUF_AT(src);
|
|
||||||
uint8_t *dst8 = (uint8_t *)dst;
|
|
||||||
|
|
||||||
while (n_read--) {
|
|
||||||
fsdevbus_unaligned_write(dst8, (fsdev_bus_t ) pma_buf->value);
|
|
||||||
dst8 += FSDEV_BUS_SIZE;
|
|
||||||
pma_buf++;
|
|
||||||
}
|
|
||||||
|
|
||||||
// odd bytes e.g 1 for 16-bit or 1-3 for 32-bit
|
|
||||||
uint16_t odd = nbytes & (FSDEV_BUS_SIZE - 1);
|
|
||||||
if (odd) {
|
|
||||||
fsdev_bus_t temp = pma_buf->value;
|
|
||||||
while (odd--) {
|
|
||||||
*dst8++ = (uint8_t) (temp & 0xfful);
|
|
||||||
temp >>= 8;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Write to PMA from FIFO
|
|
||||||
static bool dcd_write_packet_memory_ff(tu_fifo_t *ff, uint16_t dst, uint16_t wNBytes) {
|
|
||||||
if (wNBytes == 0) return true;
|
|
||||||
|
|
||||||
// Since we copy from a ring buffer FIFO, a wrap might occur making it necessary to conduct two copies
|
|
||||||
tu_fifo_buffer_info_t info;
|
|
||||||
tu_fifo_get_read_info(ff, &info);
|
|
||||||
|
|
||||||
uint16_t cnt_lin = tu_min16(wNBytes, info.len_lin);
|
|
||||||
uint16_t cnt_wrap = tu_min16(wNBytes - cnt_lin, info.len_wrap);
|
|
||||||
uint16_t const cnt_total = cnt_lin + cnt_wrap;
|
|
||||||
|
|
||||||
// We want to read from the FIFO and write it into the PMA, if LIN part is ODD and has WRAPPED part,
|
|
||||||
// last lin byte will be combined with wrapped part To ensure PMA is always access aligned
|
|
||||||
uint16_t lin_even = cnt_lin & ~(FSDEV_BUS_SIZE - 1);
|
|
||||||
uint16_t lin_odd = cnt_lin & (FSDEV_BUS_SIZE - 1);
|
|
||||||
uint8_t const *src8 = (uint8_t const*) info.ptr_lin;
|
|
||||||
|
|
||||||
// write even linear part
|
|
||||||
dcd_write_packet_memory(dst, src8, lin_even);
|
|
||||||
dst += lin_even;
|
|
||||||
src8 += lin_even;
|
|
||||||
|
|
||||||
if (lin_odd == 0) {
|
|
||||||
src8 = (uint8_t const*) info.ptr_wrap;
|
|
||||||
} else {
|
|
||||||
// Combine last linear bytes + first wrapped bytes to form fsdev bus width data
|
|
||||||
fsdev_bus_t temp = 0;
|
|
||||||
uint16_t i;
|
|
||||||
for(i = 0; i < lin_odd; i++) {
|
|
||||||
temp |= *src8++ << (i * 8);
|
|
||||||
}
|
|
||||||
|
|
||||||
src8 = (uint8_t const*) info.ptr_wrap;
|
|
||||||
for(; i < FSDEV_BUS_SIZE && cnt_wrap > 0; i++, cnt_wrap--) {
|
|
||||||
temp |= *src8++ << (i * 8);
|
|
||||||
}
|
|
||||||
|
|
||||||
dcd_write_packet_memory(dst, &temp, FSDEV_BUS_SIZE);
|
|
||||||
dst += FSDEV_BUS_SIZE;
|
|
||||||
}
|
|
||||||
|
|
||||||
// write the rest of the wrapped part
|
|
||||||
dcd_write_packet_memory(dst, src8, cnt_wrap);
|
|
||||||
|
|
||||||
tu_fifo_advance_read_pointer(ff, cnt_total);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Read from PMA to FIFO
|
|
||||||
static bool dcd_read_packet_memory_ff(tu_fifo_t *ff, uint16_t src, uint16_t wNBytes) {
|
|
||||||
if (wNBytes == 0) return true;
|
|
||||||
|
|
||||||
// Since we copy into a ring buffer FIFO, a wrap might occur making it necessary to conduct two copies
|
|
||||||
// Check for first linear part
|
|
||||||
tu_fifo_buffer_info_t info;
|
|
||||||
tu_fifo_get_write_info(ff, &info); // We want to read from the FIFO
|
|
||||||
|
|
||||||
uint16_t cnt_lin = tu_min16(wNBytes, info.len_lin);
|
|
||||||
uint16_t cnt_wrap = tu_min16(wNBytes - cnt_lin, info.len_wrap);
|
|
||||||
uint16_t cnt_total = cnt_lin + cnt_wrap;
|
|
||||||
|
|
||||||
// We want to read from the FIFO and write it into the PMA, if LIN part is ODD and has WRAPPED part,
|
|
||||||
// last lin byte will be combined with wrapped part To ensure PMA is always access aligned
|
|
||||||
|
|
||||||
uint16_t lin_even = cnt_lin & ~(FSDEV_BUS_SIZE - 1);
|
|
||||||
uint16_t lin_odd = cnt_lin & (FSDEV_BUS_SIZE - 1);
|
|
||||||
uint8_t *dst8 = (uint8_t *) info.ptr_lin;
|
|
||||||
|
|
||||||
// read even linear part
|
|
||||||
dcd_read_packet_memory(dst8, src, lin_even);
|
|
||||||
dst8 += lin_even;
|
|
||||||
src += lin_even;
|
|
||||||
|
|
||||||
if (lin_odd == 0) {
|
|
||||||
dst8 = (uint8_t *) info.ptr_wrap;
|
|
||||||
} else {
|
|
||||||
// Combine last linear bytes + first wrapped bytes to form fsdev bus width data
|
|
||||||
fsdev_bus_t temp;
|
|
||||||
dcd_read_packet_memory(&temp, src, FSDEV_BUS_SIZE);
|
|
||||||
src += FSDEV_BUS_SIZE;
|
|
||||||
|
|
||||||
uint16_t i;
|
|
||||||
for (i = 0; i < lin_odd; i++) {
|
|
||||||
*dst8++ = (uint8_t) (temp & 0xfful);
|
|
||||||
temp >>= 8;
|
|
||||||
}
|
|
||||||
|
|
||||||
dst8 = (uint8_t *) info.ptr_wrap;
|
|
||||||
for (; i < FSDEV_BUS_SIZE && cnt_wrap > 0; i++, cnt_wrap--) {
|
|
||||||
*dst8++ = (uint8_t) (temp & 0xfful);
|
|
||||||
temp >>= 8;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// read the rest of the wrapped part
|
|
||||||
dcd_read_packet_memory(dst8, src, cnt_wrap);
|
|
||||||
|
|
||||||
tu_fifo_advance_write_pointer(ff, cnt_total);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@ -150,8 +150,6 @@
|
|||||||
#define USB_EPRX_DTOG2 ((uint16_t)0x2000U) /*!< EndPoint RX Data TOGgle bit1 */
|
#define USB_EPRX_DTOG2 ((uint16_t)0x2000U) /*!< EndPoint RX Data TOGgle bit1 */
|
||||||
#define USB_EPRX_DTOGMASK (USB_EPRX_STAT|USB_EPREG_MASK)
|
#define USB_EPRX_DTOGMASK (USB_EPRX_STAT|USB_EPREG_MASK)
|
||||||
|
|
||||||
#include "fsdev_type.h"
|
|
||||||
|
|
||||||
//--------------------------------------------------------------------+
|
//--------------------------------------------------------------------+
|
||||||
//
|
//
|
||||||
//--------------------------------------------------------------------+
|
//--------------------------------------------------------------------+
|
||||||
@ -168,7 +166,7 @@ enum { FSDEV_IRQ_NUM = TU_ARRAY_SIZE(fsdev_irq) };
|
|||||||
#error "Unsupported MCU"
|
#error "Unsupported MCU"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
void fsdev_int_enable(uint8_t rhport) {
|
TU_ATTR_ALWAYS_INLINE static inline void fsdev_int_enable(uint8_t rhport) {
|
||||||
(void)rhport;
|
(void)rhport;
|
||||||
#if (CFG_TUSB_MCU == OPT_MCU_AT32F403A_407) || (CFG_TUSB_MCU == OPT_MCU_AT32F413)
|
#if (CFG_TUSB_MCU == OPT_MCU_AT32F403A_407) || (CFG_TUSB_MCU == OPT_MCU_AT32F413)
|
||||||
// AT32F403A/407 devices allow to remap the USB interrupt vectors from
|
// AT32F403A/407 devices allow to remap the USB interrupt vectors from
|
||||||
@ -187,7 +185,7 @@ void fsdev_int_enable(uint8_t rhport) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void fsdev_int_disable(uint8_t rhport) {
|
TU_ATTR_ALWAYS_INLINE static inline void fsdev_int_disable(uint8_t rhport) {
|
||||||
(void)rhport;
|
(void)rhport;
|
||||||
#if (CFG_TUSB_MCU == OPT_MCU_AT32F403A_407) || (CFG_TUSB_MCU == OPT_MCU_AT32F413)
|
#if (CFG_TUSB_MCU == OPT_MCU_AT32F403A_407) || (CFG_TUSB_MCU == OPT_MCU_AT32F413)
|
||||||
// AT32F403A/407 devices allow to remap the USB interrupt vectors from
|
// AT32F403A/407 devices allow to remap the USB interrupt vectors from
|
||||||
@ -206,7 +204,7 @@ void fsdev_int_disable(uint8_t rhport) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void fsdev_disconnect(uint8_t rhport) {
|
TU_ATTR_ALWAYS_INLINE static inline void fsdev_disconnect(uint8_t rhport) {
|
||||||
(void) rhport;
|
(void) rhport;
|
||||||
/* disable usb phy */
|
/* disable usb phy */
|
||||||
*(volatile uint32_t*)(FSDEV_REG_BASE + 0x40) |= USB_CNTR_PDWN;
|
*(volatile uint32_t*)(FSDEV_REG_BASE + 0x40) |= USB_CNTR_PDWN;
|
||||||
@ -214,7 +212,7 @@ void fsdev_disconnect(uint8_t rhport) {
|
|||||||
*(volatile uint32_t *)(FSDEV_REG_BASE+0x60) |= (1u<<1);
|
*(volatile uint32_t *)(FSDEV_REG_BASE+0x60) |= (1u<<1);
|
||||||
}
|
}
|
||||||
|
|
||||||
void fsdev_connect(uint8_t rhport) {
|
TU_ATTR_ALWAYS_INLINE static inline void fsdev_connect(uint8_t rhport) {
|
||||||
(void) rhport;
|
(void) rhport;
|
||||||
/* enable usb phy */
|
/* enable usb phy */
|
||||||
*(volatile uint32_t*)(FSDEV_REG_BASE + 0x40) &= ~USB_CNTR_PDWN;
|
*(volatile uint32_t*)(FSDEV_REG_BASE + 0x40) &= ~USB_CNTR_PDWN;
|
||||||
|
|||||||
@ -168,8 +168,6 @@
|
|||||||
#define USB_EPRX_DTOG2 ((uint16_t)0x2000U) /*!< EndPoint RX Data TOGgle bit1 */
|
#define USB_EPRX_DTOG2 ((uint16_t)0x2000U) /*!< EndPoint RX Data TOGgle bit1 */
|
||||||
#define USB_EPRX_DTOGMASK (USB_EPRX_STAT|USB_EPREG_MASK)
|
#define USB_EPRX_DTOGMASK (USB_EPRX_STAT|USB_EPREG_MASK)
|
||||||
|
|
||||||
#include "fsdev_type.h"
|
|
||||||
|
|
||||||
//--------------------------------------------------------------------+
|
//--------------------------------------------------------------------+
|
||||||
//
|
//
|
||||||
//--------------------------------------------------------------------+
|
//--------------------------------------------------------------------+
|
||||||
@ -185,26 +183,26 @@ enum { FSDEV_IRQ_NUM = TU_ARRAY_SIZE(fsdev_irq) };
|
|||||||
#error "Unsupported MCU"
|
#error "Unsupported MCU"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
void fsdev_int_enable(uint8_t rhport) {
|
TU_ATTR_ALWAYS_INLINE static inline void fsdev_int_enable(uint8_t rhport) {
|
||||||
(void)rhport;
|
(void)rhport;
|
||||||
for(uint8_t i=0; i < FSDEV_IRQ_NUM; i++) {
|
for(uint8_t i=0; i < FSDEV_IRQ_NUM; i++) {
|
||||||
NVIC_EnableIRQ(fsdev_irq[i]);
|
NVIC_EnableIRQ(fsdev_irq[i]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void fsdev_int_disable(uint8_t rhport) {
|
TU_ATTR_ALWAYS_INLINE static inline void fsdev_int_disable(uint8_t rhport) {
|
||||||
(void)rhport;
|
(void)rhport;
|
||||||
for(uint8_t i=0; i < FSDEV_IRQ_NUM; i++) {
|
for(uint8_t i=0; i < FSDEV_IRQ_NUM; i++) {
|
||||||
NVIC_DisableIRQ(fsdev_irq[i]);
|
NVIC_DisableIRQ(fsdev_irq[i]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void fsdev_disconnect(uint8_t rhport) {
|
TU_ATTR_ALWAYS_INLINE static inline void fsdev_disconnect(uint8_t rhport) {
|
||||||
(void) rhport;
|
(void) rhport;
|
||||||
EXTEN->EXTEN_CTR &= ~EXTEN_USBD_PU_EN;
|
EXTEN->EXTEN_CTR &= ~EXTEN_USBD_PU_EN;
|
||||||
}
|
}
|
||||||
|
|
||||||
void fsdev_connect(uint8_t rhport) {
|
TU_ATTR_ALWAYS_INLINE static inline void fsdev_connect(uint8_t rhport) {
|
||||||
(void) rhport;
|
(void) rhport;
|
||||||
EXTEN->EXTEN_CTR |= EXTEN_USBD_PU_EN;
|
EXTEN->EXTEN_CTR |= EXTEN_USBD_PU_EN;
|
||||||
}
|
}
|
||||||
|
|||||||
241
src/portable/st/stm32_fsdev/fsdev_common.c
Normal file
241
src/portable/st/stm32_fsdev/fsdev_common.c
Normal file
@ -0,0 +1,241 @@
|
|||||||
|
/*
|
||||||
|
* The MIT License (MIT)
|
||||||
|
*
|
||||||
|
* Copyright (c) 2024 Ha Thach (tinyusb.org)
|
||||||
|
* Copyright (c) 2025, HiFiPhile (Zixun LI)
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
* in the Software without restriction, including without limitation the rights
|
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in
|
||||||
|
* all copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
* THE SOFTWARE.
|
||||||
|
*
|
||||||
|
* This file is part of the TinyUSB stack.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "tusb_option.h"
|
||||||
|
|
||||||
|
#if defined(TUP_USBIP_FSDEV) && (CFG_TUH_ENABLED || CFG_TUD_ENABLED)
|
||||||
|
|
||||||
|
#include "fsdev_common.h"
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------+
|
||||||
|
// PMA read/write
|
||||||
|
//--------------------------------------------------------------------+
|
||||||
|
|
||||||
|
// Write to packet memory area (PMA) from user memory
|
||||||
|
// - Packet memory must be either strictly 16-bit or 32-bit depending on FSDEV_BUS_32BIT
|
||||||
|
// - Uses unaligned for RAM (since M0 cannot access unaligned address)
|
||||||
|
bool fsdev_write_packet_memory(uint16_t dst, const void *__restrict src, uint16_t nbytes) {
|
||||||
|
if (nbytes == 0) return true;
|
||||||
|
uint32_t n_write = nbytes / FSDEV_BUS_SIZE;
|
||||||
|
|
||||||
|
fsdev_pma_buf_t* pma_buf = PMA_BUF_AT(dst);
|
||||||
|
const uint8_t *src8 = src;
|
||||||
|
|
||||||
|
while (n_write--) {
|
||||||
|
pma_buf->value = fsdevbus_unaligned_read(src8);
|
||||||
|
src8 += FSDEV_BUS_SIZE;
|
||||||
|
pma_buf++;
|
||||||
|
}
|
||||||
|
|
||||||
|
// odd bytes e.g 1 for 16-bit or 1-3 for 32-bit
|
||||||
|
uint16_t odd = nbytes & (FSDEV_BUS_SIZE - 1);
|
||||||
|
if (odd) {
|
||||||
|
fsdev_bus_t temp = 0;
|
||||||
|
for(uint16_t i = 0; i < odd; i++) {
|
||||||
|
temp |= *src8++ << (i * 8);
|
||||||
|
}
|
||||||
|
pma_buf->value = temp;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Read from packet memory area (PMA) to user memory.
|
||||||
|
// - Packet memory must be either strictly 16-bit or 32-bit depending on FSDEV_BUS_32BIT
|
||||||
|
// - Uses unaligned for RAM (since M0 cannot access unaligned address)
|
||||||
|
bool fsdev_read_packet_memory(void *__restrict dst, uint16_t src, uint16_t nbytes) {
|
||||||
|
if (nbytes == 0) return true;
|
||||||
|
uint32_t n_read = nbytes / FSDEV_BUS_SIZE;
|
||||||
|
|
||||||
|
fsdev_pma_buf_t* pma_buf = PMA_BUF_AT(src);
|
||||||
|
uint8_t *dst8 = (uint8_t *)dst;
|
||||||
|
|
||||||
|
while (n_read--) {
|
||||||
|
fsdevbus_unaligned_write(dst8, (fsdev_bus_t ) pma_buf->value);
|
||||||
|
dst8 += FSDEV_BUS_SIZE;
|
||||||
|
pma_buf++;
|
||||||
|
}
|
||||||
|
|
||||||
|
// odd bytes e.g 1 for 16-bit or 1-3 for 32-bit
|
||||||
|
uint16_t odd = nbytes & (FSDEV_BUS_SIZE - 1);
|
||||||
|
if (odd) {
|
||||||
|
fsdev_bus_t temp = pma_buf->value;
|
||||||
|
while (odd--) {
|
||||||
|
*dst8++ = (uint8_t) (temp & 0xfful);
|
||||||
|
temp >>= 8;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Write to PMA from FIFO
|
||||||
|
bool fsdev_write_packet_memory_ff(tu_fifo_t *ff, uint16_t dst, uint16_t wNBytes) {
|
||||||
|
if (wNBytes == 0) return true;
|
||||||
|
|
||||||
|
// Since we copy from a ring buffer FIFO, a wrap might occur making it necessary to conduct two copies
|
||||||
|
tu_fifo_buffer_info_t info;
|
||||||
|
tu_fifo_get_read_info(ff, &info);
|
||||||
|
|
||||||
|
uint16_t cnt_lin = tu_min16(wNBytes, info.len_lin);
|
||||||
|
uint16_t cnt_wrap = tu_min16(wNBytes - cnt_lin, info.len_wrap);
|
||||||
|
uint16_t const cnt_total = cnt_lin + cnt_wrap;
|
||||||
|
|
||||||
|
// We want to read from the FIFO and write it into the PMA, if LIN part is ODD and has WRAPPED part,
|
||||||
|
// last lin byte will be combined with wrapped part To ensure PMA is always access aligned
|
||||||
|
uint16_t lin_even = cnt_lin & ~(FSDEV_BUS_SIZE - 1);
|
||||||
|
uint16_t lin_odd = cnt_lin & (FSDEV_BUS_SIZE - 1);
|
||||||
|
uint8_t const *src8 = (uint8_t const*) info.ptr_lin;
|
||||||
|
|
||||||
|
// write even linear part
|
||||||
|
fsdev_write_packet_memory(dst, src8, lin_even);
|
||||||
|
dst += lin_even;
|
||||||
|
src8 += lin_even;
|
||||||
|
|
||||||
|
if (lin_odd == 0) {
|
||||||
|
src8 = (uint8_t const*) info.ptr_wrap;
|
||||||
|
} else {
|
||||||
|
// Combine last linear bytes + first wrapped bytes to form fsdev bus width data
|
||||||
|
fsdev_bus_t temp = 0;
|
||||||
|
uint16_t i;
|
||||||
|
for(i = 0; i < lin_odd; i++) {
|
||||||
|
temp |= *src8++ << (i * 8);
|
||||||
|
}
|
||||||
|
|
||||||
|
src8 = (uint8_t const*) info.ptr_wrap;
|
||||||
|
for(; i < FSDEV_BUS_SIZE && cnt_wrap > 0; i++, cnt_wrap--) {
|
||||||
|
temp |= *src8++ << (i * 8);
|
||||||
|
}
|
||||||
|
|
||||||
|
fsdev_write_packet_memory(dst, &temp, FSDEV_BUS_SIZE);
|
||||||
|
dst += FSDEV_BUS_SIZE;
|
||||||
|
}
|
||||||
|
|
||||||
|
// write the rest of the wrapped part
|
||||||
|
fsdev_write_packet_memory(dst, src8, cnt_wrap);
|
||||||
|
|
||||||
|
tu_fifo_advance_read_pointer(ff, cnt_total);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Read from PMA to FIFO
|
||||||
|
bool fsdev_read_packet_memory_ff(tu_fifo_t *ff, uint16_t src, uint16_t wNBytes) {
|
||||||
|
if (wNBytes == 0) return true;
|
||||||
|
|
||||||
|
// Since we copy into a ring buffer FIFO, a wrap might occur making it necessary to conduct two copies
|
||||||
|
// Check for first linear part
|
||||||
|
tu_fifo_buffer_info_t info;
|
||||||
|
tu_fifo_get_write_info(ff, &info); // We want to read from the FIFO
|
||||||
|
|
||||||
|
uint16_t cnt_lin = tu_min16(wNBytes, info.len_lin);
|
||||||
|
uint16_t cnt_wrap = tu_min16(wNBytes - cnt_lin, info.len_wrap);
|
||||||
|
uint16_t cnt_total = cnt_lin + cnt_wrap;
|
||||||
|
|
||||||
|
// We want to read from the FIFO and write it into the PMA, if LIN part is ODD and has WRAPPED part,
|
||||||
|
// last lin byte will be combined with wrapped part To ensure PMA is always access aligned
|
||||||
|
|
||||||
|
uint16_t lin_even = cnt_lin & ~(FSDEV_BUS_SIZE - 1);
|
||||||
|
uint16_t lin_odd = cnt_lin & (FSDEV_BUS_SIZE - 1);
|
||||||
|
uint8_t *dst8 = (uint8_t *) info.ptr_lin;
|
||||||
|
|
||||||
|
// read even linear part
|
||||||
|
fsdev_read_packet_memory(dst8, src, lin_even);
|
||||||
|
dst8 += lin_even;
|
||||||
|
src += lin_even;
|
||||||
|
|
||||||
|
if (lin_odd == 0) {
|
||||||
|
dst8 = (uint8_t *) info.ptr_wrap;
|
||||||
|
} else {
|
||||||
|
// Combine last linear bytes + first wrapped bytes to form fsdev bus width data
|
||||||
|
fsdev_bus_t temp;
|
||||||
|
fsdev_read_packet_memory(&temp, src, FSDEV_BUS_SIZE);
|
||||||
|
src += FSDEV_BUS_SIZE;
|
||||||
|
|
||||||
|
uint16_t i;
|
||||||
|
for (i = 0; i < lin_odd; i++) {
|
||||||
|
*dst8++ = (uint8_t) (temp & 0xfful);
|
||||||
|
temp >>= 8;
|
||||||
|
}
|
||||||
|
|
||||||
|
dst8 = (uint8_t *) info.ptr_wrap;
|
||||||
|
for (; i < FSDEV_BUS_SIZE && cnt_wrap > 0; i++, cnt_wrap--) {
|
||||||
|
*dst8++ = (uint8_t) (temp & 0xfful);
|
||||||
|
temp >>= 8;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// read the rest of the wrapped part
|
||||||
|
fsdev_read_packet_memory(dst8, src, cnt_wrap);
|
||||||
|
|
||||||
|
tu_fifo_advance_write_pointer(ff, cnt_total);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------+
|
||||||
|
// BTable Helper
|
||||||
|
//--------------------------------------------------------------------+
|
||||||
|
|
||||||
|
/* Aligned buffer size according to hardware */
|
||||||
|
uint16_t pma_align_buffer_size(uint16_t size, uint8_t* blsize, uint8_t* num_block) {
|
||||||
|
/* The STM32 full speed USB peripheral supports only a limited set of
|
||||||
|
* buffer sizes given by the RX buffer entry format in the USB_BTABLE. */
|
||||||
|
uint16_t block_in_bytes;
|
||||||
|
if (size > 62) {
|
||||||
|
block_in_bytes = 32;
|
||||||
|
*blsize = 1;
|
||||||
|
*num_block = tu_div_ceil(size, 32);
|
||||||
|
} else {
|
||||||
|
block_in_bytes = 2;
|
||||||
|
*blsize = 0;
|
||||||
|
*num_block = tu_div_ceil(size, 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
return (*num_block) * block_in_bytes;
|
||||||
|
}
|
||||||
|
|
||||||
|
void btable_set_rx_bufsize(uint32_t ep_id, uint8_t buf_id, uint16_t wCount) {
|
||||||
|
uint8_t blsize, num_block;
|
||||||
|
(void) pma_align_buffer_size(wCount, &blsize, &num_block);
|
||||||
|
|
||||||
|
/* Encode into register. When BLSIZE==1, we need to subtract 1 block count */
|
||||||
|
uint16_t bl_nb = (blsize << 15) | ((num_block - blsize) << 10);
|
||||||
|
if (bl_nb == 0) {
|
||||||
|
// zlp but 0 is invalid value, set blsize to 1 (32 bytes)
|
||||||
|
// Note: lower value can cause PMAOVR on setup with ch32v203
|
||||||
|
bl_nb = 1 << 15;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef FSDEV_BUS_32BIT
|
||||||
|
uint32_t count_addr = FSDEV_BTABLE->ep32[ep_id][buf_id].count_addr;
|
||||||
|
count_addr = (bl_nb << 16) | (count_addr & 0x0000FFFFu);
|
||||||
|
FSDEV_BTABLE->ep32[ep_id][buf_id].count_addr = count_addr;
|
||||||
|
#else
|
||||||
|
FSDEV_BTABLE->ep16[ep_id][buf_id].count = bl_nb;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
@ -1,8 +1,9 @@
|
|||||||
/*
|
/*
|
||||||
* The MIT License (MIT)
|
* The MIT License (MIT)
|
||||||
*
|
*
|
||||||
* Copyright(c) N Conrad
|
* Copyright (c) N Conrad
|
||||||
* Copyright(c) 2024, hathach (tinyusb.org)
|
* Copyright (c) 2024, hathach (tinyusb.org)
|
||||||
|
* Copyright (c) 2025, HiFiPhile (Zixun LI)
|
||||||
*
|
*
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
* of this software and associated documentation files (the "Software"), to deal
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
@ -25,14 +26,32 @@
|
|||||||
* This file is part of the TinyUSB stack.
|
* This file is part of the TinyUSB stack.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef TUSB_FSDEV_TYPE_H
|
#ifndef TUSB_FSDEV_COMMON_H
|
||||||
#define TUSB_FSDEV_TYPE_H
|
#define TUSB_FSDEV_COMMON_H
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#include "common/tusb_common.h"
|
||||||
extern "C" {
|
|
||||||
|
#if CFG_TUD_ENABLED
|
||||||
|
#include "device/dcd.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "stdint.h"
|
#if CFG_TUH_ENABLED
|
||||||
|
#include "host/hcd.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(TUP_USBIP_FSDEV_STM32)
|
||||||
|
#include "fsdev_stm32.h"
|
||||||
|
#elif defined(TUP_USBIP_FSDEV_CH32)
|
||||||
|
#include "fsdev_ch32.h"
|
||||||
|
#elif defined(TUP_USBIP_FSDEV_AT32)
|
||||||
|
#include "fsdev_at32.h"
|
||||||
|
#else
|
||||||
|
#error "Unknown USB IP"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
// If sharing with CAN, one can set this to be non-zero to give CAN space where it wants it
|
// If sharing with CAN, one can set this to be non-zero to give CAN space where it wants it
|
||||||
// Both of these MUST be a multiple of 2, and are in byte units.
|
// Both of these MUST be a multiple of 2, and are in byte units.
|
||||||
@ -177,11 +196,6 @@ typedef enum {
|
|||||||
#define CH_STAT_MASK(_dir) (3u << (USB_EPTX_STAT_Pos + ((_dir) == TUSB_DIR_IN ? 8 : 0)))
|
#define CH_STAT_MASK(_dir) (3u << (USB_EPTX_STAT_Pos + ((_dir) == TUSB_DIR_IN ? 8 : 0)))
|
||||||
#define CH_DTOG_MASK(_dir) (1u << (USB_EP_DTOG_TX_Pos + ((_dir) == TUSB_DIR_IN ? 8 : 0)))
|
#define CH_DTOG_MASK(_dir) (1u << (USB_EP_DTOG_TX_Pos + ((_dir) == TUSB_DIR_IN ? 8 : 0)))
|
||||||
|
|
||||||
void fsdev_int_enable(uint8_t rhport);
|
|
||||||
void fsdev_int_disable(uint8_t rhport);
|
|
||||||
void fsdev_connect(uint8_t rhport);
|
|
||||||
void fsdev_disconnect(uint8_t rhport);
|
|
||||||
|
|
||||||
//--------------------------------------------------------------------+
|
//--------------------------------------------------------------------+
|
||||||
// Endpoint Helper
|
// Endpoint Helper
|
||||||
// - CTR is write 0 to clear
|
// - CTR is write 0 to clear
|
||||||
@ -298,47 +312,32 @@ TU_ATTR_ALWAYS_INLINE static inline void btable_set_count(uint32_t ep_id, uint8_
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Aligned buffer size according to hardware */
|
/* Aligned buffer size according to hardware */
|
||||||
TU_ATTR_ALWAYS_INLINE static inline uint16_t pma_align_buffer_size(uint16_t size, uint8_t* blsize, uint8_t* num_block) {
|
uint16_t pma_align_buffer_size(uint16_t size, uint8_t* blsize, uint8_t* num_block);
|
||||||
/* The STM32 full speed USB peripheral supports only a limited set of
|
|
||||||
* buffer sizes given by the RX buffer entry format in the USB_BTABLE. */
|
|
||||||
uint16_t block_in_bytes;
|
|
||||||
if (size > 62) {
|
|
||||||
block_in_bytes = 32;
|
|
||||||
*blsize = 1;
|
|
||||||
*num_block = tu_div_ceil(size, 32);
|
|
||||||
} else {
|
|
||||||
block_in_bytes = 2;
|
|
||||||
*blsize = 0;
|
|
||||||
*num_block = tu_div_ceil(size, 2);
|
|
||||||
}
|
|
||||||
|
|
||||||
return (*num_block) * block_in_bytes;
|
void btable_set_rx_bufsize(uint32_t ep_id, uint8_t buf_id, uint16_t wCount);
|
||||||
}
|
|
||||||
|
|
||||||
TU_ATTR_ALWAYS_INLINE static inline void btable_set_rx_bufsize(uint32_t ep_id, uint8_t buf_id, uint16_t wCount) {
|
//--------------------------------------------------------------------+
|
||||||
uint8_t blsize, num_block;
|
// PMA (Packet Memory Area) Access
|
||||||
(void) pma_align_buffer_size(wCount, &blsize, &num_block);
|
//--------------------------------------------------------------------+
|
||||||
|
|
||||||
/* Encode into register. When BLSIZE==1, we need to subtract 1 block count */
|
// Write to packet memory area (PMA) from user memory
|
||||||
uint16_t bl_nb = (blsize << 15) | ((num_block - blsize) << 10);
|
// - Packet memory must be either strictly 16-bit or 32-bit depending on FSDEV_BUS_32BIT
|
||||||
if (bl_nb == 0) {
|
// - Uses unaligned for RAM (since M0 cannot access unaligned address)
|
||||||
// zlp but 0 is invalid value, set blsize to 1 (32 bytes)
|
bool fsdev_write_packet_memory(uint16_t dst, const void *__restrict src, uint16_t nbytes);
|
||||||
// Note: lower value can cause PMAOVR on setup with ch32v203
|
|
||||||
bl_nb = 1 << 15;
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef FSDEV_BUS_32BIT
|
// Read from packet memory area (PMA) to user memory.
|
||||||
uint32_t count_addr = FSDEV_BTABLE->ep32[ep_id][buf_id].count_addr;
|
// - Packet memory must be either strictly 16-bit or 32-bit depending on FSDEV_BUS_32BIT
|
||||||
count_addr = (bl_nb << 16) | (count_addr & 0x0000FFFFu);
|
// - Uses unaligned for RAM (since M0 cannot access unaligned address)
|
||||||
FSDEV_BTABLE->ep32[ep_id][buf_id].count_addr = count_addr;
|
bool fsdev_read_packet_memory(void *__restrict dst, uint16_t src, uint16_t nbytes);
|
||||||
#else
|
|
||||||
FSDEV_BTABLE->ep16[ep_id][buf_id].count = bl_nb;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
}
|
// Write to PMA from FIFO
|
||||||
|
bool fsdev_write_packet_memory_ff(tu_fifo_t *ff, uint16_t dst, uint16_t wNBytes);
|
||||||
|
|
||||||
|
// Read from PMA to FIFO
|
||||||
|
bool fsdev_read_packet_memory_ff(tu_fifo_t *ff, uint16_t src, uint16_t wNBytes);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif
|
#endif /* TUSB_FSDEV_COMMON_H */
|
||||||
@ -321,8 +321,6 @@
|
|||||||
#define FSDEV_USE_SBUF_ISO 0
|
#define FSDEV_USE_SBUF_ISO 0
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "fsdev_type.h"
|
|
||||||
|
|
||||||
//--------------------------------------------------------------------+
|
//--------------------------------------------------------------------+
|
||||||
//
|
//
|
||||||
//--------------------------------------------------------------------+
|
//--------------------------------------------------------------------+
|
||||||
@ -374,7 +372,7 @@ static const IRQn_Type fsdev_irq[] = {
|
|||||||
};
|
};
|
||||||
enum { FSDEV_IRQ_NUM = TU_ARRAY_SIZE(fsdev_irq) };
|
enum { FSDEV_IRQ_NUM = TU_ARRAY_SIZE(fsdev_irq) };
|
||||||
|
|
||||||
void fsdev_int_enable(uint8_t rhport) {
|
TU_ATTR_ALWAYS_INLINE static inline void fsdev_int_enable(uint8_t rhport) {
|
||||||
(void)rhport;
|
(void)rhport;
|
||||||
|
|
||||||
// forces write to RAM before allowing ISR to execute
|
// forces write to RAM before allowing ISR to execute
|
||||||
@ -397,7 +395,7 @@ void fsdev_int_enable(uint8_t rhport) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void fsdev_int_disable(uint8_t rhport) {
|
TU_ATTR_ALWAYS_INLINE static inline void fsdev_int_disable(uint8_t rhport) {
|
||||||
(void)rhport;
|
(void)rhport;
|
||||||
|
|
||||||
#if CFG_TUSB_MCU == OPT_MCU_STM32F3 && defined(SYSCFG_CFGR1_USB_IT_RMP)
|
#if CFG_TUSB_MCU == OPT_MCU_STM32F3 && defined(SYSCFG_CFGR1_USB_IT_RMP)
|
||||||
@ -422,24 +420,24 @@ void fsdev_int_disable(uint8_t rhport) {
|
|||||||
// Define only on MCU with internal pull-up. BSP can define on MCU without internal PU.
|
// Define only on MCU with internal pull-up. BSP can define on MCU without internal PU.
|
||||||
#if defined(USB_BCDR_DPPU)
|
#if defined(USB_BCDR_DPPU)
|
||||||
|
|
||||||
void fsdev_disconnect(uint8_t rhport) {
|
TU_ATTR_ALWAYS_INLINE static inline void fsdev_disconnect(uint8_t rhport) {
|
||||||
(void)rhport;
|
(void)rhport;
|
||||||
USB->BCDR &= ~(USB_BCDR_DPPU);
|
USB->BCDR &= ~(USB_BCDR_DPPU);
|
||||||
}
|
}
|
||||||
|
|
||||||
void fsdev_connect(uint8_t rhport) {
|
TU_ATTR_ALWAYS_INLINE static inline void fsdev_connect(uint8_t rhport) {
|
||||||
(void)rhport;
|
(void)rhport;
|
||||||
USB->BCDR |= USB_BCDR_DPPU;
|
USB->BCDR |= USB_BCDR_DPPU;
|
||||||
}
|
}
|
||||||
|
|
||||||
#elif defined(SYSCFG_PMC_USB_PU) // works e.g. on STM32L151
|
#elif defined(SYSCFG_PMC_USB_PU) // works e.g. on STM32L151
|
||||||
|
|
||||||
void fsdev_disconnect(uint8_t rhport) {
|
TU_ATTR_ALWAYS_INLINE static inline void fsdev_disconnect(uint8_t rhport) {
|
||||||
(void)rhport;
|
(void)rhport;
|
||||||
SYSCFG->PMC &= ~(SYSCFG_PMC_USB_PU);
|
SYSCFG->PMC &= ~(SYSCFG_PMC_USB_PU);
|
||||||
}
|
}
|
||||||
|
|
||||||
void fsdev_connect(uint8_t rhport) {
|
TU_ATTR_ALWAYS_INLINE static inline void fsdev_connect(uint8_t rhport) {
|
||||||
(void)rhport;
|
(void)rhport;
|
||||||
SYSCFG->PMC |= SYSCFG_PMC_USB_PU;
|
SYSCFG->PMC |= SYSCFG_PMC_USB_PU;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -30,6 +30,7 @@
|
|||||||
*
|
*
|
||||||
* C0 2048 byte buffer; 32-bit bus; host mode
|
* C0 2048 byte buffer; 32-bit bus; host mode
|
||||||
* G0 2048 byte buffer; 32-bit bus; host mode
|
* G0 2048 byte buffer; 32-bit bus; host mode
|
||||||
|
* U3 2048 byte buffer; 32-bit bus; host mode
|
||||||
* H5 2048 byte buffer; 32-bit bus; host mode
|
* H5 2048 byte buffer; 32-bit bus; host mode
|
||||||
* U535, U545 2048 byte buffer; 32-bit bus; host mode
|
* U535, U545 2048 byte buffer; 32-bit bus; host mode
|
||||||
*
|
*
|
||||||
@ -42,19 +43,14 @@
|
|||||||
|
|
||||||
#include "host/hcd.h"
|
#include "host/hcd.h"
|
||||||
#include "host/usbh.h"
|
#include "host/usbh.h"
|
||||||
|
#include "fsdev_common.h"
|
||||||
#if defined(TUP_USBIP_FSDEV_STM32)
|
|
||||||
#include "fsdev_stm32.h"
|
|
||||||
#else
|
|
||||||
#error "Unknown USB IP"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
//--------------------------------------------------------------------+
|
//--------------------------------------------------------------------+
|
||||||
// MACRO CONSTANT TYPEDEF
|
// MACRO CONSTANT TYPEDEF
|
||||||
//--------------------------------------------------------------------+
|
//--------------------------------------------------------------------+
|
||||||
|
|
||||||
// Debug level for FSDEV
|
// Debug level for FSDEV
|
||||||
#define FSDEV_DEBUG 1
|
#define FSDEV_DEBUG 3
|
||||||
|
|
||||||
// Max number of endpoints application can open, can be larger than FSDEV_EP_COUNT
|
// Max number of endpoints application can open, can be larger than FSDEV_EP_COUNT
|
||||||
#ifndef CFG_TUH_FSDEV_ENDPOINT_MAX
|
#ifndef CFG_TUH_FSDEV_ENDPOINT_MAX
|
||||||
@ -76,9 +72,12 @@ typedef struct {
|
|||||||
uint8_t ep_addr;
|
uint8_t ep_addr;
|
||||||
uint8_t ep_type;
|
uint8_t ep_type;
|
||||||
uint8_t interval;
|
uint8_t interval;
|
||||||
bool low_speed;
|
struct TU_ATTR_PACKED {
|
||||||
bool allocated;
|
uint8_t low_speed : 1;
|
||||||
bool next_setup;
|
uint8_t allocated : 1;
|
||||||
|
uint8_t next_setup : 1;
|
||||||
|
uint8_t pid : 1;
|
||||||
|
};
|
||||||
} hcd_endpoint_t;
|
} hcd_endpoint_t;
|
||||||
|
|
||||||
// Additional info for each channel when it is active
|
// Additional info for each channel when it is active
|
||||||
@ -88,7 +87,7 @@ typedef struct {
|
|||||||
uint8_t dev_addr;
|
uint8_t dev_addr;
|
||||||
uint8_t ep_num;
|
uint8_t ep_num;
|
||||||
uint8_t ep_type;
|
uint8_t ep_type;
|
||||||
bool allocated[2];
|
uint8_t allocated[2];
|
||||||
uint8_t retry[2];
|
uint8_t retry[2];
|
||||||
uint8_t result;
|
uint8_t result;
|
||||||
} hcd_xfer_t;
|
} hcd_xfer_t;
|
||||||
@ -113,24 +112,35 @@ static uint8_t endpoint_alloc(void);
|
|||||||
static uint8_t endpoint_find(uint8_t dev_addr, uint8_t ep_addr);
|
static uint8_t endpoint_find(uint8_t dev_addr, uint8_t ep_addr);
|
||||||
static uint32_t hcd_pma_alloc(uint8_t channel, tusb_dir_t dir, uint16_t len);
|
static uint32_t hcd_pma_alloc(uint8_t channel, tusb_dir_t dir, uint16_t len);
|
||||||
static uint8_t channel_alloc(uint8_t dev_addr, uint8_t ep_addr, uint8_t ep_type);
|
static uint8_t channel_alloc(uint8_t dev_addr, uint8_t ep_addr, uint8_t ep_type);
|
||||||
static bool hcd_write_packet_memory(uint16_t dst, const void *__restrict src, uint16_t nbytes);
|
|
||||||
static bool hcd_read_packet_memory(void *__restrict dst, uint16_t src, uint16_t nbytes);
|
|
||||||
static bool edpt_xfer_kickoff(uint8_t ep_id);
|
static bool edpt_xfer_kickoff(uint8_t ep_id);
|
||||||
static bool channel_xfer_start(uint8_t ch_id, tusb_dir_t dir);
|
static bool channel_xfer_start(uint8_t ch_id, tusb_dir_t dir);
|
||||||
static void edpoint_close(uint8_t ep_id);
|
static void edpoint_close(uint8_t ep_id);
|
||||||
static void port_status_handler(uint8_t rhport, bool in_isr);
|
static void port_status_handler(uint8_t rhport, bool in_isr);
|
||||||
|
static void ch_handle_ack(uint8_t ch_id, uint32_t ch_reg, tusb_dir_t dir);
|
||||||
|
static void ch_handle_nak(uint8_t ch_id, uint32_t ch_reg, tusb_dir_t dir);
|
||||||
|
static void ch_handle_stall(uint8_t ch_id, uint32_t ch_reg, tusb_dir_t dir);
|
||||||
|
static void ch_handle_error(uint8_t ch_id, uint32_t ch_reg, tusb_dir_t dir);
|
||||||
|
|
||||||
//--------------------------------------------------------------------+
|
//--------------------------------------------------------------------+
|
||||||
// Inline Functions
|
// Inline Functions
|
||||||
//--------------------------------------------------------------------+
|
//--------------------------------------------------------------------+
|
||||||
|
|
||||||
static inline void endpoint_dealloc(hcd_endpoint_t* edpt) {
|
static inline void endpoint_dealloc(hcd_endpoint_t* edpt) {
|
||||||
edpt->allocated = false;
|
edpt->allocated = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void channel_dealloc(hcd_xfer_t* xfer, tusb_dir_t dir) {
|
static inline void channel_dealloc(hcd_xfer_t* xfer, tusb_dir_t dir) {
|
||||||
xfer->allocated[dir] = false;
|
xfer->allocated[dir] = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Write channel state in specified direction
|
||||||
|
static inline void channel_write_status(uint8_t ch_id, uint32_t ch_reg, tusb_dir_t dir, ep_stat_t state, bool need_exclusive) {
|
||||||
|
ch_reg &= USB_EPREG_MASK | CH_STAT_MASK(dir);
|
||||||
|
ch_change_status(&ch_reg, dir, state);
|
||||||
|
ch_write(ch_id, ch_reg, need_exclusive);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
//--------------------------------------------------------------------+
|
//--------------------------------------------------------------------+
|
||||||
// Controller API
|
// Controller API
|
||||||
//--------------------------------------------------------------------+
|
//--------------------------------------------------------------------+
|
||||||
@ -218,139 +228,153 @@ static void port_status_handler(uint8_t rhport, bool in_isr) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Handle CTR interrupt for the TX/OUT direction
|
//--------------------------------------------------------------------+
|
||||||
static void handle_ctr_tx(uint32_t ch_id) {
|
// Interrupt Helper Functions
|
||||||
uint32_t ch_reg = ch_read(ch_id) | USB_EP_CTR_TX | USB_EP_CTR_RX;
|
//--------------------------------------------------------------------+
|
||||||
|
|
||||||
|
// Handle ACK response
|
||||||
|
static void ch_handle_ack(uint8_t ch_id, uint32_t ch_reg, tusb_dir_t dir) {
|
||||||
uint8_t const ep_num = ch_reg & USB_EPADDR_FIELD;
|
uint8_t const ep_num = ch_reg & USB_EPADDR_FIELD;
|
||||||
uint8_t const daddr = (ch_reg & USB_CHEP_DEVADDR_Msk) >> USB_CHEP_DEVADDR_Pos;
|
uint8_t const daddr = (ch_reg & USB_CHEP_DEVADDR_Msk) >> USB_CHEP_DEVADDR_Pos;
|
||||||
|
|
||||||
uint8_t ep_id = endpoint_find(daddr, ep_num);
|
uint8_t ep_id = endpoint_find(daddr, ep_num | (dir == TUSB_DIR_IN ? TUSB_DIR_IN_MASK : 0));
|
||||||
TU_VERIFY(ep_id != TUSB_INDEX_INVALID_8, );
|
if (ep_id == TUSB_INDEX_INVALID_8) return;
|
||||||
|
|
||||||
hcd_endpoint_t* edpt = &_hcd_data.edpt[ep_id];
|
hcd_endpoint_t* edpt = &_hcd_data.edpt[ep_id];
|
||||||
hcd_xfer_t* xfer = &_hcd_data.xfer[ch_id];
|
hcd_xfer_t* xfer = &_hcd_data.xfer[ch_id];
|
||||||
TU_VERIFY(xfer->allocated[TUSB_DIR_OUT],);
|
|
||||||
|
|
||||||
// Manage Correct Transaction
|
if (dir == TUSB_DIR_OUT) {
|
||||||
if ((ch_reg & USB_CH_ERRTX) == 0U) {
|
// OUT/TX direction
|
||||||
// Acked
|
if (edpt->buflen != xfer->queued_len[TUSB_DIR_OUT]) {
|
||||||
if ((ch_reg & USB_CH_TX_STTX) == USB_CH_TX_ACK_SBUF) {
|
// More data to send
|
||||||
if (edpt->buflen != xfer->queued_len[TUSB_DIR_OUT]) {
|
uint16_t const len = tu_min16(edpt->buflen - xfer->queued_len[TUSB_DIR_OUT], edpt->max_packet_size);
|
||||||
uint16_t const len = tu_min16(edpt->buflen - xfer->queued_len[TUSB_DIR_OUT], edpt->max_packet_size);
|
uint16_t pma_addr = (uint16_t) btable_get_addr(ch_id, BTABLE_BUF_TX);
|
||||||
uint16_t pma_addr = (uint16_t) btable_get_addr(ch_id, BTABLE_BUF_TX);
|
fsdev_write_packet_memory(pma_addr, &(edpt->buffer[xfer->queued_len[TUSB_DIR_OUT]]), len);
|
||||||
hcd_write_packet_memory(pma_addr, &(edpt->buffer[xfer->queued_len[TUSB_DIR_OUT]]), len);
|
btable_set_count(ch_id, BTABLE_BUF_TX, len);
|
||||||
btable_set_count(ch_id, BTABLE_BUF_TX, len);
|
xfer->queued_len[TUSB_DIR_OUT] += len;
|
||||||
xfer->queued_len[TUSB_DIR_OUT] += len;
|
channel_write_status(ch_id, ch_reg, TUSB_DIR_OUT, EP_STAT_VALID, false);
|
||||||
|
} else {
|
||||||
ch_change_status(&ch_reg, TUSB_DIR_OUT, EP_STAT_VALID);
|
// Transfer complete
|
||||||
ch_reg &= USB_EPREG_MASK | CH_STAT_MASK(TUSB_DIR_OUT); // only change TX Status, reserve other toggle bits
|
|
||||||
ch_write(ch_id, ch_reg, false);
|
|
||||||
} else {
|
|
||||||
channel_dealloc(xfer, TUSB_DIR_OUT);
|
|
||||||
hcd_event_xfer_complete(daddr, ep_num, xfer->queued_len[TUSB_DIR_OUT], XFER_RESULT_SUCCESS, true);
|
|
||||||
}
|
|
||||||
} else if ((ch_reg & USB_CH_TX_STTX) == USB_CH_TX_NAK) {
|
|
||||||
// NAKed
|
|
||||||
if (edpt->ep_type != TUSB_XFER_INTERRUPT) {
|
|
||||||
ch_reg &= USB_EPREG_MASK | CH_STAT_MASK(TUSB_DIR_OUT); // will change TX Status, reserved other toggle bits
|
|
||||||
ch_change_status(&ch_reg, TUSB_DIR_OUT, EP_STAT_VALID);
|
|
||||||
ch_write(ch_id, ch_reg, false);
|
|
||||||
}
|
|
||||||
} else if ((ch_reg & USB_CH_TX_STTX) == USB_CH_TX_STALL) {
|
|
||||||
// STALLed
|
|
||||||
channel_dealloc(xfer, TUSB_DIR_OUT);
|
channel_dealloc(xfer, TUSB_DIR_OUT);
|
||||||
ch_reg &= USB_EPREG_MASK | CH_STAT_MASK(TUSB_DIR_OUT); // will change TX Status, reserved other toggle bits
|
edpt->pid = (ch_reg & USB_CHEP_DTOG_TX) ? 1 : 0;
|
||||||
ch_change_status(&ch_reg, TUSB_DIR_OUT, EP_STAT_DISABLED);
|
hcd_event_xfer_complete(daddr, ep_num, xfer->queued_len[TUSB_DIR_OUT], XFER_RESULT_SUCCESS, true);
|
||||||
ch_write(ch_id, ch_reg, false);
|
|
||||||
hcd_event_xfer_complete(daddr, ep_num, xfer->queued_len[TUSB_DIR_OUT], XFER_RESULT_STALLED, true);
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// Error
|
// IN/RX direction
|
||||||
TU_LOG(FSDEV_DEBUG, "handle_ctr_tx error epreg=0x%08X ch=%u ep=0x%02X daddr=%u queued=%u/%u\r\n",
|
uint16_t const rx_count = btable_get_count(ch_id, BTABLE_BUF_RX);
|
||||||
ch_reg, ch_id, ep_num, daddr, xfer->queued_len[TUSB_DIR_OUT], edpt->buflen);
|
uint16_t pma_addr = (uint16_t) btable_get_addr(ch_id, BTABLE_BUF_RX);
|
||||||
ch_reg &= USB_EPREG_MASK | CH_STAT_MASK(TUSB_DIR_OUT); // will change TX Status, reserved other toggle bits
|
|
||||||
ch_reg &=~USB_CH_ERRTX;
|
fsdev_read_packet_memory(edpt->buffer + xfer->queued_len[TUSB_DIR_IN], pma_addr, rx_count);
|
||||||
if (xfer->retry[TUSB_DIR_OUT] < HCD_XFER_ERROR_MAX) {
|
xfer->queued_len[TUSB_DIR_IN] += rx_count;
|
||||||
// Retry
|
|
||||||
xfer->retry[TUSB_DIR_OUT]++;
|
if ((rx_count < edpt->max_packet_size) || (xfer->queued_len[TUSB_DIR_IN] >= edpt->buflen)) {
|
||||||
|
// Transfer complete (short packet or all bytes received)
|
||||||
|
channel_dealloc(xfer, TUSB_DIR_IN);
|
||||||
|
edpt->pid = (ch_reg & USB_CHEP_DTOG_RX) ? 1 : 0;
|
||||||
|
hcd_event_xfer_complete(daddr, ep_num | TUSB_DIR_IN_MASK, xfer->queued_len[TUSB_DIR_IN], XFER_RESULT_SUCCESS, true);
|
||||||
} else {
|
} else {
|
||||||
// Failed after retries
|
// More data expected
|
||||||
channel_dealloc(xfer, TUSB_DIR_OUT);
|
uint16_t const cnt = tu_min16(edpt->buflen - xfer->queued_len[TUSB_DIR_IN], edpt->max_packet_size);
|
||||||
ch_change_status(&ch_reg, TUSB_DIR_OUT, EP_STAT_DISABLED);
|
btable_set_rx_bufsize(ch_id, BTABLE_BUF_RX, cnt);
|
||||||
hcd_event_xfer_complete(daddr, ep_num, xfer->queued_len[TUSB_DIR_OUT], XFER_RESULT_FAILED, true);
|
channel_write_status(ch_id, ch_reg, TUSB_DIR_IN, EP_STAT_VALID, false);
|
||||||
}
|
}
|
||||||
ch_write(ch_id, ch_reg, false);
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Handle NAK response
|
||||||
|
static void ch_handle_nak(uint8_t ch_id, uint32_t ch_reg, tusb_dir_t dir) {
|
||||||
|
uint8_t const ep_num = ch_reg & USB_EPADDR_FIELD;
|
||||||
|
uint8_t const daddr = (ch_reg & USB_CHEP_DEVADDR_Msk) >> USB_CHEP_DEVADDR_Pos;
|
||||||
|
|
||||||
|
uint8_t ep_id = endpoint_find(daddr, ep_num | (dir == TUSB_DIR_IN ? TUSB_DIR_IN_MASK : 0));
|
||||||
|
if (ep_id == TUSB_INDEX_INVALID_8) return;
|
||||||
|
|
||||||
|
hcd_endpoint_t* edpt = &_hcd_data.edpt[ep_id];
|
||||||
|
// Retry non-periodic transfer immediately,
|
||||||
|
// Periodic transfer will be retried by next frame automatically
|
||||||
|
if (edpt->ep_type == TUSB_XFER_CONTROL || edpt->ep_type == TUSB_XFER_BULK) {
|
||||||
|
channel_write_status(ch_id, ch_reg, dir, EP_STAT_VALID, false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Handle STALL response
|
||||||
|
static void ch_handle_stall(uint8_t ch_id, uint32_t ch_reg, tusb_dir_t dir) {
|
||||||
|
uint8_t const ep_num = ch_reg & USB_EPADDR_FIELD;
|
||||||
|
uint8_t const daddr = (ch_reg & USB_CHEP_DEVADDR_Msk) >> USB_CHEP_DEVADDR_Pos;
|
||||||
|
|
||||||
|
hcd_xfer_t* xfer = &_hcd_data.xfer[ch_id];
|
||||||
|
channel_dealloc(xfer, dir);
|
||||||
|
|
||||||
|
channel_write_status(ch_id, ch_reg, dir, EP_STAT_DISABLED, false);
|
||||||
|
|
||||||
|
hcd_event_xfer_complete(daddr, ep_num | (dir == TUSB_DIR_IN ? TUSB_DIR_IN_MASK : 0),
|
||||||
|
xfer->queued_len[dir], XFER_RESULT_STALLED, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Handle error response
|
||||||
|
static void ch_handle_error(uint8_t ch_id, uint32_t ch_reg, tusb_dir_t dir) {
|
||||||
|
uint8_t const ep_num = ch_reg & USB_EPADDR_FIELD;
|
||||||
|
uint8_t const daddr = (ch_reg & USB_CHEP_DEVADDR_Msk) >> USB_CHEP_DEVADDR_Pos;
|
||||||
|
|
||||||
|
uint8_t ep_id = endpoint_find(daddr, ep_num | (dir == TUSB_DIR_IN ? TUSB_DIR_IN_MASK : 0));
|
||||||
|
if (ep_id == TUSB_INDEX_INVALID_8) return;
|
||||||
|
|
||||||
|
hcd_xfer_t* xfer = &_hcd_data.xfer[ch_id];
|
||||||
|
|
||||||
|
ch_reg &= USB_EPREG_MASK | CH_STAT_MASK(dir);
|
||||||
|
ch_reg &= ~(dir == TUSB_DIR_OUT ? USB_CH_ERRTX : USB_CH_ERRRX);
|
||||||
|
|
||||||
|
if (xfer->retry[dir] < HCD_XFER_ERROR_MAX) {
|
||||||
|
// Retry
|
||||||
|
xfer->retry[dir]++;
|
||||||
|
ch_change_status(&ch_reg, dir, EP_STAT_VALID);
|
||||||
|
} else {
|
||||||
|
// Failed after retries
|
||||||
|
channel_dealloc(xfer, dir);
|
||||||
|
ch_change_status(&ch_reg, dir, EP_STAT_DISABLED);
|
||||||
|
hcd_event_xfer_complete(daddr, ep_num | (dir == TUSB_DIR_IN ? TUSB_DIR_IN_MASK : 0),
|
||||||
|
xfer->queued_len[dir], XFER_RESULT_FAILED, true);
|
||||||
|
}
|
||||||
|
ch_write(ch_id, ch_reg, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Handle CTR interrupt for the TX/OUT direction
|
||||||
|
static void handle_ctr_tx(uint32_t ch_id) {
|
||||||
|
uint32_t ch_reg = ch_read(ch_id) | USB_EP_CTR_TX | USB_EP_CTR_RX;
|
||||||
|
hcd_xfer_t* xfer = &_hcd_data.xfer[ch_id];
|
||||||
|
TU_VERIFY(xfer->allocated[TUSB_DIR_OUT] == 1,);
|
||||||
|
|
||||||
|
if ((ch_reg & USB_CH_ERRTX) == 0U) {
|
||||||
|
// No error
|
||||||
|
if ((ch_reg & USB_CH_TX_STTX) == USB_CH_TX_ACK_SBUF) {
|
||||||
|
ch_handle_ack(ch_id, ch_reg, TUSB_DIR_OUT);
|
||||||
|
} else if ((ch_reg & USB_CH_TX_STTX) == USB_CH_TX_NAK) {
|
||||||
|
ch_handle_nak(ch_id, ch_reg, TUSB_DIR_OUT);
|
||||||
|
} else if ((ch_reg & USB_CH_TX_STTX) == USB_CH_TX_STALL) {
|
||||||
|
ch_handle_stall(ch_id, ch_reg, TUSB_DIR_OUT);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
ch_handle_error(ch_id, ch_reg, TUSB_DIR_OUT);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Handle CTR interrupt for the RX/IN direction
|
// Handle CTR interrupt for the RX/IN direction
|
||||||
static void handle_ctr_rx(uint32_t ch_id) {
|
static void handle_ctr_rx(uint32_t ch_id) {
|
||||||
uint32_t ch_reg = ch_read(ch_id) | USB_EP_CTR_TX | USB_EP_CTR_RX;
|
uint32_t ch_reg = ch_read(ch_id) | USB_EP_CTR_TX | USB_EP_CTR_RX;
|
||||||
uint8_t const ep_num = ch_reg & USB_EPADDR_FIELD;
|
hcd_xfer_t* xfer = &_hcd_data.xfer[ch_id];
|
||||||
|
TU_VERIFY(xfer->allocated[TUSB_DIR_IN] == 1,);
|
||||||
|
|
||||||
uint8_t const daddr = (ch_reg & USB_CHEP_DEVADDR_Msk) >> USB_CHEP_DEVADDR_Pos;
|
|
||||||
|
|
||||||
uint8_t ep_id = endpoint_find(daddr, ep_num | TUSB_DIR_IN_MASK);
|
|
||||||
TU_VERIFY(ep_id != TUSB_INDEX_INVALID_8, );
|
|
||||||
|
|
||||||
hcd_endpoint_t* edpt = &_hcd_data.edpt[ep_id];
|
|
||||||
hcd_xfer_t* xfer = &_hcd_data.xfer[ch_id];
|
|
||||||
TU_VERIFY(xfer->allocated[TUSB_DIR_IN],);
|
|
||||||
|
|
||||||
// Manage Correct Transaction
|
|
||||||
if ((ch_reg & USB_CH_ERRRX) == 0U) {
|
if ((ch_reg & USB_CH_ERRRX) == 0U) {
|
||||||
// Acked
|
// No error
|
||||||
if ((ch_reg & USB_CH_RX_STRX) == USB_CH_RX_ACK_SBUF) {
|
if ((ch_reg & USB_CH_RX_STRX) == USB_CH_RX_ACK_SBUF) {
|
||||||
uint16_t const rx_count = btable_get_count(ch_id, BTABLE_BUF_RX);
|
ch_handle_ack(ch_id, ch_reg, TUSB_DIR_IN);
|
||||||
uint16_t pma_addr = (uint16_t) btable_get_addr(ch_id, BTABLE_BUF_RX);
|
|
||||||
|
|
||||||
hcd_read_packet_memory(edpt->buffer + xfer->queued_len[TUSB_DIR_IN], pma_addr, rx_count);
|
|
||||||
xfer->queued_len[TUSB_DIR_IN] += rx_count;
|
|
||||||
|
|
||||||
if ((rx_count < edpt->max_packet_size) || (xfer->queued_len[TUSB_DIR_IN] >= edpt->buflen)) {
|
|
||||||
// all bytes received or short packet
|
|
||||||
channel_dealloc(xfer, TUSB_DIR_IN);
|
|
||||||
hcd_event_xfer_complete(daddr, ep_num | TUSB_DIR_IN_MASK, xfer->queued_len[TUSB_DIR_IN], XFER_RESULT_SUCCESS, true);
|
|
||||||
} else {
|
|
||||||
// Set endpoint active again for receiving more data. Note that isochronous endpoints stay active always
|
|
||||||
uint16_t const cnt = tu_min16(edpt->buflen - xfer->queued_len[TUSB_DIR_IN], edpt->max_packet_size);
|
|
||||||
btable_set_rx_bufsize(ch_id, BTABLE_BUF_RX, cnt);
|
|
||||||
ch_reg &= USB_EPREG_MASK | CH_STAT_MASK(TUSB_DIR_IN); // will change RX Status, reserved other toggle bits
|
|
||||||
ch_change_status(&ch_reg, TUSB_DIR_IN, EP_STAT_VALID);
|
|
||||||
ch_write(ch_id, ch_reg, false);
|
|
||||||
}
|
|
||||||
} else if ((ch_reg & USB_CH_RX_STRX) == USB_CH_RX_NAK) {
|
} else if ((ch_reg & USB_CH_RX_STRX) == USB_CH_RX_NAK) {
|
||||||
// NAKed
|
ch_handle_nak(ch_id, ch_reg, TUSB_DIR_IN);
|
||||||
if (edpt->ep_type != TUSB_XFER_INTERRUPT) {
|
} else if ((ch_reg & USB_CH_RX_STRX) == USB_CH_RX_STALL){
|
||||||
ch_reg &= USB_EPREG_MASK | CH_STAT_MASK(TUSB_DIR_IN); // will change TX Status, reserved other toggle bits
|
ch_handle_stall(ch_id, ch_reg, TUSB_DIR_IN);
|
||||||
ch_change_status(&ch_reg, TUSB_DIR_IN, EP_STAT_VALID);
|
|
||||||
ch_write(ch_id, ch_reg, false);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// STALLed
|
|
||||||
channel_dealloc(xfer, TUSB_DIR_IN);
|
|
||||||
ch_reg &= USB_EPREG_MASK | CH_STAT_MASK(TUSB_DIR_IN); // will change TX Status, reserved other toggle bits
|
|
||||||
ch_change_status(&ch_reg, TUSB_DIR_IN, EP_STAT_DISABLED);
|
|
||||||
ch_write(ch_id, ch_reg, false);
|
|
||||||
hcd_event_xfer_complete(daddr, ep_num | TUSB_DIR_IN_MASK, xfer->queued_len[TUSB_DIR_IN], XFER_RESULT_STALLED, true);
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// Error
|
ch_handle_error(ch_id, ch_reg, TUSB_DIR_IN);
|
||||||
TU_LOG(FSDEV_DEBUG, "handle_ctr_tx error epreg=0x%08X ch=%u ep=0x%02X daddr=%u queued=%u/%u\r\n",
|
|
||||||
ch_reg, ch_id, ep_num, daddr, xfer->queued_len[TUSB_DIR_IN], edpt->buflen);
|
|
||||||
ch_reg &= USB_EPREG_MASK | CH_STAT_MASK(TUSB_DIR_IN); // will change RX Status, reserved other toggle bits
|
|
||||||
ch_reg &=~USB_CH_ERRRX;
|
|
||||||
if (xfer->retry[TUSB_DIR_IN] < HCD_XFER_ERROR_MAX) {
|
|
||||||
// Retry
|
|
||||||
xfer->retry[TUSB_DIR_IN]++;
|
|
||||||
} else {
|
|
||||||
// Failed after retries
|
|
||||||
channel_dealloc(xfer, TUSB_DIR_IN);
|
|
||||||
ch_change_status(&ch_reg, TUSB_DIR_IN, EP_STAT_DISABLED);
|
|
||||||
hcd_event_xfer_complete(daddr, ep_num | TUSB_DIR_IN_MASK, xfer->queued_len[TUSB_DIR_IN], XFER_RESULT_FAILED, true);
|
|
||||||
}
|
|
||||||
ch_write(ch_id, ch_reg, false);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -468,7 +492,7 @@ void hcd_device_close(uint8_t rhport, uint8_t dev_addr) {
|
|||||||
// Close all endpoints for this device
|
// Close all endpoints for this device
|
||||||
for(uint32_t i = 0; i < CFG_TUH_FSDEV_ENDPOINT_MAX; i++) {
|
for(uint32_t i = 0; i < CFG_TUH_FSDEV_ENDPOINT_MAX; i++) {
|
||||||
hcd_endpoint_t* edpt = &_hcd_data.edpt[i];
|
hcd_endpoint_t* edpt = &_hcd_data.edpt[i];
|
||||||
if (edpt->allocated && edpt->dev_addr == dev_addr) {
|
if (edpt->allocated == 1 && edpt->dev_addr == dev_addr) {
|
||||||
edpoint_close(i);
|
edpoint_close(i);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -496,7 +520,8 @@ bool hcd_edpt_open(uint8_t rhport, uint8_t dev_addr, tusb_desc_endpoint_t const
|
|||||||
edpt->ep_type = ep_type;
|
edpt->ep_type = ep_type;
|
||||||
edpt->max_packet_size = packet_size;
|
edpt->max_packet_size = packet_size;
|
||||||
edpt->interval = ep_desc->bInterval;
|
edpt->interval = ep_desc->bInterval;
|
||||||
edpt->low_speed = (hcd_port_speed_get(rhport) == TUSB_SPEED_FULL && tuh_speed_get(dev_addr) == TUSB_SPEED_LOW);
|
edpt->pid = 0;
|
||||||
|
edpt->low_speed = (hcd_port_speed_get(rhport) == TUSB_SPEED_FULL && tuh_speed_get(dev_addr) == TUSB_SPEED_LOW) ? 1 : 0;
|
||||||
|
|
||||||
// EP0 is bi-directional, so we need to open both OUT and IN channels
|
// EP0 is bi-directional, so we need to open both OUT and IN channels
|
||||||
if (ep_addr == 0) {
|
if (ep_addr == 0) {
|
||||||
@ -525,7 +550,7 @@ bool hcd_edpt_close(uint8_t rhport, uint8_t dev_addr, uint8_t ep_addr) {
|
|||||||
edpoint_close(ep_id_in);
|
edpoint_close(ep_id_in);
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Submit a transfer
|
// Submit a transfer
|
||||||
@ -556,17 +581,12 @@ bool hcd_edpt_abort_xfer(uint8_t rhport, uint8_t dev_addr, uint8_t ep_addr) {
|
|||||||
for (uint8_t i = 0; i < FSDEV_EP_COUNT; i++) {
|
for (uint8_t i = 0; i < FSDEV_EP_COUNT; i++) {
|
||||||
hcd_xfer_t* xfer = &_hcd_data.xfer[i];
|
hcd_xfer_t* xfer = &_hcd_data.xfer[i];
|
||||||
|
|
||||||
if (xfer->allocated[dir] &&
|
if (xfer->allocated[dir] == 1 &&
|
||||||
xfer->dev_addr == dev_addr &&
|
xfer->dev_addr == dev_addr &&
|
||||||
xfer->ep_num == tu_edpt_number(ep_addr)) {
|
xfer->ep_num == tu_edpt_number(ep_addr)) {
|
||||||
|
|
||||||
channel_dealloc(xfer, dir);
|
channel_dealloc(xfer, dir);
|
||||||
|
uint32_t ch_reg = ch_read(i) | USB_EP_CTR_TX | USB_EP_CTR_RX;
|
||||||
uint32_t ch_reg = ch_read(i) | USB_EP_CTR_TX | USB_EP_CTR_RX; // reserve CTR bits
|
channel_write_status(i, ch_reg, dir, EP_STAT_DISABLED, true);
|
||||||
ch_reg &= USB_EPREG_MASK | CH_STAT_MASK(dir); // will change Status, reserved other toggle bits
|
|
||||||
ch_change_status(&ch_reg, dir, EP_STAT_DISABLED);
|
|
||||||
ch_write(i, ch_reg, true);
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -582,6 +602,7 @@ bool hcd_setup_send(uint8_t rhport, uint8_t dev_addr, uint8_t const setup_packet
|
|||||||
|
|
||||||
hcd_endpoint_t *edpt = &_hcd_data.edpt[ep_id];
|
hcd_endpoint_t *edpt = &_hcd_data.edpt[ep_id];
|
||||||
edpt->next_setup = true;
|
edpt->next_setup = true;
|
||||||
|
edpt->pid = 0;
|
||||||
|
|
||||||
return hcd_edpt_xfer(rhport, dev_addr, 0, (uint8_t*)(uintptr_t) setup_packet, 8);
|
return hcd_edpt_xfer(rhport, dev_addr, 0, (uint8_t*)(uintptr_t) setup_packet, 8);
|
||||||
}
|
}
|
||||||
@ -592,6 +613,12 @@ bool hcd_edpt_clear_stall(uint8_t rhport, uint8_t dev_addr, uint8_t ep_addr) {
|
|||||||
(void) dev_addr;
|
(void) dev_addr;
|
||||||
(void) ep_addr;
|
(void) ep_addr;
|
||||||
|
|
||||||
|
uint8_t const ep_id = endpoint_find(dev_addr, 0);
|
||||||
|
TU_ASSERT(ep_id < CFG_TUH_FSDEV_ENDPOINT_MAX);
|
||||||
|
|
||||||
|
hcd_endpoint_t *edpt = &_hcd_data.edpt[ep_id];
|
||||||
|
edpt->pid = 0;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -602,8 +629,8 @@ bool hcd_edpt_clear_stall(uint8_t rhport, uint8_t dev_addr, uint8_t ep_addr) {
|
|||||||
static uint8_t endpoint_alloc(void) {
|
static uint8_t endpoint_alloc(void) {
|
||||||
for (uint32_t i = 0; i < CFG_TUH_FSDEV_ENDPOINT_MAX; i++) {
|
for (uint32_t i = 0; i < CFG_TUH_FSDEV_ENDPOINT_MAX; i++) {
|
||||||
hcd_endpoint_t* edpt = &_hcd_data.edpt[i];
|
hcd_endpoint_t* edpt = &_hcd_data.edpt[i];
|
||||||
if (!edpt->allocated) {
|
if (edpt->allocated == 0) {
|
||||||
edpt->allocated = true;
|
edpt->allocated = 1;
|
||||||
return i;
|
return i;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -613,7 +640,7 @@ static uint8_t endpoint_alloc(void) {
|
|||||||
static uint8_t endpoint_find(uint8_t dev_addr, uint8_t ep_addr) {
|
static uint8_t endpoint_find(uint8_t dev_addr, uint8_t ep_addr) {
|
||||||
for (uint32_t i = 0; i < (uint32_t)CFG_TUH_FSDEV_ENDPOINT_MAX; i++) {
|
for (uint32_t i = 0; i < (uint32_t)CFG_TUH_FSDEV_ENDPOINT_MAX; i++) {
|
||||||
hcd_endpoint_t* edpt = &_hcd_data.edpt[i];
|
hcd_endpoint_t* edpt = &_hcd_data.edpt[i];
|
||||||
if (edpt->allocated && edpt->dev_addr == dev_addr && edpt->ep_addr == ep_addr) {
|
if (edpt->allocated == 1 && edpt->dev_addr == dev_addr && edpt->ep_addr == ep_addr) {
|
||||||
return i;
|
return i;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -628,24 +655,14 @@ static void edpoint_close(uint8_t ep_id) {
|
|||||||
// disable active channel belong to this endpoint
|
// disable active channel belong to this endpoint
|
||||||
for (uint8_t i = 0; i < FSDEV_EP_COUNT; i++) {
|
for (uint8_t i = 0; i < FSDEV_EP_COUNT; i++) {
|
||||||
hcd_xfer_t* xfer = &_hcd_data.xfer[i];
|
hcd_xfer_t* xfer = &_hcd_data.xfer[i];
|
||||||
|
uint32_t ch_reg = ch_read(i) | USB_EP_CTR_TX | USB_EP_CTR_RX;
|
||||||
if (xfer->allocated[TUSB_DIR_OUT] && xfer->edpt[TUSB_DIR_OUT] == edpt) {
|
if (xfer->allocated[TUSB_DIR_OUT] == 1 && xfer->edpt[TUSB_DIR_OUT] == edpt) {
|
||||||
channel_dealloc(xfer, TUSB_DIR_OUT);
|
channel_dealloc(xfer, TUSB_DIR_OUT);
|
||||||
|
channel_write_status(i, ch_reg, TUSB_DIR_OUT, EP_STAT_DISABLED, true);
|
||||||
uint32_t ch_reg = ch_read(i) | USB_EP_CTR_TX | USB_EP_CTR_RX; // reserve CTR bits
|
|
||||||
ch_reg &= USB_EPREG_MASK | CH_STAT_MASK(TUSB_DIR_OUT); // will change RX Status, reserved other toggle bits
|
|
||||||
ch_change_status(&ch_reg, TUSB_DIR_OUT, EP_STAT_DISABLED);
|
|
||||||
ch_write(i, ch_reg, true);
|
|
||||||
|
|
||||||
}
|
}
|
||||||
if (xfer->allocated[TUSB_DIR_IN] && xfer->edpt[TUSB_DIR_IN] == edpt) {
|
if (xfer->allocated[TUSB_DIR_IN] == 1 && xfer->edpt[TUSB_DIR_IN] == edpt) {
|
||||||
channel_dealloc(xfer, TUSB_DIR_IN);
|
channel_dealloc(xfer, TUSB_DIR_IN);
|
||||||
|
channel_write_status(i, ch_reg, TUSB_DIR_IN, EP_STAT_DISABLED, true);
|
||||||
uint32_t ch_reg = ch_read(i) | USB_EP_CTR_TX | USB_EP_CTR_RX; // reserve CTR bits
|
|
||||||
ch_reg &= USB_EPREG_MASK | CH_STAT_MASK(TUSB_DIR_IN); // will change TX Status, reserved other toggle bits
|
|
||||||
ch_change_status(&ch_reg, TUSB_DIR_IN, EP_STAT_DISABLED);
|
|
||||||
ch_write(i, ch_reg, true);
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -654,10 +671,10 @@ static void edpoint_close(uint8_t ep_id) {
|
|||||||
static uint32_t hcd_pma_alloc(uint8_t channel, tusb_dir_t dir, uint16_t len) {
|
static uint32_t hcd_pma_alloc(uint8_t channel, tusb_dir_t dir, uint16_t len) {
|
||||||
(void) len;
|
(void) len;
|
||||||
// Simple static allocation as we are unlikely to handle ISO endpoints in host mode
|
// Simple static allocation as we are unlikely to handle ISO endpoints in host mode
|
||||||
// We just give each channel a buffer of max packet size (64 bytes)
|
// We just give each channel two buffers of max packet size (64 bytes) for IN and OUT
|
||||||
|
|
||||||
uint16_t addr = FSDEV_BTABLE_BASE + 8 * FSDEV_EP_COUNT;
|
uint16_t addr = FSDEV_BTABLE_BASE + 8 * FSDEV_EP_COUNT;
|
||||||
addr += channel * 64 * 2 + (dir == TUSB_DIR_IN ? 64 : 0);
|
addr += channel * TUSB_EPSIZE_BULK_FS * 2 + (dir == TUSB_DIR_IN ? TUSB_EPSIZE_BULK_FS : 0);
|
||||||
|
|
||||||
TU_ASSERT(addr <= FSDEV_PMA_SIZE, 0xFFFF);
|
TU_ASSERT(addr <= FSDEV_PMA_SIZE, 0xFFFF);
|
||||||
|
|
||||||
@ -672,12 +689,12 @@ static uint8_t channel_alloc(uint8_t dev_addr, uint8_t ep_addr, uint8_t ep_type)
|
|||||||
// Find channel allocate for same ep_num but other direction
|
// Find channel allocate for same ep_num but other direction
|
||||||
tusb_dir_t const other_dir = (dir == TUSB_DIR_IN) ? TUSB_DIR_OUT : TUSB_DIR_IN;
|
tusb_dir_t const other_dir = (dir == TUSB_DIR_IN) ? TUSB_DIR_OUT : TUSB_DIR_IN;
|
||||||
for (uint8_t i = 0; i < FSDEV_EP_COUNT; i++) {
|
for (uint8_t i = 0; i < FSDEV_EP_COUNT; i++) {
|
||||||
if (!_hcd_data.xfer[i].allocated[dir] &&
|
if (_hcd_data.xfer[i].allocated[dir] == 0 &&
|
||||||
_hcd_data.xfer[i].allocated[other_dir] &&
|
_hcd_data.xfer[i].allocated[other_dir] == 1 &&
|
||||||
_hcd_data.xfer[i].dev_addr == dev_addr &&
|
_hcd_data.xfer[i].dev_addr == dev_addr &&
|
||||||
_hcd_data.xfer[i].ep_num == ep_num &&
|
_hcd_data.xfer[i].ep_num == ep_num &&
|
||||||
_hcd_data.xfer[i].ep_type == ep_type) {
|
_hcd_data.xfer[i].ep_type == ep_type) {
|
||||||
_hcd_data.xfer[i].allocated[dir] = true;
|
_hcd_data.xfer[i].allocated[dir] = 1;
|
||||||
_hcd_data.xfer[i].queued_len[dir] = 0;
|
_hcd_data.xfer[i].queued_len[dir] = 0;
|
||||||
_hcd_data.xfer[i].retry[dir] = 0;
|
_hcd_data.xfer[i].retry[dir] = 0;
|
||||||
return i;
|
return i;
|
||||||
@ -686,11 +703,11 @@ static uint8_t channel_alloc(uint8_t dev_addr, uint8_t ep_addr, uint8_t ep_type)
|
|||||||
|
|
||||||
// Find free channel
|
// Find free channel
|
||||||
for (uint8_t i = 0; i < FSDEV_EP_COUNT; i++) {
|
for (uint8_t i = 0; i < FSDEV_EP_COUNT; i++) {
|
||||||
if (!_hcd_data.xfer[i].allocated[0] && !_hcd_data.xfer[i].allocated[1]) {
|
if (_hcd_data.xfer[i].allocated[0] == 0 && _hcd_data.xfer[i].allocated[1] == 0) {
|
||||||
_hcd_data.xfer[i].dev_addr = dev_addr;
|
_hcd_data.xfer[i].dev_addr = dev_addr;
|
||||||
_hcd_data.xfer[i].ep_num = ep_num;
|
_hcd_data.xfer[i].ep_num = ep_num;
|
||||||
_hcd_data.xfer[i].ep_type = ep_type;
|
_hcd_data.xfer[i].ep_type = ep_type;
|
||||||
_hcd_data.xfer[i].allocated[dir] = true;
|
_hcd_data.xfer[i].allocated[dir] = 1;
|
||||||
_hcd_data.xfer[i].queued_len[dir] = 0;
|
_hcd_data.xfer[i].queued_len[dir] = 0;
|
||||||
_hcd_data.xfer[i].retry[dir] = 0;
|
_hcd_data.xfer[i].retry[dir] = 0;
|
||||||
return i;
|
return i;
|
||||||
@ -748,86 +765,37 @@ static bool channel_xfer_start(uint8_t ch_id, tusb_dir_t dir) {
|
|||||||
if (dir == TUSB_DIR_OUT) {
|
if (dir == TUSB_DIR_OUT) {
|
||||||
uint16_t const len = tu_min16(edpt->buflen - xfer->queued_len[TUSB_DIR_OUT], edpt->max_packet_size);
|
uint16_t const len = tu_min16(edpt->buflen - xfer->queued_len[TUSB_DIR_OUT], edpt->max_packet_size);
|
||||||
|
|
||||||
hcd_write_packet_memory(pma_addr, &(edpt->buffer[xfer->queued_len[TUSB_DIR_OUT]]), len);
|
fsdev_write_packet_memory(pma_addr, &(edpt->buffer[xfer->queued_len[TUSB_DIR_OUT]]), len);
|
||||||
btable_set_count(ch_id, BTABLE_BUF_TX, len);
|
btable_set_count(ch_id, BTABLE_BUF_TX, len);
|
||||||
|
|
||||||
xfer->queued_len[TUSB_DIR_OUT] += len;
|
xfer->queued_len[TUSB_DIR_OUT] += len;
|
||||||
if (edpt->next_setup) {
|
|
||||||
// Setup packet uses IN token
|
|
||||||
edpt->next_setup = false;
|
|
||||||
ch_reg |= USB_EP_SETUP;
|
|
||||||
}
|
|
||||||
|
|
||||||
ch_change_status(&ch_reg, TUSB_DIR_OUT, EP_STAT_VALID);
|
|
||||||
ch_reg &= USB_EPREG_MASK | CH_STAT_MASK(TUSB_DIR_OUT); // only change TX Status, reserve other toggle bits
|
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
btable_set_rx_bufsize(ch_id, BTABLE_BUF_RX, edpt->max_packet_size);
|
btable_set_rx_bufsize(ch_id, BTABLE_BUF_RX, edpt->max_packet_size);
|
||||||
ch_change_status(&ch_reg, TUSB_DIR_IN, EP_STAT_VALID);
|
|
||||||
ch_reg &= USB_EPREG_MASK | CH_STAT_MASK(TUSB_DIR_IN); // will change RX Status, reserved other toggle bits
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (edpt->low_speed == 1) {
|
||||||
|
ch_reg |= USB_CHEP_LSEP;
|
||||||
|
} else {
|
||||||
|
ch_reg &= ~USB_CHEP_LSEP;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (tu_edpt_number(edpt->ep_addr) == 0) {
|
||||||
|
edpt->pid = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (edpt->next_setup) {
|
||||||
|
// Setup packet uses IN token
|
||||||
|
edpt->next_setup = false;
|
||||||
|
ch_reg |= USB_EP_SETUP;
|
||||||
|
edpt->pid = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
ch_change_status(&ch_reg, dir, EP_STAT_VALID);
|
||||||
|
ch_change_dtog(&ch_reg, dir, edpt->pid);
|
||||||
|
ch_reg &= USB_EPREG_MASK | CH_STAT_MASK(dir) | CH_DTOG_MASK(dir);
|
||||||
ch_write(ch_id, ch_reg, true);
|
ch_write(ch_id, ch_reg, true);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
//--------------------------------------------------------------------+
|
|
||||||
// PMA read/write
|
|
||||||
//--------------------------------------------------------------------+
|
|
||||||
|
|
||||||
// Write to packet memory area (PMA) from user memory
|
|
||||||
static bool hcd_write_packet_memory(uint16_t dst, const void *__restrict src, uint16_t nbytes) {
|
|
||||||
if (nbytes == 0) return true;
|
|
||||||
uint32_t n_write = nbytes / FSDEV_BUS_SIZE;
|
|
||||||
|
|
||||||
fsdev_pma_buf_t *pma_buf = PMA_BUF_AT(dst);
|
|
||||||
const uint8_t *src8 = src;
|
|
||||||
|
|
||||||
while (n_write--) {
|
|
||||||
pma_buf->value = fsdevbus_unaligned_read(src8);
|
|
||||||
src8 += FSDEV_BUS_SIZE;
|
|
||||||
pma_buf++;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Handle odd bytes
|
|
||||||
uint16_t odd = nbytes & (FSDEV_BUS_SIZE - 1);
|
|
||||||
if (odd) {
|
|
||||||
fsdev_bus_t temp = 0;
|
|
||||||
for (uint16_t i = 0; i < odd; i++) {
|
|
||||||
temp |= *src8++ << (i * 8);
|
|
||||||
}
|
|
||||||
pma_buf->value = temp;
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Read from packet memory area (PMA) to user memory
|
|
||||||
static bool hcd_read_packet_memory(void *__restrict dst, uint16_t src, uint16_t nbytes) {
|
|
||||||
if (nbytes == 0) return true;
|
|
||||||
uint32_t n_read = nbytes / FSDEV_BUS_SIZE;
|
|
||||||
|
|
||||||
fsdev_pma_buf_t *pma_buf = PMA_BUF_AT(src);
|
|
||||||
uint8_t *dst8 = (uint8_t *)dst;
|
|
||||||
|
|
||||||
while (n_read--) {
|
|
||||||
fsdevbus_unaligned_write(dst8, (fsdev_bus_t) pma_buf->value);
|
|
||||||
dst8 += FSDEV_BUS_SIZE;
|
|
||||||
pma_buf++;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Handle odd bytes
|
|
||||||
uint16_t odd = nbytes & (FSDEV_BUS_SIZE - 1);
|
|
||||||
if (odd) {
|
|
||||||
fsdev_bus_t temp = pma_buf->value;
|
|
||||||
while (odd--) {
|
|
||||||
*dst8++ = (uint8_t)(temp & 0xfful);
|
|
||||||
temp >>= 8;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@ -217,7 +217,9 @@
|
|||||||
</group>
|
</group>
|
||||||
<group name="src/portable/st/stm32_fsdev">
|
<group name="src/portable/st/stm32_fsdev">
|
||||||
<path>$TUSB_DIR$/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c</path>
|
<path>$TUSB_DIR$/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c</path>
|
||||||
<path>$TUSB_DIR$/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.h</path>
|
<path>$TUSB_DIR$/src/portable/st/stm32_fsdev/hcd_stm32_fsdev.c</path>
|
||||||
|
<path>$TUSB_DIR$/src/portable/st/stm32_fsdev/fsdev_common.c</path>
|
||||||
|
<path>$TUSB_DIR$/src/portable/st/stm32_fsdev/fsdev_common.h</path>
|
||||||
</group>
|
</group>
|
||||||
<group name="src/portable/st/typec">
|
<group name="src/portable/st/typec">
|
||||||
<path>$TUSB_DIR$/src/portable/st/typec/typec_stm32.c</path>
|
<path>$TUSB_DIR$/src/portable/st/typec/typec_stm32.c</path>
|
||||||
|
|||||||
Reference in New Issue
Block a user