Merge branch 'master' into renesas_ra_hs_rebased

This commit is contained in:
hathach 2023-07-27 16:50:34 +07:00
commit ec093bebad
No known key found for this signature in database
GPG Key ID: F5D50C6D51D17CBA
67 changed files with 1550 additions and 856 deletions

View File

@ -35,7 +35,7 @@ jobs:
# Alphabetical order
- 'imxrt'
- 'kinetis_kl'
- 'lpc18'
- 'lpc18 lpc40'
- 'lpc55'
- 'mcx'
- 'ra'

10
.idea/runConfigurations/lpc4088.xml generated Normal file
View File

@ -0,0 +1,10 @@
<component name="ProjectRunConfigurationManager">
<configuration default="false" name="lpc4088" type="com.jetbrains.cidr.embedded.customgdbserver.type" factoryName="com.jetbrains.cidr.embedded.customgdbserver.factory" PROGRAM_PARAMS="-device &quot;lpc4088&quot; -if swd -speed 50000 -port 25321 -nogui -singlerun" REDIRECT_INPUT="false" ELEVATE="false" USE_EXTERNAL_CONSOLE="false" PASS_PARENT_ENVS_2="true" PROJECT_NAME="cdc_msc" TARGET_NAME="cdc_msc" CONFIG_NAME="ea4088 quickstart" version="1" RUN_TARGET_PROJECT_NAME="cdc_msc" RUN_TARGET_NAME="cdc_msc">
<custom-gdb-server version="1" gdb-connect="tcp::25321" executable="/usr/bin/JLinkGDBServer" warmup-ms="0" download-type="UPDATED_ONLY" reset-cmd="monitor reset" reset-type="AFTER_DOWNLOAD">
<debugger kind="GDB" isBundled="true" />
</custom-gdb-server>
<method v="2">
<option name="CLION.COMPOUND.BUILD" enabled="true" />
</method>
</configuration>
</component>

View File

@ -1,4 +1,5 @@
board:mimxrt1060_evk
board:mimxrt1064_evk
board:mcb1800
mcu:RP2040
mcu:ra6m5

View File

@ -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

View File

@ -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

View File

@ -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
};

View File

@ -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<<configPRIO_BITS) - 1)
/* The highest interrupt priority that can be used by any interrupt service
routine that makes calls to interrupt safe FreeRTOS API functions. DO NOT CALL
INTERRUPT SAFE FREERTOS API FUNCTIONS FROM ANY INTERRUPT THAT HAS A HIGHER
PRIORITY THAN THIS! (higher priorities are lower numeric values. */
#define configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY 2
/* Interrupt priorities used by the kernel port layer itself. These are generic
to all Cortex-M ports, and do not rely on any particular library functions. */
#define configKERNEL_INTERRUPT_PRIORITY ( configLIBRARY_LOWEST_INTERRUPT_PRIORITY << (8 - configPRIO_BITS) )
/* !!!! configMAX_SYSCALL_INTERRUPT_PRIORITY must not be set to zero !!!!
See http://www.FreeRTOS.org/RTOS-Cortex-M3-M4.html. */
#define configMAX_SYSCALL_INTERRUPT_PRIORITY ( configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY << (8 - configPRIO_BITS) )
#endif

View File

@ -0,0 +1,9 @@
set(JLINK_DEVICE LPC4088)
set(PYOCD_TARGET LPC4088)
set(NXPLINK_DEVICE LPC4088:LPC4088)
set(LD_FILE_GNU ${CMAKE_CURRENT_LIST_DIR}/lpc4088.ld)
function(update_board TARGET)
# nothing to do
endfunction()

View File

