diff --git a/.github/workflows/cmake_arm.yml b/.github/workflows/cmake_arm.yml
index 4d8cd5591..276360650 100644
--- a/.github/workflows/cmake_arm.yml
+++ b/.github/workflows/cmake_arm.yml
@@ -35,7 +35,7 @@ jobs:
# Alphabetical order
- 'imxrt'
- 'kinetis_kl'
- - 'lpc18'
+ - 'lpc18 lpc40'
- 'lpc55'
- 'mcx'
- 'ra'
diff --git a/.idea/runConfigurations/lpc4088.xml b/.idea/runConfigurations/lpc4088.xml
new file mode 100644
index 000000000..89226ac30
--- /dev/null
+++ b/.idea/runConfigurations/lpc4088.xml
@@ -0,0 +1,10 @@
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/examples/dual/host_hid_to_device_cdc/only.txt b/examples/dual/host_hid_to_device_cdc/only.txt
index d9700677f..a3b567f9a 100644
--- a/examples/dual/host_hid_to_device_cdc/only.txt
+++ b/examples/dual/host_hid_to_device_cdc/only.txt
@@ -1,4 +1,5 @@
board:mimxrt1060_evk
board:mimxrt1064_evk
+board:mcb1800
mcu:RP2040
mcu:ra6m5
diff --git a/examples/rules.mk b/examples/rules.mk
index e50c0ec7d..44698b019 100644
--- a/examples/rules.mk
+++ b/examples/rules.mk
@@ -99,19 +99,16 @@ endif
JLINK_IF ?= swd
# Jlink script
-define jlink_script
-halt
-loadfile $^
-r
-go
-exit
-endef
-export jlink_script
+$(BUILD)/$(BOARD).jlink: $(BUILD)/$(PROJECT).hex
+ @echo halt > $@
+ @echo loadfile $^ >> $@
+ @echo r >> $@
+ @echo go >> $@
+ @echo exit >> $@
# Flash using jlink
-flash-jlink: $(BUILD)/$(PROJECT).hex
- @echo "$$jlink_script" > $(BUILD)/$(BOARD).jlink
- $(JLINKEXE) -device $(JLINK_DEVICE) -if $(JLINK_IF) -JTAGConf -1,-1 -speed auto -CommandFile $(BUILD)/$(BOARD).jlink
+flash-jlink: $(BUILD)/$(BOARD).jlink
+ $(JLINKEXE) -device $(JLINK_DEVICE) -if $(JLINK_IF) -JTAGConf -1,-1 -speed auto -CommandFile $<
# Flash STM32 MCU using stlink with STM32 Cube Programmer CLI
flash-stlink: $(BUILD)/$(PROJECT).elf
diff --git a/hw/bsp/imxrt/family.cmake b/hw/bsp/imxrt/family.cmake
index f1c5b0ab1..96ed4b030 100644
--- a/hw/bsp/imxrt/family.cmake
+++ b/hw/bsp/imxrt/family.cmake
@@ -22,69 +22,71 @@ set(FAMILY_MCUS MIMXRT1XXX CACHE INTERNAL "")
#------------------------------------
# only need to be built ONCE for all examples
function(add_board_target BOARD_TARGET)
- if (NOT TARGET ${BOARD_TARGET})
- add_library(${BOARD_TARGET} STATIC
- ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/boards/${BOARD}/board/clock_config.c
- #${SDK_DIR}/drivers/adc_12b1msps_sar/fsl_adc.c
- ${SDK_DIR}/drivers/common/fsl_common.c
- ${SDK_DIR}/drivers/igpio/fsl_gpio.c
- ${SDK_DIR}/drivers/lpspi/fsl_lpspi.c
- ${SDK_DIR}/drivers/lpuart/fsl_lpuart.c
- ${SDK_DIR}/devices/${MCU_VARIANT}/system_${MCU_VARIANT}.c
- ${SDK_DIR}/devices/${MCU_VARIANT}/xip/fsl_flexspi_nor_boot.c
- ${SDK_DIR}/devices/${MCU_VARIANT}/drivers/fsl_clock.c
+ if (TARGET ${BOARD_TARGET})
+ return()
+ endif ()
+
+ add_library(${BOARD_TARGET} STATIC
+ ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/boards/${BOARD}/board/clock_config.c
+ #${SDK_DIR}/drivers/adc_12b1msps_sar/fsl_adc.c
+ ${SDK_DIR}/drivers/common/fsl_common.c
+ ${SDK_DIR}/drivers/igpio/fsl_gpio.c
+ ${SDK_DIR}/drivers/lpspi/fsl_lpspi.c
+ ${SDK_DIR}/drivers/lpuart/fsl_lpuart.c
+ ${SDK_DIR}/devices/${MCU_VARIANT}/system_${MCU_VARIANT}.c
+ ${SDK_DIR}/devices/${MCU_VARIANT}/xip/fsl_flexspi_nor_boot.c
+ ${SDK_DIR}/devices/${MCU_VARIANT}/drivers/fsl_clock.c
+ )
+ target_compile_definitions(${BOARD_TARGET} PUBLIC
+ __ARMVFP__=0
+ __ARMFPV5__=0
+ XIP_EXTERNAL_FLASH=1
+ XIP_BOOT_HEADER_ENABLE=1
+ )
+ target_include_directories(${BOARD_TARGET} PUBLIC
+ ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/boards/${BOARD}
+ ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/boards/${BOARD}/board
+ ${CMSIS_DIR}/CMSIS/Core/Include
+ ${SDK_DIR}/devices/${MCU_VARIANT}
+ ${SDK_DIR}/devices/${MCU_VARIANT}/drivers
+ #${SDK_DIR}/drivers/adc_12b1msps_sar
+ ${SDK_DIR}/drivers/common
+ ${SDK_DIR}/drivers/igpio
+ ${SDK_DIR}/drivers/lpspi
+ ${SDK_DIR}/drivers/lpuart
+ )
+
+ update_board(${BOARD_TARGET})
+
+ # LD_FILE and STARTUP_FILE can be defined in board.cmake
+ if (NOT DEFINED LD_FILE_${CMAKE_C_COMPILER_ID})
+ set(LD_FILE_GNU ${SDK_DIR}/devices/${MCU_VARIANT}/gcc/${MCU_VARIANT}xxxxx_flexspi_nor.ld)
+ #set(LD_FILE_IAR ${SDK_DIR}/devices/${MCU_VARIANT}/gcc/${MCU_VARIANT}xxxxx_flexspi_nor.ld)
+ endif ()
+
+ if (NOT DEFINED STARTUP_FILE_${CMAKE_C_COMPILER_ID})
+ set(STARTUP_FILE_GNU ${SDK_DIR}/devices/${MCU_VARIANT}/gcc/startup_${MCU_VARIANT}.S)
+ #set(STARTUP_FILE_IAR ${SDK_DIR}/devices/${MCU_VARIANT}/gcc/startup_${MCU_VARIANT}.S)
+ endif ()
+
+ target_sources(${BOARD_TARGET} PUBLIC
+ ${STARTUP_FILE_${CMAKE_C_COMPILER_ID}}
+ )
+
+ if (CMAKE_C_COMPILER_ID STREQUAL "GNU")
+ target_link_options(${BOARD_TARGET} PUBLIC
+ "LINKER:--script=${LD_FILE_GNU}"
+ # nanolib
+ --specs=nosys.specs
+ --specs=nano.specs
+ # force linker to look for these symbols
+ -Wl,-uimage_vector_table
+ -Wl,-ug_boot_data
)
- target_compile_definitions(${BOARD_TARGET} PUBLIC
- __ARMVFP__=0
- __ARMFPV5__=0
- XIP_EXTERNAL_FLASH=1
- XIP_BOOT_HEADER_ENABLE=1
+ elseif (CMAKE_C_COMPILER_ID STREQUAL "IAR")
+ target_link_options(${BOARD_TARGET} PUBLIC
+ "LINKER:--config=${LD_FILE_IAR}"
)
- target_include_directories(${BOARD_TARGET} PUBLIC
- ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/boards/${BOARD}
- ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/boards/${BOARD}/board
- ${CMSIS_DIR}/CMSIS/Core/Include
- ${SDK_DIR}/devices/${MCU_VARIANT}
- ${SDK_DIR}/devices/${MCU_VARIANT}/drivers
- #${SDK_DIR}/drivers/adc_12b1msps_sar
- ${SDK_DIR}/drivers/common
- ${SDK_DIR}/drivers/igpio
- ${SDK_DIR}/drivers/lpspi
- ${SDK_DIR}/drivers/lpuart
- )
-
- update_board(${BOARD_TARGET})
-
- # LD_FILE and STARTUP_FILE can be defined in board.cmake
- if (NOT DEFINED LD_FILE_${CMAKE_C_COMPILER_ID})
- set(LD_FILE_GNU ${SDK_DIR}/devices/${MCU_VARIANT}/gcc/${MCU_VARIANT}xxxxx_flexspi_nor.ld)
- #set(LD_FILE_IAR ${SDK_DIR}/devices/${MCU_VARIANT}/gcc/${MCU_VARIANT}xxxxx_flexspi_nor.ld)
- endif ()
-
- if (NOT DEFINED STARTUP_FILE_${CMAKE_C_COMPILER_ID})
- set(STARTUP_FILE_GNU ${SDK_DIR}/devices/${MCU_VARIANT}/gcc/startup_${MCU_VARIANT}.S)
- #set(STARTUP_FILE_IAR ${SDK_DIR}/devices/${MCU_VARIANT}/gcc/startup_${MCU_VARIANT}.S)
- endif ()
-
- target_sources(${BOARD_TARGET} PUBLIC
- ${STARTUP_FILE_${CMAKE_C_COMPILER_ID}}
- )
-
- if (CMAKE_C_COMPILER_ID STREQUAL "GNU")
- target_link_options(${BOARD_TARGET} PUBLIC
- "LINKER:--script=${LD_FILE_GNU}"
- # nanolib
- --specs=nosys.specs
- --specs=nano.specs
- # force linker to look for these symbols
- -Wl,-uimage_vector_table
- -Wl,-ug_boot_data
- )
- elseif (CMAKE_C_COMPILER_ID STREQUAL "IAR")
- target_link_options(${BOARD_TARGET} PUBLIC
- "LINKER:--config=${LD_FILE_IAR}"
- )
- endif ()
endif ()
endfunction()
@@ -114,7 +116,7 @@ function(family_configure_example TARGET RTOS)
# Add TinyUSB target and port source
family_add_tinyusb(${TARGET} OPT_MCU_MIMXRT1XXX ${RTOS})
- target_sources(${TARGET}-tinyusb PUBLIC
+ target_sources(${TARGET}-tinyusb PRIVATE
${TOP}/src/portable/chipidea/ci_hs/dcd_ci_hs.c
${TOP}/src/portable/chipidea/ci_hs/hcd_ci_hs.c
${TOP}/src/portable/ehci/ehci.c
diff --git a/hw/bsp/lpc18/boards/mcb1800/board.h b/hw/bsp/lpc18/boards/mcb1800/board.h
index 5bfaa37cd..93b3cd112 100644
--- a/hw/bsp/lpc18/boards/mcb1800/board.h
+++ b/hw/bsp/lpc18/boards/mcb1800/board.h
@@ -71,7 +71,6 @@ static inline void board_lpc18_pinmux(void) {
// USB0
{ 0x6, 3, SCU_MODE_PULLUP | SCU_MODE_INBUFF_EN | SCU_MODE_FUNC1 }, // P6_3 USB0_PWR_EN, USB0 VBus function
-
{ 0x9, 5, SCU_MODE_PULLUP | SCU_MODE_INBUFF_EN | SCU_MODE_FUNC2 }, // P9_5 USB1_VBUS_EN, USB1 VBus function
{ 0x2, 5, SCU_MODE_INACT | SCU_MODE_INBUFF_EN | SCU_MODE_ZIF_DIS | SCU_MODE_FUNC2 }, // P2_5 USB1_VBUS, MUST CONFIGURE THIS SIGNAL FOR USB1 NORMAL OPERATION
};
diff --git a/hw/bsp/lpc40/FreeRTOSConfig/FreeRTOSConfig.h b/hw/bsp/lpc40/FreeRTOSConfig/FreeRTOSConfig.h
new file mode 100644
index 000000000..96611ca1c
--- /dev/null
+++ b/hw/bsp/lpc40/FreeRTOSConfig/FreeRTOSConfig.h
@@ -0,0 +1,165 @@
+/*
+ * FreeRTOS Kernel V10.0.0
+ * Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
+ *
+ * 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. If you wish to use our Amazon
+ * FreeRTOS name, please do so in a fair use way that does not cause confusion.
+ *
+ * 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.
+ *
+ * http://www.FreeRTOS.org
+ * http://aws.amazon.com/freertos
+ *
+ * 1 tab == 4 spaces!
+ */
+
+
+#ifndef FREERTOS_CONFIG_H
+#define FREERTOS_CONFIG_H
+
+/*-----------------------------------------------------------
+ * Application specific definitions.
+ *
+ * These definitions should be adjusted for your particular hardware and
+ * application requirements.
+ *
+ * THESE PARAMETERS ARE DESCRIBED WITHIN THE 'CONFIGURATION' SECTION OF THE
+ * FreeRTOS API DOCUMENTATION AVAILABLE ON THE FreeRTOS.org WEB SITE.
+ *
+ * See http://www.freertos.org/a00110.html.
+ *----------------------------------------------------------*/
+
+// skip if included from IAR assembler
+#ifndef __IASMARM__
+ #include "chip.h"
+#endif
+
+/* Cortex M23/M33 port configuration. */
+#define configENABLE_MPU 0
+#define configENABLE_FPU 1
+#define configENABLE_TRUSTZONE 0
+#define configMINIMAL_SECURE_STACK_SIZE (1024)
+
+#define configUSE_PREEMPTION 1
+#define configUSE_PORT_OPTIMISED_TASK_SELECTION 0
+#define configCPU_CLOCK_HZ SystemCoreClock
+#define configTICK_RATE_HZ ( 1000 )
+#define configMAX_PRIORITIES ( 5 )
+#define configMINIMAL_STACK_SIZE ( 128 )
+#define configTOTAL_HEAP_SIZE ( configSUPPORT_DYNAMIC_ALLOCATION*4*1024 )
+#define configMAX_TASK_NAME_LEN 16
+#define configUSE_16_BIT_TICKS 0
+#define configIDLE_SHOULD_YIELD 1
+#define configUSE_MUTEXES 1
+#define configUSE_RECURSIVE_MUTEXES 1
+#define configUSE_COUNTING_SEMAPHORES 1
+#define configQUEUE_REGISTRY_SIZE 2
+#define configUSE_QUEUE_SETS 0
+#define configUSE_TIME_SLICING 0
+#define configUSE_NEWLIB_REENTRANT 0
+#define configENABLE_BACKWARD_COMPATIBILITY 1
+#define configSTACK_ALLOCATION_FROM_SEPARATE_HEAP 0
+
+#define configSUPPORT_STATIC_ALLOCATION 0
+#define configSUPPORT_DYNAMIC_ALLOCATION 1
+
+/* Hook function related definitions. */
+#define configUSE_IDLE_HOOK 0
+#define configUSE_TICK_HOOK 0
+#define configUSE_MALLOC_FAILED_HOOK 0 // cause nested extern warning
+#define configCHECK_FOR_STACK_OVERFLOW 2
+
+/* Run time and task stats gathering related definitions. */
+#define configGENERATE_RUN_TIME_STATS 0
+#define configRECORD_STACK_HIGH_ADDRESS 1
+#define configUSE_TRACE_FACILITY 1 // legacy trace
+#define configUSE_STATS_FORMATTING_FUNCTIONS 0
+
+/* Co-routine definitions. */
+#define configUSE_CO_ROUTINES 0
+#define configMAX_CO_ROUTINE_PRIORITIES 2
+
+/* Software timer related definitions. */
+#define configUSE_TIMERS 1
+#define configTIMER_TASK_PRIORITY (configMAX_PRIORITIES-2)
+#define configTIMER_QUEUE_LENGTH 32
+#define configTIMER_TASK_STACK_DEPTH configMINIMAL_STACK_SIZE
+
+/* Optional functions - most linkers will remove unused functions anyway. */
+#define INCLUDE_vTaskPrioritySet 0
+#define INCLUDE_uxTaskPriorityGet 0
+#define INCLUDE_vTaskDelete 0
+#define INCLUDE_vTaskSuspend 1 // required for queue, semaphore, mutex to be blocked indefinitely with portMAX_DELAY
+#define INCLUDE_xResumeFromISR 0
+#define INCLUDE_vTaskDelayUntil 1
+#define INCLUDE_vTaskDelay 1
+#define INCLUDE_xTaskGetSchedulerState 0
+#define INCLUDE_xTaskGetCurrentTaskHandle 1
+#define INCLUDE_uxTaskGetStackHighWaterMark 0
+#define INCLUDE_xTaskGetIdleTaskHandle 0
+#define INCLUDE_xTimerGetTimerDaemonTaskHandle 0
+#define INCLUDE_pcTaskGetTaskName 0
+#define INCLUDE_eTaskGetState 0
+#define INCLUDE_xEventGroupSetBitFromISR 0
+#define INCLUDE_xTimerPendFunctionCall 0
+
+/* Define to trap errors during development. */
+// Halt CPU (breakpoint) when hitting error, only apply for Cortex M3, M4, M7
+#if defined(__ARM_ARCH_7M__) || defined (__ARM_ARCH_7EM__)
+ #define configASSERT(_exp) \
+ do {\
+ if ( !(_exp) ) { \
+ volatile uint32_t* ARM_CM_DHCSR = ((volatile uint32_t*) 0xE000EDF0UL); /* Cortex M CoreDebug->DHCSR */ \
+ if ( (*ARM_CM_DHCSR) & 1UL ) { /* Only halt mcu if debugger is attached */ \
+ taskDISABLE_INTERRUPTS(); \
+ __asm("BKPT #0\n"); \
+ }\
+ }\
+ } while(0)
+#else
+ #define configASSERT( x )
+#endif
+
+/* FreeRTOS hooks to NVIC vectors */
+#define xPortPendSVHandler PendSV_Handler
+#define xPortSysTickHandler SysTick_Handler
+#define vPortSVCHandler SVC_Handler
+
+//--------------------------------------------------------------------+
+// Interrupt nesting behavior configuration.
+//--------------------------------------------------------------------+
+
+// For Cortex-M specific: __NVIC_PRIO_BITS is defined in mcu header
+#define configPRIO_BITS 5
+
+/* The lowest interrupt priority that can be used in a call to a "set priority" function. */
+#define configLIBRARY_LOWEST_INTERRUPT_PRIORITY ((1<OTGClkCtrl = USBCLK_ALL;
@@ -151,40 +121,37 @@ void board_init(void)
// Board porting API
//--------------------------------------------------------------------+
-void board_led_write(bool state)
-{
+void board_led_write(bool state) {
Chip_GPIO_SetPinState(LPC_GPIO, LED_PORT, LED_PIN, state);
}
-uint32_t board_button_read(void)
-{
- // active low
- return Chip_GPIO_GetPinState(LPC_GPIO, BUTTON_PORT, BUTTON_PIN) ? 0 : 1;
+uint32_t board_button_read(void) {
+ return BUTTON_ACTIV_STATE == Chip_GPIO_GetPinState(LPC_GPIO, BUTTON_PORT, BUTTON_PIN);
}
-int board_uart_read(uint8_t* buf, int len)
-{
+int board_uart_read(uint8_t *buf, int len) {
//return UART_ReceiveByte(BOARD_UART_PORT);
- (void) buf; (void) len;
+ (void) buf;
+ (void) len;
return 0;
}
-int board_uart_write(void const * buf, int len)
-{
+int board_uart_write(void const *buf, int len) {
//UART_Send(BOARD_UART_PORT, &c, 1, BLOCKING);
- (void) buf; (void) len;
+ (void) buf;
+ (void) len;
return 0;
}
#if CFG_TUSB_OS == OPT_OS_NONE
volatile uint32_t system_ticks = 0;
-void SysTick_Handler (void)
-{
+
+void SysTick_Handler(void) {
system_ticks++;
}
-uint32_t board_millis(void)
-{
+uint32_t board_millis(void) {
return system_ticks;
}
+
#endif
diff --git a/hw/bsp/lpc40/family.cmake b/hw/bsp/lpc40/family.cmake
new file mode 100644
index 000000000..56eb37a2f
--- /dev/null
+++ b/hw/bsp/lpc40/family.cmake
@@ -0,0 +1,102 @@
+include_guard()
+
+set(SDK_DIR ${TOP}/hw/mcu/nxp/lpcopen/lpc40xx/lpc_chip_40xx)
+
+# include board specific
+include(${CMAKE_CURRENT_LIST_DIR}/boards/${BOARD}/board.cmake)
+
+# toolchain set up
+set(CMAKE_SYSTEM_PROCESSOR cortex-m4 CACHE INTERNAL "System Processor")
+set(CMAKE_TOOLCHAIN_FILE ${TOP}/tools/cmake/toolchain/arm_${TOOLCHAIN}.cmake)
+
+set(FAMILY_MCUS LPC18XX CACHE INTERNAL "")
+
+
+#------------------------------------
+# BOARD_TARGET
+#------------------------------------
+# only need to be built ONCE for all examples
+function(add_board_target BOARD_TARGET)
+ if (TARGET ${BOARD_TARGET})
+ return()
+ endif ()
+
+ add_library(${BOARD_TARGET} STATIC
+ ${SDK_DIR}/../gcc/cr_startup_lpc40xx.c
+ ${SDK_DIR}/src/chip_17xx_40xx.c
+ ${SDK_DIR}/src/clock_17xx_40xx.c
+ ${SDK_DIR}/src/fpu_init.c
+ ${SDK_DIR}/src/gpio_17xx_40xx.c
+ ${SDK_DIR}/src/iocon_17xx_40xx.c
+ ${SDK_DIR}/src/sysctl_17xx_40xx.c
+ ${SDK_DIR}/src/sysinit_17xx_40xx.c
+ ${SDK_DIR}/src/uart_17xx_40xx.c
+ )
+ target_compile_options(${BOARD_TARGET} PUBLIC
+ -nostdlib
+ )
+ target_compile_definitions(${BOARD_TARGET} PUBLIC
+ __USE_LPCOPEN
+ CORE_M4
+ CFG_TUSB_MEM_SECTION=__attribute__\(\(section\(\".data.$RAM2\"\)\)\)
+ )
+ target_include_directories(${BOARD_TARGET} PUBLIC
+ ${SDK_DIR}/inc
+ )
+
+ update_board(${BOARD_TARGET})
+
+ if (CMAKE_C_COMPILER_ID STREQUAL "GNU")
+ target_link_options(${BOARD_TARGET} PUBLIC
+ "LINKER:--script=${LD_FILE_GNU}"
+ # nanolib
+ --specs=nosys.specs
+ --specs=nano.specs
+ )
+ elseif (CMAKE_C_COMPILER_ID STREQUAL "IAR")
+ target_link_options(${BOARD_TARGET} PUBLIC
+ "LINKER:--config=${LD_FILE_IAR}"
+ )
+ endif ()
+endfunction()
+
+
+#------------------------------------
+# Functions
+#------------------------------------
+function(family_configure_example TARGET RTOS)
+ family_configure_common(${TARGET} ${RTOS})
+
+ # Board target
+ add_board_target(board_${BOARD})
+
+ #---------- Port Specific ----------
+ # These files are built for each example since it depends on example's tusb_config.h
+ target_sources(${TARGET} PUBLIC
+ # BSP
+ ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/family.c
+ ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/../board.c
+ )
+ target_include_directories(${TARGET} PUBLIC
+ # family, hw, board
+ ${CMAKE_CURRENT_FUNCTION_LIST_DIR}
+ ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/../../
+ ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/boards/${BOARD}
+ )
+
+ # Add TinyUSB target and port source
+ family_add_tinyusb(${TARGET} OPT_MCU_LPC40XX ${RTOS})
+ target_sources(${TARGET}-tinyusb PUBLIC
+ ${TOP}/src/portable/nxp/lpc17_40/dcd_lpc17_40.c
+ ${TOP}/src/portable/nxp/lpc17_40/hcd_lpc17_40.c
+ ${TOP}/src/portable/ohci/ohci.c
+ )
+ target_link_libraries(${TARGET}-tinyusb PUBLIC board_${BOARD})
+
+ # Link dependencies
+ target_link_libraries(${TARGET} PUBLIC board_${BOARD} ${TARGET}-tinyusb)
+
+ # Flashing
+ family_flash_jlink(${TARGET})
+ #family_flash_nxplink(${TARGET})
+endfunction()
diff --git a/hw/bsp/ea4088qs/board.mk b/hw/bsp/lpc40/family.mk
similarity index 59%
rename from hw/bsp/ea4088qs/board.mk
rename to hw/bsp/lpc40/family.mk
index e1e14b717..c11325890 100644
--- a/hw/bsp/ea4088qs/board.mk
+++ b/hw/bsp/lpc40/family.mk
@@ -1,47 +1,33 @@
DEPS_SUBMODULES += hw/mcu/nxp/lpcopen
+MCU_DIR = hw/mcu/nxp/lpcopen/lpc40xx/lpc_chip_40xx
+include $(TOP)/$(BOARD_PATH)/board.mk
+CPU_CORE ?= cortex-m4
+
CFLAGS += \
-flto \
- -mthumb \
- -mabi=aapcs \
- -mcpu=cortex-m4 \
- -mfloat-abi=hard \
- -mfpu=fpv4-sp-d16 \
-nostdlib \
-DCORE_M4 \
-D__USE_LPCOPEN \
- -DCFG_TUD_MEM_SECTION='__attribute__((section(".data.$$RAM2")))' \
- -DCFG_TUH_MEM_SECTION='__attribute__((section(".data.$$RAM2")))' \
+ -DCFG_TUSB_MEM_SECTION='__attribute__((section(".data.$$RAM2")))' \
-DCFG_TUSB_MCU=OPT_MCU_LPC40XX
# mcu driver cause following warnings
CFLAGS += -Wno-error=strict-prototypes -Wno-error=unused-parameter -Wno-error=cast-qual
-MCU_DIR = hw/mcu/nxp/lpcopen/lpc40xx/lpc_chip_40xx
-
# All source paths should be relative to the top level.
-LD_FILE = hw/bsp/$(BOARD)/lpc4088.ld
-
SRC_C += \
src/portable/nxp/lpc17_40/dcd_lpc17_40.c \
$(MCU_DIR)/../gcc/cr_startup_lpc40xx.c \
$(MCU_DIR)/src/chip_17xx_40xx.c \
$(MCU_DIR)/src/clock_17xx_40xx.c \
+ $(MCU_DIR)/src/fpu_init.c \
$(MCU_DIR)/src/gpio_17xx_40xx.c \
$(MCU_DIR)/src/iocon_17xx_40xx.c \
$(MCU_DIR)/src/sysctl_17xx_40xx.c \
$(MCU_DIR)/src/sysinit_17xx_40xx.c \
$(MCU_DIR)/src/uart_17xx_40xx.c \
- $(MCU_DIR)/src/fpu_init.c
INC += \
- $(TOP)/$(MCU_DIR)/inc
-
-# For freeRTOS port source
-FREERTOS_PORTABLE_SRC = $(FREERTOS_PORTABLE_PATH)/ARM_CM4F
-
-# For flash-jlink target
-JLINK_DEVICE = LPC4088
-
-# flash using jlink
-flash: flash-jlink
+ $(TOP)/$(MCU_DIR)/inc \
+ $(TOP)/$(BOARD_PATH)
diff --git a/hw/bsp/rp2040/board.h b/hw/bsp/rp2040/board.h
index 934e1c7ae..063c9580e 100644
--- a/hw/bsp/rp2040/board.h
+++ b/hw/bsp/rp2040/board.h
@@ -54,19 +54,19 @@
// default to pin on Adafruit Feather rp2040 USB Host or Tester if defined
//--------------------------------------------------------------------+
-// #define USE_ADAFRUIT_RP2040_TESTER
-#ifdef USE_ADAFRUIT_RP2040_TESTER
-#define PICO_DEFAULT_PIO_USB_DP_PIN 20
-#define PICO_DEFAULT_PIO_USB_VBUSEN_PIN 22
+// #define USE_ADAFRUIT_FEATHER_RP2040_USBHOST
+#ifdef USE_ADAFRUIT_FEATHER_RP2040_USBHOST
+#define PICO_DEFAULT_PIO_USB_DP_PIN 16
+#define PICO_DEFAULT_PIO_USB_VBUSEN_PIN 18
#endif
#ifndef PICO_DEFAULT_PIO_USB_DP_PIN
-#define PICO_DEFAULT_PIO_USB_DP_PIN 16
+#define PICO_DEFAULT_PIO_USB_DP_PIN 20
#endif
// VBUS enable pin and its active state
#ifndef PICO_DEFAULT_PIO_USB_VBUSEN_PIN
-#define PICO_DEFAULT_PIO_USB_VBUSEN_PIN 18
+#define PICO_DEFAULT_PIO_USB_VBUSEN_PIN 22
#endif
// VBUS enable state
diff --git a/hw/bsp/rp2040/family.cmake b/hw/bsp/rp2040/family.cmake
index b986b3ebb..17900dd7a 100644
--- a/hw/bsp/rp2040/family.cmake
+++ b/hw/bsp/rp2040/family.cmake
@@ -183,6 +183,15 @@ function(family_add_pico_pio_usb TARGET)
target_link_libraries(${TARGET} PUBLIC tinyusb_pico_pio_usb)
endfunction()
+# since Pico-PIO_USB compiler support may lag, and change from version to version, add a function that pico-sdk/pico-examples
+# can check (if present) in case the user has updated their TinyUSB
+function(is_compiler_supported_by_pico_pio_usb OUTVAR)
+ if ((NOT CMAKE_C_COMPILER_ID STREQUAL "GNU"))
+ SET(${OUTVAR} 0 PARENT_SCOPE)
+ else()
+ set(${OUTVAR} 1 PARENT_SCOPE)
+ endif()
+endfunction()
function(family_configure_host_example TARGET RTOS)
family_configure_target(${TARGET} ${RTOS})
@@ -191,8 +200,9 @@ function(family_configure_host_example TARGET RTOS)
# For rp2040 enable pico-pio-usb
if (TARGET tinyusb_pico_pio_usb)
- # code does not compile with non GCC, or GCC 11.3+
- if (CMAKE_C_COMPILER_ID STREQUAL "GNU" AND NOT CMAKE_C_COMPILER_VERSION VERSION_GREATER_EQUAL 11.3)
+ # Pico-PIO-USB does not compile with all pico-sdk supported compilers, so check before enabling it
+ is_compiler_supported_by_pico_pio_usb(PICO_PIO_USB_COMPILER_SUPPORTED)
+ if (PICO_PIO_USB_COMPILER_SUPPORTED)
family_add_pico_pio_usb(${PROJECT})
endif()
endif()
diff --git a/hw/bsp/stm32h7/boards/stm32h743eval/board.h b/hw/bsp/stm32h7/boards/stm32h743eval/board.h
index 7e3c015c8..c46b525ca 100644
--- a/hw/bsp/stm32h7/boards/stm32h743eval/board.h
+++ b/hw/bsp/stm32h7/boards/stm32h743eval/board.h
@@ -61,8 +61,7 @@
//--------------------------------------------------------------------+
// RCC Clock
//--------------------------------------------------------------------+
-static inline void board_stm32h7_clock_init(void)
-{
+static inline void board_stm32h7_clock_init(void) {
RCC_ClkInitTypeDef RCC_ClkInitStruct = { 0 };
RCC_OscInitTypeDef RCC_OscInitStruct = { 0 };
RCC_PeriphCLKInitTypeDef PeriphClkInitStruct = { 0 };
@@ -75,7 +74,7 @@ static inline void board_stm32h7_clock_init(void)
regarding system frequency refer to product datasheet. */
__HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1);
- while ((PWR->D3CR & (PWR_D3CR_VOSRDY)) != PWR_D3CR_VOSRDY) {}
+ while ( (PWR->D3CR & (PWR_D3CR_VOSRDY)) != PWR_D3CR_VOSRDY ) {}
/* Enable HSE Oscillator and activate PLL with HSE as source */
RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
@@ -85,40 +84,23 @@ static inline void board_stm32h7_clock_init(void)
RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
- // PLL1 for System Clock
-#ifdef TRACE_ETM
- // From H743 eval board manual
- // - ETM can only work at 50 MHz clock by default because ETM signals are shared with other peripherals. If better
- // performance of ETM is required (84 MHz/98 MHz), R217, R230, R231, R234, R236, SB2, SB5, SB8, SB11,
- // SB42, SB57 must be removed to reduce the stub on ETM signals. In this configuration SAI and PDM are not
- // functional and NOR Flash and the address of SRAM are limited on A18.
- // - ETM trace function would be abnormal as SAI_SDB share the same pins with TRACE_D0, and TRACE_D0
- // would be forced high by SAI_SDB. When using ETM trace it is necessary to set ADCDAT1 pin (SAI_SDB signal
- // of the STM32) of audio codec WM8994ECS/R (U22) by software to be tri-state.
-
- // Since Trace CLK = PLL1 / 3 --> max PLL1 clock is 150Mhz
- RCC_OscInitStruct.PLL.PLLM = 2;
- RCC_OscInitStruct.PLL.PLLN = 24;
- RCC_OscInitStruct.PLL.PLLP = 2;
- RCC_OscInitStruct.PLL.PLLQ = 4;
- RCC_OscInitStruct.PLL.PLLR = 2;
- RCC_OscInitStruct.PLL.PLLFRACN = 0;
-#else
- // Set PLL1 to 400Mhz
+ // PLL1 for System Clock (400Mhz)
+ // From H743 eval manual ETM can only work at 50 MHz clock by default because ETM signals
+ // are shared with other peripherals. Trace CLK = PLL1R.
RCC_OscInitStruct.PLL.PLLM = 5;
RCC_OscInitStruct.PLL.PLLN = 160;
RCC_OscInitStruct.PLL.PLLP = 2;
- RCC_OscInitStruct.PLL.PLLR = 2;
RCC_OscInitStruct.PLL.PLLQ = 4;
-#endif
+ RCC_OscInitStruct.PLL.PLLR = 6; // Trace clock is 400/6 = 66.67 MHz (larger than 50 MHz but work well)
RCC_OscInitStruct.PLL.PLLVCOSEL = RCC_PLL1VCOMEDIUM;
+ RCC_OscInitStruct.PLL.PLLFRACN = 0;
RCC_OscInitStruct.PLL.PLLRGE = RCC_PLL1VCIRANGE_2;
HAL_RCC_OscConfig(&RCC_OscInitStruct);
/* Select PLL as system clock source and configure bus clocks dividers */
RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_PCLK1 |
- RCC_CLOCKTYPE_PCLK2 | RCC_CLOCKTYPE_D1PCLK1 | RCC_CLOCKTYPE_D3PCLK1;
+ RCC_CLOCKTYPE_PCLK2 | RCC_CLOCKTYPE_D1PCLK1 | RCC_CLOCKTYPE_D3PCLK1;
RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
RCC_ClkInitStruct.SYSCLKDivider = RCC_SYSCLK_DIV1;
@@ -141,10 +123,10 @@ static inline void board_stm32h7_clock_init(void)
HAL_RCCEx_PeriphCLKConfig(&PeriphClkInitStruct);
/*activate CSI clock mondatory for I/O Compensation Cell*/
- __HAL_RCC_CSI_ENABLE() ;
+ __HAL_RCC_CSI_ENABLE();
/* Enable SYSCFG clock mondatory for I/O Compensation Cell */
- __HAL_RCC_SYSCFG_CLK_ENABLE() ;
+ __HAL_RCC_SYSCFG_CLK_ENABLE();
/* Enables the I/O Compensation Cell */
HAL_EnableCompensationCell();
diff --git a/hw/bsp/stm32h7/boards/stm32h743eval/cubemx/stm32h743eval.ioc b/hw/bsp/stm32h7/boards/stm32h743eval/cubemx/stm32h743eval.ioc
index 331080c17..01458a0a9 100644
--- a/hw/bsp/stm32h7/boards/stm32h743eval/cubemx/stm32h743eval.ioc
+++ b/hw/bsp/stm32h7/boards/stm32h743eval/cubemx/stm32h743eval.ioc
@@ -892,93 +892,95 @@ ProjectManager.ProjectStructure=
ProjectManager.RegisterCallBack=
ProjectManager.StackSize=0x400
ProjectManager.TargetToolchain=Makefile
-ProjectManager.ToolChainLocation=Src
+ProjectManager.ToolChainLocation=Src/
ProjectManager.UnderRoot=false
ProjectManager.functionlistsort=1-SystemClock_Config-RCC-false-HAL-false,2-MX_GPIO_Init-GPIO-false-HAL-true,3-MX_USB_OTG_FS_PCD_Init-USB_OTG_FS-false-HAL-true,4-MX_USB_OTG_HS_PCD_Init-USB_OTG_HS-false-HAL-true,0-MX_CORTEX_M7_Init-CORTEX_M7-false-HAL-true
RCC.ADCFreq_Value=50390625
-RCC.AHB12Freq_Value=150000000
-RCC.AHB4Freq_Value=150000000
-RCC.APB1Freq_Value=75000000
-RCC.APB2Freq_Value=75000000
-RCC.APB3Freq_Value=75000000
-RCC.APB4Freq_Value=75000000
-RCC.AXIClockFreq_Value=150000000
+RCC.AHB12Freq_Value=200000000
+RCC.AHB4Freq_Value=200000000
+RCC.APB1Freq_Value=100000000
+RCC.APB2Freq_Value=100000000
+RCC.APB3Freq_Value=100000000
+RCC.APB4Freq_Value=100000000
+RCC.AXIClockFreq_Value=200000000
RCC.CECFreq_Value=32000
RCC.CKPERFreq_Value=64000000
-RCC.CortexFreq_Value=150000000
-RCC.CpuClockFreq_Value=150000000
-RCC.D1CPREFreq_Value=150000000
+RCC.CortexFreq_Value=400000000
+RCC.CpuClockFreq_Value=400000000
+RCC.D1CPREFreq_Value=400000000
RCC.D1PPRE=RCC_APB3_DIV2
RCC.D2PPRE1=RCC_APB1_DIV2
RCC.D2PPRE2=RCC_APB2_DIV2
RCC.D3PPRE=RCC_APB4_DIV2
-RCC.DFSDMACLkFreq_Value=75000000
-RCC.DFSDMFreq_Value=75000000
-RCC.DIVM1=2
+RCC.DFSDMACLkFreq_Value=200000000
+RCC.DFSDMFreq_Value=100000000
+RCC.DIVM1=5
RCC.DIVM3=25
-RCC.DIVN1=24
+RCC.DIVN1=160
RCC.DIVN3=336
-RCC.DIVP1Freq_Value=150000000
+RCC.DIVP1Freq_Value=400000000
RCC.DIVP2Freq_Value=50390625
RCC.DIVP3Freq_Value=168000000
RCC.DIVQ1=4
-RCC.DIVQ1Freq_Value=75000000
+RCC.DIVQ1Freq_Value=200000000
RCC.DIVQ2Freq_Value=50390625
RCC.DIVQ3=7
RCC.DIVQ3Freq_Value=48000000
-RCC.DIVR1Freq_Value=150000000
+RCC.DIVR1=6
+RCC.DIVR1Freq_Value=133333333.33333333
RCC.DIVR2Freq_Value=50390625
RCC.DIVR3Freq_Value=168000000
RCC.EnbaleCSS=true
-RCC.FDCANFreq_Value=75000000
-RCC.FMCFreq_Value=150000000
+RCC.FDCANFreq_Value=200000000
+RCC.FMCFreq_Value=200000000
RCC.FamilyName=M
-RCC.HCLK3ClockFreq_Value=150000000
-RCC.HCLKFreq_Value=150000000
+RCC.HCLK3ClockFreq_Value=200000000
+RCC.HCLKFreq_Value=200000000
+RCC.HPRE=RCC_HCLK_DIV2
RCC.HPREFreq_Value=64000000
-RCC.HRTIMFreq_Value=150000000
+RCC.HRTIMFreq_Value=200000000
RCC.HSICalibrationValue=32
-RCC.I2C123Freq_Value=75000000
-RCC.I2C4Freq_Value=75000000
-RCC.IPParameters=ADCFreq_Value,AHB12Freq_Value,AHB4Freq_Value,APB1Freq_Value,APB2Freq_Value,APB3Freq_Value,APB4Freq_Value,AXIClockFreq_Value,CECFreq_Value,CKPERFreq_Value,CortexFreq_Value,CpuClockFreq_Value,D1CPREFreq_Value,D1PPRE,D2PPRE1,D2PPRE2,D3PPRE,DFSDMACLkFreq_Value,DFSDMFreq_Value,DIVM1,DIVM3,DIVN1,DIVN3,DIVP1Freq_Value,DIVP2Freq_Value,DIVP3Freq_Value,DIVQ1,DIVQ1Freq_Value,DIVQ2Freq_Value,DIVQ3,DIVQ3Freq_Value,DIVR1Freq_Value,DIVR2Freq_Value,DIVR3Freq_Value,EnbaleCSS,FDCANFreq_Value,FMCFreq_Value,FamilyName,HCLK3ClockFreq_Value,HCLKFreq_Value,HPREFreq_Value,HRTIMFreq_Value,HSICalibrationValue,I2C123Freq_Value,I2C4Freq_Value,LPTIM1Freq_Value,LPTIM2Freq_Value,LPTIM345Freq_Value,LPUART1Freq_Value,LTDCFreq_Value,MCO1PinFreq_Value,MCO2PinFreq_Value,PLL2FRACN,PLL3FRACN,PLLFRACN,PLLSourceVirtual,PWR_Regulator_Voltage_Scale,QSPIFreq_Value,RNGFreq_Value,RTCFreq_Value,SAI1Freq_Value,SAI23Freq_Value,SAI4AFreq_Value,SAI4BFreq_Value,SDMMCFreq_Value,SPDIFRXFreq_Value,SPI123Freq_Value,SPI45Freq_Value,SPI6Freq_Value,SWPMI1Freq_Value,SYSCLKFreq_VALUE,SYSCLKSource,Tim1OutputFreq_Value,Tim2OutputFreq_Value,TraceFreq_Value,USART16Freq_Value,USART234578Freq_Value,USBCLockSelection,USBFreq_Value,VCO1OutputFreq_Value,VCO2OutputFreq_Value,VCO3OutputFreq_Value,VCOInput1Freq_Value,VCOInput2Freq_Value,VCOInput3Freq_Value
-RCC.LPTIM1Freq_Value=75000000
-RCC.LPTIM2Freq_Value=75000000
-RCC.LPTIM345Freq_Value=75000000
-RCC.LPUART1Freq_Value=75000000
+RCC.I2C123Freq_Value=100000000
+RCC.I2C4Freq_Value=100000000
+RCC.IPParameters=ADCFreq_Value,AHB12Freq_Value,AHB4Freq_Value,APB1Freq_Value,APB2Freq_Value,APB3Freq_Value,APB4Freq_Value,AXIClockFreq_Value,CECFreq_Value,CKPERFreq_Value,CortexFreq_Value,CpuClockFreq_Value,D1CPREFreq_Value,D1PPRE,D2PPRE1,D2PPRE2,D3PPRE,DFSDMACLkFreq_Value,DFSDMFreq_Value,DIVM1,DIVM3,DIVN1,DIVN3,DIVP1Freq_Value,DIVP2Freq_Value,DIVP3Freq_Value,DIVQ1,DIVQ1Freq_Value,DIVQ2Freq_Value,DIVQ3,DIVQ3Freq_Value,DIVR1,DIVR1Freq_Value,DIVR2Freq_Value,DIVR3Freq_Value,EnbaleCSS,FDCANFreq_Value,FMCFreq_Value,FamilyName,HCLK3ClockFreq_Value,HCLKFreq_Value,HPRE,HPREFreq_Value,HRTIMFreq_Value,HSICalibrationValue,I2C123Freq_Value,I2C4Freq_Value,LPTIM1Freq_Value,LPTIM2Freq_Value,LPTIM345Freq_Value,LPUART1Freq_Value,LTDCFreq_Value,MCO1PinFreq_Value,MCO2PinFreq_Value,PLL2FRACN,PLL3FRACN,PLLFRACN,PLLSourceVirtual,PWR_Regulator_Voltage_Scale,QSPIFreq_Value,RNGFreq_Value,RTCFreq_Value,SAI1Freq_Value,SAI23Freq_Value,SAI4AFreq_Value,SAI4BFreq_Value,SDMMCFreq_Value,SPDIFRXFreq_Value,SPI123Freq_Value,SPI45Freq_Value,SPI6Freq_Value,SWPMI1Freq_Value,SYSCLKFreq_VALUE,SYSCLKSource,Tim1OutputFreq_Value,Tim2OutputFreq_Value,TraceFreq_Value,USART16Freq_Value,USART234578Freq_Value,USBCLockSelection,USBFreq_Value,VCO1OutputFreq_Value,VCO2OutputFreq_Value,VCO3OutputFreq_Value,VCOInput1Freq_Value,VCOInput2Freq_Value,VCOInput3Freq_Value
+RCC.LPTIM1Freq_Value=100000000
+RCC.LPTIM2Freq_Value=100000000
+RCC.LPTIM345Freq_Value=100000000
+RCC.LPUART1Freq_Value=100000000
RCC.LTDCFreq_Value=168000000
RCC.MCO1PinFreq_Value=64000000
-RCC.MCO2PinFreq_Value=150000000
+RCC.MCO2PinFreq_Value=400000000
RCC.PLL2FRACN=0
RCC.PLL3FRACN=0
RCC.PLLFRACN=0
RCC.PLLSourceVirtual=RCC_PLLSOURCE_HSE
RCC.PWR_Regulator_Voltage_Scale=PWR_REGULATOR_VOLTAGE_SCALE1
-RCC.QSPIFreq_Value=150000000
+RCC.QSPIFreq_Value=200000000
RCC.RNGFreq_Value=48000000
RCC.RTCFreq_Value=32000
-RCC.SAI1Freq_Value=75000000
-RCC.SAI23Freq_Value=75000000
-RCC.SAI4AFreq_Value=75000000
-RCC.SAI4BFreq_Value=75000000
-RCC.SDMMCFreq_Value=75000000
-RCC.SPDIFRXFreq_Value=75000000
-RCC.SPI123Freq_Value=75000000
-RCC.SPI45Freq_Value=75000000
-RCC.SPI6Freq_Value=75000000
-RCC.SWPMI1Freq_Value=75000000
-RCC.SYSCLKFreq_VALUE=150000000
+RCC.SAI1Freq_Value=200000000
+RCC.SAI23Freq_Value=200000000
+RCC.SAI4AFreq_Value=200000000
+RCC.SAI4BFreq_Value=200000000
+RCC.SDMMCFreq_Value=200000000
+RCC.SPDIFRXFreq_Value=200000000
+RCC.SPI123Freq_Value=200000000
+RCC.SPI45Freq_Value=100000000
+RCC.SPI6Freq_Value=100000000
+RCC.SWPMI1Freq_Value=100000000
+RCC.SYSCLKFreq_VALUE=400000000
RCC.SYSCLKSource=RCC_SYSCLKSOURCE_PLLCLK
-RCC.Tim1OutputFreq_Value=150000000
-RCC.Tim2OutputFreq_Value=150000000
-RCC.TraceFreq_Value=150000000
-RCC.USART16Freq_Value=75000000
-RCC.USART234578Freq_Value=75000000
+RCC.Tim1OutputFreq_Value=200000000
+RCC.Tim2OutputFreq_Value=200000000
+RCC.TraceFreq_Value=133333333.33333333
+RCC.USART16Freq_Value=100000000
+RCC.USART234578Freq_Value=100000000
RCC.USBCLockSelection=RCC_USBCLKSOURCE_PLL3
RCC.USBFreq_Value=48000000
-RCC.VCO1OutputFreq_Value=300000000
+RCC.VCO1OutputFreq_Value=800000000
RCC.VCO2OutputFreq_Value=100781250
RCC.VCO3OutputFreq_Value=336000000
-RCC.VCOInput1Freq_Value=12500000
+RCC.VCOInput1Freq_Value=5000000
RCC.VCOInput2Freq_Value=781250
RCC.VCOInput3Freq_Value=1000000
SH.ADCx_INN1.0=ADC1_INN1
diff --git a/hw/bsp/xmc4000/boards/xmc4500_relax/board.mk b/hw/bsp/xmc4000/boards/xmc4500_relax/board.mk
index 371adff91..2b8f7bc57 100644
--- a/hw/bsp/xmc4000/boards/xmc4500_relax/board.mk
+++ b/hw/bsp/xmc4000/boards/xmc4500_relax/board.mk
@@ -3,7 +3,7 @@ CFLAGS += \
-DXMC4500_F100x1024 \
# mcu driver cause following warnings
-CFLAGS += -Wno-error=stringop-overread
+CFLAGS += -Wno-stringop-overread
LD_FILE = $(MCU_DIR)/CMSIS/Infineon/COMPONENT_$(MCU_VARIANT)/Source/TOOLCHAIN_GCC_ARM/XMC4500x1024.ld
diff --git a/hw/bsp/xmc4000/boards/xmc4700_relax/board.h b/hw/bsp/xmc4000/boards/xmc4700_relax/board.h
new file mode 100644
index 000000000..aa12fde3b
--- /dev/null
+++ b/hw/bsp/xmc4000/boards/xmc4700_relax/board.h
@@ -0,0 +1,81 @@
+/*
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2021, Ha Thach (tinyusb.org)
+ *
+ * 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.
+ */
+
+#ifndef BOARD_H_
+#define BOARD_H_
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+#define LED_PIN P5_9
+#define LED_STATE_ON 1
+
+#define BUTTON_PIN P15_13
+#define BUTTON_STATE_ACTIVE 0
+
+#define UART_DEV XMC_UART0_CH0
+#define UART_TX_PIN P1_5
+#define UART_TX_PIN_AF P1_5_AF_U0C0_DOUT0
+#define UART_RX_PIN P1_4
+#define UART_RX_INPUT USIC0_C0_DX0_P1_4
+
+static inline void board_clock_init(void)
+{
+ /* Clock configuration */
+ /* fPLL = 144MHz */
+ /* fSYS = 144MHz */
+ /* fUSB = 48MHz */
+ const XMC_SCU_CLOCK_CONFIG_t clock_config =
+ {
+ .syspll_config.p_div = 2,
+ .syspll_config.n_div = 48,
+ .syspll_config.k_div = 1,
+ .syspll_config.mode = XMC_SCU_CLOCK_SYSPLL_MODE_NORMAL,
+ .syspll_config.clksrc = XMC_SCU_CLOCK_SYSPLLCLKSRC_OSCHP,
+ .enable_oschp = true,
+ .calibration_mode = XMC_SCU_CLOCK_FOFI_CALIBRATION_MODE_FACTORY,
+ .fsys_clksrc = XMC_SCU_CLOCK_SYSCLKSRC_PLL,
+ .fsys_clkdiv = 2,
+ .fcpu_clkdiv = 1,
+ .fccu_clkdiv = 1,
+ .fperipheral_clkdiv = 1
+ };
+
+ /* Setup settings for USB clock */
+ XMC_SCU_CLOCK_Init(&clock_config);
+
+ XMC_SCU_CLOCK_SetUsbClockDivider(6);
+ XMC_SCU_CLOCK_SetUsbClockSource(XMC_SCU_CLOCK_USBCLKSRC_SYSPLL);
+ XMC_SCU_CLOCK_EnableClock(XMC_SCU_CLOCK_USB);
+}
+
+
+#ifdef __cplusplus
+ }
+#endif
+
+#endif /* BOARD_H_ */
diff --git a/hw/bsp/xmc4000/boards/xmc4700_relax/board.mk b/hw/bsp/xmc4000/boards/xmc4700_relax/board.mk
new file mode 100644
index 000000000..28fadf8f4
--- /dev/null
+++ b/hw/bsp/xmc4000/boards/xmc4700_relax/board.mk
@@ -0,0 +1,12 @@
+MCU_VARIANT = XMC4700
+CFLAGS += \
+ -DXMC4700_F144x2048 \
+
+# mcu driver cause following warnings
+CFLAGS += -Wno-stringop-overread
+
+LD_FILE = $(MCU_DIR)/CMSIS/Infineon/COMPONENT_$(MCU_VARIANT)/Source/TOOLCHAIN_GCC_ARM/XMC4700x2048.ld
+
+JLINK_DEVICE = XMC4700-2048
+
+flash: flash-jlink
diff --git a/hw/bsp/xmc4000/family.c b/hw/bsp/xmc4000/family.c
index bf6684736..146bef373 100644
--- a/hw/bsp/xmc4000/family.c
+++ b/hw/bsp/xmc4000/family.c
@@ -26,6 +26,7 @@
#include "xmc_gpio.h"
#include "xmc_scu.h"
+#include "xmc_uart.h"
#include "bsp/board.h"
#include "board.h"
@@ -45,17 +46,31 @@ void board_init(void)
SystemCoreClockUpdate();
// LED
- XMC_GPIO_CONFIG_t led_cfg;
+ XMC_GPIO_CONFIG_t led_cfg = {0};
led_cfg.mode = XMC_GPIO_MODE_OUTPUT_PUSH_PULL;
led_cfg.output_level = XMC_GPIO_OUTPUT_LEVEL_HIGH;
led_cfg.output_strength = XMC_GPIO_OUTPUT_STRENGTH_MEDIUM;
XMC_GPIO_Init(LED_PIN, &led_cfg);
// Button
- XMC_GPIO_CONFIG_t button_cfg;
+ XMC_GPIO_CONFIG_t button_cfg = {0};
button_cfg.mode = XMC_GPIO_MODE_INPUT_TRISTATE;
XMC_GPIO_Init(BUTTON_PIN, &button_cfg);
+#ifdef UART_DEV
+ XMC_UART_CH_CONFIG_t uart_cfg = {0};
+ uart_cfg.baudrate = CFG_BOARD_UART_BAUDRATE;
+ uart_cfg.data_bits = 8;
+ uart_cfg.stop_bits = 1;
+ XMC_UART_CH_Init(UART_DEV, &uart_cfg);
+
+ XMC_GPIO_SetMode(UART_RX_PIN, XMC_GPIO_MODE_INPUT_PULL_UP);
+ XMC_UART_CH_SetInputSource(UART_DEV, XMC_UART_CH_INPUT_RXD, UART_RX_INPUT);
+
+ XMC_UART_CH_Start(UART_DEV);
+ XMC_GPIO_SetMode(UART_TX_PIN, (XMC_GPIO_MODE_t)(XMC_GPIO_MODE_OUTPUT_PUSH_PULL | UART_TX_PIN_AF));
+#endif
+
#if CFG_TUSB_OS == OPT_OS_NONE
// 1ms tick timer
SysTick_Config(SystemCoreClock / 1000);
@@ -69,6 +84,9 @@ void board_init(void)
#endif
// USB Power Enable
+#if(UC_SERIES != XMC45)
+ XMC_SCU_CLOCK_UngatePeripheralClock(XMC_SCU_PERIPHERAL_CLOCK_USB0);
+#endif
XMC_SCU_RESET_DeassertPeripheralReset(XMC_SCU_PERIPHERAL_RESET_USB0);
XMC_SCU_POWER_EnableUsb();
}
@@ -93,7 +111,7 @@ int board_uart_read(uint8_t* buf, int len)
{
#ifdef UART_DEV
for(int i=0;i 0
- CFG_TUSB_MEM_SECTION CFG_TUSB_MEM_ALIGN uint8_t audio_ep_in_sw_buf_1[CFG_TUD_AUDIO_FUNC_1_EP_IN_SW_BUF_SZ];
+ CFG_TUD_MEM_SECTION CFG_TUSB_MEM_ALIGN uint8_t audio_ep_in_sw_buf_1[CFG_TUD_AUDIO_FUNC_1_EP_IN_SW_BUF_SZ];
#if CFG_FIFO_MUTEX
osal_mutex_def_t ep_in_ff_mutex_wr_1; // No need for read mutex as only USB driver reads from FIFO
#endif
#endif // CFG_TUD_AUDIO_FUNC_1_EP_IN_SW_BUF_SZ > 0
#if CFG_TUD_AUDIO > 1 && CFG_TUD_AUDIO_FUNC_2_EP_IN_SW_BUF_SZ > 0
- CFG_TUSB_MEM_SECTION CFG_TUSB_MEM_ALIGN uint8_t audio_ep_in_sw_buf_2[CFG_TUD_AUDIO_FUNC_2_EP_IN_SW_BUF_SZ];
+ CFG_TUD_MEM_SECTION CFG_TUSB_MEM_ALIGN uint8_t audio_ep_in_sw_buf_2[CFG_TUD_AUDIO_FUNC_2_EP_IN_SW_BUF_SZ];
#if CFG_FIFO_MUTEX
osal_mutex_def_t ep_in_ff_mutex_wr_2; // No need for read mutex as only USB driver reads from FIFO
#endif
#endif // CFG_TUD_AUDIO > 1 && CFG_TUD_AUDIO_FUNC_2_EP_IN_SW_BUF_SZ > 0
#if CFG_TUD_AUDIO > 2 && CFG_TUD_AUDIO_FUNC_3_EP_IN_SW_BUF_SZ > 0
- CFG_TUSB_MEM_SECTION CFG_TUSB_MEM_ALIGN uint8_t audio_ep_in_sw_buf_3[CFG_TUD_AUDIO_FUNC_3_EP_IN_SW_BUF_SZ];
+ CFG_TUD_MEM_SECTION CFG_TUSB_MEM_ALIGN uint8_t audio_ep_in_sw_buf_3[CFG_TUD_AUDIO_FUNC_3_EP_IN_SW_BUF_SZ];
#if CFG_FIFO_MUTEX
osal_mutex_def_t ep_in_ff_mutex_wr_3; // No need for read mutex as only USB driver reads from FIFO
#endif
@@ -139,36 +139,36 @@
// - the software encoding is used - in this case the linear buffers serve as a target memory where logical channels are encoded into
#if CFG_TUD_AUDIO_ENABLE_EP_IN && (USE_LINEAR_BUFFER || CFG_TUD_AUDIO_ENABLE_ENCODING)
#if CFG_TUD_AUDIO_FUNC_1_EP_IN_SZ_MAX > 0
- CFG_TUSB_MEM_SECTION CFG_TUSB_MEM_ALIGN uint8_t lin_buf_in_1[CFG_TUD_AUDIO_FUNC_1_EP_IN_SZ_MAX];
+ CFG_TUD_MEM_SECTION CFG_TUSB_MEM_ALIGN uint8_t lin_buf_in_1[CFG_TUD_AUDIO_FUNC_1_EP_IN_SZ_MAX];
#endif
#if CFG_TUD_AUDIO > 1 && CFG_TUD_AUDIO_FUNC_2_EP_IN_SZ_MAX > 0
- CFG_TUSB_MEM_SECTION CFG_TUSB_MEM_ALIGN uint8_t lin_buf_in_2[CFG_TUD_AUDIO_FUNC_2_EP_IN_SZ_MAX];
+ CFG_TUD_MEM_SECTION CFG_TUSB_MEM_ALIGN uint8_t lin_buf_in_2[CFG_TUD_AUDIO_FUNC_2_EP_IN_SZ_MAX];
#endif
#if CFG_TUD_AUDIO > 2 && CFG_TUD_AUDIO_FUNC_3_EP_IN_SZ_MAX > 0
- CFG_TUSB_MEM_SECTION CFG_TUSB_MEM_ALIGN uint8_t lin_buf_in_3[CFG_TUD_AUDIO_FUNC_3_EP_IN_SZ_MAX];
+ CFG_TUD_MEM_SECTION CFG_TUSB_MEM_ALIGN uint8_t lin_buf_in_3[CFG_TUD_AUDIO_FUNC_3_EP_IN_SZ_MAX];
#endif
#endif // CFG_TUD_AUDIO_ENABLE_EP_IN && (USE_LINEAR_BUFFER || CFG_TUD_AUDIO_ENABLE_DECODING)
// EP OUT software buffers and mutexes
#if CFG_TUD_AUDIO_ENABLE_EP_OUT && !CFG_TUD_AUDIO_ENABLE_DECODING
#if CFG_TUD_AUDIO_FUNC_1_EP_OUT_SW_BUF_SZ > 0
- CFG_TUSB_MEM_SECTION CFG_TUSB_MEM_ALIGN uint8_t audio_ep_out_sw_buf_1[CFG_TUD_AUDIO_FUNC_1_EP_OUT_SW_BUF_SZ];
+ CFG_TUD_MEM_SECTION CFG_TUSB_MEM_ALIGN uint8_t audio_ep_out_sw_buf_1[CFG_TUD_AUDIO_FUNC_1_EP_OUT_SW_BUF_SZ];
#if CFG_FIFO_MUTEX
osal_mutex_def_t ep_out_ff_mutex_rd_1; // No need for write mutex as only USB driver writes into FIFO
#endif
#endif // CFG_TUD_AUDIO_FUNC_1_EP_OUT_SW_BUF_SZ > 0
#if CFG_TUD_AUDIO > 1 && CFG_TUD_AUDIO_FUNC_2_EP_OUT_SW_BUF_SZ > 0
- CFG_TUSB_MEM_SECTION CFG_TUSB_MEM_ALIGN uint8_t audio_ep_out_sw_buf_2[CFG_TUD_AUDIO_FUNC_2_EP_OUT_SW_BUF_SZ];
+ CFG_TUD_MEM_SECTION CFG_TUSB_MEM_ALIGN uint8_t audio_ep_out_sw_buf_2[CFG_TUD_AUDIO_FUNC_2_EP_OUT_SW_BUF_SZ];
#if CFG_FIFO_MUTEX
osal_mutex_def_t ep_out_ff_mutex_rd_2; // No need for write mutex as only USB driver writes into FIFO
#endif
#endif // CFG_TUD_AUDIO > 1 && CFG_TUD_AUDIO_FUNC_2_EP_OUT_SW_BUF_SZ > 0
#if CFG_TUD_AUDIO > 2 && CFG_TUD_AUDIO_FUNC_3_EP_OUT_SW_BUF_SZ > 0
- CFG_TUSB_MEM_SECTION CFG_TUSB_MEM_ALIGN uint8_t audio_ep_out_sw_buf_3[CFG_TUD_AUDIO_FUNC_3_EP_OUT_SW_BUF_SZ];
+ CFG_TUD_MEM_SECTION CFG_TUSB_MEM_ALIGN uint8_t audio_ep_out_sw_buf_3[CFG_TUD_AUDIO_FUNC_3_EP_OUT_SW_BUF_SZ];
#if CFG_FIFO_MUTEX
osal_mutex_def_t ep_out_ff_mutex_rd_3; // No need for write mutex as only USB driver writes into FIFO
#endif
@@ -180,27 +180,27 @@
// - the software encoding is used - in this case the linear buffers serve as a target memory where logical channels are encoded into
#if CFG_TUD_AUDIO_ENABLE_EP_OUT && (USE_LINEAR_BUFFER || CFG_TUD_AUDIO_ENABLE_DECODING)
#if CFG_TUD_AUDIO_FUNC_1_EP_OUT_SZ_MAX > 0
- CFG_TUSB_MEM_SECTION CFG_TUSB_MEM_ALIGN uint8_t lin_buf_out_1[CFG_TUD_AUDIO_FUNC_1_EP_OUT_SZ_MAX];
+ CFG_TUD_MEM_SECTION CFG_TUSB_MEM_ALIGN uint8_t lin_buf_out_1[CFG_TUD_AUDIO_FUNC_1_EP_OUT_SZ_MAX];
#endif
#if CFG_TUD_AUDIO > 1 && CFG_TUD_AUDIO_FUNC_2_EP_OUT_SZ_MAX > 0
- CFG_TUSB_MEM_SECTION CFG_TUSB_MEM_ALIGN uint8_t lin_buf_out_2[CFG_TUD_AUDIO_FUNC_2_EP_OUT_SZ_MAX];
+ CFG_TUD_MEM_SECTION CFG_TUSB_MEM_ALIGN uint8_t lin_buf_out_2[CFG_TUD_AUDIO_FUNC_2_EP_OUT_SZ_MAX];
#endif
#if CFG_TUD_AUDIO > 2 && CFG_TUD_AUDIO_FUNC_3_EP_OUT_SZ_MAX > 0
- CFG_TUSB_MEM_SECTION CFG_TUSB_MEM_ALIGN uint8_t lin_buf_out_3[CFG_TUD_AUDIO_FUNC_3_EP_OUT_SZ_MAX];
+ CFG_TUD_MEM_SECTION CFG_TUSB_MEM_ALIGN uint8_t lin_buf_out_3[CFG_TUD_AUDIO_FUNC_3_EP_OUT_SZ_MAX];
#endif
#endif // CFG_TUD_AUDIO_ENABLE_EP_OUT && (USE_LINEAR_BUFFER || CFG_TUD_AUDIO_ENABLE_DECODING)
// Control buffers
-CFG_TUSB_MEM_SECTION CFG_TUSB_MEM_ALIGN uint8_t ctrl_buf_1[CFG_TUD_AUDIO_FUNC_1_CTRL_BUF_SZ];
+CFG_TUD_MEM_SECTION CFG_TUSB_MEM_ALIGN uint8_t ctrl_buf_1[CFG_TUD_AUDIO_FUNC_1_CTRL_BUF_SZ];
#if CFG_TUD_AUDIO > 1
-CFG_TUSB_MEM_SECTION CFG_TUSB_MEM_ALIGN uint8_t ctrl_buf_2[CFG_TUD_AUDIO_FUNC_2_CTRL_BUF_SZ];
+CFG_TUD_MEM_SECTION CFG_TUSB_MEM_ALIGN uint8_t ctrl_buf_2[CFG_TUD_AUDIO_FUNC_2_CTRL_BUF_SZ];
#endif
#if CFG_TUD_AUDIO > 2
-CFG_TUSB_MEM_SECTION CFG_TUSB_MEM_ALIGN uint8_t ctrl_buf_3[CFG_TUD_AUDIO_FUNC_3_CTRL_BUF_SZ];
+CFG_TUD_MEM_SECTION CFG_TUSB_MEM_ALIGN uint8_t ctrl_buf_3[CFG_TUD_AUDIO_FUNC_3_CTRL_BUF_SZ];
#endif
// Active alternate setting of interfaces
@@ -217,7 +217,7 @@ uint8_t alt_setting_3[CFG_TUD_AUDIO_FUNC_3_N_AS_INT];
// Software encoding/decoding support FIFOs
#if CFG_TUD_AUDIO_ENABLE_EP_IN && CFG_TUD_AUDIO_ENABLE_ENCODING
#if CFG_TUD_AUDIO_FUNC_1_TX_SUPP_SW_FIFO_SZ > 0
- CFG_TUSB_MEM_SECTION CFG_TUSB_MEM_ALIGN uint8_t tx_supp_ff_buf_1[CFG_TUD_AUDIO_FUNC_1_N_TX_SUPP_SW_FIFO][CFG_TUD_AUDIO_FUNC_1_TX_SUPP_SW_FIFO_SZ];
+ CFG_TUD_MEM_SECTION CFG_TUSB_MEM_ALIGN uint8_t tx_supp_ff_buf_1[CFG_TUD_AUDIO_FUNC_1_N_TX_SUPP_SW_FIFO][CFG_TUD_AUDIO_FUNC_1_TX_SUPP_SW_FIFO_SZ];
tu_fifo_t tx_supp_ff_1[CFG_TUD_AUDIO_FUNC_1_N_TX_SUPP_SW_FIFO];
#if CFG_FIFO_MUTEX
osal_mutex_def_t tx_supp_ff_mutex_wr_1[CFG_TUD_AUDIO_FUNC_1_N_TX_SUPP_SW_FIFO]; // No need for read mutex as only USB driver reads from FIFO
@@ -225,7 +225,7 @@ uint8_t alt_setting_3[CFG_TUD_AUDIO_FUNC_3_N_AS_INT];
#endif
#if CFG_TUD_AUDIO > 1 && CFG_TUD_AUDIO_FUNC_2_TX_SUPP_SW_FIFO_SZ > 0
- CFG_TUSB_MEM_SECTION CFG_TUSB_MEM_ALIGN uint8_t tx_supp_ff_buf_2[CFG_TUD_AUDIO_FUNC_2_N_TX_SUPP_SW_FIFO][CFG_TUD_AUDIO_FUNC_2_TX_SUPP_SW_FIFO_SZ];
+ CFG_TUD_MEM_SECTION CFG_TUSB_MEM_ALIGN uint8_t tx_supp_ff_buf_2[CFG_TUD_AUDIO_FUNC_2_N_TX_SUPP_SW_FIFO][CFG_TUD_AUDIO_FUNC_2_TX_SUPP_SW_FIFO_SZ];
tu_fifo_t tx_supp_ff_2[CFG_TUD_AUDIO_FUNC_2_N_TX_SUPP_SW_FIFO];
#if CFG_FIFO_MUTEX
osal_mutex_def_t tx_supp_ff_mutex_wr_2[CFG_TUD_AUDIO_FUNC_2_N_TX_SUPP_SW_FIFO]; // No need for read mutex as only USB driver reads from FIFO
@@ -233,7 +233,7 @@ uint8_t alt_setting_3[CFG_TUD_AUDIO_FUNC_3_N_AS_INT];
#endif
#if CFG_TUD_AUDIO > 2 && CFG_TUD_AUDIO_FUNC_3_TX_SUPP_SW_FIFO_SZ > 0
- CFG_TUSB_MEM_SECTION CFG_TUSB_MEM_ALIGN uint8_t tx_supp_ff_buf_3[CFG_TUD_AUDIO_FUNC_3_N_TX_SUPP_SW_FIFO][CFG_TUD_AUDIO_FUNC_3_TX_SUPP_SW_FIFO_SZ];
+ CFG_TUD_MEM_SECTION CFG_TUSB_MEM_ALIGN uint8_t tx_supp_ff_buf_3[CFG_TUD_AUDIO_FUNC_3_N_TX_SUPP_SW_FIFO][CFG_TUD_AUDIO_FUNC_3_TX_SUPP_SW_FIFO_SZ];
tu_fifo_t tx_supp_ff_3[CFG_TUD_AUDIO_FUNC_3_N_TX_SUPP_SW_FIFO];
#if CFG_FIFO_MUTEX
osal_mutex_def_t tx_supp_ff_mutex_wr_3[CFG_TUD_AUDIO_FUNC_3_N_TX_SUPP_SW_FIFO]; // No need for read mutex as only USB driver reads from FIFO
@@ -243,7 +243,7 @@ uint8_t alt_setting_3[CFG_TUD_AUDIO_FUNC_3_N_AS_INT];
#if CFG_TUD_AUDIO_ENABLE_EP_OUT && CFG_TUD_AUDIO_ENABLE_DECODING
#if CFG_TUD_AUDIO_FUNC_1_RX_SUPP_SW_FIFO_SZ > 0
- CFG_TUSB_MEM_SECTION CFG_TUSB_MEM_ALIGN uint8_t rx_supp_ff_buf_1[CFG_TUD_AUDIO_FUNC_1_N_RX_SUPP_SW_FIFO][CFG_TUD_AUDIO_FUNC_1_RX_SUPP_SW_FIFO_SZ];
+ CFG_TUD_MEM_SECTION CFG_TUSB_MEM_ALIGN uint8_t rx_supp_ff_buf_1[CFG_TUD_AUDIO_FUNC_1_N_RX_SUPP_SW_FIFO][CFG_TUD_AUDIO_FUNC_1_RX_SUPP_SW_FIFO_SZ];
tu_fifo_t rx_supp_ff_1[CFG_TUD_AUDIO_FUNC_1_N_RX_SUPP_SW_FIFO];
#if CFG_FIFO_MUTEX
osal_mutex_def_t rx_supp_ff_mutex_rd_1[CFG_TUD_AUDIO_FUNC_1_N_RX_SUPP_SW_FIFO]; // No need for write mutex as only USB driver writes into FIFO
@@ -251,7 +251,7 @@ uint8_t alt_setting_3[CFG_TUD_AUDIO_FUNC_3_N_AS_INT];
#endif
#if CFG_TUD_AUDIO > 1 && CFG_TUD_AUDIO_FUNC_2_RX_SUPP_SW_FIFO_SZ > 0
- CFG_TUSB_MEM_SECTION CFG_TUSB_MEM_ALIGN uint8_t rx_supp_ff_buf_2[CFG_TUD_AUDIO_FUNC_2_N_RX_SUPP_SW_FIFO][CFG_TUD_AUDIO_FUNC_2_RX_SUPP_SW_FIFO_SZ];
+ CFG_TUD_MEM_SECTION CFG_TUSB_MEM_ALIGN uint8_t rx_supp_ff_buf_2[CFG_TUD_AUDIO_FUNC_2_N_RX_SUPP_SW_FIFO][CFG_TUD_AUDIO_FUNC_2_RX_SUPP_SW_FIFO_SZ];
tu_fifo_t rx_supp_ff_2[CFG_TUD_AUDIO_FUNC_2_N_RX_SUPP_SW_FIFO];
#if CFG_FIFO_MUTEX
osal_mutex_def_t rx_supp_ff_mutex_rd_2[CFG_TUD_AUDIO_FUNC_2_N_RX_SUPP_SW_FIFO]; // No need for write mutex as only USB driver writes into FIFO
@@ -259,7 +259,7 @@ uint8_t alt_setting_3[CFG_TUD_AUDIO_FUNC_3_N_AS_INT];
#endif
#if CFG_TUD_AUDIO > 2 && CFG_TUD_AUDIO_FUNC_3_RX_SUPP_SW_FIFO_SZ > 0
- CFG_TUSB_MEM_SECTION CFG_TUSB_MEM_ALIGN uint8_t rx_supp_ff_buf_3[CFG_TUD_AUDIO_FUNC_3_N_RX_SUPP_SW_FIFO][CFG_TUD_AUDIO_FUNC_3_RX_SUPP_SW_FIFO_SZ];
+ CFG_TUD_MEM_SECTION CFG_TUSB_MEM_ALIGN uint8_t rx_supp_ff_buf_3[CFG_TUD_AUDIO_FUNC_3_N_RX_SUPP_SW_FIFO][CFG_TUD_AUDIO_FUNC_3_RX_SUPP_SW_FIFO_SZ];
tu_fifo_t rx_supp_ff_3[CFG_TUD_AUDIO_FUNC_3_N_RX_SUPP_SW_FIFO];
#if CFG_FIFO_MUTEX
osal_mutex_def_t rx_supp_ff_mutex_rd_3[CFG_TUD_AUDIO_FUNC_3_N_RX_SUPP_SW_FIFO]; // No need for write mutex as only USB driver writes into FIFO
@@ -416,7 +416,7 @@ typedef struct
//--------------------------------------------------------------------+
// INTERNAL OBJECT & FUNCTION DECLARATION
//--------------------------------------------------------------------+
-CFG_TUSB_MEM_SECTION audiod_function_t _audiod_fct[CFG_TUD_AUDIO];
+CFG_TUD_MEM_SECTION audiod_function_t _audiod_fct[CFG_TUD_AUDIO];
#if CFG_TUD_AUDIO_ENABLE_EP_OUT
static bool audiod_rx_done_cb(uint8_t rhport, audiod_function_t* audio, uint16_t n_bytes_received);
diff --git a/src/class/bth/bth_device.c b/src/class/bth/bth_device.c
index f96bb3552..c5c74d26a 100755
--- a/src/class/bth/bth_device.c
+++ b/src/class/bth/bth_device.c
@@ -55,7 +55,7 @@ typedef struct
//--------------------------------------------------------------------+
// INTERNAL OBJECT & FUNCTION DECLARATION
//--------------------------------------------------------------------+
-CFG_TUSB_MEM_SECTION btd_interface_t _btd_itf;
+CFG_TUD_MEM_SECTION btd_interface_t _btd_itf;
static bool bt_tx_data(uint8_t ep, void *data, uint16_t len)
{
diff --git a/src/class/cdc/cdc_device.c b/src/class/cdc/cdc_device.c
index 5adce521d..f658df4d0 100644
--- a/src/class/cdc/cdc_device.c
+++ b/src/class/cdc/cdc_device.c
@@ -76,7 +76,7 @@ typedef struct
//--------------------------------------------------------------------+
// INTERNAL OBJECT & FUNCTION DECLARATION
//--------------------------------------------------------------------+
-CFG_TUSB_MEM_SECTION tu_static cdcd_interface_t _cdcd_itf[CFG_TUD_CDC];
+CFG_TUD_MEM_SECTION tu_static cdcd_interface_t _cdcd_itf[CFG_TUD_CDC];
static bool _prep_out_transaction (cdcd_interface_t* p_cdc)
{
diff --git a/src/class/dfu/dfu_device.c b/src/class/dfu/dfu_device.c
index 464c4bd6b..bffdb8376 100644
--- a/src/class/dfu/dfu_device.c
+++ b/src/class/dfu/dfu_device.c
@@ -56,7 +56,7 @@ typedef struct
} dfu_state_ctx_t;
// Only a single dfu state is allowed
-CFG_TUSB_MEM_SECTION tu_static dfu_state_ctx_t _dfu_ctx;
+CFG_TUD_MEM_SECTION tu_static dfu_state_ctx_t _dfu_ctx;
static void reset_state(void)
{
diff --git a/src/class/hid/hid_device.c b/src/class/hid/hid_device.c
index 9240fe2ca..5637ea6b4 100644
--- a/src/class/hid/hid_device.c
+++ b/src/class/hid/hid_device.c
@@ -58,7 +58,7 @@ typedef struct
tusb_hid_descriptor_hid_t const * hid_descriptor;
} hidd_interface_t;
-CFG_TUSB_MEM_SECTION tu_static hidd_interface_t _hidd_itf[CFG_TUD_HID];
+CFG_TUD_MEM_SECTION tu_static hidd_interface_t _hidd_itf[CFG_TUD_HID];
/*------------- Helpers -------------*/
static inline uint8_t get_index_by_itfnum(uint8_t itf_num)
diff --git a/src/class/midi/midi_device.c b/src/class/midi/midi_device.c
index e3e7826da..052372a93 100644
--- a/src/class/midi/midi_device.c
+++ b/src/class/midi/midi_device.c
@@ -82,7 +82,7 @@ typedef struct
//--------------------------------------------------------------------+
// INTERNAL OBJECT & FUNCTION DECLARATION
//--------------------------------------------------------------------+
-CFG_TUSB_MEM_SECTION midid_interface_t _midid_itf[CFG_TUD_MIDI];
+CFG_TUD_MEM_SECTION midid_interface_t _midid_itf[CFG_TUD_MIDI];
bool tud_midi_n_mounted (uint8_t itf)
{
diff --git a/src/class/msc/msc_device.c b/src/class/msc/msc_device.c
index 159a11259..a602e9672 100644
--- a/src/class/msc/msc_device.c
+++ b/src/class/msc/msc_device.c
@@ -34,13 +34,16 @@
#include "msc_device.h"
+// Level where CFG_TUSB_DEBUG must be at least for this driver is logged
+#ifndef CFG_TUD_MSC_LOG_LEVEL
+ #define CFG_TUD_MSC_LOG_LEVEL 2
+#endif
+
+#define TU_LOG_DRV(...) TU_LOG(CFG_TUD_MSC_LOG_LEVEL, __VA_ARGS__)
+
//--------------------------------------------------------------------+
// MACRO CONSTANT TYPEDEF
//--------------------------------------------------------------------+
-
-// Can be selectively disabled to reduce logging when troubleshooting other driver
-#define MSC_DEBUG 2
-
enum
{
MSC_STAGE_CMD = 0,
@@ -71,8 +74,8 @@ typedef struct
uint8_t add_sense_qualifier;
}mscd_interface_t;
-CFG_TUSB_MEM_SECTION CFG_TUSB_MEM_ALIGN tu_static mscd_interface_t _mscd_itf;
-CFG_TUSB_MEM_SECTION CFG_TUSB_MEM_ALIGN tu_static uint8_t _mscd_buf[CFG_TUD_MSC_EP_BUFSIZE];
+CFG_TUD_MEM_SECTION CFG_TUSB_MEM_ALIGN tu_static mscd_interface_t _mscd_itf;
+CFG_TUD_MEM_SECTION CFG_TUSB_MEM_ALIGN tu_static uint8_t _mscd_buf[CFG_TUD_MSC_EP_BUFSIZE];
//--------------------------------------------------------------------+
// INTERNAL OBJECT & FUNCTION DECLARATION
@@ -164,7 +167,7 @@ uint8_t rdwr10_validate_cmd(msc_cbw_t const* cbw)
{
if ( block_count )
{
- TU_LOG(MSC_DEBUG, " SCSI case 2 (Hn < Di) or case 3 (Hn < Do) \r\n");
+ TU_LOG_DRV(" SCSI case 2 (Hn < Di) or case 3 (Hn < Do) \r\n");
status = MSC_CSW_STATUS_PHASE_ERROR;
}else
{
@@ -174,22 +177,22 @@ uint8_t rdwr10_validate_cmd(msc_cbw_t const* cbw)
{
if ( SCSI_CMD_READ_10 == cbw->command[0] && !is_data_in(cbw->dir) )
{
- TU_LOG(MSC_DEBUG, " SCSI case 10 (Ho <> Di)\r\n");
+ TU_LOG_DRV(" SCSI case 10 (Ho <> Di)\r\n");
status = MSC_CSW_STATUS_PHASE_ERROR;
}
else if ( SCSI_CMD_WRITE_10 == cbw->command[0] && is_data_in(cbw->dir) )
{
- TU_LOG(MSC_DEBUG, " SCSI case 8 (Hi <> Do)\r\n");
+ TU_LOG_DRV(" SCSI case 8 (Hi <> Do)\r\n");
status = MSC_CSW_STATUS_PHASE_ERROR;
}
else if ( 0 == block_count )
{
- TU_LOG(MSC_DEBUG, " SCSI case 4 Hi > Dn (READ10) or case 9 Ho > Dn (WRITE10) \r\n");
+ TU_LOG_DRV(" SCSI case 4 Hi > Dn (READ10) or case 9 Ho > Dn (WRITE10) \r\n");
status = MSC_CSW_STATUS_FAILED;
}
else if ( cbw->total_bytes / block_count == 0 )
{
- TU_LOG(MSC_DEBUG, " Computed block size = 0. SCSI case 7 Hi < Di (READ10) or case 13 Ho < Do (WRIT10)\r\n");
+ TU_LOG_DRV(" Computed block size = 0. SCSI case 7 Hi < Di (READ10) or case 13 Ho < Do (WRIT10)\r\n");
status = MSC_CSW_STATUS_PHASE_ERROR;
}
}
@@ -352,7 +355,7 @@ bool mscd_control_xfer_cb(uint8_t rhport, uint8_t stage, tusb_control_request_t
switch ( request->bRequest )
{
case MSC_REQ_RESET:
- TU_LOG(MSC_DEBUG, " MSC BOT Reset\r\n");
+ TU_LOG_DRV(" MSC BOT Reset\r\n");
TU_VERIFY(request->wValue == 0 && request->wLength == 0);
// driver state reset
@@ -363,7 +366,7 @@ bool mscd_control_xfer_cb(uint8_t rhport, uint8_t stage, tusb_control_request_t
case MSC_REQ_GET_MAX_LUN:
{
- TU_LOG(MSC_DEBUG, " MSC Get Max Lun\r\n");
+ TU_LOG_DRV(" MSC Get Max Lun\r\n");
TU_VERIFY(request->wValue == 0 && request->wLength == 1);
uint8_t maxlun = 1;
@@ -400,7 +403,7 @@ bool mscd_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t event, uint32_t
if ( !(xferred_bytes == sizeof(msc_cbw_t) && p_cbw->signature == MSC_CBW_SIGNATURE) )
{
- TU_LOG(MSC_DEBUG, " SCSI CBW is not valid\r\n");
+ TU_LOG_DRV(" SCSI CBW is not valid\r\n");
// BOT 6.6.1 If CBW is not valid stall both endpoints until reset recovery
p_msc->stage = MSC_STAGE_NEED_RESET;
@@ -412,7 +415,7 @@ bool mscd_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t event, uint32_t
return false;
}
- TU_LOG(MSC_DEBUG, " SCSI Command [Lun%u]: %s\r\n", p_cbw->lun, tu_lookup_find(&_msc_scsi_cmd_table, p_cbw->command[0]));
+ TU_LOG_DRV(" SCSI Command [Lun%u]: %s\r\n", p_cbw->lun, tu_lookup_find(&_msc_scsi_cmd_table, p_cbw->command[0]));
//TU_LOG_MEM(MSC_DEBUG, p_cbw, xferred_bytes, 2);
p_csw->signature = MSC_CSW_SIGNATURE;
@@ -457,7 +460,7 @@ bool mscd_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t event, uint32_t
{
if (p_cbw->total_bytes > sizeof(_mscd_buf))
{
- TU_LOG(MSC_DEBUG, " SCSI reject non READ10/WRITE10 with large data\r\n");
+ TU_LOG_DRV(" SCSI reject non READ10/WRITE10 with large data\r\n");
fail_scsi_op(rhport, p_msc, MSC_CSW_STATUS_FAILED);
}else
{
@@ -479,7 +482,7 @@ bool mscd_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t event, uint32_t
if ( resplen < 0 )
{
// unsupported command
- TU_LOG(MSC_DEBUG, " SCSI unsupported or failed command\r\n");
+ TU_LOG_DRV(" SCSI unsupported or failed command\r\n");
fail_scsi_op(rhport, p_msc, MSC_CSW_STATUS_FAILED);
}
else if (resplen == 0)
@@ -514,7 +517,7 @@ bool mscd_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t event, uint32_t
break;
case MSC_STAGE_DATA:
- TU_LOG(MSC_DEBUG, " SCSI Data [Lun%u]\r\n", p_cbw->lun);
+ TU_LOG_DRV(" SCSI Data [Lun%u]\r\n", p_cbw->lun);
//TU_LOG_MEM(MSC_DEBUG, _mscd_buf, xferred_bytes, 2);
if (SCSI_CMD_READ_10 == p_cbw->command[0])
@@ -546,7 +549,7 @@ bool mscd_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t event, uint32_t
if ( cb_result < 0 )
{
// unsupported command
- TU_LOG(MSC_DEBUG, " SCSI unsupported command\r\n");
+ TU_LOG_DRV(" SCSI unsupported command\r\n");
fail_scsi_op(rhport, p_msc, MSC_CSW_STATUS_FAILED);
}else
{
@@ -575,7 +578,7 @@ bool mscd_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t event, uint32_t
// Wait for the Status phase to complete
if( (ep_addr == p_msc->ep_in) && (xferred_bytes == sizeof(msc_csw_t)) )
{
- TU_LOG(MSC_DEBUG, " SCSI Status [Lun%u] = %u\r\n", p_cbw->lun, p_csw->status);
+ TU_LOG_DRV(" SCSI Status [Lun%u] = %u\r\n", p_cbw->lun, p_csw->status);
// TU_LOG_MEM(MSC_DEBUG, p_csw, xferred_bytes, 2);
// Invoke complete callback if defined
@@ -845,7 +848,7 @@ static void proc_read10_cmd(uint8_t rhport, mscd_interface_t* p_msc)
if ( nbytes < 0 )
{
// negative means error -> endpoint is stalled & status in CSW set to failed
- TU_LOG(MSC_DEBUG, " tud_msc_read10_cb() return -1\r\n");
+ TU_LOG_DRV(" tud_msc_read10_cb() return -1\r\n");
// set sense
set_sense_medium_not_present(p_cbw->lun);
@@ -907,7 +910,7 @@ static void proc_write10_new_data(uint8_t rhport, mscd_interface_t* p_msc, uint3
if ( nbytes < 0 )
{
// negative means error -> failed this scsi op
- TU_LOG(MSC_DEBUG, " tud_msc_write10_cb() return -1\r\n");
+ TU_LOG_DRV(" tud_msc_write10_cb() return -1\r\n");
// update actual byte before failed
p_msc->xferred_len += xferred_bytes;
diff --git a/src/class/net/ecm_rndis_device.c b/src/class/net/ecm_rndis_device.c
index 8ac7cbd01..762425732 100644
--- a/src/class/net/ecm_rndis_device.c
+++ b/src/class/net/ecm_rndis_device.c
@@ -61,10 +61,10 @@ typedef struct
#define CFG_TUD_NET_PACKET_PREFIX_LEN sizeof(rndis_data_packet_t)
#define CFG_TUD_NET_PACKET_SUFFIX_LEN 0
-CFG_TUSB_MEM_SECTION CFG_TUSB_MEM_ALIGN tu_static
+CFG_TUD_MEM_SECTION CFG_TUSB_MEM_ALIGN tu_static
uint8_t received[CFG_TUD_NET_PACKET_PREFIX_LEN + CFG_TUD_NET_MTU + CFG_TUD_NET_PACKET_PREFIX_LEN];
-CFG_TUSB_MEM_SECTION CFG_TUSB_MEM_ALIGN tu_static
+CFG_TUD_MEM_SECTION CFG_TUSB_MEM_ALIGN tu_static
uint8_t transmitted[CFG_TUD_NET_PACKET_PREFIX_LEN + CFG_TUD_NET_MTU + CFG_TUD_NET_PACKET_PREFIX_LEN];
struct ecm_notify_struct
@@ -94,8 +94,8 @@ tu_static const struct ecm_notify_struct ecm_notify_csc =
.uplink = 9728000,
};
-// TODO remove CFG_TUSB_MEM_SECTION, control internal buffer is already in this special section
-CFG_TUSB_MEM_SECTION CFG_TUSB_MEM_ALIGN tu_static union
+// TODO remove CFG_TUD_MEM_SECTION, control internal buffer is already in this special section
+CFG_TUD_MEM_SECTION CFG_TUSB_MEM_ALIGN tu_static union
{
uint8_t rndis_buf[120];
struct ecm_notify_struct ecm_buf;
@@ -104,8 +104,8 @@ CFG_TUSB_MEM_SECTION CFG_TUSB_MEM_ALIGN tu_static union
//--------------------------------------------------------------------+
// INTERNAL OBJECT & FUNCTION DECLARATION
//--------------------------------------------------------------------+
-// TODO remove CFG_TUSB_MEM_SECTION
-CFG_TUSB_MEM_SECTION tu_static netd_interface_t _netd_itf;
+// TODO remove CFG_TUD_MEM_SECTION
+CFG_TUD_MEM_SECTION tu_static netd_interface_t _netd_itf;
tu_static bool can_xmit;
diff --git a/src/class/net/ncm_device.c b/src/class/net/ncm_device.c
index 9e9580249..611dc3348 100644
--- a/src/class/net/ncm_device.c
+++ b/src/class/net/ncm_device.c
@@ -130,7 +130,7 @@ typedef struct
// INTERNAL OBJECT & FUNCTION DECLARATION
//--------------------------------------------------------------------+
-CFG_TUSB_MEM_SECTION CFG_TUSB_MEM_ALIGN tu_static const ntb_parameters_t ntb_parameters = {
+CFG_TUD_MEM_SECTION CFG_TUSB_MEM_ALIGN tu_static const ntb_parameters_t ntb_parameters = {
.wLength = sizeof(ntb_parameters_t),
.bmNtbFormatsSupported = 0x01,
.dwNtbInMaxSize = CFG_TUD_NCM_IN_NTB_MAX_SIZE,
@@ -145,9 +145,9 @@ CFG_TUSB_MEM_SECTION CFG_TUSB_MEM_ALIGN tu_static const ntb_parameters_t ntb_par
.wNtbOutMaxDatagrams = 0
};
-CFG_TUSB_MEM_SECTION CFG_TUSB_MEM_ALIGN tu_static transmit_ntb_t transmit_ntb[2];
+CFG_TUD_MEM_SECTION CFG_TUSB_MEM_ALIGN tu_static transmit_ntb_t transmit_ntb[2];
-CFG_TUSB_MEM_SECTION CFG_TUSB_MEM_ALIGN tu_static uint8_t receive_ntb[CFG_TUD_NCM_OUT_NTB_MAX_SIZE];
+CFG_TUD_MEM_SECTION CFG_TUSB_MEM_ALIGN tu_static uint8_t receive_ntb[CFG_TUD_NCM_OUT_NTB_MAX_SIZE];
tu_static ncm_interface_t ncm_interface;
diff --git a/src/class/usbtmc/usbtmc_device.c b/src/class/usbtmc/usbtmc_device.c
index 4e320a778..573654d58 100644
--- a/src/class/usbtmc/usbtmc_device.c
+++ b/src/class/usbtmc/usbtmc_device.c
@@ -143,7 +143,7 @@ typedef struct
usbtmc_capabilities_specific_t const * capabilities;
} usbtmc_interface_state_t;
-CFG_TUSB_MEM_SECTION tu_static usbtmc_interface_state_t usbtmc_state =
+CFG_TUD_MEM_SECTION tu_static usbtmc_interface_state_t usbtmc_state =
{
.itf_id = 0xFF,
};
diff --git a/src/class/vendor/vendor_device.c b/src/class/vendor/vendor_device.c
index 93596ee33..389a29696 100644
--- a/src/class/vendor/vendor_device.c
+++ b/src/class/vendor/vendor_device.c
@@ -59,7 +59,7 @@ typedef struct
CFG_TUSB_MEM_ALIGN uint8_t epin_buf[CFG_TUD_VENDOR_EPSIZE];
} vendord_interface_t;
-CFG_TUSB_MEM_SECTION tu_static vendord_interface_t _vendord_itf[CFG_TUD_VENDOR];
+CFG_TUD_MEM_SECTION tu_static vendord_interface_t _vendord_itf[CFG_TUD_VENDOR];
#define ITF_MEM_RESET_SIZE offsetof(vendord_interface_t, rx_ff)
diff --git a/src/class/video/video_device.c b/src/class/video/video_device.c
index 91f452afc..e6fadf41b 100644
--- a/src/class/video/video_device.c
+++ b/src/class/video/video_device.c
@@ -130,8 +130,8 @@ typedef struct TU_ATTR_PACKED {
//--------------------------------------------------------------------+
// INTERNAL OBJECT & FUNCTION DECLARATION
//--------------------------------------------------------------------+
-CFG_TUSB_MEM_SECTION tu_static videod_interface_t _videod_itf[CFG_TUD_VIDEO];
-CFG_TUSB_MEM_SECTION tu_static videod_streaming_interface_t _videod_streaming_itf[CFG_TUD_VIDEO_STREAMING];
+CFG_TUD_MEM_SECTION tu_static videod_interface_t _videod_itf[CFG_TUD_VIDEO];
+CFG_TUD_MEM_SECTION tu_static videod_streaming_interface_t _videod_streaming_itf[CFG_TUD_VIDEO_STREAMING];
tu_static uint8_t const _cap_get = 0x1u; /* support for GET */
tu_static uint8_t const _cap_get_set = 0x3u; /* support for GET and SET */
diff --git a/src/common/tusb_common.h b/src/common/tusb_common.h
index 576cb123f..25f85e501 100644
--- a/src/common/tusb_common.h
+++ b/src/common/tusb_common.h
@@ -53,6 +53,8 @@
#define U32_TO_U8S_LE(_u32) TU_U32_BYTE0(_u32), TU_U32_BYTE1(_u32), TU_U32_BYTE2(_u32), TU_U32_BYTE3(_u32)
#define TU_BIT(n) (1UL << (n))
+
+// Generate a mask with bit from high (31) to low (0) set, e.g TU_GENMASK(3, 0) = 0b1111
#define TU_GENMASK(h, l) ( (UINT32_MAX << (l)) & (UINT32_MAX >> (31 - (h))) )
//--------------------------------------------------------------------+
@@ -99,10 +101,9 @@ TU_ATTR_WEAK extern void* tusb_app_phys_to_virt(void *phys_addr);
#define tu_varclr(_var) tu_memclr(_var, sizeof(*(_var)))
// This is a backport of memset_s from c11
-TU_ATTR_ALWAYS_INLINE static inline int tu_memset_s(void *dest, size_t destsz, int ch, size_t count)
-{
+TU_ATTR_ALWAYS_INLINE static inline int tu_memset_s(void *dest, size_t destsz, int ch, size_t count) {
// TODO may check if desst and src is not NULL
- if (count > destsz) {
+ if ( count > destsz ) {
return -1;
}
memset(dest, ch, count);
@@ -110,10 +111,9 @@ TU_ATTR_ALWAYS_INLINE static inline int tu_memset_s(void *dest, size_t destsz, i
}
// This is a backport of memcpy_s from c11
-TU_ATTR_ALWAYS_INLINE static inline int tu_memcpy_s(void *dest, size_t destsz, const void * src, size_t count )
-{
+TU_ATTR_ALWAYS_INLINE static inline int tu_memcpy_s(void *dest, size_t destsz, const void *src, size_t count) {
// TODO may check if desst and src is not NULL
- if (count > destsz) {
+ if ( count > destsz ) {
return -1;
}
memcpy(dest, src, count);
@@ -169,6 +169,9 @@ TU_ATTR_ALWAYS_INLINE static inline uint32_t tu_align32 (uint32_t value) { retur
TU_ATTR_ALWAYS_INLINE static inline uint32_t tu_align4k (uint32_t value) { return (value & 0xFFFFF000UL); }
TU_ATTR_ALWAYS_INLINE static inline uint32_t tu_offset4k(uint32_t value) { return (value & 0xFFFUL); }
+TU_ATTR_ALWAYS_INLINE static inline bool tu_is_aligned32(uint32_t value) { return (value & 0x1FUL) == 0; }
+TU_ATTR_ALWAYS_INLINE static inline bool tu_is_aligned64(uint64_t value) { return (value & 0x3FUL) == 0; }
+
//------------- Mathematics -------------//
TU_ATTR_ALWAYS_INLINE static inline uint32_t tu_div_ceil(uint32_t v, uint32_t d) { return (v + d -1)/d; }
diff --git a/src/device/usbd.c b/src/device/usbd.c
index 44c2530ce..9429cf664 100644
--- a/src/device/usbd.c
+++ b/src/device/usbd.c
@@ -43,9 +43,6 @@
#define CFG_TUD_TASK_QUEUE_SZ 16
#endif
-// Debug level of USBD
-#define USBD_DBG 2
-
//--------------------------------------------------------------------+
// Device Data
//--------------------------------------------------------------------+
@@ -81,7 +78,7 @@ tu_static usbd_device_t _usbd_dev;
//--------------------------------------------------------------------+
// Class Driver
//--------------------------------------------------------------------+
-#if CFG_TUSB_DEBUG >= 2
+#if CFG_TUSB_DEBUG >= CFG_TUD_LOG_LEVEL
#define DRIVER_NAME(_name) .name = _name,
#else
#define DRIVER_NAME(_name)
@@ -308,7 +305,7 @@ bool usbd_control_xfer_cb (uint8_t rhport, uint8_t ep_addr, xfer_result_t event,
//--------------------------------------------------------------------+
// Debug
//--------------------------------------------------------------------+
-#if CFG_TUSB_DEBUG >= 2
+#if CFG_TUSB_DEBUG >= CFG_TUD_LOG_LEVEL
tu_static char const* const _usbd_event_str[DCD_EVENT_COUNT] =
{
"Invalid" ,
@@ -330,7 +327,7 @@ void usbd_driver_print_control_complete_name(usbd_control_xfer_cb_t callback)
usbd_class_driver_t const * driver = get_driver(i);
if ( driver && driver->control_xfer_cb == callback )
{
- TU_LOG(USBD_DBG, " %s control complete\r\n", driver->name);
+ TU_LOG_USBD(" %s control complete\r\n", driver->name);
return;
}
}
@@ -396,10 +393,10 @@ bool tud_init (uint8_t rhport)
// skip if already initialized
if ( tud_inited() ) return true;
- TU_LOG(USBD_DBG, "USBD init on controller %u\r\n", rhport);
- TU_LOG_INT(USBD_DBG, sizeof(usbd_device_t));
- TU_LOG_INT(USBD_DBG, sizeof(tu_fifo_t));
- TU_LOG_INT(USBD_DBG, sizeof(tu_edpt_stream_t));
+ TU_LOG_USBD("USBD init on controller %u\r\n", rhport);
+ TU_LOG_INT(CFG_TUD_LOG_LEVEL, sizeof(usbd_device_t));
+ TU_LOG_INT(CFG_TUD_LOG_LEVEL, sizeof(tu_fifo_t));
+ TU_LOG_INT(CFG_TUD_LOG_LEVEL, sizeof(tu_edpt_stream_t));
tu_varclr(&_usbd_dev);
@@ -424,7 +421,7 @@ bool tud_init (uint8_t rhport)
{
usbd_class_driver_t const * driver = get_driver(i);
TU_ASSERT(driver);
- TU_LOG(USBD_DBG, "%s init\r\n", driver->name);
+ TU_LOG_USBD("%s init\r\n", driver->name);
driver->init();
}
@@ -496,21 +493,21 @@ void tud_task_ext(uint32_t timeout_ms, bool in_isr)
dcd_event_t event;
if ( !osal_queue_receive(_usbd_q, &event, timeout_ms) ) return;
-#if CFG_TUSB_DEBUG >= 2
- if (event.event_id == DCD_EVENT_SETUP_RECEIVED) TU_LOG(USBD_DBG, "\r\n"); // extra line for setup
- TU_LOG(USBD_DBG, "USBD %s ", event.event_id < DCD_EVENT_COUNT ? _usbd_event_str[event.event_id] : "CORRUPTED");
+#if CFG_TUSB_DEBUG >= CFG_TUD_LOG_LEVEL
+ if (event.event_id == DCD_EVENT_SETUP_RECEIVED) TU_LOG_USBD("\r\n"); // extra line for setup
+ TU_LOG_USBD("USBD %s ", event.event_id < DCD_EVENT_COUNT ? _usbd_event_str[event.event_id] : "CORRUPTED");
#endif
switch ( event.event_id )
{
case DCD_EVENT_BUS_RESET:
- TU_LOG(USBD_DBG, ": %s Speed\r\n", tu_str_speed[event.bus_reset.speed]);
+ TU_LOG_USBD(": %s Speed\r\n", tu_str_speed[event.bus_reset.speed]);
usbd_reset(event.rhport);
_usbd_dev.speed = event.bus_reset.speed;
break;
case DCD_EVENT_UNPLUGGED:
- TU_LOG(USBD_DBG, "\r\n");
+ TU_LOG_USBD("\r\n");
usbd_reset(event.rhport);
// invoke callback
@@ -518,8 +515,8 @@ void tud_task_ext(uint32_t timeout_ms, bool in_isr)
break;
case DCD_EVENT_SETUP_RECEIVED:
- TU_LOG_PTR(USBD_DBG, &event.setup_received);
- TU_LOG(USBD_DBG, "\r\n");
+ TU_LOG_PTR(CFG_TUD_LOG_LEVEL, &event.setup_received);
+ TU_LOG_USBD("\r\n");
// Mark as connected after receiving 1st setup packet.
// But it is easier to set it every time instead of wasting time to check then set
@@ -534,7 +531,7 @@ void tud_task_ext(uint32_t timeout_ms, bool in_isr)
// Process control request
if ( !process_control_request(event.rhport, &event.setup_received) )
{
- TU_LOG(USBD_DBG, " Stall EP0\r\n");
+ TU_LOG_USBD(" Stall EP0\r\n");
// Failed -> stall both control endpoint IN and OUT
dcd_edpt_stall(event.rhport, 0);
dcd_edpt_stall(event.rhport, 0 | TUSB_DIR_IN_MASK);
@@ -548,7 +545,7 @@ void tud_task_ext(uint32_t timeout_ms, bool in_isr)
uint8_t const epnum = tu_edpt_number(ep_addr);
uint8_t const ep_dir = tu_edpt_dir(ep_addr);
- TU_LOG(USBD_DBG, "on EP %02X with %u bytes\r\n", ep_addr, (unsigned int) event.xfer_complete.len);
+ TU_LOG_USBD("on EP %02X with %u bytes\r\n", ep_addr, (unsigned int) event.xfer_complete.len);
_usbd_dev.ep_status[epnum][ep_dir].busy = 0;
_usbd_dev.ep_status[epnum][ep_dir].claimed = 0;
@@ -563,7 +560,7 @@ void tud_task_ext(uint32_t timeout_ms, bool in_isr)
usbd_class_driver_t const * driver = get_driver( _usbd_dev.ep2drv[epnum][ep_dir] );
TU_ASSERT(driver, );
- TU_LOG(USBD_DBG, " %s xfer callback\r\n", driver->name);
+ TU_LOG_USBD(" %s xfer callback\r\n", driver->name);
driver->xfer_cb(event.rhport, ep_addr, (xfer_result_t) event.xfer_complete.result, event.xfer_complete.len);
}
}
@@ -575,27 +572,27 @@ void tud_task_ext(uint32_t timeout_ms, bool in_isr)
// e.g suspend -> resume -> unplug/plug. Skip suspend/resume if not connected
if ( _usbd_dev.connected )
{
- TU_LOG(USBD_DBG, ": Remote Wakeup = %u\r\n", _usbd_dev.remote_wakeup_en);
+ TU_LOG_USBD(": Remote Wakeup = %u\r\n", _usbd_dev.remote_wakeup_en);
if (tud_suspend_cb) tud_suspend_cb(_usbd_dev.remote_wakeup_en);
}else
{
- TU_LOG(USBD_DBG, " Skipped\r\n");
+ TU_LOG_USBD(" Skipped\r\n");
}
break;
case DCD_EVENT_RESUME:
if ( _usbd_dev.connected )
{
- TU_LOG(USBD_DBG, "\r\n");
+ TU_LOG_USBD("\r\n");
if (tud_resume_cb) tud_resume_cb();
}else
{
- TU_LOG(USBD_DBG, " Skipped\r\n");
+ TU_LOG_USBD(" Skipped\r\n");
}
break;
case USBD_EVENT_FUNC_CALL:
- TU_LOG(USBD_DBG, "\r\n");
+ TU_LOG_USBD("\r\n");
if ( event.func_call.func ) event.func_call.func(event.func_call.param);
break;
@@ -620,7 +617,7 @@ void tud_task_ext(uint32_t timeout_ms, bool in_isr)
static bool invoke_class_control(uint8_t rhport, usbd_class_driver_t const * driver, tusb_control_request_t const * request)
{
usbd_control_set_complete_callback(driver->control_xfer_cb);
- TU_LOG(USBD_DBG, " %s control request\r\n", driver->name);
+ TU_LOG_USBD(" %s control request\r\n", driver->name);
return driver->control_xfer_cb(rhport, CONTROL_STAGE_SETUP, request);
}
@@ -641,11 +638,11 @@ static bool process_control_request(uint8_t rhport, tusb_control_request_t const
return tud_vendor_control_xfer_cb(rhport, CONTROL_STAGE_SETUP, p_request);
}
-#if CFG_TUSB_DEBUG >= 2
+#if CFG_TUSB_DEBUG >= CFG_TUD_LOG_LEVEL
if (TUSB_REQ_TYPE_STANDARD == p_request->bmRequestType_bit.type && p_request->bRequest <= TUSB_REQ_SYNCH_FRAME)
{
- TU_LOG(USBD_DBG, " %s", tu_str_std_request[p_request->bRequest]);
- if (TUSB_REQ_GET_DESCRIPTOR != p_request->bRequest) TU_LOG(USBD_DBG, "\r\n");
+ TU_LOG_USBD(" %s", tu_str_std_request[p_request->bRequest]);
+ if (TUSB_REQ_GET_DESCRIPTOR != p_request->bRequest) TU_LOG_USBD("\r\n");
}
#endif
@@ -701,7 +698,7 @@ static bool process_control_request(uint8_t rhport, tusb_control_request_t const
if ( _usbd_dev.cfg_num )
{
// already configured: need to clear all endpoints and driver first
- TU_LOG(USBD_DBG, " Clear current Configuration (%u) before switching\r\n", _usbd_dev.cfg_num);
+ TU_LOG_USBD(" Clear current Configuration (%u) before switching\r\n", _usbd_dev.cfg_num);
// close all non-control endpoints, cancel all pending transfers if any
dcd_edpt_close_all(rhport);
@@ -730,7 +727,7 @@ static bool process_control_request(uint8_t rhport, tusb_control_request_t const
// Only support remote wakeup for device feature
TU_VERIFY(TUSB_REQ_FEATURE_REMOTE_WAKEUP == p_request->wValue);
- TU_LOG(USBD_DBG, " Enable Remote Wakeup\r\n");
+ TU_LOG_USBD(" Enable Remote Wakeup\r\n");
// Host may enable remote wake up before suspending especially HID device
_usbd_dev.remote_wakeup_en = true;
@@ -741,7 +738,7 @@ static bool process_control_request(uint8_t rhport, tusb_control_request_t const
// Only support remote wakeup for device feature
TU_VERIFY(TUSB_REQ_FEATURE_REMOTE_WAKEUP == p_request->wValue);
- TU_LOG(USBD_DBG, " Disable Remote Wakeup\r\n");
+ TU_LOG_USBD(" Disable Remote Wakeup\r\n");
// Host may disable remote wake up after resuming
_usbd_dev.remote_wakeup_en = false;
@@ -924,7 +921,7 @@ static bool process_set_config(uint8_t rhport, uint8_t cfg_num)
if ( (sizeof(tusb_desc_interface_t) <= drv_len) && (drv_len <= remaining_len) )
{
// Open successfully
- TU_LOG(USBD_DBG, " %s opened\r\n", driver->name);
+ TU_LOG_USBD(" %s opened\r\n", driver->name);
// Some drivers use 2 or more interfaces but may not have IAD e.g MIDI (always) or
// BTH (even CDC) with class in device descriptor (single interface)
@@ -983,7 +980,7 @@ static bool process_get_descriptor(uint8_t rhport, tusb_control_request_t const
{
case TUSB_DESC_DEVICE:
{
- TU_LOG(USBD_DBG, " Device\r\n");
+ TU_LOG_USBD(" Device\r\n");
void* desc_device = (void*) (uintptr_t) tud_descriptor_device_cb();
@@ -1007,7 +1004,7 @@ static bool process_get_descriptor(uint8_t rhport, tusb_control_request_t const
case TUSB_DESC_BOS:
{
- TU_LOG(USBD_DBG, " BOS\r\n");
+ TU_LOG_USBD(" BOS\r\n");
// requested by host if USB > 2.0 ( i.e 2.1 or 3.x )
if (!tud_descriptor_bos_cb) return false;
@@ -1029,12 +1026,12 @@ static bool process_get_descriptor(uint8_t rhport, tusb_control_request_t const
if ( desc_type == TUSB_DESC_CONFIGURATION )
{
- TU_LOG(USBD_DBG, " Configuration[%u]\r\n", desc_index);
+ TU_LOG_USBD(" Configuration[%u]\r\n", desc_index);
desc_config = (uintptr_t) tud_descriptor_configuration_cb(desc_index);
}else
{
// Host only request this after getting Device Qualifier descriptor
- TU_LOG(USBD_DBG, " Other Speed Configuration\r\n");
+ TU_LOG_USBD(" Other Speed Configuration\r\n");
TU_VERIFY( tud_descriptor_other_speed_configuration_cb );
desc_config = (uintptr_t) tud_descriptor_other_speed_configuration_cb(desc_index);
}
@@ -1050,7 +1047,7 @@ static bool process_get_descriptor(uint8_t rhport, tusb_control_request_t const
case TUSB_DESC_STRING:
{
- TU_LOG(USBD_DBG, " String[%u]\r\n", desc_index);
+ TU_LOG_USBD(" String[%u]\r\n", desc_index);
// String Descriptor always uses the desc set from user
uint8_t const* desc_str = (uint8_t const*) tud_descriptor_string_cb(desc_index, tu_le16toh(p_request->wIndex));
@@ -1063,7 +1060,7 @@ static bool process_get_descriptor(uint8_t rhport, tusb_control_request_t const
case TUSB_DESC_DEVICE_QUALIFIER:
{
- TU_LOG(USBD_DBG, " Device Qualifier\r\n");
+ TU_LOG_USBD(" Device Qualifier\r\n");
TU_VERIFY( tud_descriptor_device_qualifier_cb );
@@ -1248,7 +1245,7 @@ bool usbd_edpt_xfer(uint8_t rhport, uint8_t ep_addr, uint8_t * buffer, uint16_t
// TODO skip ready() check for now since enumeration also use this API
// TU_VERIFY(tud_ready());
- TU_LOG(USBD_DBG, " Queue EP %02X with %u bytes ...\r\n", ep_addr, total_bytes);
+ TU_LOG_USBD(" Queue EP %02X with %u bytes ...\r\n", ep_addr, total_bytes);
// Attempt to transfer on a busy endpoint, sound like an race condition !
TU_ASSERT(_usbd_dev.ep_status[epnum][dir].busy == 0);
@@ -1265,7 +1262,7 @@ bool usbd_edpt_xfer(uint8_t rhport, uint8_t ep_addr, uint8_t * buffer, uint16_t
// DCD error, mark endpoint as ready to allow next transfer
_usbd_dev.ep_status[epnum][dir].busy = 0;
_usbd_dev.ep_status[epnum][dir].claimed = 0;
- TU_LOG(USBD_DBG, "FAILED\r\n");
+ TU_LOG_USBD("FAILED\r\n");
TU_BREAKPOINT();
return false;
}
@@ -1282,7 +1279,7 @@ bool usbd_edpt_xfer_fifo(uint8_t rhport, uint8_t ep_addr, tu_fifo_t * ff, uint16
uint8_t const epnum = tu_edpt_number(ep_addr);
uint8_t const dir = tu_edpt_dir(ep_addr);
- TU_LOG(USBD_DBG, " Queue ISO EP %02X with %u bytes ... ", ep_addr, total_bytes);
+ TU_LOG_USBD(" Queue ISO EP %02X with %u bytes ... ", ep_addr, total_bytes);
// Attempt to transfer on a busy endpoint, sound like an race condition !
TU_ASSERT(_usbd_dev.ep_status[epnum][dir].busy == 0);
@@ -1293,14 +1290,14 @@ bool usbd_edpt_xfer_fifo(uint8_t rhport, uint8_t ep_addr, tu_fifo_t * ff, uint16
if (dcd_edpt_xfer_fifo(rhport, ep_addr, ff, total_bytes))
{
- TU_LOG(USBD_DBG, "OK\r\n");
+ TU_LOG_USBD("OK\r\n");
return true;
}else
{
// DCD error, mark endpoint as ready to allow next transfer
_usbd_dev.ep_status[epnum][dir].busy = 0;
_usbd_dev.ep_status[epnum][dir].claimed = 0;
- TU_LOG(USBD_DBG, "failed\r\n");
+ TU_LOG_USBD("failed\r\n");
TU_BREAKPOINT();
return false;
}
@@ -1326,7 +1323,7 @@ void usbd_edpt_stall(uint8_t rhport, uint8_t ep_addr)
// only stalled if currently cleared
if ( !_usbd_dev.ep_status[epnum][dir].stalled )
{
- TU_LOG(USBD_DBG, " Stall EP %02X\r\n", ep_addr);
+ TU_LOG_USBD(" Stall EP %02X\r\n", ep_addr);
dcd_edpt_stall(rhport, ep_addr);
_usbd_dev.ep_status[epnum][dir].stalled = 1;
_usbd_dev.ep_status[epnum][dir].busy = 1;
@@ -1343,7 +1340,7 @@ void usbd_edpt_clear_stall(uint8_t rhport, uint8_t ep_addr)
// only clear if currently stalled
if ( _usbd_dev.ep_status[epnum][dir].stalled )
{
- TU_LOG(USBD_DBG, " Clear Stall EP %02X\r\n", ep_addr);
+ TU_LOG_USBD(" Clear Stall EP %02X\r\n", ep_addr);
dcd_edpt_clear_stall(rhport, ep_addr);
_usbd_dev.ep_status[epnum][dir].stalled = 0;
_usbd_dev.ep_status[epnum][dir].busy = 0;
@@ -1371,7 +1368,7 @@ void usbd_edpt_close(uint8_t rhport, uint8_t ep_addr)
rhport = _usbd_rhport;
TU_ASSERT(dcd_edpt_close, /**/);
- TU_LOG(USBD_DBG, " CLOSING Endpoint: 0x%02X\r\n", ep_addr);
+ TU_LOG_USBD(" CLOSING Endpoint: 0x%02X\r\n", ep_addr);
uint8_t const epnum = tu_edpt_number(ep_addr);
uint8_t const dir = tu_edpt_dir(ep_addr);
diff --git a/src/device/usbd_control.c b/src/device/usbd_control.c
index 2afe967b5..76d062e40 100644
--- a/src/device/usbd_control.c
+++ b/src/device/usbd_control.c
@@ -32,10 +32,7 @@
#include "tusb.h"
#include "device/usbd_pvt.h"
-// Debug level of USBD Control
-#define USBD_CONTROL_DEBUG 2
-
-#if CFG_TUSB_DEBUG >= USBD_CONTROL_DEBUG
+#if CFG_TUSB_DEBUG >= CFG_TUD_LOG_LEVEL
extern void usbd_driver_print_control_complete_name(usbd_control_xfer_cb_t callback);
#endif
@@ -58,7 +55,7 @@ typedef struct
tu_static usbd_control_xfer_t _ctrl_xfer;
-CFG_TUSB_MEM_SECTION CFG_TUSB_MEM_ALIGN
+CFG_TUD_MEM_SECTION CFG_TUSB_MEM_ALIGN
tu_static uint8_t _usbd_ctrl_buf[CFG_TUD_ENDPOINT0_SIZE];
//--------------------------------------------------------------------+
@@ -191,7 +188,7 @@ bool usbd_control_xfer_cb (uint8_t rhport, uint8_t ep_addr, xfer_result_t result
{
TU_VERIFY(_ctrl_xfer.buffer);
memcpy(_ctrl_xfer.buffer, _usbd_ctrl_buf, xferred_bytes);
- TU_LOG_MEM(USBD_CONTROL_DEBUG, _usbd_ctrl_buf, xferred_bytes, 2);
+ TU_LOG_MEM(CFG_TUD_LOG_LEVEL, _usbd_ctrl_buf, xferred_bytes, 2);
}
_ctrl_xfer.total_xferred += (uint16_t) xferred_bytes;
@@ -208,7 +205,7 @@ bool usbd_control_xfer_cb (uint8_t rhport, uint8_t ep_addr, xfer_result_t result
// callback can still stall control in status phase e.g out data does not make sense
if ( _ctrl_xfer.complete_cb )
{
- #if CFG_TUSB_DEBUG >= USBD_CONTROL_DEBUG
+ #if CFG_TUSB_DEBUG >= CFG_TUD_LOG_LEVEL
usbd_driver_print_control_complete_name(_ctrl_xfer.complete_cb);
#endif
diff --git a/src/device/usbd_pvt.h b/src/device/usbd_pvt.h
index 8393d3469..940b2858b 100644
--- a/src/device/usbd_pvt.h
+++ b/src/device/usbd_pvt.h
@@ -33,13 +33,20 @@
extern "C" {
#endif
+// Level where CFG_TUSB_DEBUG must be at least for USBD is logged
+#ifndef CFG_TUD_LOG_LEVEL
+#define CFG_TUD_LOG_LEVEL 2
+#endif
+
+#define TU_LOG_USBD(...) TU_LOG(CFG_TUD_LOG_LEVEL, __VA_ARGS__)
+
//--------------------------------------------------------------------+
// Class Driver API
//--------------------------------------------------------------------+
typedef struct
{
- #if CFG_TUSB_DEBUG >= 2
+ #if CFG_TUSB_DEBUG >= CFG_TUD_LOG_LEVEL
char const* name;
#endif
diff --git a/src/host/hcd.h b/src/host/hcd.h
index 3355c18b2..d77dd6e2f 100644
--- a/src/host/hcd.h
+++ b/src/host/hcd.h
@@ -110,15 +110,15 @@ typedef struct
// clean/flush data cache: write cache -> memory.
// Required before an DMA TX transfer to make sure data is in memory
-void hcd_dcache_clean(void const* addr, uint32_t data_size) TU_ATTR_WEAK;
+bool hcd_dcache_clean(void const* addr, uint32_t data_size) TU_ATTR_WEAK;
// invalidate data cache: mark cache as invalid, next read will read from memory
// Required BOTH before and after an DMA RX transfer
-void hcd_dcache_invalidate(void const* addr, uint32_t data_size) TU_ATTR_WEAK;
+bool hcd_dcache_invalidate(void const* addr, uint32_t data_size) TU_ATTR_WEAK;
// clean and invalidate data cache
// Required before an DMA transfer where memory is both read/write by DMA
-void hcd_dcache_clean_invalidate(void const* addr, uint32_t data_size) TU_ATTR_WEAK;
+bool hcd_dcache_clean_invalidate(void const* addr, uint32_t data_size) TU_ATTR_WEAK;
//--------------------------------------------------------------------+
// Controller API
@@ -171,11 +171,15 @@ bool hcd_edpt_open(uint8_t rhport, uint8_t dev_addr, tusb_desc_endpoint_t const
// Submit a transfer, when complete hcd_event_xfer_complete() must be invoked
bool hcd_edpt_xfer(uint8_t rhport, uint8_t dev_addr, uint8_t ep_addr, uint8_t * buffer, uint16_t buflen);
+// Abort a queued transfer. Note: it can only abort transfer that has not been started
+// Return true if a queued transfer is aborted, false if there is no transfer to abort
+bool hcd_edpt_abort_xfer(uint8_t rhport, uint8_t dev_addr, uint8_t ep_addr);
+
// Submit a special transfer to send 8-byte Setup Packet, when complete hcd_event_xfer_complete() must be invoked
bool hcd_setup_send(uint8_t rhport, uint8_t dev_addr, uint8_t const setup_packet[8]);
// clear stall, data toggle is also reset to DATA0
-bool hcd_edpt_clear_stall(uint8_t daddr, uint8_t ep_addr);
+bool hcd_edpt_clear_stall(uint8_t rhport, uint8_t dev_addr, uint8_t ep_addr);
//--------------------------------------------------------------------+
// USBH implemented API
diff --git a/src/host/hub.c b/src/host/hub.c
index 182bd6ce8..16dd534d2 100644
--- a/src/host/hub.c
+++ b/src/host/hub.c
@@ -45,8 +45,8 @@ typedef struct
uint8_t itf_num;
uint8_t ep_in;
uint8_t port_count;
- uint8_t status_change; // data from status change interrupt endpoint
+ CFG_TUH_MEM_ALIGN uint8_t status_change;
CFG_TUH_MEM_ALIGN hub_port_status_response_t port_status;
CFG_TUH_MEM_ALIGN hub_status_response_t hub_status;
} hub_interface_t;
diff --git a/src/host/usbh.c b/src/host/usbh.c
index 1418cfb79..c8eb91be3 100644
--- a/src/host/usbh.c
+++ b/src/host/usbh.c
@@ -38,17 +38,19 @@
//--------------------------------------------------------------------+
#ifndef CFG_TUH_TASK_QUEUE_SZ
-#define CFG_TUH_TASK_QUEUE_SZ 16
+ #define CFG_TUH_TASK_QUEUE_SZ 16
#endif
#ifndef CFG_TUH_INTERFACE_MAX
-#define CFG_TUH_INTERFACE_MAX 8
+ #define CFG_TUH_INTERFACE_MAX 8
#endif
-// Debug level, TUSB_CFG_DEBUG must be at least this level for debug message
-#define USBH_DEBUG 2
+// Level where CFG_TUSB_DEBUG must be at least for USBH is logged
+#ifndef CFG_TUH_LOG_LEVEL
+ #define CFG_TUH_LOG_LEVEL 2
+#endif
-#define TU_LOG_USBH(...) TU_LOG(USBH_DEBUG, __VA_ARGS__)
+#define TU_LOG_USBH(...) TU_LOG(CFG_TUH_LOG_LEVEL, __VA_ARGS__)
//--------------------------------------------------------------------+
// USBH-HCD common data structure
@@ -322,12 +324,12 @@ bool tuh_init(uint8_t controller_id)
if ( tuh_inited() ) return true;
TU_LOG_USBH("USBH init on controller %u\r\n", controller_id);
- TU_LOG_INT(USBH_DEBUG, sizeof(usbh_device_t));
- TU_LOG_INT(USBH_DEBUG, sizeof(hcd_event_t));
- TU_LOG_INT(USBH_DEBUG, sizeof(_ctrl_xfer));
- TU_LOG_INT(USBH_DEBUG, sizeof(tuh_xfer_t));
- TU_LOG_INT(USBH_DEBUG, sizeof(tu_fifo_t));
- TU_LOG_INT(USBH_DEBUG, sizeof(tu_edpt_stream_t));
+ TU_LOG_INT(CFG_TUH_LOG_LEVEL, sizeof(usbh_device_t));
+ TU_LOG_INT(CFG_TUH_LOG_LEVEL, sizeof(hcd_event_t));
+ TU_LOG_INT(CFG_TUH_LOG_LEVEL, sizeof(_ctrl_xfer));
+ TU_LOG_INT(CFG_TUH_LOG_LEVEL, sizeof(tuh_xfer_t));
+ TU_LOG_INT(CFG_TUH_LOG_LEVEL, sizeof(tu_fifo_t));
+ TU_LOG_INT(CFG_TUH_LOG_LEVEL, sizeof(tu_edpt_stream_t));
// Event queue
_usbh_q = osal_queue_create( &_usbh_qdef );
@@ -450,39 +452,28 @@ void tuh_task_ext(uint32_t timeout_ms, bool in_isr)
TU_LOG_USBH("on EP %02X with %u bytes: %s\r\n", ep_addr, (unsigned int) event.xfer_complete.len,
tu_str_xfer_result[event.xfer_complete.result]);
- if (event.dev_addr == 0)
- {
+ if (event.dev_addr == 0) {
// device 0 only has control endpoint
TU_ASSERT(epnum == 0, );
usbh_control_xfer_cb(event.dev_addr, ep_addr, (xfer_result_t) event.xfer_complete.result, event.xfer_complete.len);
- }
- else
- {
+ } else {
usbh_device_t* dev = get_device(event.dev_addr);
TU_VERIFY(dev && dev->connected, );
dev->ep_status[epnum][ep_dir].busy = 0;
dev->ep_status[epnum][ep_dir].claimed = 0;
- if ( 0 == epnum )
- {
- usbh_control_xfer_cb(event.dev_addr, ep_addr, (xfer_result_t) event.xfer_complete.result, event.xfer_complete.len);
- }else
- {
- uint8_t drv_id = dev->ep2drv[epnum][ep_dir];
- if(drv_id < USBH_CLASS_DRIVER_COUNT)
- {
- TU_LOG_USBH("%s xfer callback\r\n", usbh_class_drivers[drv_id].name);
- usbh_class_drivers[drv_id].xfer_cb(event.dev_addr, ep_addr, (xfer_result_t) event.xfer_complete.result, event.xfer_complete.len);
- }
- else
- {
-#if CFG_TUH_API_EDPT_XFER
- tuh_xfer_cb_t complete_cb = dev->ep_callback[epnum][ep_dir].complete_cb;
- if ( complete_cb )
- {
- tuh_xfer_t xfer =
- {
+ if ( 0 == epnum ) {
+ usbh_control_xfer_cb(event.dev_addr, ep_addr, (xfer_result_t) event.xfer_complete.result,
+ event.xfer_complete.len);
+ }else {
+ // Prefer application callback over built-in one if available. This occurs when tuh_edpt_xfer() is used
+ // with enabled driver e.g HID endpoint
+ #if CFG_TUH_API_EDPT_XFER
+ tuh_xfer_cb_t const complete_cb = dev->ep_callback[epnum][ep_dir].complete_cb;
+ if ( complete_cb ) {
+ // re-construct xfer info
+ tuh_xfer_t xfer = {
.daddr = event.dev_addr,
.ep_addr = ep_addr,
.result = event.xfer_complete.result,
@@ -491,16 +482,21 @@ void tuh_task_ext(uint32_t timeout_ms, bool in_isr)
.buffer = NULL, // not available
.complete_cb = complete_cb,
.user_data = dev->ep_callback[epnum][ep_dir].user_data
- };
+ };
- complete_cb(&xfer);
- }else
-#endif
- {
+ complete_cb(&xfer);
+ }else
+ #endif
+ {
+ uint8_t const drv_id = dev->ep2drv[epnum][ep_dir];
+ if ( drv_id < USBH_CLASS_DRIVER_COUNT ) {
+ TU_LOG_USBH("%s xfer callback\r\n", usbh_class_drivers[drv_id].name);
+ usbh_class_drivers[drv_id].xfer_cb(event.dev_addr, ep_addr, (xfer_result_t) event.xfer_complete.result,
+ event.xfer_complete.len);
+ } else {
// no driver/callback responsible for this transfer
- TU_ASSERT(false, );
+ TU_ASSERT(false,);
}
-
}
}
}
@@ -565,7 +561,7 @@ bool tuh_control_xfer (tuh_xfer_t* xfer)
TU_LOG_USBH("[%u:%u] %s: ", rhport, daddr,
(xfer->setup->bmRequestType_bit.type == TUSB_REQ_TYPE_STANDARD && xfer->setup->bRequest <= TUSB_REQ_SYNCH_FRAME) ?
tu_str_std_request[xfer->setup->bRequest] : "Class Request");
- TU_LOG_PTR(USBH_DEBUG, xfer->setup);
+ TU_LOG_PTR(CFG_TUH_LOG_LEVEL, xfer->setup);
TU_LOG_USBH("\r\n");
if (xfer->complete_cb)
@@ -671,7 +667,7 @@ static bool usbh_control_xfer_cb (uint8_t dev_addr, uint8_t ep_addr, xfer_result
if (request->wLength)
{
TU_LOG_USBH("[%u:%u] Control data:\r\n", rhport, dev_addr);
- TU_LOG_MEM(USBH_DEBUG, _ctrl_xfer.buffer, xferred_bytes, 2);
+ TU_LOG_MEM(CFG_TUH_LOG_LEVEL, _ctrl_xfer.buffer, xferred_bytes, 2);
}
_ctrl_xfer.actual_len = (uint16_t) xferred_bytes;
@@ -714,6 +710,25 @@ bool tuh_edpt_xfer(tuh_xfer_t* xfer)
return true;
}
+bool tuh_edpt_abort_xfer(uint8_t daddr, uint8_t ep_addr) {
+ usbh_device_t* dev = get_device(daddr);
+ TU_VERIFY(dev);
+
+ uint8_t const epnum = tu_edpt_number(ep_addr);
+ uint8_t const dir = tu_edpt_dir(ep_addr);
+
+ // skip if not busy
+ TU_VERIFY(dev->ep_status[epnum][dir].busy);
+
+ bool const ret = hcd_edpt_abort_xfer(dev->rhport, daddr, ep_addr);
+ if (ret) {
+ // mark as ready if transfer is aborted
+ dev->ep_status[epnum][dir].busy = false;
+ }
+
+ return ret;
+}
+
//--------------------------------------------------------------------+
// USBH API For Class Driver
//--------------------------------------------------------------------+
@@ -745,7 +760,7 @@ void usbh_int_set(bool enabled)
// Endpoint API
//--------------------------------------------------------------------+
-// TODO has some duplication code with device, refactor later
+// Claim an endpoint for transfer
bool usbh_edpt_claim(uint8_t dev_addr, uint8_t ep_addr)
{
// Note: addr0 only use tuh_control_xfer
@@ -761,7 +776,7 @@ bool usbh_edpt_claim(uint8_t dev_addr, uint8_t ep_addr)
return true;
}
-// TODO has some duplication code with device, refactor later
+// Release an claimed endpoint due to failed transfer attempt
bool usbh_edpt_release(uint8_t dev_addr, uint8_t ep_addr)
{
// Note: addr0 only use tuh_control_xfer
@@ -777,7 +792,7 @@ bool usbh_edpt_release(uint8_t dev_addr, uint8_t ep_addr)
return true;
}
-// TODO has some duplication code with device, refactor later
+// Submit an transfer
bool usbh_edpt_xfer_with_callback(uint8_t dev_addr, uint8_t ep_addr, uint8_t * buffer, uint16_t total_bytes,
tuh_xfer_cb_t complete_cb, uintptr_t user_data)
{
@@ -844,14 +859,13 @@ bool tuh_edpt_open(uint8_t dev_addr, tusb_desc_endpoint_t const * desc_ep)
return hcd_edpt_open(usbh_get_rhport(dev_addr), dev_addr, desc_ep);
}
-bool usbh_edpt_busy(uint8_t dev_addr, uint8_t ep_addr)
-{
- uint8_t const epnum = tu_edpt_number(ep_addr);
- uint8_t const dir = tu_edpt_dir(ep_addr);
-
+bool usbh_edpt_busy(uint8_t dev_addr, uint8_t ep_addr) {
usbh_device_t* dev = get_device(dev_addr);
TU_VERIFY(dev);
+ uint8_t const epnum = tu_edpt_number(ep_addr);
+ uint8_t const dir = tu_edpt_dir(ep_addr);
+
return dev->ep_status[epnum][dir].busy;
}
@@ -1186,7 +1200,7 @@ static void process_removing_device(uint8_t rhport, uint8_t hub_addr, uint8_t hu
TU_LOG_USBH("Device unplugged address = %u\r\n", daddr);
if (is_hub_addr(daddr)) {
- TU_LOG(USBH_DEBUG, " is a HUB device %u\r\n", daddr);
+ TU_LOG(CFG_TUH_LOG_LEVEL, " is a HUB device %u\r\n", daddr);
// Submit removed event If the device itself is a hub (un-rolled recursive)
// TODO a better to unroll recursrive is using array of removing_hubs and mark it here
@@ -1657,7 +1671,7 @@ static bool _parse_configuration_descriptor(uint8_t dev_addr, tusb_desc_configur
if( drv_id >= USBH_CLASS_DRIVER_COUNT )
{
- TU_LOG(USBH_DEBUG, "Interface %u: class = %u subclass = %u protocol = %u is not supported\r\n",
+ TU_LOG(CFG_TUH_LOG_LEVEL, "Interface %u: class = %u subclass = %u protocol = %u is not supported\r\n",
desc_itf->bInterfaceNumber, desc_itf->bInterfaceClass, desc_itf->bInterfaceSubClass, desc_itf->bInterfaceProtocol);
}
}
@@ -1695,7 +1709,7 @@ void usbh_driver_set_config_complete(uint8_t dev_addr, uint8_t itf_num)
if (is_hub_addr(dev_addr))
{
- TU_LOG(USBH_DEBUG, "HUB address = %u is mounted\r\n", dev_addr);
+ TU_LOG(CFG_TUH_LOG_LEVEL, "HUB address = %u is mounted\r\n", dev_addr);
}else
{
// Invoke callback if available
diff --git a/src/host/usbh.h b/src/host/usbh.h
index 0f969a46a..0d56f40c9 100644
--- a/src/host/usbh.h
+++ b/src/host/usbh.h
@@ -172,8 +172,12 @@ bool tuh_control_xfer(tuh_xfer_t* xfer);
// - sync : blocking if complete callback is NULL.
bool tuh_edpt_xfer(tuh_xfer_t* xfer);
-// Open an non-control endpoint
-bool tuh_edpt_open(uint8_t dev_addr, tusb_desc_endpoint_t const * desc_ep);
+// Open a non-control endpoint
+bool tuh_edpt_open(uint8_t daddr, tusb_desc_endpoint_t const * desc_ep);
+
+// Abort a queued transfer. Note: it can only abort transfer that has not been started
+// Return true if a queued transfer is aborted, false if there is no transfer to abort
+bool tuh_edpt_abort_xfer(uint8_t daddr, uint8_t ep_addr);
// Set Configuration (control transfer)
// config_num = 0 will un-configure device. Note: config_num = config_descriptor_index + 1
diff --git a/src/portable/bridgetek/ft9xx/dcd_ft9xx.c b/src/portable/bridgetek/ft9xx/dcd_ft9xx.c
index 95dfda49c..f02415904 100644
--- a/src/portable/bridgetek/ft9xx/dcd_ft9xx.c
+++ b/src/portable/bridgetek/ft9xx/dcd_ft9xx.c
@@ -51,7 +51,7 @@ extern int8_t board_ft9xx_vbus(void);
extern int board_uart_write(void const *buf, int len);
// Static array to store an incoming SETUP request for processing by tinyusb.
-CFG_TUSB_MEM_SECTION CFG_TUSB_MEM_ALIGN
+CFG_TUD_MEM_SECTION CFG_TUSB_MEM_ALIGN
static uint8_t _ft9xx_setup_packet[8];
struct ft9xx_xfer_state
diff --git a/src/portable/chipidea/ci_fs/dcd_ci_fs.c b/src/portable/chipidea/ci_fs/dcd_ci_fs.c
index 37265df8b..9327e09d8 100644
--- a/src/portable/chipidea/ci_fs/dcd_ci_fs.c
+++ b/src/portable/chipidea/ci_fs/dcd_ci_fs.c
@@ -116,7 +116,7 @@ typedef struct
// INTERNAL OBJECT & FUNCTION DECLARATION
//--------------------------------------------------------------------+
// BDT(Buffer Descriptor Table) must be 256-byte aligned
-CFG_TUSB_MEM_SECTION TU_ATTR_ALIGNED(512) static dcd_data_t _dcd;
+CFG_TUD_MEM_SECTION TU_ATTR_ALIGNED(512) static dcd_data_t _dcd;
TU_VERIFY_STATIC( sizeof(_dcd.bdt) == 512, "size is not correct" );
diff --git a/src/portable/chipidea/ci_hs/ci_hs_imxrt.h b/src/portable/chipidea/ci_hs/ci_hs_imxrt.h
index c14f00431..c59c107ff 100644
--- a/src/portable/chipidea/ci_hs/ci_hs_imxrt.h
+++ b/src/portable/chipidea/ci_hs/ci_hs_imxrt.h
@@ -68,25 +68,34 @@ TU_ATTR_ALWAYS_INLINE static inline bool imxrt_is_cache_mem(uintptr_t addr) {
return !(0x20000000 <= addr && addr < 0x20100000);
}
-TU_ATTR_ALWAYS_INLINE static inline void imxrt_dcache_clean(void const* addr, uint32_t data_size) {
+TU_ATTR_ALWAYS_INLINE static inline bool imxrt_dcache_clean(void const* addr, uint32_t data_size) {
const uintptr_t addr32 = (uintptr_t) addr;
if (imxrt_is_cache_mem(addr32)) {
+ TU_ASSERT(tu_is_aligned32(addr32));
SCB_CleanDCache_by_Addr((uint32_t *) addr32, (int32_t) data_size);
}
+ return true;
}
-TU_ATTR_ALWAYS_INLINE static inline void imxrt_dcache_invalidate(void const* addr, uint32_t data_size) {
+TU_ATTR_ALWAYS_INLINE static inline bool imxrt_dcache_invalidate(void const* addr, uint32_t data_size) {
const uintptr_t addr32 = (uintptr_t) addr;
if (imxrt_is_cache_mem(addr32)) {
+ // Invalidating does not push cached changes back to RAM so we need to be
+ // *very* careful when we do it. If we're not aligned, then we risk resetting
+ // values back to their RAM state.
+ TU_ASSERT(tu_is_aligned32(addr32));
SCB_InvalidateDCache_by_Addr((void*) addr32, (int32_t) data_size);
}
+ return true;
}
-TU_ATTR_ALWAYS_INLINE static inline void imxrt_dcache_clean_invalidate(void const* addr, uint32_t data_size) {
+TU_ATTR_ALWAYS_INLINE static inline bool imxrt_dcache_clean_invalidate(void const* addr, uint32_t data_size) {
const uintptr_t addr32 = (uintptr_t) addr;
if (imxrt_is_cache_mem(addr32)) {
+ TU_ASSERT(tu_is_aligned32(addr32));
SCB_CleanInvalidateDCache_by_Addr((uint32_t *) addr32, (int32_t) data_size);
}
+ return true;
}
#endif
diff --git a/src/portable/chipidea/ci_hs/dcd_ci_hs.c b/src/portable/chipidea/ci_hs/dcd_ci_hs.c
index f50550d33..f9ec666e5 100644
--- a/src/portable/chipidea/ci_hs/dcd_ci_hs.c
+++ b/src/portable/chipidea/ci_hs/dcd_ci_hs.c
@@ -175,7 +175,7 @@ typedef struct {
dcd_qtd_t qtd[TUP_DCD_ENDPOINT_MAX][2] TU_ATTR_ALIGNED(32);
}dcd_data_t;
-CFG_TUSB_MEM_SECTION TU_ATTR_ALIGNED(2048)
+CFG_TUD_MEM_SECTION TU_ATTR_ALIGNED(2048)
static dcd_data_t _dcd_data;
//--------------------------------------------------------------------+
diff --git a/src/portable/chipidea/ci_hs/hcd_ci_hs.c b/src/portable/chipidea/ci_hs/hcd_ci_hs.c
index 56167b8f6..6ee91e18e 100644
--- a/src/portable/chipidea/ci_hs/hcd_ci_hs.c
+++ b/src/portable/chipidea/ci_hs/hcd_ci_hs.c
@@ -41,16 +41,16 @@
#if CFG_TUSB_MCU == OPT_MCU_MIMXRT1XXX
#include "ci_hs_imxrt.h"
- void hcd_dcache_clean(void const* addr, uint32_t data_size) {
- imxrt_dcache_clean(addr, data_size);
+ bool hcd_dcache_clean(void const* addr, uint32_t data_size) {
+ return imxrt_dcache_clean(addr, data_size);
}
- void hcd_dcache_invalidate(void const* addr, uint32_t data_size) {
- imxrt_dcache_invalidate(addr, data_size);
+ bool hcd_dcache_invalidate(void const* addr, uint32_t data_size) {
+ return imxrt_dcache_invalidate(addr, data_size);
}
- void hcd_dcache_clean_invalidate(void const* addr, uint32_t data_size) {
- imxrt_dcache_clean_invalidate(addr, data_size);
+ bool hcd_dcache_clean_invalidate(void const* addr, uint32_t data_size) {
+ return imxrt_dcache_clean_invalidate(addr, data_size);
}
#elif TU_CHECK_MCU(OPT_MCU_LPC18XX, OPT_MCU_LPC43XX)
diff --git a/src/portable/ehci/ehci.c b/src/portable/ehci/ehci.c
index 38711e382..9be24c888 100644
--- a/src/portable/ehci/ehci.c
+++ b/src/portable/ehci/ehci.c
@@ -48,8 +48,8 @@
#ifdef TUP_USBIP_CHIPIDEA_HS
// NXP Transdimension: 8 elements
#define FRAMELIST_SIZE_BIT_VALUE 7u
- #define FRAMELIST_SIZE_USBCMD_VALUE (((FRAMELIST_SIZE_BIT_VALUE & 3) << EHCI_USBCMD_POS_FRAMELIST_SIZE) | \
- ((FRAMELIST_SIZE_BIT_VALUE >> 2) << EHCI_USBCMD_POS_NXP_FRAMELIST_SIZE_MSB))
+ #define FRAMELIST_SIZE_USBCMD_VALUE (((FRAMELIST_SIZE_BIT_VALUE & 3) << EHCI_USBCMD_FRAMELIST_SIZE_SHIFT) | \
+ ((FRAMELIST_SIZE_BIT_VALUE >> 2) << EHCI_USBCMD_CHIPIDEA_FRAMELIST_SIZE_MSB_SHIFT))
#else
// STD EHCI: 256 elements
#define FRAMELIST_SIZE_BIT_VALUE 2u
@@ -126,52 +126,50 @@ static inline void print_intr(uint32_t intr) {
//--------------------------------------------------------------------+
// PROTOTYPE
//--------------------------------------------------------------------+
-static inline ehci_link_t* get_period_head(uint8_t rhport, uint32_t interval_ms)
-{
- (void) rhport;
- return (ehci_link_t*) &ehci_data.period_head_arr[ tu_log2( tu_min32(FRAMELIST_SIZE, interval_ms) ) ];
-}
-static inline ehci_qhd_t* qhd_control(uint8_t dev_addr)
-{
- return &ehci_data.control[dev_addr].qhd;
-}
+// weak dcache for non-cacheable MCU
+TU_ATTR_WEAK bool hcd_dcache_clean(void const* addr, uint32_t data_size) { (void) addr; (void) data_size; return true; }
+TU_ATTR_WEAK bool hcd_dcache_invalidate(void const* addr, uint32_t data_size) { (void) addr; (void) data_size; return true; }
+TU_ATTR_WEAK bool hcd_dcache_clean_invalidate(void const* addr, uint32_t data_size) { (void) addr; (void) data_size; return true; }
-static inline ehci_qhd_t* qhd_async_head(uint8_t rhport)
-{
- (void) rhport;
- // control qhd of dev0 is used as async head
- return qhd_control(0);
-}
-
-static inline ehci_qtd_t* qtd_control(uint8_t dev_addr)
-{
- return &ehci_data.control[dev_addr].qtd;
-}
-
-
-static inline ehci_qhd_t* qhd_next (ehci_qhd_t const * p_qhd);
-static inline ehci_qhd_t* qhd_find_free (void);
-static inline ehci_qhd_t* qhd_get_from_addr (uint8_t dev_addr, uint8_t ep_addr);
+TU_ATTR_ALWAYS_INLINE static inline ehci_qhd_t* qhd_control(uint8_t dev_addr);
+TU_ATTR_ALWAYS_INLINE static inline ehci_qhd_t* qhd_next (ehci_qhd_t const * p_qhd);
+TU_ATTR_ALWAYS_INLINE static inline ehci_qhd_t* qhd_find_free (void);
+static ehci_qhd_t* qhd_get_from_addr (uint8_t dev_addr, uint8_t ep_addr);
static void qhd_init(ehci_qhd_t *p_qhd, uint8_t dev_addr, tusb_desc_endpoint_t const * ep_desc);
static void qhd_attach_qtd(ehci_qhd_t *qhd, ehci_qtd_t *qtd);
+static void qhd_remove_qtd(ehci_qhd_t *qhd);
-static inline ehci_qtd_t* qtd_find_free (void);
+TU_ATTR_ALWAYS_INLINE static inline ehci_qtd_t* qtd_control(uint8_t dev_addr);
+TU_ATTR_ALWAYS_INLINE static inline ehci_qtd_t* qtd_find_free (void);
static void qtd_init (ehci_qtd_t* qtd, void const* buffer, uint16_t total_bytes);
-static inline void list_insert (ehci_link_t *current, ehci_link_t *new, uint8_t new_type);
-static inline ehci_link_t* list_next (ehci_link_t const *p_link);
+TU_ATTR_ALWAYS_INLINE static inline ehci_link_t* list_get_period_head(uint8_t rhport, uint32_t interval_ms);
+TU_ATTR_ALWAYS_INLINE static inline ehci_qhd_t* list_get_async_head(uint8_t rhport);
+TU_ATTR_ALWAYS_INLINE static inline void list_insert (ehci_link_t *current, ehci_link_t *new, uint8_t new_type);
+TU_ATTR_ALWAYS_INLINE static inline ehci_link_t* list_next (ehci_link_t const *p_link);
+static void list_remove_qhd_by_daddr(ehci_link_t* list_head, uint8_t dev_addr);
-TU_ATTR_WEAK void hcd_dcache_clean(void const* addr, uint32_t data_size) {
- (void) addr; (void) data_size;
+static void ehci_disable_schedule(ehci_registers_t* regs, bool is_period) {
+ // maybe have a timeout for status
+ if (is_period) {
+ regs->command_bm.periodic_enable = 0;
+ while(regs->status_bm.periodic_status) {}
+ } else {
+ regs->command_bm.async_enable = 0;
+ while(regs->status_bm.async_status) {} // should have a timeout
+ }
}
-TU_ATTR_WEAK void hcd_dcache_invalidate(void const* addr, uint32_t data_size) {
- (void) addr; (void) data_size;
-}
-
-TU_ATTR_WEAK void hcd_dcache_clean_invalidate(void const* addr, uint32_t data_size) {
- (void) addr; (void) data_size;
+static void ehci_enable_schedule(ehci_registers_t* regs, bool is_period) {
+ // maybe have a timeout for status
+ if (is_period) {
+ regs->command_bm.periodic_enable = 1;
+ while ( 0 == regs->status_bm.periodic_status ) {}
+ } else {
+ regs->command_bm.async_enable = 1;
+ while( 0 == regs->status_bm.async_status ) {}
+ }
}
//--------------------------------------------------------------------+
@@ -228,43 +226,6 @@ tusb_speed_t hcd_port_speed_get(uint8_t rhport)
return (tusb_speed_t) ehci_data.regs->portsc_bm.nxp_port_speed; // NXP specific port speed
}
-static void list_remove_qhd_by_daddr(ehci_link_t* list_head, uint8_t dev_addr) {
- ehci_link_t* prev = list_head;
-
- while (prev && !prev->terminate) {
- ehci_qhd_t* qhd = (ehci_qhd_t*) (uintptr_t) list_next(prev);
-
- // done if loop back to head
- if ( (uintptr_t) qhd == (uintptr_t) list_head) {
- break;
- }
-
- if ( qhd->dev_addr == dev_addr ) {
- // TODO deactivate all TD, wait for QHD to inactive before removal
- prev->address = qhd->next.address;
-
- // EHCI 4.8.2 link the removed qhd's next to async head (which always reachable by Host Controller)
- qhd->next.address = ((uint32_t) list_head) | (EHCI_QTYPE_QHD << 1);
-
- if ( qhd->int_smask )
- {
- // period list queue element is guarantee to be free in the next frame (1 ms)
- qhd->used = 0;
- }else
- {
- // async list use async advance handshake
- // mark as removing, will completely re-usable when async advance isr occurs
- qhd->removing = 1;
- }
-
- hcd_dcache_clean(qhd, sizeof(ehci_qhd_t));
- hcd_dcache_clean(prev, sizeof(ehci_qhd_t));
- }else {
- prev = list_next(prev);
- }
- }
-}
-
// Close all opened endpoint belong to this device
void hcd_device_close(uint8_t rhport, uint8_t daddr)
{
@@ -274,7 +235,7 @@ void hcd_device_close(uint8_t rhport, uint8_t daddr)
}
// Remove from async list
- list_remove_qhd_by_daddr((ehci_link_t *) qhd_async_head(rhport), daddr);
+ list_remove_qhd_by_daddr((ehci_link_t *) list_get_async_head(rhport), daddr);
// Remove from all interval period list
for(uint8_t i = 0; i < TU_ARRAY_SIZE(ehci_data.period_head_arr); i++) {
@@ -286,37 +247,42 @@ void hcd_device_close(uint8_t rhport, uint8_t daddr)
}
static void init_periodic_list(uint8_t rhport) {
+ (void) rhport;
+
// Build the polling interval tree with 1 ms, 2 ms, 4 ms and 8 ms (framesize) only
for ( uint32_t i = 0; i < TU_ARRAY_SIZE(ehci_data.period_head_arr); i++ ) {
ehci_data.period_head_arr[i].int_smask = 1; // queue head in period list must have smask non-zero
ehci_data.period_head_arr[i].qtd_overlay.halted = 1; // dummy node, always inactive
}
- ehci_link_t * const framelist = ehci_data.period_framelist;
- ehci_link_t * const period_1ms = get_period_head(rhport, 1u);
-
+ // TODO EHCI_FRAMELIST_SIZE with other size than 8
// all links --> period_head_arr[0] (1ms)
// 0, 2, 4, 6 etc --> period_head_arr[1] (2ms)
// 1, 5 --> period_head_arr[2] (4ms)
// 3 --> period_head_arr[3] (8ms)
- // TODO EHCI_FRAMELIST_SIZE with other size than 8
+ ehci_link_t * const framelist = ehci_data.period_framelist;
+ ehci_link_t * const head_1ms = (ehci_link_t *) &ehci_data.period_head_arr[0];
+ ehci_link_t * const head_2ms = (ehci_link_t *) &ehci_data.period_head_arr[1];
+ ehci_link_t * const head_4ms = (ehci_link_t *) &ehci_data.period_head_arr[2];
+ ehci_link_t * const head_8ms = (ehci_link_t *) &ehci_data.period_head_arr[3];
+
for (uint32_t i = 0; i < FRAMELIST_SIZE; i++) {
- framelist[i].address = (uint32_t) period_1ms;
+ framelist[i].address = (uint32_t) head_1ms;
framelist[i].type = EHCI_QTYPE_QHD;
}
for (uint32_t i = 0; i < FRAMELIST_SIZE; i += 2) {
- list_insert(framelist + i, get_period_head(rhport, 2u), EHCI_QTYPE_QHD);
+ list_insert(framelist + i, head_2ms, EHCI_QTYPE_QHD);
}
for (uint32_t i = 1; i < FRAMELIST_SIZE; i += 4) {
- list_insert(framelist + i, get_period_head(rhport, 4u), EHCI_QTYPE_QHD);
+ list_insert(framelist + i, head_4ms, EHCI_QTYPE_QHD);
}
- list_insert(framelist + 3, get_period_head(rhport, 8u), EHCI_QTYPE_QHD);
+ list_insert(framelist + 3, head_8ms, EHCI_QTYPE_QHD);
- period_1ms->terminate = 1;
+ head_1ms->terminate = 1;
}
bool ehci_init(uint8_t rhport, uint32_t capability_reg, uint32_t operatial_reg)
@@ -341,18 +307,18 @@ bool ehci_init(uint8_t rhport, uint32_t capability_reg, uint32_t operatial_reg)
regs->status = (EHCI_INT_MASK_ALL & ~EHCI_INT_MASK_PORT_CHANGE);
// Enable interrupts
- regs->inten = EHCI_INT_MASK_ERROR | EHCI_INT_MASK_PORT_CHANGE | EHCI_INT_MASK_ASYNC_ADVANCE |
- EHCI_INT_MASK_NXP_PERIODIC | EHCI_INT_MASK_NXP_ASYNC | EHCI_INT_MASK_FRAMELIST_ROLLOVER;
+ regs->inten = EHCI_INT_MASK_USB | EHCI_INT_MASK_ERROR | EHCI_INT_MASK_PORT_CHANGE |
+ EHCI_INT_MASK_ASYNC_ADVANCE | EHCI_INT_MASK_FRAMELIST_ROLLOVER;
//------------- Asynchronous List -------------//
- ehci_qhd_t * const async_head = qhd_async_head(rhport);
+ ehci_qhd_t * const async_head = list_get_async_head(rhport);
tu_memclr(async_head, sizeof(ehci_qhd_t));
- async_head->next.address = (uint32_t) async_head; // circular list, next is itself
- async_head->next.type = EHCI_QTYPE_QHD;
- async_head->head_list_flag = 1;
- async_head->qtd_overlay.halted = 1; // inactive most of time
- async_head->qtd_overlay.next.terminate = 1; // TODO removed if verified
+ async_head->next.address = (uint32_t) async_head; // circular list, next is itself
+ async_head->next.type = EHCI_QTYPE_QHD;
+ async_head->head_list_flag = 1;
+ async_head->qtd_overlay.halted = 1; // inactive most of time
+ async_head->qtd_overlay.next.terminate = 1; // TODO removed if verified
regs->async_list_addr = (uint32_t) async_head;
@@ -366,8 +332,7 @@ bool ehci_init(uint8_t rhport, uint32_t capability_reg, uint32_t operatial_reg)
regs->nxp_tt_control = 0;
//------------- USB CMD Register -------------//
- regs->command |= TU_BIT(EHCI_USBCMD_POS_RUN_STOP) | TU_BIT(EHCI_USBCMD_POS_ASYNC_ENABLE) |
- TU_BIT(EHCI_USBCMD_POS_PERIOD_ENABLE) | // TODO enable period list only there is int/iso endpoint
+ regs->command |= EHCI_USBCMD_RUN_STOP | EHCI_USBCMD_PERIOD_SCHEDULE_ENABLE | EHCI_USBCMD_ASYNC_SCHEDULE_ENABLE |
FRAMELIST_SIZE_USBCMD_VALUE;
//------------- ConfigFlag Register (skip) -------------//
@@ -377,7 +342,7 @@ bool ehci_init(uint8_t rhport, uint32_t capability_reg, uint32_t operatial_reg)
if (ehci_data.cap_regs->hcsparams_bm.port_power_control) {
// mask out all change bits since they are Write 1 to clear
uint32_t portsc = (regs->portsc & ~EHCI_PORTSC_MASK_W1C);
- portsc |= ECHI_PORTSC_MASK_PORT_POWER;
+ portsc |= EHCI_PORTSC_MASK_PORT_POWER;
regs->portsc = portsc;
}
@@ -426,11 +391,11 @@ bool hcd_edpt_open(uint8_t rhport, uint8_t dev_addr, tusb_desc_endpoint_t const
{
case TUSB_XFER_CONTROL:
case TUSB_XFER_BULK:
- list_head = (ehci_link_t*) qhd_async_head(rhport);
+ list_head = (ehci_link_t*) list_get_async_head(rhport);
break;
case TUSB_XFER_INTERRUPT:
- list_head = get_period_head(rhport, p_qhd->interval_ms);
+ list_head = list_get_period_head(rhport, p_qhd->interval_ms);
break;
case TUSB_XFER_ISOCHRONOUS:
@@ -439,10 +404,8 @@ bool hcd_edpt_open(uint8_t rhport, uint8_t dev_addr, tusb_desc_endpoint_t const
default: break;
}
-
TU_ASSERT(list_head);
- // TODO might need to disable async/period list
list_insert(list_head, (ehci_link_t*) p_qhd, EHCI_QTYPE_QHD);
hcd_dcache_clean(p_qhd, sizeof(ehci_qhd_t));
@@ -476,20 +439,25 @@ bool hcd_edpt_xfer(uint8_t rhport, uint8_t dev_addr, uint8_t ep_addr, uint8_t *
uint8_t const epnum = tu_edpt_number(ep_addr);
uint8_t const dir = tu_edpt_dir(ep_addr);
- ehci_qhd_t* qhd;
+ ehci_qhd_t* qhd = qhd_get_from_addr(dev_addr, ep_addr);
ehci_qtd_t* qtd;
if (epnum == 0) {
- qhd = qhd_control(dev_addr);
- qtd = qtd_control(dev_addr);
+ // Control endpoint never be stalled. Skip reset Data Toggle since it is fixed per stage
+ if (qhd->qtd_overlay.halted) {
+ qhd->qtd_overlay.halted = false;
+ }
+ qtd = qtd_control(dev_addr);
qtd_init(qtd, buffer, buflen);
// first data toggle is always 1 (data & setup stage)
qtd->data_toggle = 1;
qtd->pid = dir ? EHCI_PID_IN : EHCI_PID_OUT;
} else {
- qhd = qhd_get_from_addr(dev_addr, ep_addr);
+ // skip if endpoint is halted
+ TU_VERIFY(!qhd->qtd_overlay.halted);
+
qtd = qtd_find_free();
TU_ASSERT(qtd);
@@ -510,12 +478,45 @@ bool hcd_edpt_xfer(uint8_t rhport, uint8_t dev_addr, uint8_t ep_addr, uint8_t *
return true;
}
-bool hcd_edpt_clear_stall(uint8_t daddr, uint8_t ep_addr)
-{
+bool hcd_edpt_abort_xfer(uint8_t rhport, uint8_t dev_addr, uint8_t ep_addr) {
+ (void) rhport;
+
+ // TODO ISO not supported yet
+ ehci_qhd_t* qhd = qhd_get_from_addr(dev_addr, ep_addr);
+ ehci_qtd_t * volatile qtd = qhd->attached_qtd;
+ TU_VERIFY(qtd != NULL); // no queued transfer
+
+ hcd_dcache_invalidate(qtd, sizeof(ehci_qtd_t));
+ TU_VERIFY(qtd->active); // transfer is already complete
+
+ // HC is still processing, disable HC list schedule before making changes
+ bool const is_period = (qhd->interval_ms > 0);
+
+ ehci_disable_schedule(ehci_data.regs, is_period);
+
+ // check active bit again just in case HC has just processed the TD
+ bool const still_active = qtd->active;
+ if (still_active) {
+ // remove TD from QH overlay
+ qhd->qtd_overlay.next.terminate = 1;
+ hcd_dcache_clean(qhd, sizeof(ehci_qhd_t));
+
+ // remove TD from QH software list
+ qhd_remove_qtd(qhd);
+ }
+
+ ehci_enable_schedule(ehci_data.regs, is_period);
+
+ return still_active; // true if removed an active transfer
+}
+
+bool hcd_edpt_clear_stall(uint8_t rhport, uint8_t daddr, uint8_t ep_addr) {
+ (void) rhport;
ehci_qhd_t *qhd = qhd_get_from_addr(daddr, ep_addr);
qhd->qtd_overlay.halted = 0;
+ qhd->qtd_overlay.data_toggle = 0;
hcd_dcache_clean_invalidate(qhd, sizeof(ehci_qhd_t));
- // TODO reset data toggle ?
+
return true;
}
@@ -541,71 +542,77 @@ void async_advance_isr(uint8_t rhport)
}
TU_ATTR_ALWAYS_INLINE static inline
-void port_connect_status_change_isr(uint8_t rhport)
-{
+void port_connect_status_change_isr(uint8_t rhport) {
// NOTE There is an sequence plug->unplug->…..-> plug if device is powering with pre-plugged device
- if (ehci_data.regs->portsc_bm.current_connect_status)
- {
+ if ( ehci_data.regs->portsc_bm.current_connect_status ) {
hcd_port_reset(rhport);
hcd_event_device_attach(rhport, true);
- }else // device unplugged
+ } else // device unplugged
{
hcd_event_device_remove(rhport, true);
}
}
+// Check queue head for potential transfer complete (successful or error)
TU_ATTR_ALWAYS_INLINE static inline
void qhd_xfer_complete_isr(ehci_qhd_t * qhd) {
- // examine TD attached to queue head
- ehci_qtd_t * volatile qtd = (ehci_qtd_t * volatile) qhd->attached_qtd;
- if (qtd == NULL) return; // no TD attached
- hcd_dcache_invalidate(qtd, sizeof(ehci_qtd_t));
+ hcd_dcache_invalidate(qhd, sizeof(ehci_qhd_t)); // HC may have updated the overlay
+ volatile ehci_qtd_t *qtd_overlay = &qhd->qtd_overlay;
- // TD is still active, no need to process
- if (qtd->active) {
- return;
- }
+ // process non-active (completed) QHD with attached (scheduled) TD
+ if ( !qtd_overlay->active && qhd->attached_qtd != NULL ) {
+ xfer_result_t xfer_result;
- uint8_t dir = (qtd->pid == EHCI_PID_IN) ? 1 : 0;
- uint32_t const xferred_bytes = qtd->expected_bytes - qtd->total_bytes;
-
- // invalidate dcache if IN transfer
- if (dir == 1 && qhd->attached_buffer != 0 && xferred_bytes > 0) {
- hcd_dcache_invalidate((void*) qhd->attached_buffer, xferred_bytes);
- }
-
- // remove and free TD before invoking callback
- qhd->attached_qtd = NULL;
- qhd->attached_buffer = 0;
- qtd->used = 0; // free QTD
-
- // notify usbh
- uint8_t const ep_addr = tu_edpt_addr(qhd->ep_number, dir);
- hcd_event_xfer_complete(qhd->dev_addr, ep_addr, xferred_bytes, XFER_RESULT_SUCCESS, true);
-}
-
-TU_ATTR_ALWAYS_INLINE static inline
-void async_list_xfer_complete_isr(ehci_qhd_t * const async_head)
-{
- ehci_qhd_t *p_qhd = async_head;
- do
- {
- hcd_dcache_invalidate(p_qhd, sizeof(ehci_qhd_t));
-
- // halted or error is processed in error isr
- if ( !p_qhd->qtd_overlay.halted ) {
- qhd_xfer_complete_isr(p_qhd);
+ if ( qtd_overlay->halted ) {
+ if (qtd_overlay->xact_err || qtd_overlay->err_count == 0 || qtd_overlay->buffer_err || qtd_overlay->babble_err) {
+ // Error count = 0 often occurs when device disconnected, or other bus-related error
+ xfer_result = XFER_RESULT_FAILED;
+ TU_LOG3(" QHD xfer err count: %d\n", qtd_overlay->err_count);
+ // TU_BREAKPOINT(); // TODO skip unplugged device
+ }else {
+ // no error bits are set, endpoint is halted due to STALL
+ xfer_result = XFER_RESULT_STALLED;
+ }
+ } else {
+ xfer_result = XFER_RESULT_SUCCESS;
}
- p_qhd = qhd_next(p_qhd);
- }while(p_qhd != async_head); // async list traversal, stop if loop around
+ ehci_qtd_t * volatile qtd = qhd->attached_qtd;
+ hcd_dcache_invalidate(qtd, sizeof(ehci_qtd_t)); // HC may have written back TD
+
+ uint8_t const dir = (qtd->pid == EHCI_PID_IN) ? 1 : 0;
+ uint32_t const xferred_bytes = qtd->expected_bytes - qtd->total_bytes;
+
+ // invalidate dcache if IN transfer with data
+ if (dir == 1 && qhd->attached_buffer != 0 && xferred_bytes > 0) {
+ hcd_dcache_invalidate((void*) qhd->attached_buffer, xferred_bytes);
+ }
+
+ // remove and free TD before invoking callback
+ qhd_remove_qtd(qhd);
+
+ // notify usbh
+ uint8_t const ep_addr = tu_edpt_addr(qhd->ep_number, dir);
+ hcd_event_xfer_complete(qhd->dev_addr, ep_addr, xferred_bytes, xfer_result, true);
+ }
}
TU_ATTR_ALWAYS_INLINE static inline
-void period_list_xfer_complete_isr(uint8_t rhport, uint32_t interval_ms)
+void proccess_async_xfer_isr(ehci_qhd_t * const list_head)
{
- uint32_t const period_1ms_addr = (uint32_t) get_period_head(rhport, 1u);
- ehci_link_t next_link = * get_period_head(rhport, interval_ms);
+ ehci_qhd_t *qhd = list_head;
+
+ do {
+ qhd_xfer_complete_isr(qhd);
+ qhd = qhd_next(qhd);
+ } while ( qhd != list_head ); // async list traversal, stop if loop around
+}
+
+TU_ATTR_ALWAYS_INLINE static inline
+void process_period_xfer_isr(uint8_t rhport, uint32_t interval_ms)
+{
+ uint32_t const period_1ms_addr = (uint32_t) list_get_period_head(rhport, 1u);
+ ehci_link_t next_link = *list_get_period_head(rhport, interval_ms);
while (!next_link.terminate) {
if (interval_ms > 1 && period_1ms_addr == tu_align32(next_link.address)) {
@@ -618,22 +625,13 @@ void period_list_xfer_complete_isr(uint8_t rhport, uint32_t interval_ms)
switch (next_link.type) {
case EHCI_QTYPE_QHD: {
ehci_qhd_t *qhd = (ehci_qhd_t *) entry_addr;
- hcd_dcache_invalidate(qhd, sizeof(ehci_qhd_t));
-
- if (!qhd->qtd_overlay.halted) {
- qhd_xfer_complete_isr(qhd);
- }
+ qhd_xfer_complete_isr(qhd);
}
break;
+ // TODO support hs/fs ISO
case EHCI_QTYPE_ITD:
- // TODO support hs ISO
- break;
-
case EHCI_QTYPE_SITD:
- // TODO support split ISO
- break;
-
case EHCI_QTYPE_FSTN:
default:
break;
@@ -643,108 +641,6 @@ void period_list_xfer_complete_isr(uint8_t rhport, uint32_t interval_ms)
}
}
-// TODO merge with qhd_xfer_complete_isr()
-TU_ATTR_ALWAYS_INLINE static inline
-void qhd_xfer_error_isr(ehci_qhd_t * qhd)
-{
- volatile ehci_qtd_t *qtd_overlay = &qhd->qtd_overlay;
-
- // TD has error
- if (qtd_overlay->halted) {
- xfer_result_t xfer_result;
-
- if (qtd_overlay->xact_err || qtd_overlay->err_count == 0 || qtd_overlay->buffer_err || qtd_overlay->babble_err) {
- // Error count = 0 often occurs when device disconnected, or other bus-related error
- xfer_result = XFER_RESULT_FAILED;
- }else {
- // no error bits are set, endpoint is halted due to STALL
- xfer_result = XFER_RESULT_STALLED;
- }
-
-// if (XFER_RESULT_FAILED == xfer_result ) {
-// TU_LOG1(" QHD xfer err count: %d\n", qtd_overlay->err_count);
-// TU_BREAKPOINT(); // TODO skip unplugged device
-// }
-
- ehci_qtd_t * volatile qtd = (ehci_qtd_t * volatile) qhd->attached_qtd;
- TU_ASSERT(qtd, ); // No TD yet, probably a race condition or cache issue !?
-
- hcd_dcache_invalidate(qtd, sizeof(ehci_qtd_t));
-
- uint8_t dir = (qtd->pid == EHCI_PID_IN) ? 1 : 0;
- uint32_t const xferred_bytes = qtd->expected_bytes - qtd->total_bytes;
-
- // invalidate dcache if IN transfer
- if (dir == 1 && qhd->attached_buffer != 0 && xferred_bytes > 0) {
- hcd_dcache_invalidate((void*) qhd->attached_buffer, xferred_bytes);
- }
-
- // remove and free TD before invoking callback
- qhd->attached_qtd = NULL;
- qhd->attached_buffer = 0;
- qtd->used = 0; // free QTD
-
- if (0 == qhd->ep_number ) {
- // control cannot be halted
- qhd->qtd_overlay.next.terminate = 1;
- qhd->qtd_overlay.alternate.terminate = 1;
- qhd->qtd_overlay.halted = 0;
-
- hcd_dcache_clean(qhd, sizeof(ehci_qhd_t));
- }
-
- // notify usbh
- uint8_t const ep_addr = tu_edpt_addr(qhd->ep_number, dir);
- hcd_event_xfer_complete(qhd->dev_addr, ep_addr, xferred_bytes, xfer_result, true);
- }
-}
-
-TU_ATTR_ALWAYS_INLINE static inline
-void xfer_error_isr(uint8_t rhport)
-{
- //------------- async list -------------//
- ehci_qhd_t * const async_head = qhd_async_head(rhport);
- ehci_qhd_t *p_qhd = async_head;
- do
- {
- hcd_dcache_invalidate(p_qhd, sizeof(ehci_qhd_t));
- qhd_xfer_error_isr( p_qhd );
- p_qhd = qhd_next(p_qhd);
- }while(p_qhd != async_head); // async list traversal, stop if loop around
-
- //------------- TODO refractor period list -------------//
- uint32_t const period_1ms_addr = (uint32_t) get_period_head(rhport, 1u);
- for (uint32_t interval_ms=1; interval_ms <= FRAMELIST_SIZE; interval_ms *= 2)
- {
- ehci_link_t next_item = * get_period_head(rhport, interval_ms);
-
- // TODO abstract max loop guard for period
- while( !next_item.terminate &&
- !(interval_ms > 1 && period_1ms_addr == tu_align32(next_item.address)) )
- {
- switch ( next_item.type )
- {
- case EHCI_QTYPE_QHD:
- {
- ehci_qhd_t *p_qhd_int = (ehci_qhd_t *) tu_align32(next_item.address);
- hcd_dcache_invalidate(p_qhd_int, sizeof(ehci_qhd_t));
-
- qhd_xfer_error_isr(p_qhd_int);
- }
- break;
-
- // TODO support hs/fs ISO
- case EHCI_QTYPE_ITD:
- case EHCI_QTYPE_SITD:
- case EHCI_QTYPE_FSTN:
- default: break;
- }
-
- next_item = *list_next(&next_item);
- }
- }
-}
-
//------------- Host Controller Driver's Interrupt Handler -------------//
void hcd_int_handler(uint8_t rhport)
{
@@ -776,29 +672,16 @@ void hcd_int_handler(uint8_t rhport)
regs->status = EHCI_INT_MASK_PORT_CHANGE; // Acknowledge
}
- if (int_status & EHCI_INT_MASK_ERROR) {
- xfer_error_isr(rhport);
- regs->status = EHCI_INT_MASK_ERROR; // Acknowledge
- }
+ // A USB transfer is completed (OK or error)
+ uint32_t const usb_int = int_status & (EHCI_INT_MASK_USB | EHCI_INT_MASK_ERROR);
+ if (usb_int) {
+ proccess_async_xfer_isr(list_get_async_head(rhport));
- //------------- some QTD/SITD/ITD with IOC set is completed -------------//
- if (int_status & EHCI_INT_MASK_NXP_ASYNC) {
- async_list_xfer_complete_isr(qhd_async_head(rhport));
- regs->status = EHCI_INT_MASK_NXP_ASYNC; // Acknowledge
- }
-
- if (int_status & EHCI_INT_MASK_NXP_PERIODIC)
- {
- for (uint32_t i=1; i <= FRAMELIST_SIZE; i *= 2)
- {
- period_list_xfer_complete_isr(rhport, i);
+ for ( uint32_t i = 1; i <= FRAMELIST_SIZE; i *= 2 ) {
+ process_period_xfer_isr(rhport, i);
}
- regs->status = EHCI_INT_MASK_NXP_PERIODIC; // Acknowledge
- }
- if (int_status & EHCI_INT_MASK_USB) {
- // TODO standard EHCI xfer complete
- regs->status = EHCI_INT_MASK_USB; // Acknowledge
+ regs->status = usb_int; // Acknowledge
}
//------------- There is some removed async previously -------------//
@@ -810,35 +693,103 @@ void hcd_int_handler(uint8_t rhport)
}
//--------------------------------------------------------------------+
-// HELPER
+// List Managing Helper
//--------------------------------------------------------------------+
+// Get head of periodic list
+TU_ATTR_ALWAYS_INLINE static inline ehci_link_t* list_get_period_head(uint8_t rhport, uint32_t interval_ms) {
+ (void) rhport;
+ return (ehci_link_t*) &ehci_data.period_head_arr[ tu_log2( tu_min32(FRAMELIST_SIZE, interval_ms) ) ];
+}
-//------------- queue head helper -------------//
-static inline ehci_qhd_t* qhd_find_free (void)
+// Get head of async list
+TU_ATTR_ALWAYS_INLINE static inline ehci_qhd_t* list_get_async_head(uint8_t rhport) {
+ (void) rhport;
+ return qhd_control(0); // control qhd of dev0 is used as async head
+}
+
+TU_ATTR_ALWAYS_INLINE static inline ehci_link_t* list_next(ehci_link_t const *p_link) {
+ return (ehci_link_t*) tu_align32(p_link->address);
+}
+
+TU_ATTR_ALWAYS_INLINE static inline void list_insert(ehci_link_t *current, ehci_link_t *new, uint8_t new_type)
{
- for (uint32_t i=0; iaddress = current->address;
+ current->address = ((uint32_t) new) | (new_type << 1);
+}
+
+// Remove all queue head belong to this device address
+static void list_remove_qhd_by_daddr(ehci_link_t* list_head, uint8_t dev_addr) {
+ ehci_link_t* prev = list_head;
+
+ while (prev && !prev->terminate) {
+ ehci_qhd_t* qhd = (ehci_qhd_t*) (uintptr_t) list_next(prev);
+
+ // done if loop back to head
+ if ( (uintptr_t) qhd == (uintptr_t) list_head) {
+ break;
+ }
+
+ if ( qhd->dev_addr == dev_addr ) {
+ // TODO deactivate all TD, wait for QHD to inactive before removal
+ prev->address = qhd->next.address;
+
+ // EHCI 4.8.2 link the removed qhd's next to async head (which always reachable by Host Controller)
+ qhd->next.address = ((uint32_t) list_head) | (EHCI_QTYPE_QHD << 1);
+
+ if ( qhd->int_smask )
+ {
+ // period list queue element is guarantee to be free in the next frame (1 ms)
+ qhd->used = 0;
+ }else
+ {
+ // async list use async advance handshake
+ // mark as removing, will completely re-usable when async advance isr occurs
+ qhd->removing = 1;
+ }
+
+ hcd_dcache_clean(qhd, sizeof(ehci_qhd_t));
+ hcd_dcache_clean(prev, sizeof(ehci_qhd_t));
+ }else {
+ prev = list_next(prev);
+ }
+ }
+}
+
+
+//--------------------------------------------------------------------+
+// Queue Header helper
+//--------------------------------------------------------------------+
+
+// Get queue head for control transfer (always available)
+TU_ATTR_ALWAYS_INLINE static inline ehci_qhd_t* qhd_control(uint8_t dev_addr) {
+ return &ehci_data.control[dev_addr].qhd;
+}
+
+// Find a free queue head
+TU_ATTR_ALWAYS_INLINE static inline ehci_qhd_t *qhd_find_free(void) {
+ for ( uint32_t i = 0; i < QHD_MAX; i++ ) {
if ( !ehci_data.qhd_pool[i].used ) return &ehci_data.qhd_pool[i];
}
-
return NULL;
}
-static inline ehci_qhd_t* qhd_next(ehci_qhd_t const * p_qhd)
-{
- return (ehci_qhd_t*) tu_align32(p_qhd->next.address);
+// Next queue head link
+TU_ATTR_ALWAYS_INLINE static inline ehci_qhd_t *qhd_next(ehci_qhd_t const *p_qhd) {
+ return (ehci_qhd_t *) tu_align32(p_qhd->next.address);
}
-static inline ehci_qhd_t* qhd_get_from_addr(uint8_t dev_addr, uint8_t ep_addr)
-{
- ehci_qhd_t* qhd_pool = ehci_data.qhd_pool;
+// Get queue head from device + endpoint address
+static ehci_qhd_t *qhd_get_from_addr(uint8_t dev_addr, uint8_t ep_addr) {
+ if ( 0 == tu_edpt_number(ep_addr) ) {
+ return qhd_control(dev_addr);
+ }
- for(uint32_t i=0; i cannot be cleared (ehci halted otherwise)
@@ -920,6 +872,7 @@ static void qhd_init(ehci_qhd_t *p_qhd, uint8_t dev_addr, tusb_desc_endpoint_t c
}
}
+// Attach a TD to queue head
static void qhd_attach_qtd(ehci_qhd_t *qhd, ehci_qtd_t *qtd) {
qhd->attached_qtd = qtd;
qhd->attached_buffer = qtd->buffer[0];
@@ -931,17 +884,35 @@ static void qhd_attach_qtd(ehci_qhd_t *qhd, ehci_qtd_t *qtd) {
hcd_dcache_clean_invalidate(qhd, sizeof(ehci_qhd_t));
}
+// Remove an attached TD from queue head
+static void qhd_remove_qtd(ehci_qhd_t *qhd) {
+ ehci_qtd_t * volatile qtd = qhd->attached_qtd;
-//------------- TD helper -------------//
-static inline ehci_qtd_t *qtd_find_free(void) {
+ qhd->attached_qtd = NULL;
+ qhd->attached_buffer = 0;
+ hcd_dcache_clean(qhd, sizeof(ehci_qhd_t));
+
+ qtd->used = 0; // free QTD
+ hcd_dcache_clean(qtd, sizeof(ehci_qtd_t));
+}
+
+//--------------------------------------------------------------------+
+// Queue TD helper
+//--------------------------------------------------------------------+
+
+// Get TD for control transfer (always available)
+TU_ATTR_ALWAYS_INLINE static inline ehci_qtd_t* qtd_control(uint8_t dev_addr) {
+ return &ehci_data.control[dev_addr].qtd;
+}
+
+TU_ATTR_ALWAYS_INLINE static inline ehci_qtd_t *qtd_find_free(void) {
for (uint32_t i = 0; i < QTD_MAX; i++) {
if (!ehci_data.qtd_pool[i].used) return &ehci_data.qtd_pool[i];
}
return NULL;
}
-static void qtd_init(ehci_qtd_t* qtd, void const* buffer, uint16_t total_bytes)
-{
+static void qtd_init(ehci_qtd_t* qtd, void const* buffer, uint16_t total_bytes) {
tu_memclr(qtd, sizeof(ehci_qtd_t));
qtd->used = 1;
@@ -955,24 +926,9 @@ static void qtd_init(ehci_qtd_t* qtd, void const* buffer, uint16_t total_bytes)
qtd->expected_bytes = total_bytes;
qtd->buffer[0] = (uint32_t) buffer;
- for(uint8_t i=1; i<5; i++)
- {
+ for(uint8_t i=1; i<5; i++) {
qtd->buffer[i] |= tu_align4k(qtd->buffer[i - 1] ) + 4096;
}
}
-//------------- List Managing Helper -------------//
-
-// insert at head
-static inline void list_insert(ehci_link_t *current, ehci_link_t *new, uint8_t new_type)
-{
- new->address = current->address;
- current->address = ((uint32_t) new) | (new_type << 1);
-}
-
-static inline ehci_link_t* list_next(ehci_link_t const *p_link)
-{
- return (ehci_link_t*) tu_align32(p_link->address);
-}
-
#endif
diff --git a/src/portable/ehci/ehci.h b/src/portable/ehci/ehci.h
index 8338fb419..457adc1d3 100644
--- a/src/portable/ehci/ehci.h
+++ b/src/portable/ehci/ehci.h
@@ -278,23 +278,24 @@ enum {
EHCI_INT_MASK_PERIODIC_SCHED_STATUS = TU_BIT(14),
EHCI_INT_MASK_ASYNC_SCHED_STATUS = TU_BIT(15),
- EHCI_INT_MASK_NXP_ASYNC = TU_BIT(18),
- EHCI_INT_MASK_NXP_PERIODIC = TU_BIT(19),
-
EHCI_INT_MASK_ALL =
EHCI_INT_MASK_USB | EHCI_INT_MASK_ERROR | EHCI_INT_MASK_PORT_CHANGE |
EHCI_INT_MASK_FRAMELIST_ROLLOVER | EHCI_INT_MASK_PCI_HOST_SYSTEM_ERROR |
- EHCI_INT_MASK_ASYNC_ADVANCE | EHCI_INT_MASK_NXP_SOF |
- EHCI_INT_MASK_NXP_ASYNC | EHCI_INT_MASK_NXP_PERIODIC
+ EHCI_INT_MASK_ASYNC_ADVANCE | EHCI_INT_MASK_NXP_SOF
};
enum {
- EHCI_USBCMD_POS_RUN_STOP = 0,
- EHCI_USBCMD_POS_FRAMELIST_SIZE = 2,
- EHCI_USBCMD_POS_PERIOD_ENABLE = 4,
- EHCI_USBCMD_POS_ASYNC_ENABLE = 5,
- EHCI_USBCMD_POS_NXP_FRAMELIST_SIZE_MSB = 15,
- EHCI_USBCMD_POS_INTERRUPT_THRESHOLD = 16
+ EHCI_USBCMD_FRAMELIST_SIZE_SHIFT = 2, // [2..3]
+ EHCI_USBCMD_CHIPIDEA_FRAMELIST_SIZE_MSB_SHIFT = 15,
+ EHCI_USBCMD_INTERRUPT_THRESHOLD_SHIFT = 16
+};
+
+enum {
+ EHCI_USBCMD_RUN_STOP = TU_BIT(0), // [0..0] 1 = Run, 0 = Stop
+ EHCI_USBCMD_HCRESET = TU_BIT(1), // [1..1] SW write 1 to reset HC, clear by HC when complete
+ EHCI_USBCMD_PERIOD_SCHEDULE_ENABLE = TU_BIT(4), // [4..4] Enable periodic schedule
+ EHCI_USBCMD_ASYNC_SCHEDULE_ENABLE = TU_BIT(5), // [5..5] Enable async schedule
+ EHCI_USBCMD_INTR_ON_ASYNC_ADVANCE_DOORBELL = TU_BIT(6), // [6..6] Tell HC to interrupt next time it advances async list. Clear by HC
};
enum {
@@ -306,7 +307,7 @@ enum {
EHCI_PORTSC_MASK_FORCE_RESUME = TU_BIT(6),
EHCI_PORTSC_MASK_PORT_SUSPEND = TU_BIT(7),
EHCI_PORTSC_MASK_PORT_RESET = TU_BIT(8),
- ECHI_PORTSC_MASK_PORT_POWER = TU_BIT(12),
+ EHCI_PORTSC_MASK_PORT_POWER = TU_BIT(12),
EHCI_PORTSC_MASK_W1C =
EHCI_PORTSC_MASK_CONNECT_STATUS_CHANGE |
diff --git a/src/portable/mentor/musb/hcd_musb.c b/src/portable/mentor/musb/hcd_musb.c
index 9eb2e005e..5d1fba6d9 100644
--- a/src/portable/mentor/musb/hcd_musb.c
+++ b/src/portable/mentor/musb/hcd_musb.c
@@ -822,9 +822,17 @@ bool hcd_edpt_xfer(uint8_t rhport, uint8_t dev_addr, uint8_t ep_addr, uint8_t *b
return ret;
}
+bool hcd_edpt_abort_xfer(uint8_t rhport, uint8_t dev_addr, uint8_t ep_addr) {
+ (void) rhport;
+ (void) dev_addr;
+ (void) ep_addr;
+ // TODO not implemented yet
+ return false;
+}
+
// clear stall, data toggle is also reset to DATA0
-bool hcd_edpt_clear_stall(uint8_t dev_addr, uint8_t ep_addr)
-{
+bool hcd_edpt_clear_stall(uint8_t rhport, uint8_t dev_addr, uint8_t ep_addr) {
+ (void) rhport;
unsigned const pipenum = find_pipe(dev_addr, ep_addr);
if (!pipenum) return false;
hw_endpoint_t volatile *regs = edpt_regs(pipenum - 1);
diff --git a/src/portable/microchip/pic/dcd_pic.c b/src/portable/microchip/pic/dcd_pic.c
index 6986c8317..ccc27c3c9 100644
--- a/src/portable/microchip/pic/dcd_pic.c
+++ b/src/portable/microchip/pic/dcd_pic.c
@@ -189,7 +189,7 @@ typedef struct
// INTERNAL OBJECT & FUNCTION DECLARATION
//--------------------------------------------------------------------+
// BDT(Buffer Descriptor Table) must be 256-byte aligned
-CFG_TUSB_MEM_SECTION TU_ATTR_ALIGNED(512) volatile static dcd_data_t _dcd;
+CFG_TUD_MEM_SECTION TU_ATTR_ALIGNED(512) volatile static dcd_data_t _dcd;
#if TU_PIC_INT_SIZE == 4
TU_VERIFY_STATIC( sizeof(_dcd.bdt) == 512, "size is not correct" );
diff --git a/src/portable/microchip/samx7x/dcd_samx7x.c b/src/portable/microchip/samx7x/dcd_samx7x.c
index 2bbb345d6..9586df84d 100644
--- a/src/portable/microchip/samx7x/dcd_samx7x.c
+++ b/src/portable/microchip/samx7x/dcd_samx7x.c
@@ -77,7 +77,7 @@ static tusb_speed_t get_speed(void);
static void dcd_transmit_packet(xfer_ctl_t * xfer, uint8_t ep_ix);
// DMA descriptors shouldn't be placed in ITCM !
-CFG_TUSB_MEM_SECTION static dma_desc_t dma_desc[6];
+CFG_TUD_MEM_SECTION static dma_desc_t dma_desc[6];
static xfer_ctl_t xfer_status[EP_MAX];
diff --git a/src/portable/mindmotion/mm32/dcd_mm32f327x_otg.c b/src/portable/mindmotion/mm32/dcd_mm32f327x_otg.c
index 39b09db68..c3d0c7297 100644
--- a/src/portable/mindmotion/mm32/dcd_mm32f327x_otg.c
+++ b/src/portable/mindmotion/mm32/dcd_mm32f327x_otg.c
@@ -110,7 +110,7 @@ typedef struct
// INTERNAL OBJECT & FUNCTION DECLARATION
//--------------------------------------------------------------------+
// BDT(Buffer Descriptor Table) must be 256-byte aligned
-CFG_TUSB_MEM_SECTION TU_ATTR_ALIGNED(512) static dcd_data_t _dcd;
+CFG_TUD_MEM_SECTION TU_ATTR_ALIGNED(512) static dcd_data_t _dcd;
TU_VERIFY_STATIC( sizeof(_dcd.bdt) == 512, "size is not correct" );
diff --git a/src/portable/nxp/khci/dcd_khci.c b/src/portable/nxp/khci/dcd_khci.c
index 52f4145f2..5c65ea33d 100644
--- a/src/portable/nxp/khci/dcd_khci.c
+++ b/src/portable/nxp/khci/dcd_khci.c
@@ -114,7 +114,7 @@ typedef struct
// INTERNAL OBJECT & FUNCTION DECLARATION
//--------------------------------------------------------------------+
// BDT(Buffer Descriptor Table) must be 256-byte aligned
-CFG_TUSB_MEM_SECTION TU_ATTR_ALIGNED(512) static dcd_data_t _dcd;
+CFG_TUD_MEM_SECTION TU_ATTR_ALIGNED(512) static dcd_data_t _dcd;
TU_VERIFY_STATIC( sizeof(_dcd.bdt) == 512, "size is not correct" );
diff --git a/src/portable/nxp/khci/hcd_khci.c b/src/portable/nxp/khci/hcd_khci.c
index f6029ee0d..928564e26 100644
--- a/src/portable/nxp/khci/hcd_khci.c
+++ b/src/portable/nxp/khci/hcd_khci.c
@@ -562,8 +562,16 @@ bool hcd_edpt_xfer(uint8_t rhport, uint8_t dev_addr, uint8_t ep_addr, uint8_t *
return true;
}
-bool hcd_edpt_clear_stall(uint8_t dev_addr, uint8_t ep_addr)
-{
+bool hcd_edpt_abort_xfer(uint8_t rhport, uint8_t dev_addr, uint8_t ep_addr) {
+ (void) rhport;
+ (void) dev_addr;
+ (void) ep_addr;
+ // TODO not implemented yet
+ return false;
+}
+
+bool hcd_edpt_clear_stall(uint8_t rhport, uint8_t dev_addr, uint8_t ep_addr) {
+ (void) rhport;
if (!tu_edpt_number(ep_addr)) return true;
int num = find_pipe(dev_addr, ep_addr);
if (num < 0) return false;
diff --git a/src/portable/nxp/lpc17_40/dcd_lpc17_40.c b/src/portable/nxp/lpc17_40/dcd_lpc17_40.c
index 86149afd8..b880c2870 100644
--- a/src/portable/nxp/lpc17_40/dcd_lpc17_40.c
+++ b/src/portable/nxp/lpc17_40/dcd_lpc17_40.c
@@ -92,7 +92,7 @@ typedef struct
} dcd_data_t;
-CFG_TUSB_MEM_SECTION TU_ATTR_ALIGNED(128) static dcd_data_t _dcd;
+CFG_TUD_MEM_SECTION TU_ATTR_ALIGNED(128) static dcd_data_t _dcd;
//--------------------------------------------------------------------+
diff --git a/src/portable/nxp/lpc_ip3511/dcd_lpc_ip3511.c b/src/portable/nxp/lpc_ip3511/dcd_lpc_ip3511.c
index 5368ef868..7ca698a93 100644
--- a/src/portable/nxp/lpc_ip3511/dcd_lpc_ip3511.c
+++ b/src/portable/nxp/lpc_ip3511/dcd_lpc_ip3511.c
@@ -176,11 +176,11 @@ typedef struct
// EP list must be 256-byte aligned
// Some MCU controller may require this variable to be placed in specific SRAM region.
// For example: LPC55s69 port1 Highspeed must be USB_RAM (0x40100000)
-// Use CFG_TUSB_MEM_SECTION to place it accordingly.
-CFG_TUSB_MEM_SECTION TU_ATTR_ALIGNED(256) static dcd_data_t _dcd;
+// Use CFG_TUD_MEM_SECTION to place it accordingly.
+CFG_TUD_MEM_SECTION TU_ATTR_ALIGNED(256) static dcd_data_t _dcd;
// Dummy buffer to fix ZLPs overwriting the buffer (probably an USB/DMA controller bug)
-CFG_TUSB_MEM_SECTION TU_ATTR_ALIGNED(64) static uint8_t dummy[8];
+CFG_TUD_MEM_SECTION TU_ATTR_ALIGNED(64) static uint8_t dummy[8];
//--------------------------------------------------------------------+
// Multiple Controllers
diff --git a/src/portable/ohci/ohci.c b/src/portable/ohci/ohci.c
index 3f702d22c..413e72037 100644
--- a/src/portable/ohci/ohci.c
+++ b/src/portable/ohci/ohci.c
@@ -341,19 +341,24 @@ static void ed_init(ohci_ed_t *p_ed, uint8_t dev_addr, uint16_t ep_size, uint8_t
p_ed->is_interrupt_xfer = (xfer_type == TUSB_XFER_INTERRUPT ? 1 : 0);
}
-static void gtd_init(ohci_gtd_t* p_td, uint8_t* data_ptr, uint16_t total_bytes)
-{
+static void gtd_init(ohci_gtd_t *p_td, uint8_t *data_ptr, uint16_t total_bytes) {
tu_memclr(p_td, sizeof(ohci_gtd_t));
- p_td->used = 1;
- p_td->expected_bytes = total_bytes;
+ p_td->used = 1;
+ p_td->expected_bytes = total_bytes;
- p_td->buffer_rounding = 1; // less than queued length is not a error
- p_td->delay_interrupt = OHCI_INT_ON_COMPLETE_NO;
- p_td->condition_code = OHCI_CCODE_NOT_ACCESSED;
+ p_td->buffer_rounding = 1; // less than queued length is not a error
+ p_td->delay_interrupt = OHCI_INT_ON_COMPLETE_NO;
+ p_td->condition_code = OHCI_CCODE_NOT_ACCESSED;
- p_td->current_buffer_pointer = _phys_addr(data_ptr);
- p_td->buffer_end = total_bytes ? (_phys_addr(data_ptr + total_bytes - 1)) : (uint8_t *)p_td->current_buffer_pointer;
+ uint8_t *cbp = (uint8_t *) _phys_addr(data_ptr);
+
+ p_td->current_buffer_pointer = cbp;
+ if ( total_bytes ) {
+ p_td->buffer_end = _phys_addr(data_ptr + total_bytes - 1);
+ } else {
+ p_td->buffer_end = cbp;
+ }
}
static ohci_ed_t * ed_from_addr(uint8_t dev_addr, uint8_t ep_addr)
@@ -487,7 +492,7 @@ bool hcd_setup_send(uint8_t rhport, uint8_t dev_addr, uint8_t const setup_packet
ohci_ed_t* ed = &ohci_data.control[dev_addr].ed;
ohci_gtd_t *qtd = &ohci_data.control[dev_addr].gtd;
- gtd_init(qtd, (uint8_t*) setup_packet, 8);
+ gtd_init(qtd, (uint8_t*)(uintptr_t) setup_packet, 8);
qtd->index = dev_addr;
qtd->pid = PID_SETUP;
qtd->data_toggle = GTD_DT_DATA0;
@@ -543,8 +548,16 @@ bool hcd_edpt_xfer(uint8_t rhport, uint8_t dev_addr, uint8_t ep_addr, uint8_t *
return true;
}
-bool hcd_edpt_clear_stall(uint8_t dev_addr, uint8_t ep_addr)
-{
+bool hcd_edpt_abort_xfer(uint8_t rhport, uint8_t dev_addr, uint8_t ep_addr) {
+ (void) rhport;
+ (void) dev_addr;
+ (void) ep_addr;
+ // TODO not implemented yet
+ return false;
+}
+
+bool hcd_edpt_clear_stall(uint8_t rhport, uint8_t dev_addr, uint8_t ep_addr) {
+ (void) rhport;
ohci_ed_t * const p_ed = ed_from_addr(dev_addr, ep_addr);
p_ed->is_stalled = 0;
diff --git a/src/portable/raspberrypi/pio_usb/hcd_pio_usb.c b/src/portable/raspberrypi/pio_usb/hcd_pio_usb.c
index 264af2e7a..45a3e80ef 100644
--- a/src/portable/raspberrypi/pio_usb/hcd_pio_usb.c
+++ b/src/portable/raspberrypi/pio_usb/hcd_pio_usb.c
@@ -138,6 +138,11 @@ bool hcd_edpt_xfer(uint8_t rhport, uint8_t dev_addr, uint8_t ep_addr, uint8_t *
return pio_usb_host_endpoint_transfer(pio_rhport, dev_addr, ep_addr, buffer, buflen);
}
+bool hcd_edpt_abort_xfer(uint8_t rhport, uint8_t dev_addr, uint8_t ep_addr) {
+ uint8_t const pio_rhport = RHPORT_PIO(rhport);
+ return pio_usb_host_endpoint_abort_transfer(pio_rhport, dev_addr, ep_addr);
+}
+
bool hcd_setup_send(uint8_t rhport, uint8_t dev_addr, uint8_t const setup_packet[8])
{
uint8_t const pio_rhport = RHPORT_PIO(rhport);
@@ -158,8 +163,8 @@ bool hcd_setup_send(uint8_t rhport, uint8_t dev_addr, uint8_t const setup_packet
// return busy;
//}
-bool hcd_edpt_clear_stall(uint8_t dev_addr, uint8_t ep_addr)
-{
+bool hcd_edpt_clear_stall(uint8_t rhport, uint8_t dev_addr, uint8_t ep_addr) {
+ (void) rhport;
(void) dev_addr;
(void) ep_addr;
diff --git a/src/portable/raspberrypi/rp2040/hcd_rp2040.c b/src/portable/raspberrypi/rp2040/hcd_rp2040.c
index 02f9968a7..6db8e2a0a 100644
--- a/src/portable/raspberrypi/rp2040/hcd_rp2040.c
+++ b/src/portable/raspberrypi/rp2040/hcd_rp2040.c
@@ -576,6 +576,14 @@ bool hcd_edpt_xfer(uint8_t rhport, uint8_t dev_addr, uint8_t ep_addr, uint8_t *
return true;
}
+bool hcd_edpt_abort_xfer(uint8_t rhport, uint8_t dev_addr, uint8_t ep_addr) {
+ (void) rhport;
+ (void) dev_addr;
+ (void) ep_addr;
+ // TODO not implemented yet
+ return false;
+}
+
bool hcd_setup_send(uint8_t rhport, uint8_t dev_addr, uint8_t const setup_packet[8])
{
(void) rhport;
@@ -617,8 +625,8 @@ bool hcd_setup_send(uint8_t rhport, uint8_t dev_addr, uint8_t const setup_packet
return true;
}
-bool hcd_edpt_clear_stall(uint8_t dev_addr, uint8_t ep_addr)
-{
+bool hcd_edpt_clear_stall(uint8_t rhport, uint8_t dev_addr, uint8_t ep_addr) {
+ (void) rhport;
(void) dev_addr;
(void) ep_addr;
diff --git a/src/portable/renesas/rusb2/hcd_rusb2.c b/src/portable/renesas/rusb2/hcd_rusb2.c
index a4b534a05..fef8bdf19 100644
--- a/src/portable/renesas/rusb2/hcd_rusb2.c
+++ b/src/portable/renesas/rusb2/hcd_rusb2.c
@@ -752,9 +752,15 @@ bool hcd_edpt_xfer(uint8_t rhport, uint8_t dev_addr, uint8_t ep_addr, uint8_t *b
return r;
}
-bool hcd_edpt_clear_stall(uint8_t dev_addr, uint8_t ep_addr)
-{
- uint8_t rhport = 0; // FIXME change API
+bool hcd_edpt_abort_xfer(uint8_t rhport, uint8_t dev_addr, uint8_t ep_addr) {
+ (void) rhport;
+ (void) dev_addr;
+ (void) ep_addr;
+ // TODO not implemented yet
+ return false;
+}
+
+bool hcd_edpt_clear_stall(uint8_t rhport, uint8_t dev_addr, uint8_t ep_addr) {
uint16_t volatile *ctr = addr_to_pipectr(rhport, dev_addr, ep_addr);
TU_ASSERT(ctr);
diff --git a/src/tusb_option.h b/src/tusb_option.h
index f16d8a5d0..7a4cfe51c 100644
--- a/src/tusb_option.h
+++ b/src/tusb_option.h
@@ -295,15 +295,14 @@
#define CFG_TUSB_DEBUG 0
#endif
-// TODO MEM_SECTION can be different for host and device controller
-// should use CFG_TUD_MEM_SECTION, CFG_TUH_MEM_SECTION
+// Memory section for placing buffer used for usb transferring. If MEM_SECTION is different for
+// host and device use: CFG_TUD_MEM_SECTION, CFG_TUH_MEM_SECTION instead
#ifndef CFG_TUSB_MEM_SECTION
#define CFG_TUSB_MEM_SECTION
#endif
-// alignment requirement of buffer used for endpoint transferring
-// TODO MEM_ALIGN can be different for host and device controller
-// should use CFG_TUD_MEM_ALIGN, CFG_TUH_MEM_ALIGN
+// Alignment requirement of buffer used for usb transferring. if MEM_ALIGN is different for
+// host and device controller use: CFG_TUD_MEM_ALIGN, CFG_TUH_MEM_ALIGN instead
#ifndef CFG_TUSB_MEM_ALIGN
#define CFG_TUSB_MEM_ALIGN TU_ATTR_ALIGNED(4)
#endif
@@ -321,24 +320,14 @@
// Device Options (Default)
//--------------------------------------------------------------------
-// Attribute to place data in accessible RAM for device controller
-// default to CFG_TUSB_MEM_SECTION for backward-compatible
+// Attribute to place data in accessible RAM for device controller (default: CFG_TUSB_MEM_SECTION)
#ifndef CFG_TUD_MEM_SECTION
- #ifdef CFG_TUSB_MEM_SECTION
- #define CFG_TUD_MEM_SECTION CFG_TUSB_MEM_SECTION
- #else
- #define CFG_TUD_MEM_SECTION
- #endif
+ #define CFG_TUD_MEM_SECTION CFG_TUSB_MEM_SECTION
#endif
-// Attribute to align memory for device controller
-// default to CFG_TUSB_MEM_ALIGN for backward-compatible
+// Attribute to align memory for device controller (default: CFG_TUSB_MEM_ALIGN)
#ifndef CFG_TUD_MEM_ALIGN
- #ifdef CFG_TUSB_MEM_ALIGN
- #define CFG_TUD_MEM_ALIGN CFG_TUSB_MEM_ALIGN
- #else
- #define CFG_TUD_MEM_ALIGN TU_ATTR_ALIGNED(4)
- #endif
+ #define CFG_TUD_MEM_ALIGN CFG_TUSB_MEM_ALIGN
#endif
#ifndef CFG_TUD_ENDPOINT0_SIZE
@@ -419,19 +408,14 @@
#endif
#endif // CFG_TUH_ENABLED
-// Attribute to place data in accessible RAM for host controller
-// default to CFG_TUSB_MEM_SECTION for backward-compatible
+// Attribute to place data in accessible RAM for host controller (default: CFG_TUSB_MEM_SECTION)
#ifndef CFG_TUH_MEM_SECTION
- #ifdef CFG_TUSB_MEM_SECTION
- #define CFG_TUH_MEM_SECTION CFG_TUSB_MEM_SECTION
- #else
- #define CFG_TUH_MEM_SECTION
- #endif
+ #define CFG_TUH_MEM_SECTION CFG_TUSB_MEM_SECTION
#endif
// Attribute to align memory for host controller
#ifndef CFG_TUH_MEM_ALIGN
- #define CFG_TUH_MEM_ALIGN TU_ATTR_ALIGNED(4)
+ #define CFG_TUH_MEM_ALIGN CFG_TUSB_MEM_ALIGN
#endif
//------------- CLASS -------------//
diff --git a/tools/get_deps.py b/tools/get_deps.py
index 21ad539c4..82f756f64 100644
--- a/tools/get_deps.py
+++ b/tools/get_deps.py
@@ -54,7 +54,7 @@ deps_optional = {
'950819b7de9b32f92c3edf396bc5ffb8d66e7009',
'kinetis_k32l2 kinetis_kl lpc51 lpc54 lpc55 mcx imxrt'],
'hw/mcu/raspberry_pi/Pico-PIO-USB': ['https://github.com/sekigon-gonnoc/Pico-PIO-USB.git',
- '58879cfa0eca5725d8db6443ec17f8896a321042',
+ 'd00a10a8c425d0d40f81b87169102944b01f3bb3',
'rp2040'],
'hw/mcu/renesas/fsp': ['https://github.com/renesas/fsp.git',
'd52e5a6a59b7c638da860c2bb309b6e78e752ff8',