Merge pull request #2058 from hathach/cmake-imxrt

Add Cmake for imxrt and Fix EHCI PortSC issue
This commit is contained in:
Ha Thach 2023-05-10 16:06:04 +07:00 committed by GitHub
commit aaff27d220
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
56 changed files with 876 additions and 367 deletions

View File

@ -33,7 +33,6 @@ jobs:
family:
# Alphabetical order
- 'broadcom_32bit'
- 'imxrt'
- 'kinetis_k32 kinetis_kl'
- 'lpc11 lpc13 lpc15 lpc17 lpc18'
- 'lpc51 lpc54 lpc55'

57
.github/workflows/cmake_arm.yml vendored Normal file
View File

@ -0,0 +1,57 @@
name: CMake ARM
on:
push:
paths:
- 'src/**'
- 'examples/**'
- 'lib/**'
- 'hw/**'
- '.github/workflows/cmake_arm.yml'
pull_request:
branches: [ master ]
paths:
- 'src/**'
- 'examples/**'
- 'lib/**'
- 'hw/**'
- '.github/workflows/cmake_arm.yml'
concurrency:
group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }}
cancel-in-progress: true
jobs:
# ---------------------------------------
# Build ARM family
# ---------------------------------------
build-arm:
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
family:
# Alphabetical order
- 'imxrt'
steps:
- name: Setup Python
uses: actions/setup-python@v4
with:
python-version: '3.x'
- name: Install ARM GCC
uses: carlosperate/arm-none-eabi-gcc-action@v1
with:
release: '11.2-2022.02'
- name: Install Ninja
run: sudo apt install -y ninja-build
- name: Checkout TinyUSB
uses: actions/checkout@v3
- name: Get Dependencies
run: python3 tools/get_family_deps.py ${{ matrix.family }}
- name: Build
run: python tools/build_cmake.py ${{ matrix.family }}

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

@ -0,0 +1,10 @@
<component name="ProjectRunConfigurationManager">
<configuration default="false" name="rp2040" type="com.jetbrains.cidr.embedded.openocd.conf.type" factoryName="com.jetbrains.cidr.embedded.openocd.conf.factory" REDIRECT_INPUT="false" ELEVATE="false" USE_EXTERNAL_CONSOLE="false" PASS_PARENT_ENVS_2="true" PROJECT_NAME="cdc_msc_hid" TARGET_NAME="cdc_msc_hid" CONFIG_NAME="rp2040" version="1" RUN_TARGET_PROJECT_NAME="cdc_msc_hid" RUN_TARGET_NAME="cdc_msc_hid">
<openocd version="1" gdb-port="3333" telnet-port="4444" board-config="$PROJECT_DIR$/hw/bsp/rp2040/rp2040-openocd.cfg" reset-type="INIT" download-type="UPDATED_ONLY">
<debugger kind="GDB" isBundled="true" />
</openocd>
<method v="2">
<option name="CLION.COMPOUND.BUILD" enabled="true" />
</method>
</configuration>
</component>

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

@ -0,0 +1,10 @@
<component name="ProjectRunConfigurationManager">
<configuration default="false" name="rt1010" type="com.jetbrains.cidr.embedded.customgdbserver.type" factoryName="com.jetbrains.cidr.embedded.customgdbserver.factory" PROGRAM_PARAMS="gdbserver -p 55503 -t mimxrt1010" REDIRECT_INPUT="false" ELEVATE="false" USE_EXTERNAL_CONSOLE="false" PASS_PARENT_ENVS_2="true" PROJECT_NAME="cdc_msc" TARGET_NAME="cdc_msc" CONFIG_NAME="rt1060 evk" version="1" RUN_TARGET_PROJECT_NAME="cdc_msc" RUN_TARGET_NAME="cdc_msc">
<custom-gdb-server version="1" gdb-connect="tcp::55503" executable="$USER_HOME$/.local/bin/pyocd" 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

@ -0,0 +1,10 @@
<component name="ProjectRunConfigurationManager">
<configuration default="false" name="rt1060 nxplink" type="com.jetbrains.cidr.embedded.customgdbserver.type" factoryName="com.jetbrains.cidr.embedded.customgdbserver.factory" PROGRAM_PARAMS="gdbserver --gdb-port 55503 --semihost-port -1 MIMXRT1062xxxxA:EVK-MIMXRT1060" REDIRECT_INPUT="false" ELEVATE="false" USE_EXTERNAL_CONSOLE="false" PASS_PARENT_ENVS_2="true" PROJECT_NAME="cdc_msc_hid" TARGET_NAME="cdc_msc_hid" CONFIG_NAME="rt1060 evk" version="1" RUN_TARGET_PROJECT_NAME="cdc_msc_hid" RUN_TARGET_NAME="cdc_msc_hid">
<custom-gdb-server version="1" gdb-connect="tcp::55503" executable="/usr/local/LinkServer/LinkServer" warmup-ms="0" download-type="ALWAYS" 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,5 +0,0 @@
<component name="ProjectRunConfigurationManager">
<configuration default="false" name="tinyusb_examples" type="CMakeListConfigurationType" factoryName="CMakeListConfigurationFactory">
<method v="2" />
</configuration>
</component>

2
.idea/vcs.xml generated
View File

@ -17,8 +17,10 @@
<mapping directory="$PROJECT_DIR$/hw/mcu/nxp/nxp_sdk" vcs="Git" />
<mapping directory="$PROJECT_DIR$/hw/mcu/raspberry_pi/Pico-PIO-USB" vcs="Git" />
<mapping directory="$PROJECT_DIR$/hw/mcu/raspberry_pi/pico-sdk" vcs="Git" />
<mapping directory="$PROJECT_DIR$/hw/mcu/raspberry_pi/pico-sdk/lib/btstack" vcs="Git" />
<mapping directory="$PROJECT_DIR$/hw/mcu/raspberry_pi/pico-sdk/lib/cyw43-driver" vcs="Git" />
<mapping directory="$PROJECT_DIR$/hw/mcu/raspberry_pi/pico-sdk/lib/lwip" vcs="Git" />
<mapping directory="$PROJECT_DIR$/hw/mcu/raspberry_pi/pico-sdk/lib/mbedtls" vcs="Git" />
<mapping directory="$PROJECT_DIR$/hw/mcu/raspberry_pi/pico-sdk/lib/tinyusb" vcs="Git" />
<mapping directory="$PROJECT_DIR$/hw/mcu/renesas/fsp" vcs="Git" />
<mapping directory="$PROJECT_DIR$/hw/mcu/renesas/rx" vcs="Git" />

View File

@ -4,11 +4,18 @@
version: 2
# Set the version of Python and other tools you might need
build:
os: ubuntu-22.04
tools:
python: "3.11"
# Build documentation in the docs/ directory with Sphinx
sphinx:
configuration: docs/conf.py
# Optionally declare the Python requirements required to build your docs
python:
version: 3.8
install:
- requirements: docs/requirements.txt

View File

@ -1,6 +0,0 @@
set(TOOLCHAIN_COMMON_FLAGS
-mthumb
-mcpu=cortex-m7
-mfloat-abi=hard
-mfpu=fpv5-d16
)

View File

@ -93,7 +93,7 @@ Controller Driver (DCD & HCD)
- CFG_TUD_ENABLED/CFG_TUH_ENABLED, CFG_TUD_MAX_SPEED/CFG_TUH_MAX_SPEED can be used to replace CFG_TUSB_RHPORT0_MODE/CFG_TUSB_RHPORT1_MODE
- tud_init(rphort), tuh_init(rhport) can be used to init stack on specified roothub port (controller) instead of tusb_init(void)
- Add dcd/hcd port specific defines TUP_ (stand for tinyusb port-specific)
- Add dcd/hcd port specific defines `TUP_` (stand for tinyusb port-specific)
- [dwc2]
- Update to support stm32 h72x, h73x with only 1 otg controller

View File

@ -1,4 +1,4 @@
sphinx~=3.0
sphinx>=5.0
furo>=2020.12.30.b24
sphinx-autodoc-typehints>=1.10
jinja2==3.0.3
jinja2>=3.0.3

View File

@ -1,9 +1,9 @@
cmake_minimum_required(VERSION 3.5)
cmake_minimum_required(VERSION 3.17)
#set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
include(${CMAKE_CURRENT_SOURCE_DIR}/../hw/bsp/family_support.cmake)
project(tinyusb_examples)
project(tinyusb_examples C CXX ASM)
add_subdirectory(device)
add_subdirectory(dual)

View File

@ -0,0 +1,12 @@
if (TOOLCHAIN STREQUAL "gcc")
list(APPEND TOOLCHAIN_COMMON_FLAGS
-mthumb
-mcpu=cortex-m7
-mfloat-abi=hard
-mfpu=fpv5-d16
)
set(FREERTOS_PORT GCC_ARM_CM7 CACHE INTERNAL "")
else ()
# TODO support IAR
endif ()