@ -0,0 +1,74 @@
/*
* The MIT License (MIT)
*
* Copyright (c) 2023 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 EA4088QS__BOARD_H
#define EA4088QS__BOARD_H
#ifdef __cplusplus
extern "C" {
#endif
#define LED_PORT 2
#define LED_PIN 19
#define BUTTON_PORT 2
#define BUTTON_PIN 10
#define BUTTON_ACTIV_STATE 0
/* System oscillator rate and RTC oscillator rate */
const uint32_t OscRateIn = 12000000;
const uint32_t RTCOscRateIn = 32768;
/* Pin muxing configuration */
static const PINMUX_GRP_T pinmuxing[] = {
// LED
{ 2, 19, (IOCON_FUNC0 | IOCON_MODE_INACT) },
// Button
{ 2, 10, (IOCON_FUNC0 | IOCON_MODE_INACT | IOCON_MODE_PULLUP) },
// USB1 as Host
{ 0, 29, (IOCON_FUNC1 | IOCON_MODE_INACT) }, // D+1
{ 0, 30, (IOCON_FUNC1 | IOCON_MODE_INACT) }, // D-1
{ 1, 18, (IOCON_FUNC1 | IOCON_MODE_INACT) }, // UP LED1
{ 1, 19, (IOCON_FUNC2 | IOCON_MODE_INACT) }, // PPWR1
// {2, 14, (IOCON_FUNC2 | IOCON_MODE_INACT)}, // VBUS1
// {2, 15, (IOCON_FUNC2 | IOCON_MODE_INACT)}, // OVRCR1
// USB2 as Device
{ 0, 31, (IOCON_FUNC1 | IOCON_MODE_INACT) }, // D+2
{ 0, 13, (IOCON_FUNC1 | IOCON_MODE_INACT) }, // UP LED
{ 0, 14, (IOCON_FUNC3 | IOCON_MODE_INACT) }, // CONNECT2
/* VBUS is not connected on this board, so leave the pin at default setting. */
/*Chip_IOCON_PinMux(LPC_IOCON, 1, 30, IOCON_MODE_INACT, IOCON_FUNC2);*/ /* USB VBUS */
};
#ifdef __cplusplus
}
#endif
#endif

View File

@ -0,0 +1,8 @@
LD_FILE = $(BOARD_PATH)/lpc4088.ld
# For flash-jlink target
JLINK_DEVICE = LPC4088
# flash using jlink
flash: flash-jlink

View File

@ -0,0 +1,238 @@
/*********************************************************************
*
* OnProjectLoad
*
* Function description
* Project load routine. Required.
*
**********************************************************************
*/
void OnProjectLoad (void) {
Edit.SysVar (VAR_POWER_SAMPLING_SPEED, FREQ_100_KHZ);
Project.AddSvdFile ("$(InstallDir)/Config/CPU/Cortex-M4F.svd");
Project.AddSvdFile ("../../../../../../../cmsis-svd/data/NXP/LPC408x_7x_v0.7.svd");
Project.SetDevice ("LPC4088");
Project.SetHostIF ("USB", "");
Project.SetTargetIF ("SWD");
Project.SetTIFSpeed ("50 MHz");
Project.SetTraceSource ("Trace Pins");
Project.SetTracePortWidth (4);
// User settings
File.Open ("../../../../../../examples/device/cdc_msc/cmake-build-ea4088-quickstart/cdc_msc.elf");
}
/*********************************************************************
*
* TargetReset
*
* Function description
* Replaces the default target device reset routine. Optional.
*
* Notes
* This example demonstrates the usage when
* debugging a RAM program on a Cortex-M target device
*
**********************************************************************
*/
//void TargetReset (void) {
//
// unsigned int SP;
// unsigned int PC;
// unsigned int VectorTableAddr;
//
// Exec.Reset();
//
// VectorTableAddr = Elf.GetBaseAddr();
//
// if (VectorTableAddr != 0xFFFFFFFF) {
//
// Util.Log("Resetting Program.");
//
// SP = Target.ReadU32(VectorTableAddr);
// Target.SetReg("SP", SP);
//
// PC = Target.ReadU32(VectorTableAddr + 4);
// Target.SetReg("PC", PC);
// }
//}
/*********************************************************************
*
* BeforeTargetReset
*
* Function description
* Event handler routine. Optional.
*
**********************************************************************
*/
//void BeforeTargetReset (void) {
//}
/*********************************************************************
*
* AfterTargetReset
*
* Function description
* Event handler routine.
* - Sets the PC register to program reset value.
* - Sets the SP register to program reset value on Cortex-M.
*
**********************************************************************
*/
void AfterTargetReset (void) {
unsigned int SP;
unsigned int PC;
unsigned int VectorTableAddr;
VectorTableAddr = Elf.GetBaseAddr();
if (VectorTableAddr == 0xFFFFFFFF) {
Util.Log("Project file error: failed to get program base");
} else {
SP = Target.ReadU32(VectorTableAddr);
Target.SetReg("SP", SP);
PC = Target.ReadU32(VectorTableAddr + 4);
Target.SetReg("PC", PC);
}
}
/*********************************************************************
*
* DebugStart
*
* Function description
* Replaces the default debug session startup routine. Optional.
*
**********************************************************************
*/
//void DebugStart (void) {
//}
/*********************************************************************
*
* TargetConnect
*
* Function description
* Replaces the default target IF connection routine. Optional.
*
**********************************************************************
*/
//void TargetConnect (void) {
//}
/*********************************************************************
*
* BeforeTargetConnect
*
* Function description
* Event handler routine. Optional.
*
**********************************************************************
*/
void BeforeTargetConnect (void) {
}
/*********************************************************************
*
* AfterTargetConnect
*
* Function description
* Event handler routine. Optional.
*
**********************************************************************
*/
//void AfterTargetConnect (void) {
//}
/*********************************************************************
*
* TargetDownload
*
* Function description
* Replaces the default program download routine. Optional.
*
**********************************************************************
*/
//void TargetDownload (void) {
//}
/*********************************************************************
*
* BeforeTargetDownload
*
* Function description
* Event handler routine. Optional.
*
**********************************************************************
*/
//void BeforeTargetDownload (void) {
//}
/*********************************************************************
*
* AfterTargetDownload
*
* Function description
* Event handler routine.
* - Sets the PC register to program reset value.
* - Sets the SP register to program reset value on Cortex-M.
*
**********************************************************************
*/
void AfterTargetDownload (void) {
unsigned int SP;
unsigned int PC;
unsigned int VectorTableAddr;
VectorTableAddr = Elf.GetBaseAddr();
if (VectorTableAddr == 0xFFFFFFFF) {
Util.Log("Project file error: failed to get program base");
} else {
SP = Target.ReadU32(VectorTableAddr);
Target.SetReg("SP", SP);
PC = Target.ReadU32(VectorTableAddr + 4);
Target.SetReg("PC", PC);
}
}
/*********************************************************************
*
* BeforeTargetDisconnect
*
* Function description
* Event handler routine. Optional.
*
**********************************************************************
*/
//void BeforeTargetDisconnect (void) {
//}
/*********************************************************************
*
* AfterTargetDisconnect
*
* Function description
* Event handler routine. Optional.
*
**********************************************************************
*/
//void AfterTargetDisconnect (void) {
//}
/*********************************************************************
*
* AfterTargetHalt
*
* Function description
* Event handler routine. Optional.
*
**********************************************************************
*/
//void AfterTargetHalt (void) {
//}

View File