View File

@ -25,7 +25,13 @@ list(APPEND TOOLCHAIN_COMMON_FLAGS
-fno-strict-aliasing
)
set(TOOLCHAIN_WARNING_FLAGS
list(APPEND TOOLCHAIN_EXE_LINKER_FLAGS
-Wl,--print-memory-usage
-Wl,--gc-sections
-Wl,--cref
)
list(APPEND TOOLCHAIN_WARNING_FLAGS
-Wall
-Wextra
-Werror

View File

@ -8,9 +8,13 @@ foreach(LANG IN ITEMS C CXX ASM)
#cmake_print_variables(CMAKE_${LANG}_FLAGS_INIT)
# optimization flags
set(CMAKE_${LANG}_FLAGS_DEBUG_INIT "-Og")
set(CMAKE_${LANG}_FLAGS_RELEASE_INIT "-Os")
set(CMAKE_${LANG}_FLAGS_DEBUG_INIT "-O0")
endforeach()
# Linker
list(JOIN TOOLCHAIN_EXE_LINKER_FLAGS " " CMAKE_EXE_LINKER_FLAGS_INIT)
# try_compile is cmake test compiling its own example,
# pass -nostdlib to skip stdlib linking
get_property(IS_IN_TRY_COMPILE GLOBAL PROPERTY IN_TRY_COMPILE)

View File

@ -1,8 +1,8 @@
cmake_minimum_required(VERSION 3.5)
cmake_minimum_required(VERSION 3.17)
include(${CMAKE_CURRENT_SOURCE_DIR}/../../hw/bsp/family_support.cmake)
project(tinyusb_device_examples)
project(tinyusb_device_examples C CXX ASM)
family_initialize_project(tinyusb_device_examples ${CMAKE_CURRENT_LIST_DIR})
# family_add_subdirectory will filter what to actually add based on selected FAMILY
@ -22,7 +22,12 @@ family_add_subdirectory(hid_generic_inout)
family_add_subdirectory(hid_multiple_interface)
family_add_subdirectory(midi_test)
family_add_subdirectory(msc_dual_lun)
# FIXME temp skip net_lwip_webserver for imxrt for now
if (NOT ${FAMILY} STREQUAL "imxrt")
family_add_subdirectory(net_lwip_webserver)
endif()
family_add_subdirectory(uac2_headset)
family_add_subdirectory(usbtmc)
family_add_subdirectory(video_capture)

View File

@ -1,4 +1,5 @@
cmake_minimum_required(VERSION 3.17)
set_property(GLOBAL PROPERTY USE_FOLDERS ON)
include(${CMAKE_CURRENT_SOURCE_DIR}/../../../hw/bsp/family_support.cmake)

View File

@ -34,11 +34,5 @@ target_include_directories(${PROJECT} PUBLIC
# in hw/bsp/FAMILY/family.cmake for details.
family_configure_device_example(${PROJECT})
if (NOT TARGET freertos_kernel)
family_add_freertos_config(${PROJECT})
add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/../../../lib/FreeRTOS-Kernel lib/FreeRTOS-Kernel)
endif()
target_link_libraries(${PROJECT} PUBLIC
freertos_kernel
)
# Add FreeRTOS for this example
family_add_freertos(${PROJECT})

View File

@ -33,11 +33,5 @@ target_include_directories(${PROJECT} PUBLIC
# in hw/bsp/FAMILY/family.cmake for details.
family_configure_device_example(${PROJECT})
if (NOT TARGET freertos_kernel)
family_add_freertos_config(${PROJECT})
add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/../../../lib/FreeRTOS-Kernel lib/FreeRTOS-Kernel)
endif()
target_link_libraries(${PROJECT} PUBLIC
freertos_kernel
)
# Add FreeRTOS for this example
family_add_freertos(${PROJECT})

View File

@ -1,9 +1,10 @@
cmake_minimum_required(VERSION 3.5)
cmake_minimum_required(VERSION 3.17)
include(${CMAKE_CURRENT_SOURCE_DIR}/../../hw/bsp/family_support.cmake)
project(tinyusb_dual_examples)
project(tinyusb_dual_examples C CXX ASM)
family_initialize_project(tinyusb_dual_examples ${CMAKE_CURRENT_LIST_DIR})
if (FAMILY STREQUAL "rp2040" AND NOT TARGET tinyusb_pico_pio_usb)
message("Skipping dual host/device mode examples as Pico-PIO-USB is not available")
else ()

View File

@ -1,11 +1,11 @@
cmake_minimum_required(VERSION 3.5)
cmake_minimum_required(VERSION 3.17)
include(${CMAKE_CURRENT_SOURCE_DIR}/../../../hw/bsp/family_support.cmake)
# gets PROJECT name for the example (e.g. <BOARD>-<DIR_NAME>)
family_get_project_name(PROJECT ${CMAKE_CURRENT_LIST_DIR})
project(${PROJECT})
project(${PROJECT} C CXX ASM)
# Checks this example is valid for the family and initializes the project
family_initialize_project(${PROJECT} ${CMAKE_CURRENT_LIST_DIR})

View File

@ -1,8 +1,8 @@
cmake_minimum_required(VERSION 3.5)
cmake_minimum_required(VERSION 3.17)
include(${CMAKE_CURRENT_SOURCE_DIR}/../../hw/bsp/family_support.cmake)
project(tinyusb_host_examples)
project(tinyusb_host_examples C CXX ASM)
family_initialize_project(tinyusb_host_examples ${CMAKE_CURRENT_LIST_DIR})
# family_add_subdirectory will filter what to actually add based on selected FAMILY

View File

@ -1,11 +1,11 @@
cmake_minimum_required(VERSION 3.5)
cmake_minimum_required(VERSION 3.17)
include(${CMAKE_CURRENT_SOURCE_DIR}/../../../hw/bsp/family_support.cmake)
# gets PROJECT name for the example
family_get_project_name(PROJECT ${CMAKE_CURRENT_LIST_DIR})
project(${PROJECT})
project(${PROJECT} C CXX ASM)
# Checks this example is valid for the family and initializes the project
family_initialize_project(${PROJECT} ${CMAKE_CURRENT_LIST_DIR})

View File

@ -5,7 +5,7 @@ include(${CMAKE_CURRENT_SOURCE_DIR}/../../../hw/bsp/family_support.cmake)
# gets PROJECT name for the example (e.g. <BOARD>-<DIR_NAME>)
family_get_project_name(PROJECT ${CMAKE_CURRENT_LIST_DIR})
project(${PROJECT})
project(${PROJECT} C CXX ASM)
# Checks this example is valid for the family and initializes the project
family_initialize_project(${PROJECT} ${CMAKE_CURRENT_LIST_DIR})

View File

@ -1,11 +1,11 @@
cmake_minimum_required(VERSION 3.5)
cmake_minimum_required(VERSION 3.17)
include(${CMAKE_CURRENT_SOURCE_DIR}/../../../hw/bsp/family_support.cmake)
# gets PROJECT name for the example (e.g. <BOARD>-<DIR_NAME>)
family_get_project_name(PROJECT ${CMAKE_CURRENT_LIST_DIR})
project(${PROJECT})
project(${PROJECT} C CXX ASM)
# Checks this example is valid for the family and initializes the project
family_initialize_project(${PROJECT} ${CMAKE_CURRENT_LIST_DIR})

View File

@ -1,11 +1,11 @@
cmake_minimum_required(VERSION 3.5)
cmake_minimum_required(VERSION 3.17)
include(${CMAKE_CURRENT_SOURCE_DIR}/../../../hw/bsp/family_support.cmake)
# gets PROJECT name for the example (e.g. <BOARD>-<DIR_NAME>)
family_get_project_name(PROJECT ${CMAKE_CURRENT_LIST_DIR})
project(${PROJECT})
project(${PROJECT} C CXX ASM)
# Checks this example is valid for the family and initializes the project
family_initialize_project(${PROJECT} ${CMAKE_CURRENT_LIST_DIR})

View File

@ -72,6 +72,11 @@ endif
LDFLAGS += $(CFLAGS) -Wl,-Map=$@.map -Wl,-cref -Wl,-gc-sections
# Some toolchain such as renesas rx does not support --print-memory-usage flags
ifneq ($(FAMILY),rx)
LDFLAGS += -Wl,--print-memory-usage
endif
ifdef LD_FILE
LDFLAGS += -Wl,-T,$(TOP)/$(LD_FILE)
endif

View File

@ -25,55 +25,6 @@
#include "board.h"
#if 0
#define LED_PHASE_MAX 8
static struct
{
uint32_t phase[LED_PHASE_MAX];
uint8_t phase_count;
bool led_state;
uint8_t current_phase;
uint32_t current_ms;
}led_pattern;
void board_led_pattern(uint32_t const phase_ms[], uint8_t count)
{
memcpy(led_pattern.phase, phase_ms, 4*count);
led_pattern.phase_count = count;
// reset with 1st phase is on
led_pattern.current_ms = board_millis();
led_pattern.current_phase = 0;
led_pattern.led_state = true;
board_led_on();
}
void board_led_task(void)
{
if ( led_pattern.phase_count == 0 ) return;
uint32_t const duration = led_pattern.phase[led_pattern.current_phase];
// return if not enough time
if (board_millis() - led_pattern.current_ms < duration) return;
led_pattern.led_state = !led_pattern.led_state;
board_led_write(led_pattern.led_state);
led_pattern.current_ms += duration;
led_pattern.current_phase++;
if (led_pattern.current_phase == led_pattern.phase_count)
{
led_pattern.current_phase = 0;
led_pattern.led_state = true;
board_led_on();
}
}
#endif
//--------------------------------------------------------------------+
// newlib read()/write() retarget
//--------------------------------------------------------------------+

View File

@ -1,4 +1,6 @@
if (NOT TARGET _family_support_marker)
add_library(_family_support_marker INTERFACE)
include(CMakePrintHelpers)
# Default to gcc
@ -6,8 +8,6 @@ if (NOT TARGET _family_support_marker)
set(TOOLCHAIN gcc)
endif()
add_library(_family_support_marker INTERFACE)
if (NOT FAMILY)
message(FATAL_ERROR "You must set a FAMILY variable for the build (e.g. rp2040, eps32s2, esp32s3). You can do this via -DFAMILY=xxx on the cmake command line")
endif()
@ -27,8 +27,8 @@ if (NOT TARGET _family_support_marker)
foreach(MCU IN LISTS FAMILY_MCUS)
# For each line in only.txt
foreach(_line ${ONLYS_LINES})
# If mcu:xxx exists for this mcu then include
if (${_line} STREQUAL "mcu:${MCU}")
# If mcu:xxx exists for this mcu or board:xxx then include
if (${_line} STREQUAL "mcu:${MCU}" OR ${_line} STREQUAL "board:${BOARD}")
set(${RESULT} 1 PARENT_SCOPE)
return()
endif()

View File

@ -0,0 +1,8 @@
if (NOT TARGET freertos_config)
add_library(freertos_config INTERFACE)
# add path to FreeRTOSConfig.h
target_include_directories(freertos_config SYSTEM INTERFACE
${CMAKE_CURRENT_LIST_DIR}
)
endif()

View File

@ -0,0 +1,15 @@
set(MCU_VARIANT MIMXRT1011)
set(JLINK_DEVICE MIMXRT1011DAE5A)
set(PYOCD_TARGET mimxrt1010)
set(NXPLINK_DEVICE MIMXRT1011xxxxx:EVK-MIMXRT1010)
function(update_board TARGET)
target_sources(${TARGET} PUBLIC
${CMAKE_CURRENT_FUNCTION_LIST_DIR}/evkmimxrt1010_flexspi_nor_config.c
)
target_compile_definitions(${TARGET} PUBLIC
CPU_MIMXRT1011DAE5A
CFG_EXAMPLE_VIDEO_READONLY
)
endfunction()

View File

@ -1,10 +1,15 @@
set(MCU_VARIANT MIMXRT1011)
target_sources(${PROJECT} PUBLIC
${CMAKE_CURRENT_LIST_DIR}/evkmimxrt1010_flexspi_nor_config.c
)
set(JLINK_DEVICE MIMXRT1011DAE5A)
set(PYOCD_TARGET mimxrt1010)
set(NXPLINK_DEVICE MIMXRT1011xxxxx:EVK-MIMXRT1010)
target_compile_definitions(${PROJECT} PUBLIC
function(update_board TARGET)
target_sources(${TARGET} PUBLIC
${CMAKE_CURRENT_FUNCTION_LIST_DIR}/evkmimxrt1010_flexspi_nor_config.c
)
target_compile_definitions(${TARGET} PUBLIC
CPU_MIMXRT1011DAE5A
CFG_EXAMPLE_VIDEO_READONLY
)
endfunction()

View File

@ -0,0 +1,15 @@
set(MCU_VARIANT MIMXRT1015)
set(JLINK_DEVICE MIMXRT1015DAF5A)
set(PYOCD_TARGET mimxrt1015)
set(NXPLINK_DEVICE MIMXRT1015xxxxx:EVK-MIMXRT1015)
function(update_board TARGET)
target_sources(${TARGET} PUBLIC
${CMAKE_CURRENT_FUNCTION_LIST_DIR}/evkmimxrt1015_flexspi_nor_config.c
)
target_compile_definitions(${TARGET} PUBLIC
CPU_MIMXRT1015DAF5A
CFG_EXAMPLE_VIDEO_READONLY
)
endfunction()

View File

@ -0,0 +1,14 @@
set(MCU_VARIANT MIMXRT1021)
set(JLINK_DEVICE MIMXRT1021DAG5A)
set(PYOCD_TARGET mimxrt1020)
set(NXPLINK_DEVICE MIMXRT1021xxxxx:EVK-MIMXRT1020)
function(update_board TARGET)
target_sources(${TARGET} PUBLIC
${CMAKE_CURRENT_FUNCTION_LIST_DIR}/evkmimxrt1020_flexspi_nor_config.c
)
target_compile_definitions(${TARGET} PUBLIC
CPU_MIMXRT1021DAG5A
)
endfunction()

View File

@ -0,0 +1,16 @@
set(MCU_VARIANT MIMXRT1024)
set(JLINK_DEVICE MIMXRT1024DAG5A)
set(PYOCD_TARGET mimxrt1024)
set(NXPLINK_DEVICE MIMXRT1024xxxxx:MIMXRT1024-EVK)
function(update_board TARGET)
target_sources(${TARGET} PUBLIC
${CMAKE_CURRENT_FUNCTION_LIST_DIR}/evkmimxrt1024_flexspi_nor_config.c
)
target_compile_definitions(${TARGET} PUBLIC
CPU_MIMXRT1024DAG5A
CFG_EXAMPLE_VIDEO_READONLY
#-Wno-error=array-bounds
)
endfunction()

View File

@ -0,0 +1,16 @@
set(MCU_VARIANT MIMXRT1052)
set(JLINK_DEVICE MIMXRT1052xxxxB)
set(PYOCD_TARGET mimxrt1050)
set(NXPLINK_DEVICE MIMXRT1052xxxxB:EVK-MIMXRT1050)
function(update_board TARGET)
target_sources(${TARGET} PUBLIC
${CMAKE_CURRENT_FUNCTION_LIST_DIR}/evkbimxrt1050_flexspi_nor_config.c
)
target_compile_definitions(${TARGET} PUBLIC
CPU_MIMXRT1052DVL6B
BOARD_TUD_RHPORT=0
BOARD_TUH_RHPORT=1
)
endfunction()

View File

@ -0,0 +1,16 @@
set(MCU_VARIANT MIMXRT1062)
set(JLINK_DEVICE MIMXRT1062xxx6A)
set(PYOCD_TARGET mimxrt1060)
set(NXPLINK_DEVICE MIMXRT1062xxxxA:EVK-MIMXRT1060)
function(update_board TARGET)
target_sources(${TARGET} PUBLIC
${CMAKE_CURRENT_FUNCTION_LIST_DIR}/evkmimxrt1060_flexspi_nor_config.c
)
target_compile_definitions(${TARGET} PUBLIC
CPU_MIMXRT1062DVL6A
BOARD_TUD_RHPORT=0
BOARD_TUH_RHPORT=1
)
endfunction()

View File

@ -7,8 +7,8 @@ JLINK_DEVICE = MIMXRT1062xxx6A
# For flash-pyocd target
PYOCD_TARGET = mimxrt1060
BOARD_TUD_RHPORT = 1
BOARD_TUH_RHPORT = 0
BOARD_TUD_RHPORT = 0
BOARD_TUH_RHPORT = 1
# flash using pyocd
flash: flash-pyocd

View File

@ -0,0 +1,16 @@
set(MCU_VARIANT MIMXRT1064)
set(JLINK_DEVICE MIMXRT1064xxx6A)
set(PYOCD_TARGET mimxrt1064)
set(NXPLINK_DEVICE MIMXRT1064xxxxA:EVK-MIMXRT1064)
function(update_board TARGET)
target_sources(${TARGET} PUBLIC
${CMAKE_CURRENT_FUNCTION_LIST_DIR}/evkmimxrt1064_flexspi_nor_config.c
)
target_compile_definitions(${TARGET} PUBLIC
CPU_MIMXRT1064DVL6A
BOARD_TUD_RHPORT=0
BOARD_TUH_RHPORT=1
)
endfunction()

View File

@ -7,8 +7,8 @@ JLINK_DEVICE = MIMXRT1064xxx6A
# For flash-pyocd target
PYOCD_TARGET = mimxrt1064
BOARD_TUD_RHPORT = 1
BOARD_TUH_RHPORT = 0
BOARD_TUD_RHPORT = 0
BOARD_TUH_RHPORT = 1
# flash using pyocd
flash: flash-pyocd

View File

@ -0,0 +1,21 @@
set(MCU_VARIANT MIMXRT1062)
set(JLINK_DEVICE MIMXRT1062xxx6A)
set(PYOCD_TARGET mimxrt1060)
set(NXPLINK_DEVICE MIMXRT1062xxxxA:EVK-MIMXRT1060)
function(update_board TARGET)
target_sources(${TARGET} PUBLIC
${CMAKE_CURRENT_FUNCTION_LIST_DIR}/teensy40_flexspi_nor_config.c
)
target_compile_definitions(${TARGET} PUBLIC
CPU_MIMXRT1062DVL6A
BOARD_TUD_RHPORT=0
BOARD_TUH_RHPORT=1
)
endfunction()
# flash by using teensy_loader_cli https://github.com/PaulStoffregen/teensy_loader_cli
# Make sure it is in your PATH
# flash: $(BUILD)/$(PROJECT).hex
# teensy_loader_cli --mcu=imxrt1062 -v -w $<

View File

@ -5,7 +5,7 @@
* SPDX-License-Identifier: BSD-3-Clause
*/
#include <bsp/imxrt/boards/teensy_40/teensy40_flexspi_nor_config.h>
#include "teensy40_flexspi_nor_config.h"
/* Component ID definition, used by tools. */
#ifndef FSL_COMPONENT_ID

View File

@ -0,0 +1,21 @@
set(MCU_VARIANT MIMXRT1062)
set(JLINK_DEVICE MIMXRT1062xxx6A)
set(PYOCD_TARGET mimxrt1060)
set(NXPLINK_DEVICE MIMXRT1062xxxxA:EVK-MIMXRT1060)
function(update_board TARGET)
target_sources(${TARGET} PUBLIC
${CMAKE_CURRENT_FUNCTION_LIST_DIR}/teensy41_flexspi_nor_config.c
)
target_compile_definitions(${TARGET} PUBLIC
CPU_MIMXRT1062DVL6A
BOARD_TUD_RHPORT=0
BOARD_TUH_RHPORT=1
)
endfunction()
# flash by using teensy_loader_cli https://github.com/PaulStoffregen/teensy_loader_cli
# Make sure it is in your PATH
# flash: $(BUILD)/$(PROJECT).hex
# teensy_loader_cli --mcu=imxrt1062 -v -w $<

View File

@ -5,7 +5,7 @@
* SPDX-License-Identifier: BSD-3-Clause
*/
#include <bsp/imxrt/boards/teensy_40/teensy40_flexspi_nor_config.h>
#include "teensy41_flexspi_nor_config.h"
/* Component ID definition, used by tools. */
#ifndef FSL_COMPONENT_ID

View File

@ -47,12 +47,28 @@
#endif
// needed by fsl_flexspi_nor_boot
TU_ATTR_USED
const uint8_t dcd_data[] = { 0x00 };
//--------------------------------------------------------------------+
//
//--------------------------------------------------------------------+
static void init_usb_phy(USBPHY_Type* usb_phy) {
// Enable PHY support for Low speed device + LS via FS Hub
usb_phy->CTRL |= USBPHY_CTRL_SET_ENUTMILEVEL2_MASK | USBPHY_CTRL_SET_ENUTMILEVEL3_MASK;
// Enable all power for normal operation
// TODO may not be needed since it is called within CLOCK_EnableUsbhs0PhyPllClock()
usb_phy->PWD = 0;
// TX Timing
uint32_t phytx = usb_phy->TX;
phytx &= ~(USBPHY_TX_D_CAL_MASK | USBPHY_TX_TXCAL45DM_MASK | USBPHY_TX_TXCAL45DP_MASK);
phytx |= USBPHY_TX_D_CAL(0x0C) | USBPHY_TX_TXCAL45DP(0x06) | USBPHY_TX_TXCAL45DM(0x06);
usb_phy->TX = phytx;
}
void board_init(void)
{
// make sure the dcache is on.
@ -70,6 +86,7 @@ void board_init(void)
#if CFG_TUSB_OS == OPT_OS_NONE
// 1ms tick timer
SysTick_Config(SystemCoreClock / 1000);
#elif CFG_TUSB_OS == OPT_OS_FREERTOS
// If freeRTOS is used, IRQ priority is limit by max syscall ( smaller is higher )
NVIC_SetPriority(USB_OTG1_IRQn, configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY);
@ -116,52 +133,24 @@ void board_init(void)
LPUART_Init(UART_PORT, &uart_config, freq);
//------------- USB0 -------------//
//------------- USB -------------//
// Note: RT105x RT106x and later have dual USB controllers.
// Clock
CLOCK_EnableUsbhs0PhyPllClock(kCLOCK_Usbphy480M, 480000000U);
CLOCK_EnableUsbhs0Clock(kCLOCK_Usb480M, 480000000U);
USBPHY_Type* usb_phy;
// RT105x RT106x have dual USB controller.
#ifdef USBPHY1
usb_phy = USBPHY1;
init_usb_phy(USBPHY1);
#else
usb_phy = USBPHY;
init_usb_phy(USBPHY);
#endif
// Enable PHY support for Low speed device + LS via FS Hub
usb_phy->CTRL |= USBPHY_CTRL_SET_ENUTMILEVEL2_MASK | USBPHY_CTRL_SET_ENUTMILEVEL3_MASK;
// Enable all power for normal operation
usb_phy->PWD = 0;
// TX Timing
uint32_t phytx = usb_phy->TX;
phytx &= ~(USBPHY_TX_D_CAL_MASK | USBPHY_TX_TXCAL45DM_MASK | USBPHY_TX_TXCAL45DP_MASK);
phytx |= USBPHY_TX_D_CAL(0x0C) | USBPHY_TX_TXCAL45DP(0x06) | USBPHY_TX_TXCAL45DM(0x06);
usb_phy->TX = phytx;
// RT105x RT106x have dual USB controller.
#ifdef USBPHY2
// USB1
CLOCK_EnableUsbhs1PhyPllClock(kCLOCK_Usbphy480M, 480000000U);
CLOCK_EnableUsbhs1Clock(kCLOCK_Usb480M, 480000000U);
usb_phy = USBPHY2;
// Enable PHY support for Low speed device + LS via FS Hub
usb_phy->CTRL |= USBPHY_CTRL_SET_ENUTMILEVEL2_MASK | USBPHY_CTRL_SET_ENUTMILEVEL3_MASK;
// Enable all power for normal operation
usb_phy->PWD = 0;
// TX Timing
phytx = usb_phy->TX;
phytx &= ~(USBPHY_TX_D_CAL_MASK | USBPHY_TX_TXCAL45DM_MASK | USBPHY_TX_TXCAL45DP_MASK);
phytx |= USBPHY_TX_D_CAL(0x0C) | USBPHY_TX_TXCAL45DP(0x06) | USBPHY_TX_TXCAL45DM(0x06);
usb_phy->TX = phytx;
init_usb_phy(USBPHY2);
#endif
}
@ -207,8 +196,28 @@ uint32_t board_button_read(void)
int board_uart_read(uint8_t* buf, int len)
{
LPUART_ReadBlocking(UART_PORT, buf, len);
return len;
int count = 0;
while( count < len )
{
uint8_t const rx_count = LPUART_GetRxFifoCount(UART_PORT);
if (!rx_count)
{
// clear all error flag if any
uint32_t status_flags = LPUART_GetStatusFlags(UART_PORT);
status_flags &= (kLPUART_RxOverrunFlag | kLPUART_ParityErrorFlag | kLPUART_FramingErrorFlag | kLPUART_NoiseErrorFlag);
LPUART_ClearStatusFlags(UART_PORT, status_flags);
break;
}
for(int i=0; i<rx_count; i++)
{
buf[count] = LPUART_ReadByte(UART_PORT);
count++;
}
}
return count;
}
int board_uart_write(void const * buf, int len)

View File

@ -1,44 +1,36 @@
# toolchain set up
set(CMAKE_SYSTEM_PROCESSOR cortex-m7 CACHE INTERNAL "System Processor")
set(CMAKE_TOOLCHAIN_FILE ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/../../../cmake/toolchain/arm_${TOOLCHAIN}.cmake)
if (TARGET _imxrt_family_inclusion_marker)
return()
endif ()
add_library(_imxrt_family_inclusion_marker INTERFACE)
function(family_configure_target TARGET)
if (NOT BOARD)
message(FATAL_ERROR "BOARD not specified")
endif ()
# set output name to .elf
set_target_properties(${TARGET} PROPERTIES OUTPUT_NAME ${TARGET}.elf)
# toolchain set up
set(CMAKE_SYSTEM_PROCESSOR cortex-m7 CACHE INTERNAL "System Processor")
set(CMAKE_TOOLCHAIN_FILE ${CMAKE_CURRENT_LIST_DIR}/../../../examples/cmake/toolchain/arm_${TOOLCHAIN}.cmake)
# TOP is absolute path to root directory of TinyUSB git repo
set(TOP "${CMAKE_CURRENT_FUNCTION_LIST_DIR}/../../..")
get_filename_component(TOP "${TOP}" REALPATH)
set(FAMILY_MCUS MIMXRT CACHE INTERNAL "")
# include board specific
include(${CMAKE_CURRENT_LIST_DIR}/boards/${BOARD}/board.cmake)
#------------------------------------
# BOARD_TARGET
#------------------------------------
# only need to be built ONCE for all examples
set(BOARD_TARGET board_${BOARD})
if (NOT TARGET ${BOARD_TARGET})
# TOP is path to root directory
set(TOP "${CMAKE_CURRENT_LIST_DIR}/../../..")
set(SDK_DIR ${TOP}/hw/mcu/nxp/mcux-sdk)
set(DEPS_SUBMODULES ${SDK_DIR})
set(CMSIS_DIR ${TOP}/lib/CMSIS_5)
include(${CMAKE_CURRENT_FUNCTION_LIST_DIR}/boards/${BOARD}/board.cmake)
target_compile_definitions(${TARGET} PUBLIC
CFG_TUSB_MCU=OPT_MCU_MIMXRT
__ARMVFP__=0
__ARMFPV5__=0
XIP_EXTERNAL_FLASH=1
XIP_BOOT_HEADER_ENABLE=1
)
target_link_options(${TARGET} PUBLIC
--specs=nosys.specs
--specs=nano.specs
)
target_sources(${TARGET} PUBLIC
# TinyUSB
${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
# BSP
${CMAKE_CURRENT_FUNCTION_LIST_DIR}/family.c
add_library(${BOARD_TARGET} STATIC
${SDK_DIR}/drivers/common/fsl_common.c
${SDK_DIR}/drivers/igpio/fsl_gpio.c
${SDK_DIR}/drivers/lpuart/fsl_lpuart.c
@ -47,24 +39,15 @@ function(family_configure_target TARGET)
${SDK_DIR}/devices/${MCU_VARIANT}/project_template/clock_config.c
${SDK_DIR}/devices/${MCU_VARIANT}/drivers/fsl_clock.c
)
if (TOOLCHAIN STREQUAL "gcc")
target_sources(${TARGET} PUBLIC
${SDK_DIR}/devices/${MCU_VARIANT}/gcc/startup_${MCU_VARIANT}.S
target_compile_definitions(${BOARD_TARGET} PUBLIC
CFG_TUSB_MCU=OPT_MCU_MIMXRT
__ARMVFP__=0
__ARMFPV5__=0
XIP_EXTERNAL_FLASH=1
XIP_BOOT_HEADER_ENABLE=1
)
target_link_options(${TARGET} PUBLIC
"LINKER:--script=${SDK_DIR}/devices/${MCU_VARIANT}/gcc/${MCU_VARIANT}xxxxx_flexspi_nor.ld"
)
else ()
# TODO support IAR
endif ()
target_include_directories(${TARGET} PUBLIC
${CMAKE_CURRENT_FUNCTION_LIST_DIR}
${CMAKE_CURRENT_FUNCTION_LIST_DIR}/../../
${CMAKE_CURRENT_FUNCTION_LIST_DIR}/boards/${BOARD}
${SDK_DIR}/CMSIS/Include
target_include_directories(${BOARD_TARGET} PUBLIC
${CMSIS_DIR}/CMSIS/Core/Include
${SDK_DIR}/devices/${MCU_VARIANT}
${SDK_DIR}/devices/${MCU_VARIANT}/project_template
${SDK_DIR}/devices/${MCU_VARIANT}/drivers
@ -72,29 +55,125 @@ function(family_configure_target TARGET)
${SDK_DIR}/drivers/igpio
${SDK_DIR}/drivers/lpuart
)
update_board(${BOARD_TARGET})
# include tinyusb cmake
include(${TOP}/src/CMakeLists.txt)
add_tinyusb(${TARGET})
endfunction()
function(family_add_freertos_config TARGET)
add_library(freertos_config INTERFACE)
# add path to FreeRTOSConfig.h
target_include_directories(freertos_config SYSTEM INTERFACE
${CMAKE_CURRENT_FUNCTION_LIST_DIR}/FreeRTOSConfig
)
# select freertos port
if (TOOLCHAIN STREQUAL "gcc")
set(FREERTOS_PORT "GCC_ARM_CM7" CACHE INTERNAL "")
target_sources(${BOARD_TARGET} PUBLIC
${SDK_DIR}/devices/${MCU_VARIANT}/gcc/startup_${MCU_VARIANT}.S
)
target_link_options(${BOARD_TARGET} PUBLIC
"LINKER:--script=${SDK_DIR}/devices/${MCU_VARIANT}/gcc/${MCU_VARIANT}xxxxx_flexspi_nor.ld"
"LINKER:-Map=$<IF:$<BOOL:$<TARGET_PROPERTY:OUTPUT_NAME>>,$<TARGET_PROPERTY:OUTPUT_NAME>,$<TARGET_PROPERTY:NAME>>${CMAKE_EXECUTABLE_SUFFIX}.map"
# nanolib
--specs=nosys.specs
--specs=nano.specs
# force linker to look for these symbols
-Wl,-uimage_vector_table
-Wl,-ug_boot_data
)
else ()
# TODO support IAR
endif ()
endif () # BOARD_TARGET
#------------------------------------
# Functions
#------------------------------------
function(family_configure_target TARGET)
# set output name to .elf
set_target_properties(${TARGET} PROPERTIES OUTPUT_NAME ${TARGET}.elf)
# TOP is path to root directory
set(TOP "${CMAKE_CURRENT_FUNCTION_LIST_DIR}/../../..")
#---------- Port Specific ----------
# These files are built for each example since it depends on example's tusb_config.h
target_sources(${TARGET} PUBLIC
# TinyUSB Port
${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
# BSP
${CMAKE_CURRENT_FUNCTION_LIST_DIR}/family.c
${CMAKE_CURRENT_FUNCTION_LIST_DIR}/../board.c
)
target_include_directories(${TARGET} PUBLIC
${CMAKE_CURRENT_FUNCTION_LIST_DIR}
${CMAKE_CURRENT_FUNCTION_LIST_DIR}/../../
${CMAKE_CURRENT_FUNCTION_LIST_DIR}/boards/${BOARD}
)
#---------- TinyUSB ----------
# tinyusb target is built for each example since it depends on example's tusb_config.h
set(TINYUSB_TARGET_PREFIX ${TARGET}-)
add_library(${TARGET}-tinyusb_config INTERFACE)
target_include_directories(${TARGET}-tinyusb_config INTERFACE
${CMAKE_CURRENT_SOURCE_DIR}/src
)
target_compile_definitions(${TARGET}-tinyusb_config INTERFACE
CFG_TUSB_MCU=OPT_MCU_MIMXRT
)
# tinyusb's CMakeList.txt
add_subdirectory(${TOP}/src ${CMAKE_CURRENT_BINARY_DIR}/tinyusb)
# Link dependencies
target_link_libraries(${TARGET} PUBLIC ${BOARD_TARGET} ${TARGET}-tinyusb)
# group target (not yet supported by clion)
set_target_properties(${TARGET}-tinyusb ${TARGET}-tinyusb_config
PROPERTIES FOLDER ${TARGET}_sub
)
#---------- Flash ----------
# Flash using pyocd
add_custom_target(${TARGET}-pyocd
COMMAND pyocd flash -t ${PYOCD_TARGET} $<TARGET_FILE:${TARGET}>
)
# Flash using NXP LinkServer (redlink)
# https://www.nxp.com/design/software/development-software/mcuxpresso-software-and-tools-/linkserver-for-microcontrollers:LINKERSERVER
# LinkServer has a bug that can only execute with full path otherwise it throws:
# realpath error: No such file or directory
execute_process(COMMAND which LinkServer OUTPUT_VARIABLE LINKSERVER_PATH OUTPUT_STRIP_TRAILING_WHITESPACE)
add_custom_target(${TARGET}-nxplink
COMMAND ${LINKSERVER_PATH} flash ${NXPLINK_DEVICE} load $<TARGET_FILE:${TARGET}>
)
endfunction()
function(family_add_freertos TARGET)
# freertos_config
add_subdirectory(${CMAKE_CURRENT_FUNCTION_LIST_DIR}/FreeRTOSConfig ${CMAKE_CURRENT_BINARY_DIR}/freertos_config)
## freertos
if (NOT TARGET freertos_kernel)
add_subdirectory(${CMAKE_CURRENT_FUNCTION_LIST_DIR}/../../../lib/FreeRTOS-Kernel ${CMAKE_CURRENT_BINARY_DIR}/freertos_kernel)
endif ()
# Add FreeRTOS option to tinyusb_config
target_compile_definitions(${TARGET}-tinyusb_config INTERFACE
CFG_TUSB_OS=OPT_OS_FREERTOS
)
# link tinyusb with freeRTOS kernel
target_link_libraries(${TARGET}-tinyusb PUBLIC
freertos_kernel
)
target_link_libraries(${TARGET} PUBLIC
freertos_kernel
)
endfunction()
function(family_configure_device_example TARGET)
family_configure_target(${TARGET})
endfunction()
function(family_configure_host_example TARGET)
family_configure_target(${TARGET})
endfunction()
function(family_configure_dual_usb_example TARGET)
family_configure_target(${TARGET})
endfunction()

View File

@ -3,10 +3,13 @@
cmake_minimum_required(VERSION 3.17)
# Add tinyusb to a target
function(add_tinyusb TARGET)
target_sources(${TARGET} PUBLIC
# common
${CMAKE_CURRENT_FUNCTION_LIST_DIR}/tusb.c
${CMAKE_CURRENT_FUNCTION_LIST_DIR}/common/tusb_fifo.c
# device
${CMAKE_CURRENT_FUNCTION_LIST_DIR}/device/usbd.c
${CMAKE_CURRENT_FUNCTION_LIST_DIR}/device/usbd_control.c
${CMAKE_CURRENT_FUNCTION_LIST_DIR}/class/audio/audio_device.c
@ -21,15 +24,44 @@ function(add_tinyusb TARGET)
${CMAKE_CURRENT_FUNCTION_LIST_DIR}/class/usbtmc/usbtmc_device.c
${CMAKE_CURRENT_FUNCTION_LIST_DIR}/class/vendor/vendor_device.c
${CMAKE_CURRENT_FUNCTION_LIST_DIR}/class/video/video_device.c
# host
${CMAKE_CURRENT_FUNCTION_LIST_DIR}/host/usbh.c
${CMAKE_CURRENT_FUNCTION_LIST_DIR}/host/hub.c
${CMAKE_CURRENT_FUNCTION_LIST_DIR}/class/cdc/cdc_host.c
${CMAKE_CURRENT_FUNCTION_LIST_DIR}/class/hid/hid_host.c
${CMAKE_CURRENT_FUNCTION_LIST_DIR}/class/msc/msc_host.c
${CMAKE_CURRENT_FUNCTION_LIST_DIR}/class/vendor/vendor_host.c
)
target_include_directories(${TARGET} PUBLIC
${CMAKE_CURRENT_FUNCTION_LIST_DIR}
)
# enable all possible warnings
target_compile_options(${TARGET} PUBLIC
)
endfunction()
set(TINYUSB_TARGET "tinyusb")
set(TINYUSB_CONFIG_TARGET "tinyusb_config")
if (DEFINED TINYUSB_TARGET_PREFIX)
set(TINYUSB_TARGET "${TINYUSB_TARGET_PREFIX}${TINYUSB_TARGET}")
set(TINYUSB_CONFIG_TARGET "${TINYUSB_TARGET_PREFIX}${TINYUSB_CONFIG_TARGET}")
endif ()
if (DEFINED TINYUSB_TARGET_SUFFIX)
set(TINYUSB_TARGET "${TINYUSB_TARGET}${TINYUSB_TARGET_SUFFIX}")
set(TINYUSB_CONFIG_TARGET "${TINYUSB_CONFIG_TARGET}${TINYUSB_TARGET_SUFFIX}")
endif ()
add_library(${TINYUSB_TARGET} STATIC)
add_tinyusb(${TINYUSB_TARGET})
# Link with tinyusb_config target
if (NOT TARGET ${TINYUSB_CONFIG_TARGET})
message(FATAL_ERROR "${TINYUSB_CONFIG_TARGET} target is not defined")
endif()
target_link_libraries(${TINYUSB_TARGET} PUBLIC
${TINYUSB_CONFIG_TARGET}
)

View File

@ -76,6 +76,8 @@ bool hcd_init(uint8_t rhport)
#endif
// FIXME force full speed, still have issue with Highspeed enumeration
// 1. Have issue when plug/unplug devices, maybe the port is not reset properly
// 2. Also does not seems to detect disconnection
hcd_reg->PORTSC1 |= PORTSC1_FORCE_FULL_SPEED;
return ehci_init(rhport, (uint32_t) &hcd_reg->CAPLENGTH, (uint32_t) &hcd_reg->USBCMD);

View File

@ -79,7 +79,8 @@ typedef struct
ehci_qhd_t qhd_pool[QHD_MAX];
ehci_qtd_t qtd_pool[QTD_MAX] TU_ATTR_ALIGNED(32);
ehci_registers_t* regs;
ehci_registers_t* regs; // operational register
ehci_cap_registers_t* cap_regs; // capability register
volatile uint32_t uframe_number;
}ehci_data_t;
@ -87,6 +88,26 @@ typedef struct
// Periodic frame list must be 4K alignment
CFG_TUH_MEM_SECTION TU_ATTR_ALIGNED(4096) static ehci_data_t ehci_data;
//--------------------------------------------------------------------+
// Debug
//--------------------------------------------------------------------+
#if CFG_TUSB_DEBUG >= EHCI_DBG
static inline void print_portsc(ehci_registers_t* regs)
{
TU_LOG_HEX(EHCI_DBG, regs->portsc);
TU_LOG(EHCI_DBG, " Current Connect Status: %u\r\n", regs->portsc_bm.current_connect_status);
TU_LOG(EHCI_DBG, " Connect Status Change : %u\r\n", regs->portsc_bm.connect_status_change);
TU_LOG(EHCI_DBG, " Port Enabled : %u\r\n", regs->portsc_bm.port_enabled);
TU_LOG(EHCI_DBG, " Port Enabled Change : %u\r\n", regs->portsc_bm.port_enable_change);
TU_LOG(EHCI_DBG, " Port Reset : %u\r\n", regs->portsc_bm.port_reset);
TU_LOG(EHCI_DBG, " Port Power : %u\r\n", regs->portsc_bm.port_power);
}
#else
#define print_portsc(_reg)
#endif
//--------------------------------------------------------------------+
// PROTOTYPE
//--------------------------------------------------------------------+
@ -152,11 +173,11 @@ void hcd_port_reset(uint8_t rhport)
ehci_registers_t* regs = ehci_data.regs;
// regs->portsc_bm.port_enabled = 0; // disable port before reset
// regs->portsc_bm.port_reset = 1;
uint32_t portsc = regs->portsc;
// mask out all change bits since they are Write 1 to clear
uint32_t portsc = regs->portsc & ~EHCI_PORTSC_MASK_CHANGE_ALL;
// EHCI Table 2-16 PortSC
// when software writes Port Reset bit to a one, it must also write a zero to the Port Enable bit.
portsc &= ~(EHCI_PORTSC_MASK_PORT_EANBLED);
portsc |= EHCI_PORTSC_MASK_PORT_RESET;
@ -167,9 +188,14 @@ void hcd_port_reset_end(uint8_t rhport)
{
(void) rhport;
#if 0
#if 0 // TODO check if this is necessary
ehci_registers_t* regs = ehci_data.regs;
regs->portsc_bm.port_reset = 0;
// mask out all change bits since they are Write 1 to clear
uint32_t portsc = regs->portsc & ~EHCI_PORTSC_MASK_CHANGE_ALL;
portsc &= ~(EHCI_PORTSC_MASK_PORT_RESET);
regs->portsc = portsc;
#endif
}
@ -240,19 +266,26 @@ void hcd_device_close(uint8_t rhport, uint8_t dev_addr)
bool ehci_init(uint8_t rhport, uint32_t capability_reg, uint32_t operatial_reg)
{
(void) capability_reg; // not used yet
tu_memclr(&ehci_data, sizeof(ehci_data_t));
ehci_data.regs = (ehci_registers_t*) operatial_reg;
ehci_data.cap_regs = (ehci_cap_registers_t*) capability_reg;
ehci_registers_t* regs = ehci_data.regs;
//------------- CTRLDSSEGMENT Register (skip) -------------//
//------------- USB INT Register -------------//
regs->inten = 0; // 1. disable all the interrupt
regs->status = EHCI_INT_MASK_ALL; // 2. clear all status
// EHCI 4.1 Host Controller Initialization
//------------- CTRLDSSEGMENT Register (skip) -------------//
//------------- USB INT Register -------------//
// disable all the interrupt
regs->inten = 0;
// clear all status except port change since device maybe connected before this driver is initialized
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;
@ -316,7 +349,16 @@ bool ehci_init(uint8_t rhport, uint32_t capability_reg, uint32_t operatial_reg)
FRAMELIST_SIZE_USBCMD_VALUE;
//------------- ConfigFlag Register (skip) -------------//
regs->portsc_bm.port_power = 1; // enable port power
// enable port power bit in portsc. The function of this bit depends on the value of the Port
// Power Control (PPC) field in the HCSPARAMS register.
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_CHANGE_ALL);
portsc |= ECHI_PORTSC_MASK_PORT_POWER;
regs->portsc = portsc;
}
return true;
}
@ -656,26 +698,6 @@ static void xfer_error_isr(uint8_t hostid)
}
}
#if CFG_TUSB_DEBUG >= EHCI_DBG
static inline void print_portsc(ehci_registers_t* regs)
{
TU_LOG_HEX(EHCI_DBG, regs->portsc);
TU_LOG(EHCI_DBG, " Current Connect Status: %u\r\n", regs->portsc_bm.current_connect_status);
TU_LOG(EHCI_DBG, " Connect Status Change : %u\r\n", regs->portsc_bm.connect_status_change);
TU_LOG(EHCI_DBG, " Port Enabled : %u\r\n", regs->portsc_bm.port_enabled);
TU_LOG(EHCI_DBG, " Port Enabled Change : %u\r\n", regs->portsc_bm.port_enable_change);
TU_LOG(EHCI_DBG, " Port Reset : %u\r\n", regs->portsc_bm.port_reset);
TU_LOG(EHCI_DBG, " Port Power : %u\r\n", regs->portsc_bm.port_power);
}
#else
#define print_portsc(_reg)
#endif
//------------- Host Controller Driver's Interrupt Handler -------------//
void hcd_int_handler(uint8_t rhport)
{
@ -695,7 +717,7 @@ void hcd_int_handler(uint8_t rhport)
if (int_status & EHCI_INT_MASK_PORT_CHANGE)
{
uint32_t const port_status = regs->portsc & EHCI_PORTSC_MASK_ALL;
uint32_t const port_status = regs->portsc & EHCI_PORTSC_MASK_CHANGE_ALL;
print_portsc(regs);
if (regs->portsc_bm.connect_status_change)

View File

@ -267,16 +267,15 @@ TU_VERIFY_STATIC( sizeof(ehci_sitd_t) == 32, "size is not correct" );
//--------------------------------------------------------------------+
// EHCI Operational Register
//--------------------------------------------------------------------+
enum ehci_interrupt_mask_{
enum {
EHCI_INT_MASK_USB = TU_BIT(0),
EHCI_INT_MASK_ERROR = TU_BIT(1),
EHCI_INT_MASK_PORT_CHANGE = TU_BIT(2),
EHCI_INT_MASK_FRAMELIST_ROLLOVER = TU_BIT(3),
EHCI_INT_MASK_PCI_HOST_SYSTEM_ERROR = TU_BIT(4),
EHCI_INT_MASK_ASYNC_ADVANCE = TU_BIT(5),
EHCI_INT_MASK_NXP_SOF = TU_BIT(7),
EHCI_INT_MASK_NXP_SOF = TU_BIT(7),
EHCI_INT_MASK_NXP_ASYNC = TU_BIT(18),
EHCI_INT_MASK_NXP_PERIODIC = TU_BIT(19),
@ -287,7 +286,7 @@ enum ehci_interrupt_mask_{
EHCI_INT_MASK_NXP_ASYNC | EHCI_INT_MASK_NXP_PERIODIC
};
enum ehci_usbcmd_pos_ {
enum {
EHCI_USBCMD_POS_RUN_STOP = 0,
EHCI_USBCMD_POS_FRAMELIST_SIZE = 2,
EHCI_USBCMD_POS_PERIOD_ENABLE = 4,
@ -296,24 +295,27 @@ enum ehci_usbcmd_pos_ {
EHCI_USBCMD_POS_INTERRUPT_THRESHOLD = 16
};
enum ehci_portsc_change_mask_{
enum {
EHCI_PORTSC_MASK_CURRENT_CONNECT_STATUS = TU_BIT(0),
EHCI_PORTSC_MASK_CONNECT_STATUS_CHANGE = TU_BIT(1),
EHCI_PORTSC_MASK_PORT_EANBLED = TU_BIT(2),
EHCI_PORTSC_MASK_PORT_ENABLE_CHAGNE = TU_BIT(3),
EHCI_PORTSC_MASK_PORT_ENABLE_CHANGE = TU_BIT(3),
EHCI_PORTSC_MASK_OVER_CURRENT_CHANGE = TU_BIT(5),
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_ALL =
EHCI_PORTSC_MASK_CHANGE_ALL =
EHCI_PORTSC_MASK_CONNECT_STATUS_CHANGE |
EHCI_PORTSC_MASK_PORT_ENABLE_CHAGNE |
EHCI_PORTSC_MASK_PORT_ENABLE_CHANGE |
EHCI_PORTSC_MASK_OVER_CURRENT_CHANGE
};
typedef volatile struct
{
union {
uint32_t command;
uint32_t command; // 0x00
struct {
uint32_t run_stop : 1 ; ///< 1=Run. 0=Stop
@ -333,7 +335,7 @@ typedef volatile struct
};
union {
uint32_t status;
uint32_t status; // 0x04
struct {
uint32_t usb : 1 ; ///< qTD with IOC is retired
@ -357,7 +359,7 @@ typedef volatile struct
};
union{
uint32_t inten;
uint32_t inten; // 0x08
struct {
uint32_t usb : 1 ;
@ -375,44 +377,88 @@ typedef volatile struct
}inten_bm;
};
uint32_t frame_index ; ///< Micro frame counter
uint32_t ctrl_ds_seg ; ///< Control Data Structure Segment
uint32_t periodic_list_base ; ///< Beginning address of perodic frame list
uint32_t async_list_addr ; ///< Address of next async QHD to be executed
uint32_t frame_index ; ///< 0x0C Micro frame counter
uint32_t ctrl_ds_seg ; ///< 0x10 Control Data Structure Segment
uint32_t periodic_list_base ; ///< 0x14 Beginning address of perodic frame list
uint32_t async_list_addr ; ///< 0x18 Address of next async QHD to be executed
uint32_t nxp_tt_control ; ///< nxp embedded transaction translator (reserved by EHCI specs)
uint32_t reserved[8] ;
uint32_t config_flag ; ///< not used by NXP
uint32_t config_flag ; ///< 0x40 not used by NXP
union {
uint32_t portsc ; ///< port status and control
struct {
uint32_t current_connect_status : 1; ///< 0: No device, 1: Device is present on port
uint32_t connect_status_change : 1; ///< Change in Current Connect Status
uint32_t port_enabled : 1; ///< Ports can only be enabled by HC as a part of the reset and enable. SW can write 0 to disable
uint32_t port_enable_change : 1; ///< Port Enabled has changed
uint32_t over_current_active : 1; ///< Port has an over-current condition
uint32_t over_current_change : 1; ///< Change to Over-current Active
uint32_t force_port_resume : 1; ///< Resume detected/driven on port. This functionality defined for manipulating this bit depends on the value of the Suspend bit.
uint32_t suspend : 1; ///< Port in suspend state
uint32_t port_reset : 1; ///< 1=Port is in Reset. 0=Port is not in Reset
uint32_t nxp_highspeed_status : 1; ///< NXP customized: 0=connected to the port is not in High-speed mode, 1=connected to the port is in High-speed mode
uint32_t line_status : 2; ///< D+/D- state: 00: SE0, 10: J-state, 01: K-state
uint32_t port_power : 1; ///< 0= power off, 1= power on
uint32_t port_owner : 1; ///< not used by NXP
uint32_t port_indicator_control : 2; ///< 00b: off, 01b: Amber, 10b: green, 11b: undefined
uint32_t port_test_control : 4; ///< Port test mode, not used by tinyusb
uint32_t wake_on_connect_enable : 1; ///< Enables device connects as wake-up events
uint32_t wake_on_disconnect_enable : 1; ///< Enables device disconnects as wake-up events
uint32_t wake_on_over_current_enable : 1; ///< Enables over-current conditions as wake-up events
uint32_t nxp_phy_clock_disable : 1; ///< NXP customized: the PHY can be put into Low Power Suspend Clock Disable when the downstream device has been put into suspend mode or when no downstream device is connected. Low power suspend is completely under the control of software. 0: enable PHY clock, 1: disable PHY clock
uint32_t nxp_port_force_fullspeed : 1; ///< NXP customized: Writing this bit to a 1 will force the port to only connect at Full Speed. It disables the chirp sequence that allowsthe port to identify itself as High Speed. This is useful for testing FS configurations with a HS host, hub or device.
uint32_t TU_RESERVED : 1;
uint32_t nxp_port_speed : 2; ///< NXP customized: This register field indicates the speed atwhich the port is operating. For HS mode operation in the host controllerand HS/FS operation in the device controller the port routing steers data to the Protocol engine. For FS and LS mode operation in the host controller, the port routing steers data to the Protocol Engine w/ Embedded Transaction Translator. 0x0: Fullspeed, 0x1: Lowspeed, 0x2: Highspeed
// mixed with RW and R/WC bits, care should be taken when writing to this register
uint32_t portsc ; ///< 0x44 port status and control
const struct {
uint32_t current_connect_status : 1; ///< 00: 0: No device, 1: Device is present on port
uint32_t connect_status_change : 1; ///< 01: [R/WC] Change in Current Connect Status
uint32_t port_enabled : 1; ///< 02: Ports can only be enabled by HC as a part of the reset and enable. SW can write 0 to disable
uint32_t port_enable_change : 1; ///< 03: [R/WC] Port Enabled has changed
uint32_t over_current_active : 1; ///< 04: Port has an over-current condition
uint32_t over_current_change : 1; ///< 05: [R/WC] Change to Over-current Active
uint32_t force_port_resume : 1; ///< 06: Resume detected/driven on port. This functionality defined for manipulating this bit depends on the value of the Suspend bit.
uint32_t suspend : 1; ///< 07: Port in suspend state
uint32_t port_reset : 1; ///< 08: 1=Port is in Reset. 0=Port is not in Reset
uint32_t nxp_highspeed_status : 1; ///< 09: NXP customized: 0=connected to the port is not in High-speed mode, 1=connected to the port is in High-speed mode
uint32_t line_status : 2; ///< 10-11: D+/D- state: 00: SE0, 10: J-state, 01: K-state
uint32_t port_power : 1; ///< 12: 0= power off, 1= power on
uint32_t port_owner : 1; ///< 13: not used by NXP
uint32_t port_indicator_control : 2; ///< 14-15: 00b: off, 01b: Amber, 10b: green, 11b: undefined
uint32_t port_test_control : 4; ///< 16-19: Port test mode, not used by tinyusb
uint32_t wake_on_connect_enable : 1; ///< 20: Enables device connects as wake-up events
uint32_t wake_on_disconnect_enable : 1; ///< 21: Enables device disconnects as wake-up events
uint32_t wake_on_over_current_enable : 1; ///< 22: Enables over-current conditions as wake-up events
uint32_t nxp_phy_clock_disable : 1; ///< 23: NXP customized: the PHY can be put into Low Power Suspend Clock Disable when the downstream device has been put into suspend mode or when no downstream device is connected. Low power suspend is completely under the control of software. 0: enable PHY clock, 1: disable PHY clock
uint32_t nxp_port_force_fullspeed : 1; ///< 24: NXP customized: Writing this bit to a 1 will force the port to only connect at Full Speed. It disables the chirp sequence that allowsthe port to identify itself as High Speed. This is useful for testing FS configurations with a HS host, hub or device.
uint32_t TU_RESERVED : 1; ///< 25
uint32_t nxp_port_speed : 2; ///< 26-27: NXP customized: This register field indicates the speed atwhich the port is operating. For HS mode operation in the host controllerand HS/FS operation in the device controller the port routing steers data to the Protocol engine. For FS and LS mode operation in the host controller, the port routing steers data to the Protocol Engine w/ Embedded Transaction Translator. 0x0: Fullspeed, 0x1: Lowspeed, 0x2: Highspeed
uint32_t TU_RESERVED : 4;
}portsc_bm;
};
} ehci_registers_t;
//--------------------------------------------------------------------+
// Capability Registers
//--------------------------------------------------------------------+
typedef volatile struct {
uint8_t caplength; // 0x00
uint8_t TU_RESERVED; // 0x01
uint16_t hciversion; // 0x02
union {
uint32_t hcsparams; // 0x04
struct {
uint32_t num_ports : 4; // [00:03]
uint32_t port_power_control : 1; // [04]
uint32_t TU_RESERVED : 2; // [05:06]
uint32_t port_route_rule : 1; // [07]
uint32_t n_pcc : 4; // [08:11] Number of Ports per Companion Controller
uint32_t n_cc : 4; // [12:15] Number of Companion Controllers
uint32_t port_ind : 1; // [16] Port Indicators
uint32_t TU_RESERVED : 3; // [17:19]
uint32_t n_ptt : 4; // [20:23] ChipIdea: Number of Ports per Transaction Translator
uint32_t n_tt : 4; // [24:27] ChipIdea: Number of Transaction Translators
uint32_t TU_RESERVED : 4; // [28:31]
} hcsparams_bm;
};
union {
uint32_t hccparams; // 0x08
struct {
uint32_t addr_64bit : 1; // [00] 64-bit Addressing Capability
uint32_t programmable_frame_list_flag : 1; // [01] Programmable Frame List Flag
uint32_t async_park_cap : 1; // [02] Asynchronous Schedule Park Capability
uint32_t TU_RESERVED : 1; // [03]
uint32_t iso_schedule_threshold : 4; // [4:7] Isochronous Scheduling Threshold
uint32_t eecp : 8; // [8:15] EHCI Extended Capabilities Pointer
uint32_t TU_RESERVED : 16;// [16:31]
} hccparams_bm;
};
uint32_t hcsp_portroute; // 0x0C HCSP Port Route Register
} ehci_cap_registers_t;
TU_VERIFY_STATIC(sizeof(ehci_cap_registers_t) == 16, "size is not correct");
#ifdef __cplusplus
}
#endif

99
tools/build_cmake.py Normal file
View File

@ -0,0 +1,99 @@
import os
import sys
import time
import subprocess
import pathlib
from multiprocessing import Pool
import build_utils
SUCCEEDED = "\033[32msucceeded\033[0m"
FAILED = "\033[31mfailed\033[0m"
SKIPPED = "\033[33mskipped\033[0m"
build_separator = '-' * 106
make_iar_option = 'CC=iccarm'
def filter_with_input(mylist):
if len(sys.argv) > 1:
input_args = list(set(mylist).intersection(sys.argv))
if len(input_args) > 0:
mylist[:] = input_args
def build_family(family, make_option):
all_boards = []
for entry in os.scandir("hw/bsp/{}/boards".format(family)):
if entry.is_dir() and entry.name != 'pico_sdk':
all_boards.append(entry.name)
all_boards.sort()
# success, failed, skipped
ret = [0, 0, 0]
for board in all_boards:
start_time = time.monotonic()
# Generate build
r = subprocess.run(f"cmake examples -B cmake-build-ci-{board} -G \"Ninja\" -DFAMILY={family} -DBOARD"
f"={board}", shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
# Build
if r.returncode == 0:
r = subprocess.run(f"cmake --build cmake-build-ci-{board}", shell=True, stdout=subprocess.PIPE,
stderr=subprocess.STDOUT)
duration = time.monotonic() - start_time
if r.returncode == 0:
status = SUCCEEDED
ret[0] += 1
else:
status = FAILED
ret[1] += 1
flash_size = "-"
sram_size = "-"
example = 'all'
print(build_utils.build_format.format(example, board, status, "{:.2f}s".format(duration), flash_size, sram_size))
if r.returncode != 0:
# group output in CI
print(f"::group::{board} build error")
print(r.stdout.decode("utf-8"))
print(f"::endgroup::")
return ret
if __name__ == '__main__':
# IAR CC
if make_iar_option not in sys.argv:
make_iar_option = ''
# If family are not specified in arguments, build all
all_families = []
for entry in os.scandir("hw/bsp"):
if entry.is_dir() and os.path.isdir(entry.path + "/boards") and entry.name != 'espressif':
all_families.append(entry.name)
filter_with_input(all_families)
all_families.sort()
print(build_separator)
print(build_utils.build_format.format('Example', 'Board', '\033[39mResult\033[0m', 'Time', 'Flash', 'SRAM'))
total_time = time.monotonic()
# succeeded, failed, skipped
total_result = [0, 0, 0]
for family in all_families:
fret = build_family(family, make_iar_option)
if len(fret) == len(total_result):
total_result = [total_result[i] + fret[i] for i in range(len(fret))]
total_time = time.monotonic() - total_time
print(build_separator)
print("Build Summary: {} {}, {} {}, {} {} and took {:.2f}s".format(total_result[0], SUCCEEDED, total_result[1],
FAILED, total_result[2], SKIPPED, total_time))
print(build_separator)
sys.exit(total_result[1])

View File

@ -41,11 +41,11 @@ if __name__ == '__main__':
# If examples are not specified in arguments, build all
all_examples = []
for dir1 in os.scandir("examples"):
if dir1.is_dir() and 'cmake-build' not in dir1.name:
for entry in os.scandir(dir1.path):
for d in os.scandir("examples"):
if d.is_dir() and 'cmake-build' not in d.name and 'cmake' not in d.name:
for entry in os.scandir(d.path):
if entry.is_dir():
all_examples.append(dir1.name + '/' + entry.name)
all_examples.append(d.name + '/' + entry.name)
filter_with_input(all_examples)
all_examples.sort()