@ -25,89 +25,60 @@
*/
#include "chip.h"
#include "../board.h"
#include "bsp/board.h"
#include "board.h"
//--------------------------------------------------------------------+
// USB Interrupt Handler
//--------------------------------------------------------------------+
void USB_IRQHandler(void)
{
void USB_IRQHandler(void) {
#if CFG_TUD_ENABLED
tud_int_handler(0);
tud_int_handler(0);
#endif
#if CFG_TUH_ENABLED
tuh_int_handler(0);
tuh_int_handler(0);
#endif
}
//--------------------------------------------------------------------+
// MACRO TYPEDEF CONSTANT ENUM DECLARATION
//--------------------------------------------------------------------+
#define LED_PORT 2
#define LED_PIN 19
#define BUTTON_PORT 2
#define BUTTON_PIN 10
/* System oscillator rate and RTC oscillator rate */
const uint32_t OscRateIn = 12000000;
const uint32_t RTCOscRateIn = 32768;
/* Pin muxing configuration */
static const PINMUX_GRP_T pinmuxing[] =
{
// LED
{2, 19, (IOCON_FUNC0 | IOCON_MODE_INACT)},
// Button
{2, 10, (IOCON_FUNC0 | IOCON_MODE_INACT | IOCON_MODE_PULLUP)},
};
static const PINMUX_GRP_T pin_usb_mux[] =
{
// USB1 as Host
{0, 29, (IOCON_FUNC1 | IOCON_MODE_INACT)}, // D+1
{0, 30, (IOCON_FUNC1 | IOCON_MODE_INACT)}, // D-1
{1, 18, (IOCON_FUNC1 | IOCON_MODE_INACT)}, // UP LED1
{1, 19, (IOCON_FUNC2 | IOCON_MODE_INACT)}, // PPWR1
// {2, 14, (IOCON_FUNC2 | IOCON_MODE_INACT)}, // VBUS1
// {2, 15, (IOCON_FUNC2 | IOCON_MODE_INACT)}, // OVRCR1
// USB2 as Device
{0, 31, (IOCON_FUNC1 | IOCON_MODE_INACT)}, // D+2
{0, 13, (IOCON_FUNC1 | IOCON_MODE_INACT)}, // UP LED
{0, 14, (IOCON_FUNC3 | IOCON_MODE_INACT)}, // CONNECT2
/* VBUS is not connected on this board, so leave the pin at default setting. */
/*Chip_IOCON_PinMux(LPC_IOCON, 1, 30, IOCON_MODE_INACT, IOCON_FUNC2);*/ /* USB VBUS */
};
// Invoked by startup code
void SystemInit(void)
{
void SystemInit(void) {
#ifdef __USE_LPCOPEN
extern void (* const g_pfnVectors[])(void);
extern void (*const g_pfnVectors[])(void);
unsigned int *pSCB_VTOR = (unsigned int *) 0xE000ED08;
*pSCB_VTOR = (unsigned int) g_pfnVectors;
*pSCB_VTOR = (unsigned int) g_pfnVectors;
#if __FPU_USED == 1
fpuInit();
#endif
#if __FPU_USED == 1
fpuInit();
#endif
#endif // __USE_LPCOPEN
Chip_IOCON_Init(LPC_IOCON);
Chip_IOCON_SetPinMuxing(LPC_IOCON, pinmuxing, sizeof(pinmuxing) / sizeof(PINMUX_GRP_T));
/* CPU clock source starts with IRC */
/* Enable PBOOST for CPU clock over 100MHz */
Chip_SYSCTL_EnableBoost();
#ifdef TRACE_ETM
const PINMUX_GRP_T trace_pinmux[] = {
{2, 2, IOCON_FUNC5 | IOCON_FASTSLEW_EN },
{2, 3, IOCON_FUNC5 | IOCON_FASTSLEW_EN },
{2, 4, IOCON_FUNC5 | IOCON_FASTSLEW_EN },
{2, 5, IOCON_FUNC5 | IOCON_FASTSLEW_EN },
{2, 6, IOCON_FUNC5 | IOCON_FASTSLEW_EN },
};
Chip_IOCON_SetPinMuxing(LPC_IOCON, trace_pinmux, sizeof(trace_pinmux) / sizeof(PINMUX_GRP_T));
#endif
/* CPU clock source starts with IRC */
/* Enable PBOOST for CPU clock over 100MHz */
Chip_SYSCTL_EnableBoost();
Chip_SetupXtalClocking();
}
void board_init(void)
{
void board_init(void) {
SystemCoreClockUpdate();
#if CFG_TUSB_OS == OPT_OS_NONE
@ -129,15 +100,14 @@ void board_init(void)
// UART
//------------- USB -------------//
Chip_IOCON_SetPinMuxing(LPC_IOCON, pin_usb_mux, sizeof(pin_usb_mux) / sizeof(PINMUX_GRP_T));
// Port1 as Host, Port2: Device
Chip_USB_Init();
enum {
USBCLK_DEVCIE = 0x12, // AHB + Device
USBCLK_HOST = 0x19 , // AHB + OTG + Host
USBCLK_ALL = 0x1B // Host + Device + OTG + AHB
USBCLK_HOST = 0x19, // AHB + OTG + Host
USBCLK_ALL = 0x1B // Host + Device + OTG + AHB
};
LPC_USB->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

102
hw/bsp/lpc40/family.cmake Normal file
View File

@ -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()

View File

@ -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)

View File

@ -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

View File

@ -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()

View File

@ -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();

View File

@ -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

View File

@ -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

View File

@ -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_ */

View File

@ -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

View File

@ -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<len;i++) {
buf[i] = uart_getc(uart_inst);
buf[i] = XMC_UART_CH_GetReceivedData(UART_DEV);
}
return len;
#else
@ -107,7 +125,7 @@ int board_uart_write(void const * buf, int len)
#ifdef UART_DEV
char const* bufch = (char const*) buf;
for(int i=0;i<len;i++) {
uart_putc(uart_inst, bufch[i]);
XMC_UART_CH_Transmit(UART_DEV, bufch[i]);
}
return len;
#else

View File

@ -20,8 +20,11 @@ SRC_C += \
src/portable/synopsys/dwc2/dcd_dwc2.c \
$(MCU_DIR)/Newlib/syscalls.c \
$(MCU_DIR)/CMSIS/Infineon/COMPONENT_$(MCU_VARIANT)/Source/system_$(MCU_VARIANT).c \
$(MCU_DIR)/XMCLib/src/xmc_gpio.c \
$(MCU_DIR)/XMCLib/src/xmc4_gpio.c \
$(MCU_DIR)/XMCLib/src/xmc4_scu.c
$(MCU_DIR)/XMCLib/src/xmc4_scu.c \
$(MCU_DIR)/XMCLib/src/xmc_usic.c \
$(MCU_DIR)/XMCLib/src/xmc_uart.c
SRC_S += $(MCU_DIR)/CMSIS/Infineon/COMPONENT_$(MCU_VARIANT)/Source/TOOLCHAIN_GCC_ARM/startup_$(MCU_VARIANT).S

View File

@ -43,7 +43,7 @@ static usb_eth_stat_t usb_eth_stat = { 0, 0, 0, 0 };
static uint32_t oid_packet_filter = 0x0000000;
static rndis_state_t rndis_state;
CFG_TUSB_MEM_SECTION CFG_TUSB_MEM_ALIGN static uint8_t ndis_report[8] = { 0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00 };
CFG_TUD_MEM_SECTION CFG_TUSB_MEM_ALIGN static uint8_t ndis_report[8] = { 0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00 };
static const uint32_t OIDSupportedList[] =
{

View File

@ -64,6 +64,7 @@ function(add_tinyusb TARGET)
-Wnull-dereference
-Wuninitialized
-Wunused
-Wunused-function
-Wreturn-type
-Wredundant-decls
)

View File

@ -113,21 +113,21 @@
// EP IN software buffers and mutexes
#if CFG_TUD_AUDIO_ENABLE_EP_IN && !CFG_TUD_AUDIO_ENABLE_ENCODING
#if CFG_TUD_AUDIO_FUNC_1_EP_IN_SW_BUF_SZ > 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);

View File

@ -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)
{

View File

@ -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)
{

View File

@ -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)
{

View File

@ -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)

View File

@ -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)
{

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

@ -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,
};

View File

@ -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)

View File

@ -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 */

View File

@ -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; }

View File

@ -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);

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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;

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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" );

View File

@ -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

View File

@ -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;
//--------------------------------------------------------------------+

View File

@ -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)

View File

@ -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; i<QHD_MAX; i++)
{
new->address = 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<QHD_MAX; i++)
{
ehci_qhd_t *qhd_pool = ehci_data.qhd_pool;
for ( uint32_t i = 0; i < QHD_MAX; i++ ) {
if ( (qhd_pool[i].dev_addr == dev_addr) &&
ep_addr == tu_edpt_addr(qhd_pool[i].ep_number, qhd_pool[i].pid) )
{
ep_addr == tu_edpt_addr(qhd_pool[i].ep_number, qhd_pool[i].pid) ) {
return &qhd_pool[i];
}
}
@ -846,6 +797,7 @@ static inline ehci_qhd_t* qhd_get_from_addr(uint8_t dev_addr, uint8_t ep_addr)
return NULL;
}
// Init queue head with endpoint descriptor
static void qhd_init(ehci_qhd_t *p_qhd, uint8_t dev_addr, tusb_desc_endpoint_t const * ep_desc)
{
// address 0 is used as async head, which always on the list --> 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

View File

@ -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 |

View File

@ -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);

View File

@ -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" );

View File

@ -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];

View File

@ -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" );

View File

@ -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" );

View File

@ -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;

View File

@ -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;
//--------------------------------------------------------------------+

View File

@ -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

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

@ -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);

View File

@ -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 -------------//

View File

@ -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',